unit emit_MUBUF; {$mode objfpc}{$H+} interface uses sysutils, ps4_shader, ps4_pssl, srConfig, srType, srReg, srLayout, srInput, spirv, emit_fetch, srVBufInfo, emit_vbuf_load, emit_vbuf_store; type TEmit_MUBUF=class(TEmitFetch) procedure emit_MUBUF; procedure make_load_zero(dst:PsrRegSlot;dtype:TsrDataType); procedure make_load_one(dst:PsrRegSlot;dtype:TsrDataType); procedure make_load_comp(dst:PsrRegSlot;dtype:TsrDataType;rsl:TsrRegNode;i:Byte); function emit_BUFFER_LOAD_VA(src:PPsrRegSlot;count:Byte):Boolean; procedure emit_BUFFER_LOAD_FORMAT (count:Byte); procedure emit_BUFFER_STORE_FORMAT(count:Byte); procedure emit_BUFFER_LOAD_DWORDX (count,dfmt:Byte); procedure emit_BUFFER_STORE_DWORDX(count,dfmt:Byte); end; implementation procedure TEmit_MUBUF.make_load_zero(dst:PsrRegSlot;dtype:TsrDataType); begin SetConst_q(dst,dtype,0); end; procedure TEmit_MUBUF.make_load_one(dst:PsrRegSlot;dtype:TsrDataType); begin if (dtype=dtFloat32) then begin SetConst_s(dst,dtype,1); end else begin SetConst_i(dst,dtype,1); end; end; procedure TEmit_MUBUF.make_load_comp(dst:PsrRegSlot;dtype:TsrDataType;rsl:TsrRegNode;i:Byte); begin if rsl.dtype.isVector then begin dst^.New(dtype); OpExtract(line,dst^.current,rsl,i); end else begin Assert(i=0); MakeCopy(dst,rsl); end; end; function TEmit_MUBUF.emit_BUFFER_LOAD_VA(src:PPsrRegSlot;count:Byte):Boolean; var dst:PsrRegSlot; grp:TsrDataLayout; PV:PVSharpResource4; idx:TsrRegNode; rsl:TsrRegNode; inp_idx:TsrInput; info:TBuf_info; elem_res:TsrDataType; elem_vec:TsrDataType; i,d,elem_count:Byte; begin Result:=False; idx:=get_vsrc8(FSPI.MUBUF.VADDR+0)^.current; inp_idx:=GetInputRegNode(idx); if (inp_idx<>nil) then if (inp_idx.itype=itVIndex) then //is input attach begin grp:=GroupingSharp(src,rtVSharp4); PV:=grp.GetSharp; // grp.RINF:=True; // info:=Buf_info(grp, dst_sel(PV^.dst_sel_x, PV^.dst_sel_y, PV^.dst_sel_z, PV^.dst_sel_w), PV^.dfmt, PV^.nfmt, count, FSPI.MUBUF.GLC, FSPI.MUBUF.SLC); elem_res:=info.GetResultType; elem_vec:=elem_res.AsVector(info.GetElemCount); rsl:=AddVertLayout(grp,elem_vec); elem_count:=GetElemCount(PV^.dfmt); For i:=0 to count-1 do begin dst:=get_vdst8(FSPI.MUBUF.VDATA+i); if (dst=nil) then Assert(false); //0=0, 1=1, 4=R, 5=G, 6=B, 7=A Case info.dsel[i] of 0:begin //0 make_load_zero(dst,elem_res); end; 1:begin //1 make_load_one(dst,elem_res); end; 4..7: begin //RGBA d:=info.dsel[i]-4; if (d0) then begin //TODO: FSPI.MUBUF.LDS Assert(false,'TODO: FSPI.MUBUF.LDS'); end; if Config.UseVertexInput then if (FExecutionModel=ExecutionModel.Vertex) then //Vertex only if (FSPI.MUBUF.IDXEN=1) and (FSPI.MUBUF.OFFEN=0) and (FSPI.MUBUF.SOFFSET=128) and (FSPI.MUBUF.LDS=0) then begin if emit_BUFFER_LOAD_VA(@src,count) then Exit; end; grp:=GroupingSharp(@src,rtVSharp4); PV:=grp.GetSharp; // grp.RINF:=True; // TEmit_vbuf_load(TObject(Self)).buf_load( Buf_info(grp, dst_sel(PV^.dst_sel_x, PV^.dst_sel_y, PV^.dst_sel_z, PV^.dst_sel_w), PV^.dfmt, PV^.nfmt, count, FSPI.MUBUF.GLC, FSPI.MUBUF.SLC) ); end; procedure TEmit_MUBUF.emit_BUFFER_STORE_FORMAT(count:Byte); var src:array[0..3] of PsrRegSlot; grp:TsrDataLayout; PV:PVSharpResource4; begin if not get_srsrc(FSPI.MUBUF.SRSRC,4,@src) then Assert(false); if (FSPI.MUBUF.LDS<>0) then begin //TODO: FSPI.MUBUF.LDS Assert(false,'TODO: FSPI.MUBUF.LDS'); end; grp:=GroupingSharp(@src,rtVSharp4); PV:=grp.GetSharp; // grp.RINF:=True; // TEmit_vbuf_store(TObject(Self)).buf_store( Buf_info(grp, dst_sel(PV^.dst_sel_x, PV^.dst_sel_y, PV^.dst_sel_z, PV^.dst_sel_w), PV^.dfmt, PV^.nfmt, count, FSPI.MUBUF.GLC, FSPI.MUBUF.SLC) ); end; procedure TEmit_MUBUF.emit_BUFFER_LOAD_DWORDX(count,dfmt:Byte); var src:array[0..3] of PsrRegSlot; grp:TsrDataLayout; PV:PVSharpResource4; begin if not get_srsrc(FSPI.MUBUF.SRSRC,4,@src) then Assert(false); if (FSPI.MUBUF.LDS<>0) then begin //TODO: FSPI.MUBUF.LDS Assert(false,'TODO: FSPI.MUBUF.LDS'); end; grp:=GroupingSharp(@src,rtVSharp4); PV:=grp.GetSharp; TEmit_vbuf_load(TObject(Self)).buf_load( Buf_info(grp, dst_sel_identity, dfmt, //PV^.nfmt, BUF_NUM_FORMAT_FLOAT, count, FSPI.MUBUF.GLC, FSPI.MUBUF.SLC) ); end; procedure TEmit_MUBUF.emit_BUFFER_STORE_DWORDX(count,dfmt:Byte); var src:array[0..3] of PsrRegSlot; grp:TsrDataLayout; PV:PVSharpResource4; begin if not get_srsrc(FSPI.MUBUF.SRSRC,4,@src) then Assert(false); if (FSPI.MUBUF.LDS<>0) then begin //TODO: FSPI.MUBUF.LDS Assert(false,'TODO: FSPI.MUBUF.LDS'); end; grp:=GroupingSharp(@src,rtVSharp4); PV:=grp.GetSharp; TEmit_vbuf_store(TObject(Self)).buf_store( Buf_info(grp, dst_sel_identity, dfmt, //PV^.nfmt, BUF_NUM_FORMAT_FLOAT, count, FSPI.MUBUF.GLC, FSPI.MUBUF.SLC) ); end; procedure TEmit_MUBUF.emit_MUBUF; begin case FSPI.MUBUF.OP of BUFFER_LOAD_FORMAT_X : emit_BUFFER_LOAD_FORMAT(1); BUFFER_LOAD_FORMAT_XY : emit_BUFFER_LOAD_FORMAT(2); BUFFER_LOAD_FORMAT_XYZ : emit_BUFFER_LOAD_FORMAT(3); BUFFER_LOAD_FORMAT_XYZW : emit_BUFFER_LOAD_FORMAT(4); BUFFER_STORE_FORMAT_X : emit_BUFFER_STORE_FORMAT(1); BUFFER_STORE_FORMAT_XY : emit_BUFFER_STORE_FORMAT(2); BUFFER_STORE_FORMAT_XYZ : emit_BUFFER_STORE_FORMAT(3); BUFFER_STORE_FORMAT_XYZW: emit_BUFFER_STORE_FORMAT(4); BUFFER_LOAD_DWORD : emit_BUFFER_LOAD_DWORDX(1,BUF_DATA_FORMAT_32); BUFFER_LOAD_DWORDX2 : emit_BUFFER_LOAD_DWORDX(2,BUF_DATA_FORMAT_32_32); BUFFER_LOAD_DWORDX3 : emit_BUFFER_LOAD_DWORDX(3,BUF_DATA_FORMAT_32_32_32); BUFFER_LOAD_DWORDX4 : emit_BUFFER_LOAD_DWORDX(4,BUF_DATA_FORMAT_32_32_32_32); BUFFER_STORE_DWORD : emit_BUFFER_STORE_DWORDX(1,BUF_DATA_FORMAT_32); BUFFER_STORE_DWORDX2 : emit_BUFFER_STORE_DWORDX(2,BUF_DATA_FORMAT_32_32); BUFFER_STORE_DWORDX3 : emit_BUFFER_STORE_DWORDX(3,BUF_DATA_FORMAT_32_32_32); BUFFER_STORE_DWORDX4 : emit_BUFFER_STORE_DWORDX(4,BUF_DATA_FORMAT_32_32_32_32); else Assert(false,'MUBUF?'+IntToStr(FSPI.MUBUF.OP)+' '+get_str_spi(FSPI)); end; end; end.