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:PsrRegNode;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:PsrRegNode;i:Byte); begin if rsl^.dtype.isVector then begin dst^.New(line,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:PsrDataLayout; PV:PVSharpResource4; idx:PsrRegNode; rsl:PsrRegNode; inp_idx:PsrInput; 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^.pData; 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); 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 (d