FPPS4/spirv/emit_vbuf_load.pas

330 lines
6.2 KiB
Plaintext
Raw Normal View History

2022-05-31 07:17:14 +00:00
unit emit_vbuf_load;
{$mode ObjFPC}{$H+}
interface
uses
sysutils,
ps4_pssl,
2022-09-05 13:30:24 +00:00
srType,
2022-05-31 07:17:14 +00:00
srReg,
srLayout,
2022-09-05 13:30:24 +00:00
emit_fetch,
2022-05-31 07:17:14 +00:00
srVBufInfo,
emit_vbuf_chain;
type
Tload_cache=record
info:TBuf_info;
v:TvarChain;
dst:PsrRegSlot;
elem_orig:TsrDataType;
elem_resl:TsrDataType;
elem_count:ptruint;
rsl:PsrRegNode;
elm:array[0..3] of PsrRegNode;
end;
2022-09-05 13:30:24 +00:00
TEmit_vbuf_load=class(TEmitFetch)
2022-05-31 07:17:14 +00:00
procedure buf_load(info:TBuf_info);
2022-09-05 13:30:24 +00:00
function convert_e(var lc:Tload_cache;src:PsrRegNode):PsrRegNode;
procedure make_load_cv_id(var lc:Tload_cache;i:Byte);
procedure make_load_ce_id(var lc:Tload_cache;i:Byte);
procedure make_load_uv_id(var lc:Tload_cache;i:Byte);
procedure make_load_ue_id(var lc:Tload_cache;i:Byte);
procedure make_load_zero(var lc:Tload_cache);
procedure make_load_one(var lc:Tload_cache);
2022-05-31 07:17:14 +00:00
procedure buf_load_cv(info:TBuf_info;v:TvarChain);
end;
implementation
procedure TEmit_vbuf_load.buf_load(info:TBuf_info);
var
v:TvarChain;
begin
2022-09-05 13:30:24 +00:00
v:=TEmit_vbuf_chain(TObject(Self)).get_chain(info);
2022-05-31 07:17:14 +00:00
if (v.vType=vcUniformVector) then
begin
//reset dst sel
info.dsel:=dst_sel_identity;
end;
buf_load_cv(info,v);
end;
2022-09-05 13:30:24 +00:00
function TEmit_vbuf_load.convert_e(var lc:Tload_cache;src:PsrRegNode):PsrRegNode;
2022-05-31 07:17:14 +00:00
begin
Result:=src;
if (lc.elem_resl<>lc.elem_orig) then
Case lc.info.NFMT of
BUF_NUM_FORMAT_UNORM : //Unsigned, normalized to range [0.0..1.0]; data/(1<<nbits-1)
begin
2022-09-05 13:30:24 +00:00
Result:=OpUToF(src,dtFloat32);
Result:=OpFMulToS(Result,1/lc.elem_orig.High);
2022-05-31 07:17:14 +00:00
end;
BUF_NUM_FORMAT_SNORM : //Signed, normalized to range [-1.0..1.0]; data/(1<<(nbits-1)-1) clamped
begin
2022-09-05 13:30:24 +00:00
Result:=OpSToF(src,dtFloat32);
Result:=OpFMulToS(Result,1/(lc.elem_orig.High shr 1));
Result:=OpFAddToS(Result,-1);
2022-05-31 07:17:14 +00:00
end;
BUF_NUM_FORMAT_USCALED : //Unsigned integer to float [0.0 .. (1<<nbits)-1]
begin
2022-09-05 13:30:24 +00:00
Result:=OpUToF(src,dtFloat32);
2022-05-31 07:17:14 +00:00
end;
BUF_NUM_FORMAT_SSCALED : //Signed integer to float [-(1<<(nbits-1)) ..(1<<(nbits-1))-1]
begin
2022-09-05 13:30:24 +00:00
Result:=OpSToF(src,dtFloat32);
2022-05-31 07:17:14 +00:00
end;
BUF_NUM_FORMAT_SNORM_NZ: //Signed, normalized to range [-1.0..1.0]; (data*2+1)/(1<<nbits-1)
begin
if (lc.info.GetElemSize=4) then
begin
2022-09-05 13:30:24 +00:00
Result:=OpSToF(src,dtFloat32);
Result:=OpFMulToS(Result,2);
Result:=OpFAddToS(Result,1);
Result:=OpFMulToS(Result,1/lc.elem_orig.High);
2022-05-31 07:17:14 +00:00
end else
begin
2022-09-05 13:30:24 +00:00
Result:=OpShlTo(src,1);
Result:=OpIAddTo(Result,1);
Result:=OpSToF(Result,dtFloat32);
Result:=OpFMulToS(Result,1/lc.elem_orig.High);
2022-05-31 07:17:14 +00:00
end;
end;
BUF_NUM_FORMAT_UINT :
begin
2022-09-05 13:30:24 +00:00
Result:=OpUToU(src,lc.elem_resl);
2022-05-31 07:17:14 +00:00
end;
BUF_NUM_FORMAT_SINT :
begin
2022-09-05 13:30:24 +00:00
Result:=OpSToS(src,lc.elem_resl);
2022-05-31 07:17:14 +00:00
end;
BUF_NUM_FORMAT_FLOAT :
begin
2022-09-05 13:30:24 +00:00
Result:=OpFToF(src,lc.elem_resl);
2022-05-31 07:17:14 +00:00
end;
end;
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_vbuf_load.make_load_cv_id(var lc:Tload_cache;i:Byte);
2022-05-31 07:17:14 +00:00
var
rsl:PsrRegNode;
begin
rsl:=lc.rsl;
if (rsl=nil) then
begin
2022-09-05 13:30:24 +00:00
rsl:=FetchLoad(lc.v.data[0],lc.elem_orig.AsVector(lc.elem_count));
2022-05-31 07:17:14 +00:00
lc.rsl:=rsl;
end;
if (lc.elm[i]=nil) then
begin
if (lc.elem_count=1) then
begin
2022-09-05 13:30:24 +00:00
rsl:=convert_e(lc,rsl);
2022-05-31 07:17:14 +00:00
lc.elm[i]:=rsl;
end else
begin
lc.elm[i]:=NewReg(lc.elem_orig);
2022-09-05 13:30:24 +00:00
OpExtract(line,lc.elm[i],rsl,i);
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
lc.elm[i]:=convert_e(lc,lc.elm[i]);
2022-05-31 07:17:14 +00:00
end;
end;
MakeCopy(lc.dst,lc.elm[i]);
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_vbuf_load.make_load_ce_id(var lc:Tload_cache;i:Byte);
2022-05-31 07:17:14 +00:00
var
orig,elm:PsrChain;
sum_d:PsrRegNode;
2022-09-05 13:30:24 +00:00
lvl_0:TsrChainLvl_0;
lvl_1:TsrChainLvl_1;
2022-05-31 07:17:14 +00:00
rsl:PsrRegNode;
begin
if (lc.elm[i]=nil) then
begin
orig:=lc.v.data[0];
2022-09-05 13:30:24 +00:00
sum_d:=orig^.pIndex;
2022-05-31 07:17:14 +00:00
if (i=0) then
begin
elm:=orig;
end else
begin
2022-09-05 13:30:24 +00:00
sum_d:=OpIAddTo(sum_d,i);
lvl_0.offset:=0;
lvl_0.size :=orig^.size;
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
lvl_1.pIndex:=sum_d;
lvl_1.stride:=orig^.stride;
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
elm:=lc.info.grp^.Fetch(@lvl_0,@lvl_1);
2022-05-31 07:17:14 +00:00
end;
rsl:=FetchLoad(elm,lc.elem_orig);
2022-09-05 13:30:24 +00:00
rsl:=convert_e(lc,rsl);
2022-05-31 07:17:14 +00:00
lc.elm[i]:=rsl;
end;
MakeCopy(lc.dst,lc.elm[i]);
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_vbuf_load.make_load_uv_id(var lc:Tload_cache;i:Byte);
2022-05-31 07:17:14 +00:00
var
rsl,idx:PsrRegNode;
begin
rsl:=lc.rsl;
if (rsl=nil) then
begin
2022-09-05 13:30:24 +00:00
rsl:=NewReg(lc.elem_resl.AsVector(4));
2022-05-31 07:17:14 +00:00
idx:=lc.v.data[1];
2022-09-05 13:30:24 +00:00
OpImageRead(line,lc.v.data[0],rsl,idx);
2022-05-31 07:17:14 +00:00
lc.rsl:=rsl;
end;
if (lc.elm[i]=nil) then
begin
lc.dst^.New(line,lc.elem_resl);
2022-09-05 13:30:24 +00:00
OpExtract(line,lc.dst^.current,rsl,i);
2022-05-31 07:17:14 +00:00
lc.elm[i]:=lc.dst^.current;
end else
begin
MakeCopy(lc.dst,lc.elm[i]);
end;
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_vbuf_load.make_load_ue_id(var lc:Tload_cache;i:Byte);
2022-05-31 07:17:14 +00:00
var
rsl,idx,sum_d:PsrRegNode;
begin
if (lc.elm[i]=nil) then
begin
idx:=lc.v.data[1];
if (i=0) then
begin
sum_d:=idx;
end else
begin
2022-09-05 13:30:24 +00:00
sum_d:=OpIAddTo(idx,i);
2022-05-31 07:17:14 +00:00
end;
rsl:=lc.dst^.New(line,lc.elem_resl);
2022-09-05 13:30:24 +00:00
OpImageRead(line,lc.v.data[0],rsl,sum_d);
2022-05-31 07:17:14 +00:00
lc.elm[i]:=rsl;
end else
begin
MakeCopy(lc.dst,lc.elm[i]);
end;
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_vbuf_load.make_load_zero(var lc:Tload_cache);
2022-05-31 07:17:14 +00:00
begin
2022-09-05 13:30:24 +00:00
SetConst_i(lc.dst,lc.elem_resl,0);
2022-05-31 07:17:14 +00:00
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_vbuf_load.make_load_one(var lc:Tload_cache);
2022-05-31 07:17:14 +00:00
begin
if (lc.elem_resl=dtFloat32) then
begin
2022-09-05 13:30:24 +00:00
SetConst_s(lc.dst,lc.elem_resl,1);
2022-05-31 07:17:14 +00:00
end else
begin
2022-09-05 13:30:24 +00:00
SetConst_i(lc.dst,lc.elem_resl,1);
2022-05-31 07:17:14 +00:00
end;
end;
procedure TEmit_vbuf_load.buf_load_cv(info:TBuf_info;v:TvarChain);
var
lc:Tload_cache;
i,d,count:Byte;
begin
if info.IsExtFormat then Assert(false,'TODO');
lc:=Default(Tload_cache);
lc.info :=info;
lc.v :=v;
lc.elem_resl :=info.GetResultType;
lc.elem_orig :=info.GetElemType;
lc.elem_count:=info.GetElemCount;
count:=info.count;
For i:=0 to count-1 do
begin
2022-09-05 13:30:24 +00:00
lc.dst:=get_vdst8(FSPI.MUBUF.VDATA+i);
2022-05-31 07:17:14 +00:00
if (lc.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
2022-09-05 13:30:24 +00:00
make_load_zero(lc);
2022-05-31 07:17:14 +00:00
end;
1:begin //1
2022-09-05 13:30:24 +00:00
make_load_one(lc);
2022-05-31 07:17:14 +00:00
end;
4..7:
begin //RGBA
d:=info.dsel[i]-4;
if (d<lc.elem_count) then
begin
Case v.vType of
2022-09-05 13:30:24 +00:00
vcInvalid :make_load_zero(lc);
vcChainVector :make_load_cv_id(lc,d);
vcChainElement :make_load_ce_id(lc,d);
vcUniformVector :make_load_uv_id(lc,d);
vcUniformElement:make_load_ue_id(lc,d);
2022-05-31 07:17:14 +00:00
end;
end else
begin //as zero
2022-09-05 13:30:24 +00:00
make_load_zero(lc);
2022-05-31 07:17:14 +00:00
end;
end;
else
begin //as zero
2022-09-05 13:30:24 +00:00
make_load_zero(lc);
2022-05-31 07:17:14 +00:00
end;
end;
end;
end;
end.