FPPS4/vulkan/vImageTiling.pas

878 lines
22 KiB
Plaintext

unit vImageTiling;
{$mode objfpc}{$H+}
interface
uses
SysUtils,
ps4_tiling,
Vulkan,
vDevice,
vMemory,
vBuffer,
vImage,
vImageManager,
vHostBufferManager,
vCmdBuffer;
procedure pm4_load_from (cmd:TvCustomCmdBuffer;image:TvCustomImage2;IMAGE_USAGE:Byte);
procedure pm4_write_back(cmd:TvCustomCmdBuffer;image:TvCustomImage2);
Function get_image_size(const key:TvImageKey):Ptruint;
implementation
Function GetLinearAlignWidth(bpp,width:Ptruint):Ptruint; inline;
var
align_m:Ptruint;
begin
align_m:=(64 div bpp)-1;
Result:=(width+align_m) and (not align_m);
end;
function Max(a,b:Ptruint):Ptruint; inline;
begin
if (a>b) then Result:=a else Result:=b;
end;
Function GetLinearSize(const key:TvImageKey;align:Boolean):Ptruint;
var
m_bytePerElement:Ptruint;
m_level,m_width,m_height:Ptruint;
m_padwidth,m_padheight:Ptruint;
m_slice:Ptruint;
begin
Assert(key.params.samples<=1,'key.params.samples>1');
m_bytePerElement:=getFormatSize(key.cformat);
m_level :=key.params.mipLevels;
m_width :=key.params.width;
m_height:=key.params.height;
Result:=0;
while (m_level>0) do
begin
m_padwidth :=m_width;
m_padheight:=m_height;
if align then
begin
m_padwidth:=GetLinearAlignWidth(m_bytePerElement,m_padwidth);
end;
if IsTexelFormat(key.cformat) then
begin
m_padwidth :=(m_padwidth +3) shr 2;
m_padheight:=(m_padheight+3) shr 2;
end;
m_slice:=m_padwidth*
m_padheight*
m_bytePerElement;
//m_slice:=(m_slice+255) and (not Ptruint(255));
Result:=Result+m_slice;
Dec(m_level);
m_width :=Max(1,m_width shr 1);
m_height:=Max(1,m_height shr 1);
end;
Result:=Result*
key.params.depth*
key.params.arrayLayers;
end;
Function GetLinearAlignSize(const key:TvImageKey):Ptruint;
begin
Result:=GetLinearSize(key,true);
end;
Function Get1dThinAlignWidth(bpp,width:Ptruint):Ptruint; inline;
var
align_m:Ptruint;
begin
align_m:=(32 div bpp)-1;
Result:=(width+align_m) and (not align_m);
end;
Function Get1dThinSize(const key:TvImageKey):Ptruint;
var
m_bytePerElement:Ptruint;
m_level,m_width,m_height:Ptruint;
m_padwidth,m_padheight:Ptruint;
m_slice:Ptruint;
begin
Assert(key.params.samples<=1,'key.params.samples>1');
m_bytePerElement:=getFormatSize(key.cformat);
m_level :=key.params.mipLevels;
m_width :=key.params.width;
m_height:=key.params.height;
Result:=0;
while (m_level>0) do
begin
m_padwidth :=Get1dThinAlignWidth(m_bytePerElement,m_width);
m_padheight:=(m_height+7) and (not 7);
if IsTexelFormat(key.cformat) then
begin
m_padwidth :=(m_padwidth +3) shr 2;
m_padheight:=(m_padheight+3) shr 2;
end;
m_slice:=m_padwidth*
m_padheight*
m_bytePerElement;
//m_slice:=(m_slice+255) and (not Ptruint(255));
Result:=Result+m_slice;
Dec(m_level);
m_width :=Max(1,m_width shr 1);
m_height:=Max(1,m_height shr 1);
end;
//Result:=(Result+255) and (not Ptruint(255));
Result:=Result*
key.params.depth*
key.params.arrayLayers;
end;
function AlignDw(addr:PtrUInt;alignment:PtrUInt):PtrUInt; inline;
begin
Result:=addr-(addr mod alignment);
end;
type
TvTempBuffer=class(TvBuffer)
procedure ReleaseTmp(Sender:TObject); register;
end;
procedure TvTempBuffer.ReleaseTmp(Sender:TObject); register;
begin
Release(nil);
Free;
end;
procedure load_clear(cmd:TvCustomCmdBuffer;image:TvCustomImage2);
var
Color:TVkClearColorValue;
DepthStencil:TVkClearDepthStencilValue;
Range:TVkImageSubresourceRange;
begin
image.PushBarrier(cmd,
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
case image.key.cformat of
//stencil
VK_FORMAT_S8_UINT,
//depth
VK_FORMAT_D16_UNORM,
VK_FORMAT_X8_D24_UNORM_PACK32,
VK_FORMAT_D32_SFLOAT,
//depth stencil
VK_FORMAT_D16_UNORM_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D32_SFLOAT_S8_UINT:
begin
DepthStencil:=Default(TVkClearDepthStencilValue);
Range:=image.GetSubresRange;
{
vkCmdClearDepthStencilImage(cmd.FCmdbuf,
image.FHandle,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
@DepthStencil,
1,
@Range);}
end;
else
begin
Color:=Default(TVkClearColorValue);
Range:=image.GetSubresRange;
{
vkCmdClearColorImage(cmd.FCmdbuf,
image.FHandle,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
@Color,
1,
@Range);}
end;
end;
end;
type
TTGAHeader=packed record
idlength :Byte;
colourmaptype :Byte;
datatypecode :Byte;
colourmaporigin:Word;
colourmaplength:Word;
colourmapdepth :Byte;
x_origin :Word;
y_origin :Word;
width :Word;
height :Word;
bitsperpixel :Byte;
imagedescriptor:Byte;
end;
Procedure SaveToTGA(const name:RawByteString;pData:Pointer;width,height,bpp:Ptruint);
var
F:THandle;
Header:TTGAHeader;
slice:Ptruint;
begin
slice:=(width*height*bpp+7) div 8;
Header:=Default(TTGAHeader);
Header.datatypecode :=3;
Header.width :=width;
Header.height :=height;
Header.bitsperpixel :=bpp;
Header.imagedescriptor:=32;
F:=FileCreate(name);
FileWrite(F,Header,SizeOf(TTGAHeader));
FileWrite(F,pData^,slice);
FileClose(F);
end;
Procedure copy_1dThin(var tiler:Tiler1d;src,dst:Pointer);
var
m_bytePerElement:Ptruint;
m_slice_size:Ptruint;
i,x,y,z:QWORD;
pSrc,pDst:Pointer;
begin
m_bytePerElement:=tiler.m_bitsPerElement div 8;
m_slice_size:=(tiler.m_linearWidth*tiler.m_linearHeight);
//
For z:=0 to tiler.m_linearDepth-1 do
For y:=0 to tiler.m_linearHeight-1 do
For x:=0 to tiler.m_linearWidth-1 do
begin
i:=0;
tiler.getTiledElementByteOffset(i,x,y,z);
pSrc:=@PByte(src)[i];
pDst:=@PByte(dst)[(z*m_slice_size+y*tiler.m_linearWidth+x)*m_bytePerElement];
Move(pSrc^,pDst^,m_bytePerElement);
end;
end;
Procedure _Copy_Linear(cmd:TvCustomCmdBuffer;buf:TvTempBuffer;image:TvCustomImage2);
var
BufferImageCopy:TVkBufferImageCopy;
size:Ptruint;
BufferImageCopyA:array of TVkBufferImageCopy;
m_bytePerElement:Ptruint;
m_level,m_width,m_height:Ptruint;
m_padwidth,m_padheight:Ptruint;
m_slice :Ptruint;
m_offset:Ptruint;
a,d,b:Ptruint;
begin
cmd.AddDependence(@buf.ReleaseTmp);
m_bytePerElement:=getFormatSize(image.key.cformat);
size:=GetLinearSize(image.key,false);
image.PushBarrier(cmd,
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
cmd.BufferMemoryBarrier(buf.FHandle,
ord(VK_ACCESS_SHADER_WRITE_BIT),
ord(VK_ACCESS_MEMORY_READ_BIT),
0,size,
ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
ord(VK_PIPELINE_STAGE_TRANSFER_BIT)
);
BufferImageCopy:=Default(TVkBufferImageCopy);
BufferImageCopy.imageSubresource:=image.GetSubresLayer;
BufferImageCopy.imageSubresource.layerCount:=1;
BufferImageCopy.imageExtent.depth:=1;
BufferImageCopyA:=nil;
SetLength(BufferImageCopyA,image.key.params.arrayLayers*image.key.params.depth*image.key.params.mipLevels);
b:=0;
m_offset:=0;
for a:=0 to image.key.params.arrayLayers-1 do
for d:=0 to image.key.params.depth-1 do
begin
BufferImageCopy.imageSubresource.baseArrayLayer:=a;
BufferImageCopy.imageOffset.z:=d;
m_level :=image.key.params.mipLevels;
m_width :=image.key.params.width;
m_height:=image.key.params.height;
while (m_level>0) do
begin
Assert((m_offset and 3)=0,'align by 4');
BufferImageCopy.bufferOffset:=m_offset;
BufferImageCopy.imageSubresource.mipLevel:=image.key.params.mipLevels-m_level;
BufferImageCopy.imageExtent.width :=m_width;
BufferImageCopy.imageExtent.height:=m_height;
BufferImageCopyA[b]:=BufferImageCopy;
Inc(b);
if IsTexelFormat(image.key.cformat) then
begin
m_padwidth :=(m_width +3) shr 2;
m_padheight:=(m_height+3) shr 2;
end else
begin
m_padwidth :=m_width ;
m_padheight:=m_height;
end;
m_slice:=m_padwidth*m_padheight*m_bytePerElement;
m_offset:=m_offset+m_slice;
Dec(m_level);
m_width :=Max(1,m_width shr 1);
m_height:=Max(1,m_height shr 1);
end;
end;
cmd.CopyBufferToImage(buf.FHandle,
image.FHandle,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
Length(BufferImageCopyA),
@BufferImageCopyA[0]);
end;
Procedure load_1dThin(cmd:TvCustomCmdBuffer;image:TvCustomImage2);
var
buf:TvTempBuffer;
vmem:TvPointer;
tiler:Tiler1d;
m_bytePerElement:Ptruint;
m_level,m_width,m_height:Ptruint;
//m_padwidth,m_padheight:Ptruint;
//m_slice:Ptruint;
m_full_linear_size:Ptruint;
m_base:Pointer;
src:Pointer;
dst:Pointer;
begin
Assert(image.key.params.samples<=1,'image.key.params.samples>1');
m_full_linear_size:=GetLinearSize(image.key,False);
//m_base:=GetMem(m_full_linear_size);
buf:=TvTempBuffer.Create(m_full_linear_size,ord(VK_BUFFER_USAGE_TRANSFER_SRC_BIT),nil);
vmem:=MemManager.FetchMemory(buf.GetRequirements,V_PROP_HOST_VISIBLE or V_PROP_DEVICE_LOCAL);
if (vmem.FMemory=nil) then
begin
vmem:=MemManager.FetchMemory(buf.GetRequirements,V_PROP_HOST_VISIBLE);
end;
buf.BindMem(vmem);
//Release ref in ReleaseTmp
m_base:=nil;
vkMapMemory(Device.FHandle,
buf.FBind.FMemory.FHandle,
buf.FBind.FOffset,
m_full_linear_size,
0,
@m_base);
dst:=m_base;
m_bytePerElement:=getFormatSize(image.key.cformat);
tiler.init_surface(m_bytePerElement,
ord(IsTexelFormat(image.key.cformat)),
image.key.params.tiling.idx,
image.key.params.tiling.alt);
//TvBuffer
m_level :=image.key.params.mipLevels;
m_width :=image.key.params.width;
m_height:=image.key.params.height;
src:=image.key.addr;
while (m_level>0) do
begin
tiler.init_size_2d(m_width,m_height);
//
if (ptruint(dst-m_base)+tiler.m_linearSizeBytes)>m_full_linear_size then
begin
Writeln(ptruint(dst-m_base)+tiler.m_linearSizeBytes,'>',m_full_linear_size);
Assert(false);
end;
copy_1dThin(tiler,src,dst);
{
SaveToTGA('shader_dump\texture_mip'+IntToStr(m_level)+
'_'+IntToStr(m_width)+
'x'+IntToStr(m_height)+
'.tga',
dst,
tiler.m_linearWidth,
tiler.m_linearHeight,
tiler.m_bitsPerElement);
}
src:=src+tiler.m_tiledSizeBytes;
dst:=dst+tiler.m_linearSizeBytes;
Dec(m_level);
m_width :=Max(1,m_width shr 1);
m_height:=Max(1,m_height shr 1);
end;
vkUnmapMemory(Device.FHandle,buf.FBind.FMemory.FHandle);
//FreeMem(m_base);
_Copy_Linear(cmd,buf,image);
end;
Procedure Load_Linear(cmd:TvCustomCmdBuffer;image:TvCustomImage2);
var
buf:TvHostBuffer;
BufferImageCopy:TVkBufferImageCopy;
size:Ptruint;
BufferImageCopyA:array of TVkBufferImageCopy;
m_bytePerElement:Ptruint;
m_level,m_width,m_height:Ptruint;
m_padwidth,m_padheight:Ptruint;
m_slice :Ptruint;
m_offset:Ptruint;
a,d,b:Ptruint;
begin
m_bytePerElement:=getFormatSize(image.key.cformat);
size:=GetLinearSize(image.key,(image.key.params.tiling.idx<>kTileModeDisplay_LinearGeneral));
buf:=FetchHostBuffer(cmd,
QWORD(image.key.addr),
size,
ord(VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
m_offset:=buf.FAddr-QWORD(image.key.addr);
image.PushBarrier(cmd,
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
cmd.BufferMemoryBarrier(buf.FHandle,
ord(VK_ACCESS_SHADER_WRITE_BIT),
ord(VK_ACCESS_MEMORY_READ_BIT),
m_offset,
size,
ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
ord(VK_PIPELINE_STAGE_TRANSFER_BIT)
);
BufferImageCopy:=Default(TVkBufferImageCopy);
BufferImageCopy.imageSubresource:=image.GetSubresLayer;
BufferImageCopy.imageSubresource.layerCount:=1;
BufferImageCopy.imageExtent.depth:=1;
BufferImageCopyA:=nil;
SetLength(BufferImageCopyA,image.key.params.arrayLayers*image.key.params.depth*image.key.params.mipLevels);
b:=0;
for a:=0 to image.key.params.arrayLayers-1 do
for d:=0 to image.key.params.depth-1 do
begin
BufferImageCopy.imageSubresource.baseArrayLayer:=a;
BufferImageCopy.imageOffset.z:=d;
m_level :=image.key.params.mipLevels;
m_width :=image.key.params.width;
m_height:=image.key.params.height;
while (m_level>0) do
begin
Assert((m_offset and 3)=0,'align by 4');
BufferImageCopy.bufferOffset:=m_offset;
BufferImageCopy.imageSubresource.mipLevel:=image.key.params.mipLevels-m_level;
BufferImageCopy.imageExtent.width :=m_width;
BufferImageCopy.imageExtent.height:=m_height;
if (image.key.params.tiling.idx=8) then
begin
BufferImageCopy.bufferRowLength:=GetLinearAlignWidth(m_bytePerElement,m_width);
end;
BufferImageCopyA[b]:=BufferImageCopy;
Inc(b);
if IsTexelFormat(image.key.cformat) then
begin
m_padwidth :=(m_width +3) shr 2;
m_padheight:=(m_height+3) shr 2;
end else
begin
m_padwidth :=m_width ;
m_padheight:=m_height;
end;
m_slice:=m_padwidth*m_padheight*m_bytePerElement;
m_offset:=m_offset+m_slice;
Dec(m_level);
m_width :=Max(1,m_width shr 1);
m_height:=Max(1,m_height shr 1);
end;
end;
cmd.CopyBufferToImage(buf.FHandle,
image.FHandle,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
Length(BufferImageCopyA),
@BufferImageCopyA[0]);
end;
Procedure Writeback_Linear(cmd:TvCustomCmdBuffer;image:TvCustomImage2);
var
buf:TvHostBuffer;
BufferImageCopy:TVkBufferImageCopy;
size:Ptruint;
BufferImageCopyA:array of TVkBufferImageCopy;
m_bytePerElement:Ptruint;
m_level,m_width,m_height:Ptruint;
m_padwidth,m_padheight:Ptruint;
m_slice :Ptruint;
m_offset:Ptruint;
a,d,b:Ptruint;
begin
m_bytePerElement:=getFormatSize(image.key.cformat);
size:=GetLinearSize(image.key,(image.key.params.tiling.idx<>kTileModeDisplay_LinearGeneral));
buf:=FetchHostBuffer(cmd,
QWORD(image.key.addr),
size,
ord(VK_BUFFER_USAGE_TRANSFER_DST_BIT));
m_offset:=buf.FAddr-QWORD(image.key.addr);
image.PushBarrier(cmd,
ord(VK_ACCESS_TRANSFER_READ_BIT),
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
cmd.BufferMemoryBarrier(buf.FHandle,
ord(VK_ACCESS_MEMORY_READ_BIT),
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
m_offset,
size,
ord(VK_PIPELINE_STAGE_HOST_BIT),
ord(VK_PIPELINE_STAGE_TRANSFER_BIT)
);
BufferImageCopy:=Default(TVkBufferImageCopy);
BufferImageCopy.imageSubresource:=image.GetSubresLayer;
BufferImageCopy.imageSubresource.layerCount:=1;
BufferImageCopy.imageExtent.depth:=1;
BufferImageCopyA:=nil;
SetLength(BufferImageCopyA,image.key.params.arrayLayers*image.key.params.depth*image.key.params.mipLevels);
b:=0;
for a:=0 to image.key.params.arrayLayers-1 do
for d:=0 to image.key.params.depth-1 do
begin
BufferImageCopy.imageSubresource.baseArrayLayer:=a;
BufferImageCopy.imageOffset.z:=d;
m_level :=image.key.params.mipLevels;
m_width :=image.key.params.width;
m_height:=image.key.params.height;
while (m_level>0) do
begin
Assert((m_offset and 3)=0,'align by 4');
BufferImageCopy.bufferOffset:=m_offset;
BufferImageCopy.imageSubresource.mipLevel:=image.key.params.mipLevels-m_level;
BufferImageCopy.imageExtent.width :=m_width;
BufferImageCopy.imageExtent.height:=m_height;
if (image.key.params.tiling.idx=8) then
begin
BufferImageCopy.bufferRowLength:=GetLinearAlignWidth(m_bytePerElement,m_width);
end;
BufferImageCopyA[b]:=BufferImageCopy;
Inc(b);
if IsTexelFormat(image.key.cformat) then
begin
m_padwidth :=(m_width +3) shr 2;
m_padheight:=(m_height+3) shr 2;
end else
begin
m_padwidth :=m_width ;
m_padheight:=m_height;
end;
m_slice:=m_padwidth*m_padheight*m_bytePerElement;
m_offset:=m_offset+m_slice;
Dec(m_level);
m_width :=Max(1,m_width shr 1);
m_height:=Max(1,m_height shr 1);
end;
end;
cmd.CopyImageToBuffer(image.FHandle,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
buf.FHandle,
Length(BufferImageCopyA),
@BufferImageCopyA[0]);
end;
type
t_load_from_cb =procedure(cmd:TvCustomCmdBuffer;image:TvCustomImage2);
t_write_back_cb=t_load_from_cb;
t_get_size_cb =function(const key:TvImageKey):Ptruint;
t_tiling_cbs=record
load_from :t_load_from_cb;
write_back:t_write_back_cb;
get_size :t_get_size_cb;
end;
var
a_tiling_cbs:array[0..63] of t_tiling_cbs;
function TileIdx(idx,alt:Byte):Byte; inline;
begin
Result:=idx;
TvTiling(Result).alt:=alt;
end;
procedure set_tiling_cbs(idx,alt:Byte;
l:t_load_from_cb;
w:t_write_back_cb;
g:t_get_size_cb
); inline;
begin
with a_tiling_cbs[TileIdx(idx,alt)] do
begin
load_from :=l;
write_back:=w;
get_size :=g;
end;
end;
procedure Init;
begin
set_tiling_cbs(kTileModeDisplay_2dThin ,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
set_tiling_cbs(kTileModeDisplay_2dThin ,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
set_tiling_cbs(kTileModeDepth_2dThin_256 ,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
set_tiling_cbs(kTileModeDepth_2dThin_256 ,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
set_tiling_cbs(kTileModeDepth_2dThin_64 ,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
set_tiling_cbs(kTileModeDepth_2dThin_64 ,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
//
set_tiling_cbs(kTileModeDepth_1dThin ,0,@load_1dThin,nil,@Get1dThinSize);
set_tiling_cbs(kTileModeDepth_1dThin ,1,@load_1dThin,nil,@Get1dThinSize);
set_tiling_cbs(kTileModeDisplay_1dThin ,0,@load_1dThin,nil,@Get1dThinSize);
set_tiling_cbs(kTileModeDisplay_1dThin ,1,@load_1dThin,nil,@Get1dThinSize);
set_tiling_cbs(kTileModeThin_1dThin ,0,@load_1dThin,nil,@Get1dThinSize);
set_tiling_cbs(kTileModeThin_1dThin ,1,@load_1dThin,nil,@Get1dThinSize);
//
set_tiling_cbs(kTileModeDisplay_LinearAligned,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize);
set_tiling_cbs(kTileModeDisplay_LinearAligned,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize);
end;
procedure pm4_load_from(cmd:TvCustomCmdBuffer;image:TvCustomImage2;IMAGE_USAGE:Byte);
var
cb:t_load_from_cb;
change_rate:t_change_rate;
begin
if (cmd=nil) or (image=nil) then Exit;
if (IMAGE_USAGE and TM_READ)=0 then Exit;
change_rate:=image.get_change_rate;
if not change_rate.need_read then Exit;
cb:=a_tiling_cbs[Byte(image.key.params.tiling)].load_from;
if (cb=nil) then
begin
Writeln(stderr,'tiling:'+IntToStr(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
Assert (false ,'tiling:'+IntToStr(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
end;
cmd.EndRenderPass;
image.restore_vm_track;
cb(cmd,image);
change_rate.mark_init;
image.apply_change_rate(change_rate);
image.assign_vm_track;
end;
procedure pm4_write_back(cmd:TvCustomCmdBuffer;image:TvCustomImage2);
var
cb:t_write_back_cb;
begin
if (cmd=nil) or (image=nil) then Exit;
cb:=a_tiling_cbs[Byte(image.key.params.tiling)].write_back;
if (cb=nil) then
begin
Writeln(stderr,'tiling:'+IntToStr(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
Assert (false ,'tiling:'+IntToStr(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
end;
cmd.EndRenderPass;
cb(cmd,image);
image.mark_init;
image.assign_vm_track;
cmd.AddPlannedTrigger(QWORD(image.key.Addr),QWORD(image.key.Addr)+image.size,image.tobj);
end;
Function get_image_size(const key:TvImageKey):Ptruint; [public, alias:'tiling_get_image_size'];
var
cb:t_get_size_cb;
begin
cb:=a_tiling_cbs[Byte(key.params.tiling)].get_size;
if (cb=nil) then
begin
Writeln(stderr,'tiling:'+IntToStr(key.params.tiling.idx)+' alt:'+IntToStr(key.params.tiling.alt));
Assert (false ,'tiling:'+IntToStr(key.params.tiling.idx)+' alt:'+IntToStr(key.params.tiling.alt));
end;
Result:=cb(key);
end;
{
Procedure LoadFromBuffer(cmd:TvCustomCmdBuffer;image:TObject);
begin
if (cmd=nil) then Exit;
Case TvCustomImage2(image).key.params.tiling_idx of
kTileModeDisplay_LinearAligned,
kTileModeDisplay_LinearGeneral:
_Load_Linear(cmd,TvCustomImage2(image));
kTileModeDisplay_2dThin: //render target tiling todo
_Load_Linear(cmd,TvCustomImage2(image));
kTileModeDepth_2dThin_64 ,
kTileModeDepth_2dThin_128,
kTileModeDepth_2dThin_256,
kTileModeDepth_2dThin_512,
kTileModeDepth_2dThin_1K : //depth tiling todo
_Load_Linear(cmd,TvCustomImage2(image));
kTileModeDepth_1dThin,
kTileModeDisplay_1dThin,
kTileModeThin_1dThin, //texture
$1B:
_Load_Thin_1dThin(cmd,TvCustomImage2(image));
kTileModeThin_2dThin:
_Load_Linear(cmd,TvCustomImage2(image)); //TODO
else
if not SKIP_UNKNOW_TILING then
Assert(false,'TODO tiling_idx:'+get_tiling_idx_str(TvCustomImage2(image).key.params.tiling_idx));
end;
end;
}
initialization
Init;
end.