mirror of https://github.com/red-prig/fpPS4.git
1286 lines
32 KiB
Plaintext
1286 lines
32 KiB
Plaintext
unit vImageTiling;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils,
|
|
sys_bootparam,
|
|
ps4_tiling,
|
|
kern_dmem,
|
|
Vulkan,
|
|
vDevice,
|
|
vMemory,
|
|
vBuffer,
|
|
vImage,
|
|
vImageManager,
|
|
vHostBufferManager,
|
|
vCmdBuffer;
|
|
|
|
Function pm4_load_from (cmd:TvCustomCmdBuffer;image:TvCustomImage2;IMAGE_USAGE:Byte):Boolean;
|
|
Function pm4_write_back(cmd:TvCustomCmdBuffer;image:TvCustomImage2):Boolean;
|
|
Function get_image_size(const key:TvImageKey):Ptruint;
|
|
|
|
implementation
|
|
|
|
const
|
|
VK_ACCESS_BUF_ANY=ord(VK_ACCESS_MEMORY_READ_BIT) or ord(VK_ACCESS_MEMORY_WRITE_BIT);
|
|
VK_STAGE_BUF_ANY =ord(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
|
|
|
function Max(a,b:Ptruint):Ptruint; inline;
|
|
begin
|
|
if (a>b) then Result:=a else Result:=b;
|
|
end;
|
|
|
|
Function GetLinearAlignWidth(bpp,width,height:Ptruint):Ptruint; inline;
|
|
var
|
|
pitch_align:Ptruint;
|
|
slice_align:Ptruint;
|
|
log_sz:Ptruint;
|
|
begin
|
|
|
|
pitch_align:=max(8,64 div bpp);
|
|
|
|
width:=(width + pitch_align - 1) and (not (pitch_align - 1));
|
|
|
|
slice_align:=max(64,256 div bpp);
|
|
|
|
log_sz:=width * height{ * num_samples};
|
|
while ((log_sz mod slice_align)<>0) do
|
|
begin
|
|
width:=width+pitch_align;
|
|
log_sz:=width * height{ * num_samples};
|
|
end;
|
|
|
|
Result:=width;
|
|
end;
|
|
|
|
function nextPowerOfTwo(x:Ptruint):Ptruint; inline;
|
|
begin
|
|
x:=(x-1);
|
|
x:=x or (x shr 1);
|
|
x:=x or (x shr 2);
|
|
x:=x or (x shr 4);
|
|
x:=x or (x shr 8);
|
|
x:=x or (x shr 16);
|
|
x:=x or (x shr 32);
|
|
Result:=(x+1);
|
|
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
|
|
if key.params.samples>1 then
|
|
begin
|
|
Writeln(stderr,'TODO:samples:',key.params.samples);
|
|
Assert(key.params.samples<=1,'key.params.samples>1');
|
|
end;
|
|
|
|
m_bytePerElement:=getFormatSize(key.cformat);
|
|
|
|
m_level :=key.params.mipLevels;
|
|
m_width :=key.params.width;
|
|
m_height:=key.params.height;
|
|
|
|
if (key.params.pow2pad<>0) then
|
|
begin
|
|
m_width :=nextPowerOfTwo(m_width);
|
|
m_height:=nextPowerOfTwo(m_height);
|
|
end;
|
|
|
|
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,m_padheight);
|
|
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*
|
|
key.params.depth*
|
|
key.params.arrayLayers*
|
|
m_bytePerElement;
|
|
|
|
//64?
|
|
|
|
Result:=Result+m_slice;
|
|
|
|
Dec(m_level);
|
|
m_width :=Max(1,m_width shr 1);
|
|
m_height:=Max(1,m_height shr 1);
|
|
end;
|
|
|
|
end;
|
|
|
|
Function GetLinearAlignSize(const key:TvImageKey):Ptruint;
|
|
begin
|
|
Result:=GetLinearSize(key,true);
|
|
end;
|
|
|
|
Function Get1dThinSize(const key:TvImageKey):Ptruint;
|
|
const
|
|
m_tileThickness=1;
|
|
var
|
|
m_bytePerElement:Ptruint;
|
|
m_level,m_width,m_height:Ptruint;
|
|
m_padwidth :Ptruint;
|
|
m_padheight :Ptruint;
|
|
m_depth :Ptruint;
|
|
m_arrayLayers:Ptruint;
|
|
m_slice :Ptruint;
|
|
log_sz :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;
|
|
m_depth :=key.params.depth;
|
|
m_arrayLayers:=key.params.arrayLayers;
|
|
|
|
if (key.params.pow2pad<>0) then
|
|
begin
|
|
m_width :=nextPowerOfTwo(m_width);
|
|
m_height :=nextPowerOfTwo(m_height);
|
|
m_depth :=nextPowerOfTwo(m_depth);
|
|
m_arrayLayers:=nextPowerOfTwo(m_arrayLayers);
|
|
end;
|
|
|
|
Result:=0;
|
|
|
|
while (m_level>0) do
|
|
begin
|
|
m_padwidth :=m_width;
|
|
m_padheight:=m_height;
|
|
|
|
if IsTexelFormat(key.cformat) then
|
|
begin
|
|
m_padwidth :=(m_padwidth +3) shr 2;
|
|
m_padheight:=(m_padheight+3) shr 2;
|
|
end;
|
|
|
|
//microtile align
|
|
m_padwidth :=(m_padwidth +7) and (not 7);
|
|
m_padheight:=(m_padheight+7) and (not 7);
|
|
|
|
//for 1d textures
|
|
m_padheight:=max(m_padheight,8);
|
|
|
|
//align pitch to pipe_interleave_size
|
|
log_sz:=(m_padwidth*m_padheight*m_bytePerElement*m_tileThickness);
|
|
while (log_sz and 255)<>0 do //(log_sz mod 256)<>0
|
|
begin
|
|
m_padwidth:=m_padwidth+8;
|
|
log_sz:=(m_padwidth*m_padheight*m_bytePerElement*m_tileThickness);
|
|
end;
|
|
|
|
if (m_level<>1) then
|
|
begin
|
|
m_slice:=m_padwidth*
|
|
m_padheight*
|
|
m_depth*
|
|
m_arrayLayers*
|
|
m_bytePerElement;
|
|
|
|
m_slice:=(m_slice+255) and (not Ptruint(255));
|
|
end else
|
|
begin
|
|
//Trim the last layer
|
|
|
|
m_slice:=m_padwidth*
|
|
m_padheight*
|
|
key.params.depth*
|
|
key.params.arrayLayers*
|
|
m_bytePerElement;
|
|
|
|
end;
|
|
|
|
Result:=Result+m_slice;
|
|
|
|
Dec(m_level);
|
|
m_width :=Max(1,m_width shr 1);
|
|
m_height:=Max(1,m_height shr 1);
|
|
end;
|
|
|
|
end;
|
|
|
|
function AlignDw(addr:PtrUInt;alignment:PtrUInt):PtrUInt; inline;
|
|
begin
|
|
Result:=addr-(addr mod alignment);
|
|
end;
|
|
|
|
type
|
|
TvTempBuffer=class(TvBuffer)
|
|
Function ReleaseTmp(Sender:TObject):Boolean; virtual; register;
|
|
end;
|
|
|
|
Function TvTempBuffer.ReleaseTmp(Sender:TObject):Boolean; register;
|
|
begin
|
|
//force free
|
|
Result:=Drop(nil);
|
|
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;
|
|
|
|
type
|
|
t_copy_type=(BufferToImage,ImageToBuffer);
|
|
|
|
Procedure _Copy_Linear(ctype:t_copy_type;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
|
|
|
|
buf.Hold(nil);
|
|
cmd.AddDependence(@buf.ReleaseTmp);
|
|
|
|
m_bytePerElement:=getFormatSize(image.key.cformat);
|
|
|
|
size:=GetLinearSize(image.key,false);
|
|
|
|
case ctype of
|
|
BufferToImage:
|
|
begin
|
|
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,
|
|
VK_ACCESS_BUF_ANY,
|
|
ord(VK_ACCESS_TRANSFER_READ_BIT),
|
|
0,size,
|
|
VK_STAGE_BUF_ANY,
|
|
ord(VK_PIPELINE_STAGE_TRANSFER_BIT)
|
|
);
|
|
end;
|
|
ImageToBuffer:
|
|
begin
|
|
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,
|
|
VK_ACCESS_BUF_ANY,
|
|
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
|
|
0,size,
|
|
VK_STAGE_BUF_ANY,
|
|
ord(VK_PIPELINE_STAGE_TRANSFER_BIT)
|
|
);
|
|
end;
|
|
end;
|
|
|
|
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;
|
|
|
|
//mips
|
|
m_level :=image.key.params.mipLevels;
|
|
m_width :=image.key.params.width;
|
|
m_height:=image.key.params.height;
|
|
|
|
while (m_level>0) do
|
|
begin
|
|
BufferImageCopy.imageSubresource.mipLevel:=image.key.params.mipLevels-m_level;
|
|
|
|
BufferImageCopy.imageExtent.width :=m_width;
|
|
BufferImageCopy.imageExtent.height:=m_height;
|
|
|
|
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;
|
|
|
|
//array
|
|
for a:=0 to image.key.params.arrayLayers-1 do
|
|
for d:=0 to image.key.params.depth-1 do
|
|
begin
|
|
//Assert((m_offset and 3)=0,'align by 4');
|
|
BufferImageCopy.bufferOffset:=m_offset;
|
|
|
|
BufferImageCopy.imageSubresource.baseArrayLayer:=a;
|
|
BufferImageCopy.imageOffset.z:=d;
|
|
|
|
BufferImageCopyA[b]:=BufferImageCopy;
|
|
Inc(b);
|
|
|
|
m_offset:=m_offset+m_slice;
|
|
end;
|
|
//array
|
|
|
|
Dec(m_level);
|
|
m_width :=Max(1,m_width shr 1);
|
|
m_height:=Max(1,m_height shr 1);
|
|
end;
|
|
//mips
|
|
|
|
case ctype of
|
|
BufferToImage:
|
|
begin
|
|
cmd.CopyBufferToImage(buf.FHandle,
|
|
image.FHandle,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
Length(BufferImageCopyA),
|
|
@BufferImageCopyA[0]);
|
|
end;
|
|
ImageToBuffer:
|
|
begin
|
|
cmd.CopyImageToBuffer(image.FHandle,
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
buf.FHandle,
|
|
Length(BufferImageCopyA),
|
|
@BufferImageCopyA[0]);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
Procedure copy_1dThin_to_linear(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_bytePerElement;
|
|
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_to_1dThin(var tiler:Tiler1d;src,dst:Pointer);
|
|
var
|
|
m_bytePerElement:Ptruint;
|
|
m_slice_size:Ptruint;
|
|
i,x,y,z:QWORD;
|
|
pSrc,pDst:Pointer;
|
|
begin
|
|
|
|
//ImageToBuffer
|
|
|
|
dst:=get_dmem_ptr(dst);
|
|
|
|
//
|
|
m_bytePerElement:=tiler.m_bytePerElement;
|
|
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
|
|
pSrc:=@PByte(src)[(z*m_slice_size+y*tiler.m_linearWidth+x)*m_bytePerElement];
|
|
//
|
|
i:=0;
|
|
tiler.getTiledElementByteOffset(i,x,y,z);
|
|
pDst:=@PByte(dst)[i];
|
|
//
|
|
Move(pSrc^,pDst^,m_bytePerElement);
|
|
end;
|
|
end;
|
|
|
|
Procedure load_write_1dThin(ctype:t_copy_type;
|
|
image:TvCustomImage2;
|
|
m_full_linear_size:Ptruint;
|
|
m_base:Pointer);
|
|
var
|
|
tiler:Tiler1d;
|
|
|
|
m_bytePerElement:Ptruint;
|
|
m_level,m_width,m_height:Ptruint;
|
|
|
|
src:Pointer;
|
|
dst:Pointer;
|
|
|
|
a:Ptruint;
|
|
begin
|
|
|
|
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
|
|
|
|
//mips
|
|
m_level :=image.key.params.mipLevels;
|
|
//
|
|
m_width :=image.key.params.width;
|
|
m_height:=image.key.params.height;
|
|
|
|
if (image.key.params.pow2pad<>0) then
|
|
begin
|
|
m_width :=nextPowerOfTwo(m_width);
|
|
m_height:=nextPowerOfTwo(m_height);
|
|
end;
|
|
|
|
src:=image.key.addr;
|
|
|
|
while (m_level>0) do
|
|
begin
|
|
tiler.init_size_2d(m_width,m_height);
|
|
|
|
//array
|
|
for a:=0 to image.key.params.arrayLayers-1 do
|
|
begin
|
|
|
|
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;
|
|
|
|
//x,y,z
|
|
case ctype of
|
|
BufferToImage:copy_1dThin_to_linear(tiler,src,dst);
|
|
ImageToBuffer:copy_linear_to_1dThin(tiler,dst,src);
|
|
end;
|
|
//x,y,z
|
|
|
|
{
|
|
if ctype=BufferToImage then
|
|
SaveToTGA('shader_dump\texture_a'+IntToStr(a)+
|
|
'_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;
|
|
|
|
end;
|
|
//array
|
|
|
|
if (image.key.params.pow2pad<>0) then
|
|
begin
|
|
a:=nextPowerOfTwo(image.key.params.arrayLayers)-image.key.params.arrayLayers;
|
|
|
|
src:=src+tiler.m_tiledSizeBytes*a;
|
|
end;
|
|
|
|
//Writeln('nextPowerOfTwo =',nextPowerOfTwo(image.key.params.arrayLayers));
|
|
|
|
src:=Pointer((qword(src)+255) and (not 255));
|
|
|
|
Dec(m_level);
|
|
m_width :=Max(1,m_width shr 1);
|
|
m_height:=Max(1,m_height shr 1);
|
|
end;
|
|
//mips
|
|
|
|
//Writeln('size1=',(src-image.key.addr));
|
|
//Writeln('size2=',Get1dThinSize(image.key));
|
|
|
|
end;
|
|
|
|
function load_1dThin(cmd:TvCustomCmdBuffer;image:TvCustomImage2):Boolean;
|
|
var
|
|
buf:TvTempBuffer;
|
|
vmem:TvPointer;
|
|
|
|
m_full_linear_size:Ptruint;
|
|
|
|
m_base:Pointer;
|
|
begin
|
|
Result:=True;
|
|
|
|
Assert(image.key.params.samples<=1,'image.key.params.samples>1');
|
|
|
|
m_full_linear_size:=GetLinearSize(image.key,False);
|
|
|
|
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,buf);
|
|
|
|
if (vmem.FMemory=nil) then
|
|
begin
|
|
vmem:=MemManager.FetchMemory(buf.GetRequirements,V_PROP_HOST_VISIBLE,buf);
|
|
end;
|
|
|
|
if (vmem.FMemory=nil) then
|
|
begin
|
|
FreeAndNil(buf);
|
|
Exit(False);
|
|
end;
|
|
|
|
buf.BindMem(vmem);
|
|
|
|
vmem.Release; //FetchMemory
|
|
|
|
m_base:=nil;
|
|
vkMapMemory(Device.FHandle,
|
|
buf.FBind.FMemory.FHandle,
|
|
buf.FBind.FOffset,
|
|
m_full_linear_size,
|
|
0,
|
|
@m_base);
|
|
|
|
load_write_1dThin(BufferToImage,
|
|
image,
|
|
m_full_linear_size,
|
|
m_base);
|
|
|
|
vkUnmapMemory(Device.FHandle,buf.FBind.FMemory.FHandle);
|
|
|
|
_Copy_Linear(BufferToImage,cmd,buf,image);
|
|
end;
|
|
|
|
type
|
|
TvTempBufferWriteback=class(TvTempBuffer)
|
|
image:TvCustomImage2;
|
|
m_full_linear_size:Ptruint;
|
|
function ReleaseTmp(Sender:TObject):Boolean; override; register;
|
|
end;
|
|
|
|
function TvTempBufferWriteback.ReleaseTmp(Sender:TObject):Boolean; register;
|
|
var
|
|
m_base:Pointer;
|
|
begin
|
|
m_base:=nil;
|
|
vkMapMemory(Device.FHandle,
|
|
FBind.FMemory.FHandle,
|
|
FBind.FOffset,
|
|
m_full_linear_size,
|
|
0,
|
|
@m_base);
|
|
|
|
load_write_1dThin(ImageToBuffer,
|
|
image,
|
|
m_full_linear_size,
|
|
m_base);
|
|
|
|
vkUnmapMemory(Device.FHandle,FBind.FMemory.FHandle);
|
|
|
|
image.Drop(Self);
|
|
Result:=inherited;
|
|
end;
|
|
|
|
function write_1dThin(cmd:TvCustomCmdBuffer;image:TvCustomImage2):Boolean;
|
|
var
|
|
buf:TvTempBufferWriteback;
|
|
vmem:TvPointer;
|
|
|
|
m_full_linear_size:Ptruint;
|
|
|
|
begin
|
|
Result:=True;
|
|
|
|
Assert(image.key.params.samples<=1,'image.key.params.samples>1');
|
|
|
|
m_full_linear_size:=GetLinearSize(image.key,False);
|
|
|
|
buf:=TvTempBufferWriteback.Create(m_full_linear_size,ord(VK_BUFFER_USAGE_TRANSFER_DST_BIT),nil);
|
|
|
|
buf.image:=image;
|
|
buf.m_full_linear_size:=m_full_linear_size;
|
|
|
|
image.Hold(buf);
|
|
|
|
vmem:=MemManager.FetchMemory(buf.GetRequirements,V_PROP_HOST_VISIBLE or V_PROP_DEVICE_LOCAL,buf);
|
|
|
|
if (vmem.FMemory=nil) then
|
|
begin
|
|
vmem:=MemManager.FetchMemory(buf.GetRequirements,V_PROP_HOST_VISIBLE,buf);
|
|
end;
|
|
|
|
if (vmem.FMemory=nil) then
|
|
begin
|
|
FreeAndNil(buf);
|
|
Exit(False);
|
|
end;
|
|
|
|
buf.BindMem(vmem);
|
|
|
|
vmem.Release; //FetchMemory
|
|
|
|
_Copy_Linear(ImageToBuffer,cmd,buf,image);
|
|
end;
|
|
|
|
function Load_Linear(cmd:TvCustomCmdBuffer;image:TvCustomImage2):Boolean;
|
|
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
|
|
Result:=True;
|
|
|
|
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);
|
|
|
|
if (buf=nil) then
|
|
begin
|
|
Exit(False);
|
|
end;
|
|
|
|
m_offset:=QWORD(image.key.addr)-buf.FAddr;
|
|
|
|
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,
|
|
VK_ACCESS_BUF_ANY,
|
|
ord(VK_ACCESS_TRANSFER_READ_BIT),
|
|
m_offset,
|
|
size,
|
|
VK_STAGE_BUF_ANY,
|
|
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;
|
|
|
|
//mips
|
|
m_level :=image.key.params.mipLevels;
|
|
m_width :=image.key.params.width;
|
|
m_height:=image.key.params.height;
|
|
|
|
{
|
|
SaveToTGA('shader_dump\texture_mip'+IntToStr(m_level)+
|
|
'_'+IntToStr(m_width)+
|
|
'x'+IntToStr(m_height)+
|
|
'.tga',
|
|
Pointer(image.key.addr),
|
|
m_width,
|
|
m_height,
|
|
32);
|
|
}
|
|
|
|
while (m_level>0) do
|
|
begin
|
|
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=kTileModeDisplay_LinearAligned) then
|
|
begin
|
|
BufferImageCopy.bufferRowLength:=GetLinearAlignWidth(m_bytePerElement,m_width,m_height);
|
|
end;
|
|
|
|
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;
|
|
|
|
//array
|
|
for a:=0 to image.key.params.arrayLayers-1 do
|
|
for d:=0 to image.key.params.depth-1 do
|
|
begin
|
|
//Assert((m_offset and 3)=0,'align by 4');
|
|
|
|
BufferImageCopy.bufferOffset:=m_offset;
|
|
|
|
BufferImageCopy.imageSubresource.baseArrayLayer:=a;
|
|
BufferImageCopy.imageOffset.z:=d;
|
|
|
|
BufferImageCopyA[b]:=BufferImageCopy;
|
|
Inc(b);
|
|
|
|
m_offset:=m_offset+m_slice;
|
|
end;
|
|
//array
|
|
|
|
Dec(m_level);
|
|
m_width :=Max(1,m_width shr 1);
|
|
m_height:=Max(1,m_height shr 1);
|
|
end;
|
|
//mips
|
|
|
|
cmd.CopyBufferToImage(buf.FHandle,
|
|
image.FHandle,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
Length(BufferImageCopyA),
|
|
@BufferImageCopyA[0]);
|
|
|
|
|
|
end;
|
|
|
|
function Writeback_Linear(cmd:TvCustomCmdBuffer;image:TvCustomImage2):Boolean;
|
|
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
|
|
Result:=True;
|
|
|
|
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);
|
|
|
|
if (buf=nil) then
|
|
begin
|
|
Exit(False);
|
|
end;
|
|
|
|
m_offset:=QWORD(image.key.addr)-buf.FAddr;
|
|
|
|
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,
|
|
VK_ACCESS_BUF_ANY,
|
|
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
|
|
m_offset,
|
|
size,
|
|
VK_STAGE_BUF_ANY,
|
|
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;
|
|
|
|
//mips
|
|
m_level :=image.key.params.mipLevels;
|
|
m_width :=image.key.params.width;
|
|
m_height:=image.key.params.height;
|
|
|
|
while (m_level>0) do
|
|
begin
|
|
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=kTileModeDisplay_LinearAligned) then
|
|
begin
|
|
BufferImageCopy.bufferRowLength:=GetLinearAlignWidth(m_bytePerElement,m_width,m_height);
|
|
end;
|
|
|
|
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;
|
|
|
|
//array
|
|
for a:=0 to image.key.params.arrayLayers-1 do
|
|
for d:=0 to image.key.params.depth-1 do
|
|
begin
|
|
//Assert((m_offset and 3)=0,'align by 4');
|
|
BufferImageCopy.bufferOffset:=m_offset;
|
|
|
|
BufferImageCopy.imageSubresource.baseArrayLayer:=a;
|
|
BufferImageCopy.imageOffset.z:=d;
|
|
|
|
BufferImageCopyA[b]:=BufferImageCopy;
|
|
Inc(b);
|
|
|
|
m_offset:=m_offset+m_slice;
|
|
end;
|
|
//array
|
|
|
|
Dec(m_level);
|
|
m_width :=Max(1,m_width shr 1);
|
|
m_height:=Max(1,m_height shr 1);
|
|
end;
|
|
//mips
|
|
|
|
cmd.CopyImageToBuffer(image.FHandle,
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
buf.FHandle,
|
|
Length(BufferImageCopyA),
|
|
@BufferImageCopyA[0]);
|
|
|
|
|
|
end;
|
|
|
|
type
|
|
t_load_from_cb =function(cmd:TvCustomCmdBuffer;image:TvCustomImage2):Boolean;
|
|
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(kTileModeThin_2dThin ,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
|
|
set_tiling_cbs(kTileModeThin_2dThin ,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
|
|
|
|
set_tiling_cbs(kTileModeThick_1dThick ,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
|
|
set_tiling_cbs(kTileModeThick_1dThick ,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
|
|
|
|
//
|
|
set_tiling_cbs(kTileModeDepth_1dThin ,0,@load_1dThin,@write_1dThin,@Get1dThinSize);
|
|
set_tiling_cbs(kTileModeDepth_1dThin ,1,@load_1dThin,@write_1dThin,@Get1dThinSize);
|
|
|
|
set_tiling_cbs(kTileModeDisplay_1dThin ,0,@load_1dThin,@write_1dThin,@Get1dThinSize);
|
|
set_tiling_cbs(kTileModeDisplay_1dThin ,1,@load_1dThin,@write_1dThin,@Get1dThinSize);
|
|
|
|
set_tiling_cbs(kTileModeThin_1dThin ,0,@load_1dThin,@write_1dThin,@Get1dThinSize);
|
|
set_tiling_cbs(kTileModeThin_1dThin ,1,@load_1dThin,@write_1dThin,@Get1dThinSize);
|
|
//
|
|
|
|
set_tiling_cbs(kTileModeDisplay_LinearAligned,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize);
|
|
set_tiling_cbs(kTileModeDisplay_LinearAligned,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize);
|
|
end;
|
|
|
|
function get_tiling_name(i:Byte):RawByteString;
|
|
begin
|
|
case i of
|
|
// Depth modes (for depth buffers)
|
|
kTileModeDepth_2dThin_64 :Result:='Depth_2dThin_64';
|
|
kTileModeDepth_2dThin_128 :Result:='Depth_2dThin_128';
|
|
kTileModeDepth_2dThin_256 :Result:='Depth_2dThin_256';
|
|
kTileModeDepth_2dThin_512 :Result:='Depth_2dThin_512';
|
|
kTileModeDepth_2dThin_1K :Result:='Depth_2dThin_1K';
|
|
kTileModeDepth_1dThin :Result:='Depth_1dThin';
|
|
kTileModeDepth_2dThinPrt_256:Result:='Depth_2dThinPrt_256';
|
|
kTileModeDepth_2dThinPrt_1K :Result:='Depth_2dThinPrt_1K';
|
|
// Display modes
|
|
kTileModeDisplay_LinearAligned:Result:='LinearAligned';
|
|
kTileModeDisplay_1dThin :Result:='Display_1dThin';
|
|
kTileModeDisplay_2dThin :Result:='Display_2dThin';
|
|
kTileModeDisplay_ThinPrt :Result:='Display_ThinPrt';
|
|
kTileModeDisplay_2dThinPrt :Result:='Display_2dThinPrt';
|
|
// Thin modes (for non-displayable 1D/2D/3D
|
|
kTileModeThin_1dThin :Result:='Thin_1dThin';
|
|
kTileModeThin_2dThin :Result:='Thin_2dThin';
|
|
kTileModeThin_3dThin :Result:='Thin_3dThin';
|
|
kTileModeThin_ThinPrt :Result:='Thin_ThinPrt';
|
|
kTileModeThin_2dThinPrt:Result:='Thin_2dThinPrt';
|
|
kTileModeThin_3dThinPrt:Result:='Thin_3dThinPrt';
|
|
// Thick modes (for 3D textures)
|
|
kTileModeThick_1dThick :Result:='Thick_1dThick';
|
|
kTileModeThick_2dThick :Result:='Thick_2dThick';
|
|
kTileModeThick_3dThick :Result:='Thick_3dThick';
|
|
kTileModeThick_ThickPrt :Result:='Thick_ThickPrt';
|
|
kTileModeThick_2dThickPrt:Result:='Thick_2dThickPrt';
|
|
kTileModeThick_3dThickPrt:Result:='Thick_3dThickPrt';
|
|
kTileModeThick_2dXThick :Result:='Thick_2dXThick';
|
|
kTileModeThick_3dXThick :Result:='Thick_3dXThick';
|
|
// Hugely inefficient linear display mode -
|
|
kTileModeDisplay_LinearGeneral:Result:='LinearGeneral';
|
|
else
|
|
Result:=IntToStr(i);
|
|
end;
|
|
end;
|
|
|
|
function pm4_load_from(cmd:TvCustomCmdBuffer;image:TvCustomImage2;IMAGE_USAGE:Byte):Boolean;
|
|
var
|
|
cb:t_load_from_cb;
|
|
change_rate:t_change_rate;
|
|
begin
|
|
Result:=True;
|
|
if (cmd=nil) or (image=nil) then Exit;
|
|
|
|
if (IMAGE_USAGE and TM_READ)=0 then Exit;
|
|
|
|
if (image.key.params.samples>1) then
|
|
begin
|
|
Exit;
|
|
end;
|
|
|
|
if (image.key.params.invalid<>0) then
|
|
begin
|
|
Exit;
|
|
end;
|
|
|
|
if image.IsDepthAndStencil then
|
|
begin
|
|
Result:=Result and pm4_load_from(cmd,image.DepthOnly ,IMAGE_USAGE);
|
|
Result:=Result and pm4_load_from(cmd,image.StencilOnly,IMAGE_USAGE);
|
|
Exit;
|
|
end;
|
|
|
|
change_rate:=image.get_change_rate;
|
|
|
|
if not change_rate.need_read then Exit;
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln('loadfrom: ',image.FName);
|
|
end;
|
|
|
|
cb:=a_tiling_cbs[Byte(image.key.params.tiling)].load_from;
|
|
|
|
if (cb=nil) then
|
|
begin
|
|
Writeln(stderr,'tiling:'+get_tiling_name(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
|
Assert (false ,'tiling:'+get_tiling_name(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
|
Exit;
|
|
end;
|
|
|
|
cmd.EndRenderPass;
|
|
|
|
image.restore_vm_track;
|
|
|
|
cmd.BeginLabel('loadfrom');
|
|
|
|
Result:=cb(cmd,image);
|
|
|
|
cmd.EndLabel();
|
|
|
|
if not Result then Exit;
|
|
|
|
change_rate.mark_init;
|
|
|
|
image.apply_change_rate(change_rate);
|
|
|
|
image.assign_vm_track;
|
|
end;
|
|
|
|
function pm4_write_back(cmd:TvCustomCmdBuffer;image:TvCustomImage2):Boolean;
|
|
var
|
|
cb:t_write_back_cb;
|
|
begin
|
|
Result:=True;
|
|
if (cmd=nil) or (image=nil) then Exit;
|
|
|
|
if (image.key.params.samples>1) then
|
|
begin
|
|
Exit;
|
|
end;
|
|
|
|
if (image.key.params.invalid<>0) then
|
|
begin
|
|
Exit;
|
|
end;
|
|
|
|
if image.IsDepthAndStencil then
|
|
begin
|
|
Result:=Result and pm4_write_back(cmd,image.DepthOnly );
|
|
Result:=Result and pm4_write_back(cmd,image.StencilOnly);
|
|
Exit;
|
|
end;
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln('writeback:',image.FName);
|
|
end;
|
|
|
|
cb:=a_tiling_cbs[Byte(image.key.params.tiling)].write_back;
|
|
|
|
if (cb=nil) then
|
|
begin
|
|
Writeln(stderr,'tiling:'+get_tiling_name(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
|
Assert (false ,'tiling:'+get_tiling_name(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
|
Exit;
|
|
end;
|
|
|
|
cmd.EndRenderPass;
|
|
|
|
cmd.BeginLabel('writeback');
|
|
|
|
Result:=cb(cmd,image);
|
|
|
|
cmd.EndLabel();
|
|
|
|
if not Result then Exit;
|
|
|
|
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:'+get_tiling_name(key.params.tiling.idx)+' alt:'+IntToStr(key.params.tiling.alt));
|
|
Assert (false ,'tiling:'+get_tiling_name(key.params.tiling.idx)+' alt:'+IntToStr(key.params.tiling.alt));
|
|
Exit(0);
|
|
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.
|
|
|