mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
refactor gpu: consolidate texture tile layout calculations
This commit is contained in:
1 parent
a76f3ac2fe
commit
389fd1e5be
9 files changed
+802
-1147
No files matched your search
+310
-609
File diff suppressed because it is too large.
Load diff
@@ -39,7 +39,7 @@ enum class TileBlockFamily : uint32_t {
|
||||
};
|
||||
|
||||
struct TileBlockLayout {
|
||||
TileBlockFamily family = TileBlockFamily::Standard256B;
|
||||
TileBlockFamily family = TileBlockFamily::Count;
|
||||
uint32_t bytes_per_element = 0;
|
||||
uint32_t block_size = 0;
|
||||
uint32_t block_width = 0;
|
||||
@@ -47,38 +47,69 @@ struct TileBlockLayout {
|
||||
uint32_t block_depth = 0;
|
||||
};
|
||||
|
||||
struct TileVolumeLayout {
|
||||
TileBlockFamily family = TileBlockFamily::Count;
|
||||
uint32_t bytes_per_element = 0;
|
||||
uint32_t texel_width = 1;
|
||||
uint32_t texel_height = 1;
|
||||
uint32_t first_tail_level = 0;
|
||||
uint32_t block_depth = 1;
|
||||
uint64_t block_slice_size = 0;
|
||||
uint64_t total_size = 0;
|
||||
uint64_t level_offsets[16] = {};
|
||||
uint64_t level_sizes[16] = {};
|
||||
uint32_t tail_x[16] = {};
|
||||
uint32_t tail_y[16] = {};
|
||||
uint32_t level_widths[16] = {};
|
||||
uint32_t level_heights[16] = {};
|
||||
struct TileTextureElementLayout {
|
||||
uint32_t bytes = 0;
|
||||
uint32_t texel_width = 1;
|
||||
uint32_t texel_height = 1;
|
||||
};
|
||||
|
||||
struct TileTextureBlockLayout {
|
||||
TileBlockLayout block;
|
||||
uint32_t texel_width = 1;
|
||||
uint32_t texel_height = 1;
|
||||
};
|
||||
|
||||
enum class TileSurfaceDimension : uint32_t {
|
||||
Dim2D,
|
||||
Dim3D,
|
||||
};
|
||||
|
||||
struct TileSurfaceDescription {
|
||||
uint32_t format = 0;
|
||||
uint32_t tile_mode = 0;
|
||||
TileSurfaceDimension dimension = TileSurfaceDimension::Dim2D;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t depth = 1;
|
||||
uint32_t levels = 1;
|
||||
uint32_t layers = 1;
|
||||
};
|
||||
|
||||
// Width/height fields are measured in addressable elements, not texture texels.
|
||||
struct TileMipLayout {
|
||||
uint64_t offset = 0;
|
||||
uint64_t size = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t padded_width = 0;
|
||||
uint32_t padded_height = 0;
|
||||
uint32_t tail_x = 0;
|
||||
uint32_t tail_y = 0;
|
||||
};
|
||||
|
||||
struct TileSurfaceLayout {
|
||||
TileSurfaceDescription description;
|
||||
TileTextureBlockLayout texture;
|
||||
uint32_t first_tail_level = 0;
|
||||
uint64_t block_slice_size = 0;
|
||||
uint64_t total_size = 0;
|
||||
TileMipLayout mips[16] = {};
|
||||
};
|
||||
|
||||
bool TileGetBlockLayout(TileBlockFamily family, uint32_t bytes_per_element,
|
||||
TileBlockLayout& layout);
|
||||
bool TileGetTextureElementLayout(uint32_t format, TileTextureElementLayout& layout);
|
||||
bool TileGetTextureBlockLayout(uint32_t format, uint32_t tile, bool volume,
|
||||
TileTextureBlockLayout& layout);
|
||||
bool TileGetTiledTextureLayout(const TileSurfaceDescription& description,
|
||||
TileSurfaceLayout& layout);
|
||||
bool TileGetBlockOffset(const TileBlockLayout& layout, uint32_t x, uint32_t y, uint32_t z,
|
||||
uint32_t& byte_offset);
|
||||
bool TileGetBlockXor(const TileBlockLayout& layout, uint32_t block_x, uint32_t block_y,
|
||||
uint32_t& byte_offset);
|
||||
bool TileGetBlockXor(const TileBlockLayout& layout, uint32_t block_x, uint32_t block_y,
|
||||
uint32_t block_z, uint32_t& byte_offset);
|
||||
bool TileIsStandard256BTextureSupported(uint32_t format);
|
||||
bool TileIsStandard4KBTextureSupported(uint32_t format);
|
||||
bool TileIsStandard64KBTextureSupported(uint32_t format);
|
||||
bool TileGetTextureVolumeLayout(uint32_t format, uint32_t width, uint32_t height, uint32_t depth,
|
||||
uint32_t levels, uint32_t tile, TileVolumeLayout& layout);
|
||||
|
||||
bool TileGetHtileSize(uint32_t width, uint32_t height, TileSizeAlign& htile_size);
|
||||
bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t z_format,
|
||||
uint32_t stencil_format, bool htile, TileSizeAlign& stencil_size,
|
||||
TileSizeAlign& htile_size, TileSizeAlign& depth_size,
|
||||
@@ -94,13 +125,13 @@ bool TileGetRenderTargetMipLayout(uint32_t width, uint32_t height, uint32_t
|
||||
uint32_t bytes_per_element, uint32_t levels,
|
||||
TileSizeAlign& total_size, TileSizeOffset* level_sizes,
|
||||
TilePaddedSize* padded_size);
|
||||
void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32_t pitch,
|
||||
uint32_t levels, uint32_t tile, TileSizeAlign* total_size,
|
||||
TileSizeOffset* level_sizes, TilePaddedSize* padded_size);
|
||||
void TileGetTextureTotalSize(uint32_t format, uint32_t width, uint32_t height, uint32_t depth,
|
||||
uint32_t pitch, uint32_t levels, uint32_t tile, bool volume_texture,
|
||||
TileSizeAlign& total_size);
|
||||
uint32_t TileGetTexturePitch(uint32_t format, uint32_t width, uint32_t levels, uint32_t tile);
|
||||
void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32_t levels,
|
||||
uint32_t tile, TileSizeAlign* total_size, TileSizeOffset* level_sizes,
|
||||
TilePaddedSize* padded_size);
|
||||
void TileGetTextureTotalSize(uint32_t format, uint32_t width, uint32_t height, uint32_t depth,
|
||||
uint32_t levels, uint32_t tile, bool volume_texture,
|
||||
TileSizeAlign& total_size);
|
||||
uint32_t TileGetTexturePitch(uint32_t format, uint32_t width, uint32_t tile);
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
|
||||
|
||||
+13
-24
@@ -911,7 +911,6 @@ TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
|
||||
uint32_t format = info.guest_format;
|
||||
uint32_t layers = info.TransferLayers();
|
||||
bool volume = info.IsVolume();
|
||||
bool layered = info.IsLayered();
|
||||
bool allow_depth_tile = direction == TransferDirection::Upload;
|
||||
const char* owner =
|
||||
direction == TransferDirection::Upload ? "TextureCache" : "TextureCache readback";
|
||||
@@ -940,7 +939,6 @@ TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
|
||||
format = info.guest_format;
|
||||
layers = info.resources.layers;
|
||||
volume = false;
|
||||
layered = layers > 1;
|
||||
allow_depth_tile = false;
|
||||
plan.swap_bgra16 = info.bgra16;
|
||||
owner = "VideoOut";
|
||||
@@ -958,19 +956,14 @@ TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
|
||||
plan.swap_bgra16 = info.bgra16;
|
||||
}
|
||||
|
||||
plan.layout = TextureCalcUploadLayout(format, info.extent.width, info.extent.height,
|
||||
info.resources.levels, layers, info.pitch, info.tile_mode,
|
||||
info.data.size, allow_depth_tile, volume, owner);
|
||||
plan.regions = TextureBuildImageCopies(plan.layout, info.extent.width, info.extent.height,
|
||||
layers, info.resources.levels, layered, volume);
|
||||
plan.tiled = static_cast<Prospero::TileMode>(plan.layout.tile) != Prospero::TileMode::kLinear;
|
||||
plan.layout = TextureCalcUploadLayout(format, info.extent.width, info.extent.height,
|
||||
info.resources.levels, layers, info.tile_mode,
|
||||
info.data.size, allow_depth_tile, volume, owner);
|
||||
plan.regions = TextureBuildImageCopies(plan.layout);
|
||||
plan.tiled = static_cast<Prospero::TileMode>(plan.layout.surface.description.tile_mode) !=
|
||||
Prospero::TileMode::kLinear;
|
||||
if (plan.tiled) {
|
||||
// CMASK/FMASK decoding is intentionally deferred.
|
||||
if (plan.layout.tile_family == TileBlockFamily::Depth64KB &&
|
||||
Prospero::IsFmaskTextureFormat(format)) {
|
||||
return plan;
|
||||
}
|
||||
if (!TextureBuildGpuTileInfos(info.data.size, plan.regions, plan.layout, format, layers,
|
||||
if (!TextureBuildGpuTileInfos(info.data.size, plan.regions, plan.layout,
|
||||
info.resources.levels, plan.tiles)) {
|
||||
return plan;
|
||||
}
|
||||
@@ -1017,9 +1010,10 @@ void TextureCache::UploadImage(Image& image, const ImageDesc& desc, Buffer& sour
|
||||
" size=0x%016" PRIx64 " format=%u tile=%u family=%u extent=%ux%ux%u "
|
||||
"pitch=%u levels=%u layers=%u samples=%u\n",
|
||||
static_cast<uint32_t>(desc.type), info.data.address, info.data.size,
|
||||
info.guest_format, info.tile_mode, static_cast<uint32_t>(plan.layout.tile_family),
|
||||
info.extent.width, info.extent.height, info.extent.depth, info.pitch,
|
||||
info.resources.levels, info.resources.layers, info.samples);
|
||||
info.guest_format, info.tile_mode,
|
||||
static_cast<uint32_t>(plan.layout.surface.texture.block.family), info.extent.width,
|
||||
info.extent.height, info.extent.depth, info.pitch, info.resources.levels,
|
||||
info.resources.layers, info.samples);
|
||||
}
|
||||
TileManager::Result linear {source.Handle(), source_offset, info.data.size};
|
||||
if (plan.tiled) {
|
||||
@@ -1718,14 +1712,9 @@ bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, uint64_t vaddr, uin
|
||||
return false;
|
||||
}
|
||||
if (color.tiled) {
|
||||
const auto binding = m_texture_cache.UploadBinding(image);
|
||||
const auto format =
|
||||
binding == TextureCache::BindingType::RenderTarget
|
||||
? ImageOps::RenderTargetTransferFormat(image.info.bytes_per_block)
|
||||
: image.info.guest_format;
|
||||
color.tiles.clear();
|
||||
if (!TextureBuildGpuTileInfos(copy_size, color.regions, color.layout, format,
|
||||
image.info.TransferLayers(), levels, color.tiles)) {
|
||||
if (!TextureBuildGpuTileInfos(copy_size, color.regions, color.layout, levels,
|
||||
color.tiles)) {
|
||||
return false;
|
||||
}
|
||||
color.linear_size = GetLinearSize(color.tiles);
|
||||
|
||||
@@ -178,10 +178,10 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
|
||||
pitch = (rt.pitch.pitch_div8_minus1 + 1u) << 3u;
|
||||
} else if (tile) {
|
||||
if (volume) {
|
||||
pitch = TileGetTexturePitch(transfer_format, width, levels, rt.attrib3.tile_mode);
|
||||
pitch = TileGetTexturePitch(transfer_format, width, rt.attrib3.tile_mode);
|
||||
} else if (standard64) {
|
||||
pitch = TileGetTexturePitch(Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float),
|
||||
width, levels, rt.attrib3.tile_mode);
|
||||
width, rt.attrib3.tile_mode);
|
||||
} else {
|
||||
pitch = TileGetRenderTargetPitch(width, bytes_per_element, rt.attrib.num_fragments);
|
||||
}
|
||||
@@ -192,13 +192,20 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
|
||||
pitch = width;
|
||||
}
|
||||
|
||||
TileSizeOffset mip_sizes[16] {};
|
||||
TilePaddedSize mip_padded[16] {};
|
||||
TileVolumeLayout volume_layout {};
|
||||
uint64_t backing_size = 0;
|
||||
TileSizeOffset mip_sizes[16] {};
|
||||
TilePaddedSize mip_padded[16] {};
|
||||
TileSurfaceLayout volume_layout {};
|
||||
uint64_t backing_size = 0;
|
||||
if (volume) {
|
||||
if (!tile || !TileGetTextureVolumeLayout(transfer_format, width, height, depth, levels,
|
||||
rt.attrib3.tile_mode, volume_layout)) {
|
||||
const TileSurfaceDescription description {transfer_format,
|
||||
rt.attrib3.tile_mode,
|
||||
TileSurfaceDimension::Dim3D,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
levels,
|
||||
1};
|
||||
if (!tile || !TileGetTiledTextureLayout(description, volume_layout)) {
|
||||
EXIT("unsupported 3D render-target layout: %ux%ux%u levels=%u tile=%u\n", width, height,
|
||||
depth, levels, rt.attrib3.tile_mode);
|
||||
}
|
||||
@@ -209,7 +216,7 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
|
||||
bool valid_layout = false;
|
||||
if (standard64) {
|
||||
TileGetTextureSize(Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float), width,
|
||||
height, pitch, levels, rt.attrib3.tile_mode, &layout, mip_sizes,
|
||||
height, levels, rt.attrib3.tile_mode, &layout, mip_sizes,
|
||||
mip_padded);
|
||||
valid_layout = layout.size != 0 && layout.align == 65536;
|
||||
} else {
|
||||
@@ -289,11 +296,12 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
|
||||
desc.info.tile_mode = rt.attrib3.tile_mode;
|
||||
for (uint32_t level = 0; level < levels; level++) {
|
||||
if (volume) {
|
||||
const auto& mip = volume_layout.mips[level];
|
||||
desc.info.mip_layout[level] = {
|
||||
volume_layout.level_offsets[level],
|
||||
volume_layout.level_sizes[level],
|
||||
volume_layout.level_widths[level],
|
||||
volume_layout.level_heights[level],
|
||||
mip.offset,
|
||||
mip.size,
|
||||
mip.padded_width,
|
||||
mip.padded_height,
|
||||
};
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -168,14 +168,6 @@ RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t raw_layout, uint32_
|
||||
|
||||
namespace {
|
||||
|
||||
static uint64_t GetLevelSrcOffset(const TileSizeOffset& level_size) {
|
||||
return (level_size.src_size != 0 ? level_size.src_offset : level_size.offset);
|
||||
}
|
||||
|
||||
static uint64_t GetLevelSrcSize(const TileSizeOffset& level_size) {
|
||||
return (level_size.src_size != 0 ? level_size.src_size : level_size.size);
|
||||
}
|
||||
|
||||
static uint32_t GetTextureLevelDepth(uint32_t depth, uint32_t level, bool volume_texture) {
|
||||
return volume_texture ? std::max(depth >> level, 1u) : depth;
|
||||
}
|
||||
@@ -188,20 +180,6 @@ static size_t GetTextureRegionCount(uint32_t depth, uint64_t levels, bool volume
|
||||
return count;
|
||||
}
|
||||
|
||||
uint64_t TextureUploadSliceSourceOffset(const TextureUploadLayout& layout, uint32_t level,
|
||||
uint32_t slice) {
|
||||
if (level >= 16 || layout.level_sizes[level].size == 0) {
|
||||
EXIT("invalid texture upload slice source, level=%u slice=%u\n", level, slice);
|
||||
}
|
||||
const auto level_offset = GetLevelSrcOffset(layout.level_sizes[level]);
|
||||
const auto slice_stride =
|
||||
layout.source_slice_stride != 0 ? layout.source_slice_stride : layout.slice_stride;
|
||||
if (slice_stride != 0 && slice > (UINT64_MAX - level_offset) / slice_stride) {
|
||||
EXIT("texture upload slice source offset overflow, level=%u slice=%u\n", level, slice);
|
||||
}
|
||||
return level_offset + static_cast<uint64_t>(slice) * slice_stride;
|
||||
}
|
||||
|
||||
vk::ComponentSwizzle TextureGetComponentSwizzle(uint8_t s) {
|
||||
switch (static_cast<Prospero::CompSwizzle>(s)) {
|
||||
case Prospero::CompSwizzle::kZero: return vk::ComponentSwizzle::eZero;
|
||||
@@ -241,12 +219,11 @@ vk::Format TextureGetFormat(uint32_t fmt) {
|
||||
|
||||
namespace {
|
||||
|
||||
uint64_t CalcTextureSliceStride(const TileSizeOffset* level_sizes, uint64_t levels,
|
||||
uint64_t CalcTextureSliceStride(const TextureUploadMipLayout* mips, uint64_t levels,
|
||||
uint64_t total_size, uint32_t depth) {
|
||||
uint64_t stride = 0;
|
||||
for (uint32_t i = 0; i < levels; i++) {
|
||||
stride =
|
||||
std::max(stride, static_cast<uint64_t>(level_sizes[i].offset) + level_sizes[i].size);
|
||||
stride = std::max(stride, mips[i].offset + mips[i].size);
|
||||
}
|
||||
|
||||
if (depth > 1 && total_size != 0 && total_size % depth == 0) {
|
||||
@@ -259,39 +236,26 @@ uint64_t CalcTextureSliceStride(const TileSizeOffset* level_sizes, uint64_t leve
|
||||
return stride;
|
||||
}
|
||||
|
||||
uint64_t CalcLinearUploadLevelSize(uint32_t fmt, uint32_t pitch, uint32_t height) {
|
||||
if (const uint32_t bytes_per_element = Prospero::NumBytesPerElement(fmt);
|
||||
bytes_per_element != 0) {
|
||||
return static_cast<uint64_t>(pitch) * height * bytes_per_element;
|
||||
}
|
||||
|
||||
if (const uint32_t bytes_per_block = Prospero::BlockCompressedBytesPerBlock(fmt);
|
||||
bytes_per_block != 0) {
|
||||
const uint32_t blocks_w = std::max((pitch + 3u) / 4u, 1u);
|
||||
const uint32_t blocks_h = std::max((height + 3u) / 4u, 1u);
|
||||
return static_cast<uint64_t>(blocks_w) * blocks_h * bytes_per_block;
|
||||
}
|
||||
|
||||
return 0;
|
||||
uint64_t CalcLinearUploadLevelSize(const TileTextureElementLayout& element, uint32_t pitch,
|
||||
uint32_t height) {
|
||||
const uint32_t elements_w =
|
||||
std::max((pitch + element.texel_width - 1u) / element.texel_width, 1u);
|
||||
const uint32_t elements_h =
|
||||
std::max((height + element.texel_height - 1u) / element.texel_height, 1u);
|
||||
return static_cast<uint64_t>(elements_w) * elements_h * element.bytes;
|
||||
}
|
||||
|
||||
uint64_t SetLinearUploadLevels(TileSizeOffset* level_sizes, uint32_t fmt, uint64_t height,
|
||||
uint64_t SetLinearUploadLevels(TextureUploadMipLayout* mips,
|
||||
const TileTextureElementLayout& element, uint64_t height,
|
||||
uint64_t levels, uint32_t base_pitch) {
|
||||
uint64_t offset = 0;
|
||||
auto pitch = base_pitch;
|
||||
auto h = static_cast<uint32_t>(height);
|
||||
|
||||
for (uint32_t i = 0; i < levels; i++) {
|
||||
const auto size = CalcLinearUploadLevelSize(fmt, pitch, h);
|
||||
EXIT_NOT_IMPLEMENTED(size > 0xffffffffull);
|
||||
EXIT_NOT_IMPLEMENTED(offset > 0xffffffffull);
|
||||
|
||||
level_sizes[i].size = static_cast<uint32_t>(size);
|
||||
level_sizes[i].offset = static_cast<uint32_t>(offset);
|
||||
level_sizes[i].src_size = 0;
|
||||
level_sizes[i].src_offset = 0;
|
||||
level_sizes[i].x = 0;
|
||||
level_sizes[i].y = 0;
|
||||
const auto size = CalcLinearUploadLevelSize(element, pitch, h);
|
||||
mips[i].size = size;
|
||||
mips[i].offset = offset;
|
||||
|
||||
offset += size;
|
||||
if (pitch > 1) {
|
||||
@@ -307,141 +271,123 @@ uint64_t SetLinearUploadLevels(TileSizeOffset* level_sizes, uint32_t fmt, uint64
|
||||
|
||||
} // namespace
|
||||
|
||||
TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint64_t width, uint64_t height,
|
||||
uint64_t levels, uint32_t depth, uint64_t pitch,
|
||||
uint64_t tile, uint64_t upload_size,
|
||||
bool allow_depth_tile, bool volume_texture,
|
||||
const char* owner) {
|
||||
TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint32_t width, uint32_t height,
|
||||
uint32_t levels, uint32_t depth, uint32_t tile,
|
||||
uint64_t upload_size, bool allow_depth_tile,
|
||||
bool volume_texture, const char* owner) {
|
||||
TextureUploadLayout layout {};
|
||||
layout.tile = static_cast<uint32_t>(tile);
|
||||
layout.pitch = static_cast<uint32_t>(pitch);
|
||||
layout.texel_block = Prospero::BlockCompressedBytesPerBlock(fmt) != 0 ? 4u : 1u;
|
||||
layout.volume_texture = volume_texture;
|
||||
layout.surface.description = {
|
||||
fmt,
|
||||
tile,
|
||||
volume_texture ? TileSurfaceDimension::Dim3D : TileSurfaceDimension::Dim2D,
|
||||
width,
|
||||
height,
|
||||
volume_texture ? depth : 1u,
|
||||
levels,
|
||||
volume_texture ? 1u : depth,
|
||||
};
|
||||
const auto& description = layout.surface.description;
|
||||
const auto tile_mode = static_cast<Prospero::TileMode>(description.tile_mode);
|
||||
TileTextureElementLayout element {};
|
||||
|
||||
if (fmt != 0) {
|
||||
if (layout.tile != 0) {
|
||||
const auto tile_mode = static_cast<Prospero::TileMode>(layout.tile);
|
||||
switch (tile_mode) {
|
||||
case Prospero::TileMode::kStandard256B:
|
||||
if (TileIsStandard256BTextureSupported(fmt)) {
|
||||
layout.tile_family = TileBlockFamily::Standard256B;
|
||||
}
|
||||
break;
|
||||
case Prospero::TileMode::kStandard4KB:
|
||||
if (TileIsStandard4KBTextureSupported(fmt)) {
|
||||
layout.tile_family = TileBlockFamily::Standard4KB;
|
||||
}
|
||||
break;
|
||||
case Prospero::TileMode::kStandard64KB:
|
||||
if (TileIsStandard64KBTextureSupported(fmt)) {
|
||||
layout.tile_family = TileBlockFamily::Standard64KB;
|
||||
}
|
||||
break;
|
||||
case Prospero::TileMode::kPrt:
|
||||
if (TileIsStandard64KBTextureSupported(fmt)) {
|
||||
layout.tile_family = TileBlockFamily::Prt64KB;
|
||||
}
|
||||
break;
|
||||
case Prospero::TileMode::kRenderTarget:
|
||||
if (Prospero::RenderTargetBytesPerElement(fmt) != 0) {
|
||||
layout.tile_family = TileBlockFamily::RenderTarget64KB;
|
||||
}
|
||||
break;
|
||||
case Prospero::TileMode::kDepth:
|
||||
if (allow_depth_tile && Prospero::RenderTargetBytesPerElement(fmt) != 0) {
|
||||
layout.tile_family = TileBlockFamily::Depth64KB;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (layout.tile_family == TileBlockFamily::Count) {
|
||||
EXIT("%s: unsupported typed tiled upload: fmt=%u tile=%u "
|
||||
"size=%" PRIu64 " extent=%" PRIu64 "x%" PRIu64 " pitch=%" PRIu64
|
||||
" levels=%" PRIu64 "\n",
|
||||
owner, static_cast<uint32_t>(fmt), layout.tile, upload_size, width, height,
|
||||
pitch, levels);
|
||||
}
|
||||
}
|
||||
|
||||
layout.pitch = TileGetTexturePitch(fmt, width, levels, layout.tile);
|
||||
|
||||
TileGetTextureSize(fmt, width, height, layout.pitch, levels, layout.tile, nullptr,
|
||||
layout.level_sizes, layout.padded_sizes);
|
||||
|
||||
if (static_cast<Prospero::TileMode>(layout.tile) != Prospero::TileMode::kLinear) {
|
||||
if (layout.volume_texture) {
|
||||
layout.slice_stride = SetLinearUploadLevels(layout.level_sizes, fmt, height, levels,
|
||||
static_cast<uint32_t>(width));
|
||||
} else {
|
||||
TileSizeOffset tiled_levels[16] {};
|
||||
std::copy_n(layout.level_sizes, levels, tiled_levels);
|
||||
layout.source_slice_stride =
|
||||
CalcTextureSliceStride(tiled_levels, levels, upload_size, depth);
|
||||
SetLinearUploadLevels(layout.level_sizes, fmt, height, levels, layout.pitch);
|
||||
for (uint32_t i = 0; i < levels; ++i) {
|
||||
if (tiled_levels[i].src_size > tiled_levels[i].size) {
|
||||
layout.first_tail_level = std::min(layout.first_tail_level, i);
|
||||
}
|
||||
layout.level_sizes[i].src_offset = GetLevelSrcOffset(tiled_levels[i]);
|
||||
layout.level_sizes[i].src_size = GetLevelSrcSize(tiled_levels[i]);
|
||||
layout.level_sizes[i].x = tiled_levels[i].x;
|
||||
layout.level_sizes[i].y = tiled_levels[i].y;
|
||||
}
|
||||
}
|
||||
} else if (layout.volume_texture) {
|
||||
layout.slice_stride =
|
||||
CalcTextureSliceStride(layout.level_sizes, levels, upload_size, depth);
|
||||
}
|
||||
} else {
|
||||
if (fmt == 0) {
|
||||
EXIT("%s: legacy texture upload format unsupported: fmt=0 tile=%u size=%" PRIu64
|
||||
" extent=%" PRIu64 "x%" PRIu64 " pitch=%" PRIu64 " levels=%" PRIu64 "\n",
|
||||
owner, layout.tile, upload_size, width, height, pitch, levels);
|
||||
" extent=%ux%u levels=%u\n",
|
||||
owner, description.tile_mode, upload_size, width, height, levels);
|
||||
}
|
||||
|
||||
if (!layout.volume_texture) {
|
||||
layout.slice_stride =
|
||||
CalcTextureSliceStride(layout.level_sizes, levels, upload_size, depth);
|
||||
switch (tile_mode) {
|
||||
case Prospero::TileMode::kLinear:
|
||||
if (!TileGetTextureElementLayout(fmt, element)) {
|
||||
EXIT("%s: unsupported linear texture format: fmt=%u\n", owner, fmt);
|
||||
}
|
||||
break;
|
||||
case Prospero::TileMode::kDepth:
|
||||
if (!allow_depth_tile || !TileGetTiledTextureLayout(description, layout.surface)) {
|
||||
EXIT("%s: unsupported typed tiled upload: fmt=%u tile=%u "
|
||||
"size=%" PRIu64 " extent=%ux%u levels=%u\n",
|
||||
owner, static_cast<uint32_t>(fmt), description.tile_mode, upload_size, width,
|
||||
height, levels);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!TileGetTiledTextureLayout(description, layout.surface)) {
|
||||
EXIT("%s: unsupported typed tiled upload: fmt=%u tile=%u "
|
||||
"size=%" PRIu64 " extent=%ux%u levels=%u\n",
|
||||
owner, static_cast<uint32_t>(fmt), description.tile_mode, upload_size, width,
|
||||
height, levels);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (tile_mode != Prospero::TileMode::kLinear) {
|
||||
element = {layout.surface.texture.block.bytes_per_element,
|
||||
layout.surface.texture.texel_width, layout.surface.texture.texel_height};
|
||||
}
|
||||
layout.pitch = TileGetTexturePitch(fmt, width, description.tile_mode);
|
||||
if (tile_mode == Prospero::TileMode::kLinear) {
|
||||
TileSizeOffset level_sizes[16] {};
|
||||
TilePaddedSize padded_sizes[16] {};
|
||||
TileGetTextureSize(fmt, width, height, levels, description.tile_mode, nullptr, level_sizes,
|
||||
padded_sizes);
|
||||
for (uint32_t level = 0; level < levels; ++level) {
|
||||
layout.mips[level] = {level_sizes[level].offset, level_sizes[level].size,
|
||||
padded_sizes[level].width, padded_sizes[level].height};
|
||||
}
|
||||
} else if (volume_texture) {
|
||||
layout.slice_stride = SetLinearUploadLevels(layout.mips, element, height, levels, width);
|
||||
} else {
|
||||
layout.source_slice_stride = layout.surface.block_slice_size;
|
||||
if (depth > 1 && upload_size != 0 && upload_size % depth == 0) {
|
||||
layout.source_slice_stride = std::max(layout.source_slice_stride, upload_size / depth);
|
||||
}
|
||||
SetLinearUploadLevels(layout.mips, element, height, levels, layout.pitch);
|
||||
}
|
||||
|
||||
if (!volume_texture || tile_mode == Prospero::TileMode::kLinear) {
|
||||
layout.slice_stride = CalcTextureSliceStride(layout.mips, levels, upload_size, depth);
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayout& layout,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t depth, uint64_t levels,
|
||||
bool array_texture, bool volume_texture) {
|
||||
uint32_t mip_width = width;
|
||||
uint32_t mip_height = height;
|
||||
uint32_t mip_pitch = volume_texture && static_cast<Prospero::TileMode>(layout.tile) !=
|
||||
Prospero::TileMode::kLinear
|
||||
? width
|
||||
: layout.pitch;
|
||||
std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayout& layout) {
|
||||
const auto& description = layout.surface.description;
|
||||
const bool volume_texture = description.dimension == TileSurfaceDimension::Dim3D;
|
||||
const auto depth = volume_texture ? description.depth : description.layers;
|
||||
uint32_t mip_width = description.width;
|
||||
uint32_t mip_height = description.height;
|
||||
uint32_t mip_pitch = volume_texture && static_cast<Prospero::TileMode>(description.tile_mode) !=
|
||||
Prospero::TileMode::kLinear
|
||||
? description.width
|
||||
: layout.pitch;
|
||||
|
||||
std::vector<vk::BufferImageCopy> regions;
|
||||
regions.reserve(GetTextureRegionCount(depth, levels, volume_texture));
|
||||
for (uint32_t i = 0; i < levels; i++) {
|
||||
EXIT_NOT_IMPLEMENTED(layout.level_sizes[i].size == 0);
|
||||
regions.reserve(GetTextureRegionCount(depth, description.levels, volume_texture));
|
||||
for (uint32_t i = 0; i < description.levels; i++) {
|
||||
EXIT_NOT_IMPLEMENTED(layout.mips[i].size == 0);
|
||||
|
||||
const auto mip_depth = GetTextureLevelDepth(depth, i, volume_texture);
|
||||
|
||||
for (uint32_t z = 0; z < mip_depth; z++) {
|
||||
const auto slice_offset = z * layout.slice_stride;
|
||||
vk::BufferImageCopy region {};
|
||||
region.bufferOffset = layout.level_sizes[i].offset + slice_offset;
|
||||
region.imageSubresource = {vk::ImageAspectFlagBits::eColor, i, array_texture ? z : 0,
|
||||
region.bufferOffset = layout.mips[i].offset + slice_offset;
|
||||
region.imageSubresource = {vk::ImageAspectFlagBits::eColor, i, volume_texture ? 0u : z,
|
||||
1};
|
||||
region.imageOffset.z = volume_texture ? static_cast<int>(z) : 0;
|
||||
region.imageExtent = {mip_width, mip_height, 1};
|
||||
const bool linear =
|
||||
static_cast<Prospero::TileMode>(layout.tile) == Prospero::TileMode::kLinear;
|
||||
const bool linear = static_cast<Prospero::TileMode>(description.tile_mode) ==
|
||||
Prospero::TileMode::kLinear;
|
||||
if (linear) {
|
||||
region.bufferRowLength = layout.padded_sizes[i].width;
|
||||
region.bufferImageHeight = layout.padded_sizes[i].height;
|
||||
region.bufferRowLength = layout.mips[i].row_length;
|
||||
region.bufferImageHeight = layout.mips[i].image_height;
|
||||
} else {
|
||||
const auto align = [](uint32_t value, uint32_t block) {
|
||||
const auto texel_width = layout.surface.texture.texel_width;
|
||||
const auto align = [](uint32_t value, uint32_t block) {
|
||||
return ((value + block - 1u) / block) * block;
|
||||
};
|
||||
const auto pitch = align(mip_pitch, layout.texel_block);
|
||||
region.bufferRowLength = pitch > align(mip_width, layout.texel_block) ? pitch : 0;
|
||||
const auto pitch = align(mip_pitch, texel_width);
|
||||
region.bufferRowLength = pitch > align(mip_width, texel_width) ? pitch : 0;
|
||||
}
|
||||
regions.push_back(region);
|
||||
}
|
||||
@@ -460,24 +406,6 @@ std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayo
|
||||
return regions;
|
||||
}
|
||||
|
||||
struct GpuTileElementLayout {
|
||||
uint32_t bytes = 0;
|
||||
uint32_t wide = 1;
|
||||
uint32_t tall = 1;
|
||||
};
|
||||
|
||||
static bool GetGpuTileElementLayout(uint32_t fmt, GpuTileElementLayout& out) {
|
||||
if (const auto bytes = Prospero::NumBytesPerElement(fmt); bytes != 0) {
|
||||
out = {bytes, 1, 1};
|
||||
return true;
|
||||
}
|
||||
if (const auto bytes = Prospero::BlockCompressedBytesPerBlock(fmt); bytes != 0) {
|
||||
out = {bytes, 4, 4};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SetGpuTileSize(uint64_t offset, uint64_t length, uint64_t capacity, uint64_t& size) {
|
||||
if (offset > capacity || length > capacity - offset) {
|
||||
return false;
|
||||
@@ -487,42 +415,32 @@ static bool SetGpuTileSize(uint64_t offset, uint64_t length, uint64_t capacity,
|
||||
}
|
||||
|
||||
bool TextureBuildGpuTileInfos(uint64_t tiled_size, const std::vector<vk::BufferImageCopy>& regions,
|
||||
const TextureUploadLayout& layout, uint32_t fmt, uint32_t depth,
|
||||
uint64_t levels, std::vector<GpuTileInfo>& out_infos) {
|
||||
const TextureUploadLayout& layout, uint32_t levels,
|
||||
std::vector<GpuTileInfo>& out_infos) {
|
||||
const auto& description = layout.surface.description;
|
||||
const bool volume_texture = description.dimension == TileSurfaceDimension::Dim3D;
|
||||
const auto depth = volume_texture ? description.depth : description.layers;
|
||||
if (tiled_size == 0 || levels == 0 || levels > 16 || depth == 0 ||
|
||||
regions.size() != GetTextureRegionCount(depth, levels, layout.volume_texture) ||
|
||||
Prospero::IsFmaskTextureFormat(fmt)) {
|
||||
regions.size() != GetTextureRegionCount(depth, levels, volume_texture) ||
|
||||
Prospero::IsFmaskTextureFormat(description.format)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GpuTileElementLayout element {};
|
||||
if (layout.tile_family == TileBlockFamily::RenderTarget64KB ||
|
||||
layout.tile_family == TileBlockFamily::Depth64KB) {
|
||||
element.bytes = Prospero::RenderTargetBytesPerElement(fmt);
|
||||
} else if (!GetGpuTileElementLayout(fmt, element)) {
|
||||
return false;
|
||||
}
|
||||
if (element.bytes == 0) {
|
||||
const auto& surface = layout.surface;
|
||||
const auto& texture = surface.texture;
|
||||
const auto& block = texture.block;
|
||||
if (surface.description.levels < levels || block.bytes_per_element == 0 ||
|
||||
block.family == TileBlockFamily::Count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<GpuTileInfo> infos;
|
||||
infos.reserve(regions.size());
|
||||
if (layout.volume_texture) {
|
||||
TileVolumeLayout volume {};
|
||||
if (!TileGetTextureVolumeLayout(fmt, regions[0].imageExtent.width,
|
||||
regions[0].imageExtent.height, depth,
|
||||
static_cast<uint32_t>(levels), layout.tile, volume)) {
|
||||
return false;
|
||||
}
|
||||
element = {volume.bytes_per_element, volume.texel_width, volume.texel_height};
|
||||
TileBlockLayout block {};
|
||||
if (!TileGetBlockLayout(volume.family, element.bytes, block)) return false;
|
||||
|
||||
if (volume_texture) {
|
||||
size_t region_base = 0;
|
||||
for (uint32_t level = 0; level < levels; ++level) {
|
||||
const uint32_t mip_depth = GetTextureLevelDepth(depth, level, true);
|
||||
const bool tail = level >= volume.first_tail_level;
|
||||
const bool tail = level >= surface.first_tail_level;
|
||||
const uint64_t linear_stride = layout.slice_stride;
|
||||
for (uint32_t z = 0; z < mip_depth; z += block.block_depth) {
|
||||
const uint32_t copy_depth = std::min(block.block_depth, mip_depth - z);
|
||||
@@ -537,50 +455,43 @@ bool TextureBuildGpuTileInfos(uint64_t tiled_size, const std::vector<vk::BufferI
|
||||
info.bytes_per_element = block.bytes_per_element;
|
||||
info.linear_offset = region.bufferOffset;
|
||||
info.tiled_offset =
|
||||
static_cast<uint64_t>(z / block.block_depth) * volume.block_slice_size +
|
||||
volume.level_offsets[level];
|
||||
static_cast<uint64_t>(z / block.block_depth) * surface.block_slice_size +
|
||||
surface.mips[level].offset;
|
||||
const uint64_t linear_span =
|
||||
static_cast<uint64_t>(copy_depth - 1u) * linear_stride +
|
||||
layout.level_sizes[level].size;
|
||||
layout.mips[level].size;
|
||||
if (!SetGpuTileSize(info.linear_offset, linear_span, UINT64_MAX,
|
||||
info.linear_size) ||
|
||||
!SetGpuTileSize(info.tiled_offset, volume.level_sizes[level], tiled_size,
|
||||
!SetGpuTileSize(info.tiled_offset, surface.mips[level].size, tiled_size,
|
||||
info.tiled_size)) {
|
||||
return false;
|
||||
}
|
||||
info.linear_slice_stride = linear_stride;
|
||||
info.width =
|
||||
std::max((region.imageExtent.width + element.wide - 1u) / element.wide, 1u);
|
||||
info.height = std::max((logical_height + element.tall - 1u) / element.tall, 1u);
|
||||
info.depth = copy_depth;
|
||||
info.width = std::max((region.imageExtent.width + texture.texel_width - 1u) /
|
||||
texture.texel_width,
|
||||
1u);
|
||||
info.height = std::max(
|
||||
(logical_height + texture.texel_height - 1u) / texture.texel_height, 1u);
|
||||
info.depth = copy_depth;
|
||||
info.surface_z =
|
||||
block.block_depth == 1 ? static_cast<uint32_t>(region.imageOffset.z) : 0;
|
||||
info.pitch = std::max((pitch + element.wide - 1u) / element.wide, 1u);
|
||||
info.tail_x = tail ? volume.tail_x[level] : 0;
|
||||
info.tail_y = tail ? volume.tail_y[level] : 0;
|
||||
info.pitch = std::max((pitch + texture.texel_width - 1u) / texture.texel_width, 1u);
|
||||
info.tail_x = tail ? surface.mips[level].tail_x : 0;
|
||||
info.tail_y = tail ? surface.mips[level].tail_y : 0;
|
||||
info.tail = tail;
|
||||
info.tiled_width = volume.level_widths[level];
|
||||
info.tiled_height = volume.level_heights[level];
|
||||
info.tiled_width = surface.mips[level].padded_width;
|
||||
info.tiled_height = surface.mips[level].padded_height;
|
||||
infos.push_back(info);
|
||||
}
|
||||
region_base += mip_depth;
|
||||
}
|
||||
} else {
|
||||
const auto base_family = layout.tile_family;
|
||||
if (base_family == TileBlockFamily::Count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t region_index = 0;
|
||||
for (uint32_t level = 0; level < levels; level++) {
|
||||
const auto& level_size = layout.level_sizes[level];
|
||||
const bool tail = level >= layout.first_tail_level;
|
||||
const auto family = base_family;
|
||||
TileBlockLayout block {};
|
||||
if (!TileGetBlockLayout(family, element.bytes, block)) {
|
||||
return false;
|
||||
}
|
||||
const auto level_depth = GetTextureLevelDepth(depth, level, layout.volume_texture);
|
||||
const auto& level_size = layout.mips[level];
|
||||
const auto& mip = surface.mips[level];
|
||||
const bool tail = level >= surface.first_tail_level;
|
||||
const auto level_depth = GetTextureLevelDepth(depth, level, false);
|
||||
for (uint32_t z = 0; z < level_depth; z++) {
|
||||
const auto& region = regions[region_index++];
|
||||
const auto pitch =
|
||||
@@ -589,39 +500,36 @@ bool TextureBuildGpuTileInfos(uint64_t tiled_size, const std::vector<vk::BufferI
|
||||
? region.bufferImageHeight
|
||||
: region.imageExtent.height;
|
||||
GpuTileInfo info {};
|
||||
info.family = block.family;
|
||||
info.bytes_per_element = block.bytes_per_element;
|
||||
info.linear_offset = region.bufferOffset;
|
||||
info.tiled_offset = TextureUploadSliceSourceOffset(layout, level, z);
|
||||
if (!SetGpuTileSize(info.linear_offset, level_size.size, UINT64_MAX,
|
||||
info.linear_size) ||
|
||||
!SetGpuTileSize(info.tiled_offset, GetLevelSrcSize(level_size), tiled_size,
|
||||
info.tiled_size)) {
|
||||
info.family = block.family;
|
||||
info.bytes_per_element = block.bytes_per_element;
|
||||
info.linear_offset = region.bufferOffset;
|
||||
const auto source_stride = layout.source_slice_stride != 0
|
||||
? layout.source_slice_stride
|
||||
: surface.block_slice_size;
|
||||
if (z > (UINT64_MAX - mip.offset) / source_stride) {
|
||||
return false;
|
||||
}
|
||||
info.width =
|
||||
std::max((region.imageExtent.width + element.wide - 1u) / element.wide, 1u);
|
||||
info.height = std::max((logical_height + element.tall - 1u) / element.tall, 1u);
|
||||
info.surface_z = base_family == TileBlockFamily::RenderTarget64KB ||
|
||||
base_family == TileBlockFamily::Depth64KB
|
||||
info.tiled_offset = mip.offset + static_cast<uint64_t>(z) * source_stride;
|
||||
if (!SetGpuTileSize(info.linear_offset, level_size.size, UINT64_MAX,
|
||||
info.linear_size) ||
|
||||
!SetGpuTileSize(info.tiled_offset, mip.size, tiled_size, info.tiled_size)) {
|
||||
return false;
|
||||
}
|
||||
info.width = std::max((region.imageExtent.width + texture.texel_width - 1u) /
|
||||
texture.texel_width,
|
||||
1u);
|
||||
info.height = std::max(
|
||||
(logical_height + texture.texel_height - 1u) / texture.texel_height, 1u);
|
||||
info.surface_z = block.family == TileBlockFamily::RenderTarget64KB ||
|
||||
block.family == TileBlockFamily::Depth64KB
|
||||
? region.imageSubresource.baseArrayLayer
|
||||
: 0;
|
||||
info.pitch = std::max((pitch + element.wide - 1u) / element.wide, 1u);
|
||||
info.tail = tail;
|
||||
info.tail_x = tail ? level_size.x : 0;
|
||||
info.tail_y = tail ? level_size.y : 0;
|
||||
info.tiled_width =
|
||||
layout.padded_sizes[level].width != 0
|
||||
? std::max((layout.padded_sizes[level].width + element.wide - 1u) /
|
||||
element.wide,
|
||||
1u)
|
||||
: info.pitch;
|
||||
info.tiled_height =
|
||||
layout.padded_sizes[level].height != 0
|
||||
? std::max((layout.padded_sizes[level].height + element.tall - 1u) /
|
||||
element.tall,
|
||||
1u)
|
||||
: info.height;
|
||||
info.pitch = std::max((pitch + texture.texel_width - 1u) / texture.texel_width, 1u);
|
||||
info.tail = tail;
|
||||
info.tail_x = tail ? mip.tail_x : 0;
|
||||
info.tail_y = tail ? mip.tail_y : 0;
|
||||
info.tiled_width = mip.padded_width;
|
||||
info.tiled_height = mip.padded_height;
|
||||
infos.push_back(info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,34 +19,32 @@ struct RenderTargetFormatInfo {
|
||||
Prospero::ColorComponentMapping export_mapping;
|
||||
};
|
||||
|
||||
struct TextureUploadMipLayout {
|
||||
uint64_t offset = 0;
|
||||
uint64_t size = 0;
|
||||
uint32_t row_length = 0;
|
||||
uint32_t image_height = 0;
|
||||
};
|
||||
|
||||
struct TextureUploadLayout {
|
||||
uint32_t tile = 0;
|
||||
uint32_t pitch = 0;
|
||||
uint32_t texel_block = 1;
|
||||
uint64_t slice_stride = 0;
|
||||
uint64_t source_slice_stride = 0;
|
||||
uint32_t first_tail_level = 16;
|
||||
TileBlockFamily tile_family = TileBlockFamily::Count;
|
||||
bool volume_texture = false;
|
||||
TileSizeOffset level_sizes[16] = {};
|
||||
TilePaddedSize padded_sizes[16] = {};
|
||||
uint32_t pitch = 0;
|
||||
uint64_t slice_stride = 0;
|
||||
uint64_t source_slice_stride = 0;
|
||||
TileSurfaceLayout surface;
|
||||
TextureUploadMipLayout mips[16] = {};
|
||||
};
|
||||
|
||||
vk::ComponentMapping TextureGetComponentMapping(uint32_t swizzle);
|
||||
vk::Format TextureGetFormat(uint32_t fmt);
|
||||
RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t layout, uint32_t type, uint32_t order);
|
||||
TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint64_t width, uint64_t height,
|
||||
uint64_t levels, uint32_t depth, uint64_t pitch,
|
||||
uint64_t tile, uint64_t upload_size,
|
||||
bool allow_depth_tile, bool volume_texture,
|
||||
const char* owner);
|
||||
std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayout& layout,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t depth, uint64_t levels,
|
||||
bool array_texture, bool volume_texture);
|
||||
TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint32_t width, uint32_t height,
|
||||
uint32_t levels, uint32_t depth, uint32_t tile,
|
||||
uint64_t upload_size, bool allow_depth_tile,
|
||||
bool volume_texture, const char* owner);
|
||||
std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayout& layout);
|
||||
bool TextureBuildGpuTileInfos(uint64_t tiled_size, const std::vector<vk::BufferImageCopy>& regions,
|
||||
const TextureUploadLayout& layout, uint32_t fmt, uint32_t depth,
|
||||
uint64_t levels, std::vector<GpuTileInfo>& infos);
|
||||
const TextureUploadLayout& layout, uint32_t levels,
|
||||
std::vector<GpuTileInfo>& infos);
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, c
|
||||
const auto samples = multisampled ? 1u << descriptor.LastLevel() : 1u;
|
||||
const auto pitch =
|
||||
multisampled ? TileGetDepthPitch(width, image.info.bytes_per_block, descriptor.LastLevel())
|
||||
: TileGetTexturePitch(descriptor.Format(), width, 1, descriptor.TileMode());
|
||||
: TileGetTexturePitch(descriptor.Format(), width, descriptor.TileMode());
|
||||
const bool supported_2d = type == Prospero::ImageType::kColor2D &&
|
||||
image.info.resources.layers == 1 && descriptor.Depth() == 0 &&
|
||||
descriptor.BaseArray5() == 0;
|
||||
@@ -321,7 +321,7 @@ static void ValidateDepthTargetBinding(const ShaderRecompiler::IR::ImageResource
|
||||
return;
|
||||
}
|
||||
const auto descriptor_pitch =
|
||||
TileGetTexturePitch(descriptor.Format(), static_cast<uint32_t>(descriptor.Width5()) + 1u, 1,
|
||||
TileGetTexturePitch(descriptor.Format(), static_cast<uint32_t>(descriptor.Width5()) + 1u,
|
||||
descriptor.TileMode());
|
||||
EXIT("unsupported sampled depth target: resource=%d descriptor=%d encoding=%d format=%d "
|
||||
"kind=%u dimension=%u mip_mode=%u read=%d written=%d atomic=%d compare=%d "
|
||||
@@ -373,26 +373,33 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
|
||||
const bool is_3d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D &&
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D) &&
|
||||
descriptor.BaseArray5() == 0;
|
||||
TileBlockLayout depth_block {};
|
||||
const auto depth_bpe = Prospero::RenderTargetBytesPerElement(descriptor.Format());
|
||||
const bool supported_depth_tile =
|
||||
tile == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && !resource.read &&
|
||||
!Prospero::IsFmaskTextureFormat(descriptor.Format()) && (is_2d || is_2d_array) &&
|
||||
TileGetBlockLayout(TileBlockFamily::Depth64KB, depth_bpe, depth_block);
|
||||
const bool supported_standard_256b =
|
||||
(is_2d || is_2d_array) &&
|
||||
tile == Prospero::GpuEnumValue(Prospero::TileMode::kStandard256B) &&
|
||||
TileIsStandard256BTextureSupported(descriptor.Format());
|
||||
const bool supported_standard_tile =
|
||||
(tile == Prospero::GpuEnumValue(Prospero::TileMode::kStandard4KB) &&
|
||||
TileIsStandard4KBTextureSupported(descriptor.Format())) ||
|
||||
(tile == Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB) &&
|
||||
TileIsStandard64KBTextureSupported(descriptor.Format()));
|
||||
const bool supported_tile = tile == Prospero::GpuEnumValue(Prospero::TileMode::kLinear) ||
|
||||
tile == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) ||
|
||||
supported_depth_tile || supported_standard_256b ||
|
||||
supported_standard_tile;
|
||||
const auto swizzle = descriptor.DstSelXYZW();
|
||||
TileTextureBlockLayout tile_layout {};
|
||||
bool supported_tile = false;
|
||||
switch (static_cast<Prospero::TileMode>(tile)) {
|
||||
case Prospero::TileMode::kLinear: supported_tile = true; break;
|
||||
case Prospero::TileMode::kDepth:
|
||||
supported_tile =
|
||||
!resource.read && !Prospero::IsFmaskTextureFormat(descriptor.Format()) &&
|
||||
(is_2d || is_2d_array) &&
|
||||
TileGetTextureBlockLayout(descriptor.Format(), tile, false, tile_layout);
|
||||
break;
|
||||
case Prospero::TileMode::kStandard256B:
|
||||
supported_tile =
|
||||
(is_2d || is_2d_array) &&
|
||||
TileGetTextureBlockLayout(descriptor.Format(), tile, false, tile_layout);
|
||||
break;
|
||||
case Prospero::TileMode::kStandard4KB:
|
||||
case Prospero::TileMode::kStandard64KB:
|
||||
supported_tile =
|
||||
TileGetTextureBlockLayout(descriptor.Format(), tile, is_3d, tile_layout);
|
||||
break;
|
||||
case Prospero::TileMode::kRenderTarget:
|
||||
supported_tile =
|
||||
TileGetTextureBlockLayout(descriptor.Format(), tile, false, tile_layout);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
const auto swizzle = descriptor.DstSelXYZW();
|
||||
const bool supported_swizzle =
|
||||
IsValidImageSwizzle(swizzle) &&
|
||||
(swizzle == DstSel(4, 5, 6, 7) || !resource.read || resource.atomic);
|
||||
@@ -498,18 +505,20 @@ static TextureCache::ImageDesc NullTextureDesc(const ShaderRecompiler::IR::Image
|
||||
|
||||
static void PopulateTextureMipLayout(ImageInfo& info) {
|
||||
if (info.IsVolume() && info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kLinear)) {
|
||||
TileVolumeLayout volume {};
|
||||
if (!TileGetTextureVolumeLayout(info.guest_format, info.extent.width, info.extent.height,
|
||||
info.extent.depth, info.resources.levels, info.tile_mode,
|
||||
volume)) {
|
||||
TileSurfaceLayout surface {};
|
||||
const TileSurfaceDescription description {
|
||||
info.guest_format, info.tile_mode, TileSurfaceDimension::Dim3D, info.extent.width,
|
||||
info.extent.height, info.extent.depth, info.resources.levels, 1};
|
||||
if (!TileGetTiledTextureLayout(description, surface)) {
|
||||
EXIT("unsupported normalized volume texture layout\n");
|
||||
}
|
||||
for (uint32_t level = 0; level < info.resources.levels; level++) {
|
||||
const auto& mip = surface.mips[level];
|
||||
info.mip_layout[level] = {
|
||||
volume.level_offsets[level],
|
||||
volume.level_sizes[level],
|
||||
volume.level_widths[level],
|
||||
volume.level_heights[level],
|
||||
mip.offset,
|
||||
mip.size,
|
||||
mip.padded_width,
|
||||
mip.padded_height,
|
||||
};
|
||||
}
|
||||
return;
|
||||
@@ -517,7 +526,7 @@ static void PopulateTextureMipLayout(ImageInfo& info) {
|
||||
|
||||
TileSizeOffset levels[16] {};
|
||||
TilePaddedSize padded[16] {};
|
||||
TileGetTextureSize(info.guest_format, info.extent.width, info.extent.height, info.pitch,
|
||||
TileGetTextureSize(info.guest_format, info.extent.width, info.extent.height,
|
||||
info.resources.levels, info.tile_mode, nullptr, levels, padded);
|
||||
for (uint32_t level = 0; level < info.resources.levels; level++) {
|
||||
const auto offset =
|
||||
@@ -675,9 +684,9 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
|
||||
}
|
||||
size.size *= image_layers;
|
||||
} else {
|
||||
pitch = TileGetTexturePitch(format, width, levels, tile);
|
||||
TileGetTextureTotalSize(format, width, height, volume ? depth : image_layers, pitch, levels,
|
||||
tile, volume, size);
|
||||
pitch = TileGetTexturePitch(format, width, tile);
|
||||
TileGetTextureTotalSize(format, width, height, volume ? depth : image_layers, levels, tile,
|
||||
volume, size);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(size.size == 0 || size.align == 0 ||
|
||||
(address & (static_cast<uint64_t>(size.align) - 1u)) != 0);
|
||||
|
||||
@@ -537,10 +537,10 @@ Graphics::ImageInfo BufferAttributeGroup::ImageInfo(const VideoOutBuffer& buffer
|
||||
const auto tile_mode =
|
||||
Graphics::Prospero::GpuEnumValue(Graphics::Prospero::TileMode::kRenderTarget);
|
||||
const auto pitch =
|
||||
Graphics::TileGetTexturePitch(pixel_format.guest_format, attribute.width, 1, tile_mode);
|
||||
Graphics::TileGetTexturePitch(pixel_format.guest_format, attribute.width, tile_mode);
|
||||
Graphics::TileSizeAlign total {};
|
||||
Graphics::TileGetTextureTotalSize(pixel_format.guest_format, attribute.width, attribute.height,
|
||||
1, pitch, 1, tile_mode, false, total);
|
||||
1, 1, tile_mode, false, total);
|
||||
if (total.size == 0 || total.align != 65536 ||
|
||||
(buffer.data_address & (total.align - 1u)) != 0) {
|
||||
EXIT("invalid video-out surface footprint or alignment\n");
|
||||
|
||||
@@ -2970,11 +2970,11 @@ public:
|
||||
constexpr uint32_t mip_height = 1;
|
||||
constexpr uint32_t mip_levels = 1;
|
||||
const uint32_t mip_pitch =
|
||||
TileGetTexturePitch(mip_format, mip_width, mip_levels, mip_tile);
|
||||
TileGetTexturePitch(mip_format, mip_width, mip_tile);
|
||||
TileSizeAlign mip_total {};
|
||||
std::array<TileSizeOffset, 16> mip_sizes {};
|
||||
std::array<TilePaddedSize, 16> mip_padded {};
|
||||
TileGetTextureSize(mip_format, mip_width, mip_height, mip_pitch, mip_levels, mip_tile,
|
||||
TileGetTextureSize(mip_format, mip_width, mip_height, mip_levels, mip_tile,
|
||||
&mip_total, mip_sizes.data(), mip_padded.data());
|
||||
const uint64_t mip_prefix_size = mip_sizes[0].offset + mip_sizes[0].size;
|
||||
const uint64_t mip_guest_size = mip_total.size + 256;
|
||||
@@ -3866,11 +3866,10 @@ public:
|
||||
0.625f, 0.75f, 0.875f, 1.0f, 0.0625f};
|
||||
std::memset(memory + layered_offset, 0, layered_guest_size);
|
||||
const auto layered_layout = TextureCalcUploadLayout(
|
||||
Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float), 2, 2, 2, 2, 2,
|
||||
Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float), 2, 2, 2, 2,
|
||||
Prospero::GpuEnumValue(Prospero::TileMode::kLinear), layered_guest_size, true,
|
||||
false, "UnifiedTextureCacheFlow");
|
||||
const auto layered_upload_regions =
|
||||
TextureBuildImageCopies(layered_layout, 2, 2, 2, 2, true, false);
|
||||
const auto layered_upload_regions = TextureBuildImageCopies(layered_layout);
|
||||
Require(name, "layered guest layout", layered_upload_regions.size() == 4,
|
||||
"unexpected layered/mipped upload-region count");
|
||||
for (const auto& region: layered_upload_regions) {
|
||||
@@ -5181,11 +5180,11 @@ public:
|
||||
{
|
||||
GpuResourceManager resources(m_runtime_context, scheduler);
|
||||
resources.MapMemory(base, allocation_size);
|
||||
const uint32_t pitch = TileGetTexturePitch(format, 1, 1, tile);
|
||||
const uint32_t pitch = TileGetTexturePitch(format, 1, tile);
|
||||
TileSizeAlign total {};
|
||||
TileSizeOffset mip {};
|
||||
TilePaddedSize padded {};
|
||||
TileGetTextureSize(format, 1, 1, pitch, 1, tile, &total, &mip, &padded);
|
||||
TileGetTextureSize(format, 1, 1, 1, tile, &total, &mip, &padded);
|
||||
Require(name, "tiled layout", total.size >= 8 && total.size <= allocation_size,
|
||||
"BGRA16 tiled layout exceeds its guest allocation");
|
||||
std::memset(mapped, 0x5a, total.size);
|
||||
@@ -5465,9 +5464,8 @@ public:
|
||||
|
||||
constexpr auto stencil_format = Prospero::GpuEnumValue(Prospero::BufferFormat::k8UInt);
|
||||
constexpr auto linear = Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||
const auto stencil_pitch = TileGetTexturePitch(stencil_format, 1, 1, linear);
|
||||
TileSizeAlign stencil_layout {};
|
||||
TileGetTextureTotalSize(stencil_format, 1, 1, 1, stencil_pitch, 1, linear, false,
|
||||
TileGetTextureTotalSize(stencil_format, 1, 1, 1, 1, linear, false,
|
||||
stencil_layout);
|
||||
Require(name, "stencil footprint",
|
||||
stencil_layout.size != 0 && stencil_layout.align != 0 &&
|
||||
@@ -7717,7 +7715,7 @@ public:
|
||||
TileSizeAlign total {};
|
||||
TileSizeOffset mip[levels] {};
|
||||
TilePaddedSize padded[levels] {};
|
||||
TileGetTextureSize(format, 65, 33, 72, levels,
|
||||
TileGetTextureSize(format, 65, 33, levels,
|
||||
Prospero::GpuEnumValue(Prospero::TileMode::kStandard256B), &total,
|
||||
mip, padded);
|
||||
constexpr u32 offsets[levels] = {0x1a00, 0xb00, 0x500, 0x300, 0x200, 0x100, 0};
|
||||
@@ -7826,18 +7824,57 @@ public:
|
||||
struct StandardMode {
|
||||
u32 tile;
|
||||
TileBlockFamily family;
|
||||
bool (*supported)(u32);
|
||||
};
|
||||
constexpr StandardMode standard_modes[] = {
|
||||
{Prospero::GpuEnumValue(Prospero::TileMode::kStandard256B),
|
||||
TileBlockFamily::Standard256B, TileIsStandard256BTextureSupported},
|
||||
{Prospero::GpuEnumValue(Prospero::TileMode::kStandard4KB), TileBlockFamily::Standard4KB,
|
||||
TileIsStandard4KBTextureSupported},
|
||||
TileBlockFamily::Standard256B},
|
||||
{Prospero::GpuEnumValue(Prospero::TileMode::kStandard4KB),
|
||||
TileBlockFamily::Standard4KB},
|
||||
{Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB),
|
||||
TileBlockFamily::Standard64KB, TileIsStandard64KBTextureSupported},
|
||||
{Prospero::GpuEnumValue(Prospero::TileMode::kPrt), TileBlockFamily::Prt64KB,
|
||||
TileIsStandard64KBTextureSupported},
|
||||
TileBlockFamily::Standard64KB},
|
||||
{Prospero::GpuEnumValue(Prospero::TileMode::kPrt), TileBlockFamily::Prt64KB},
|
||||
};
|
||||
for (const auto format: {Prospero::BufferFormat::k8Srgb,
|
||||
Prospero::BufferFormat::k8_8Srgb,
|
||||
Prospero::BufferFormat::k9_9_9_5Float}) {
|
||||
for (const auto tile: {Prospero::TileMode::kDepth,
|
||||
Prospero::TileMode::kRenderTarget}) {
|
||||
TileTextureBlockLayout texture {};
|
||||
Require(name, "RT format policy",
|
||||
!TileGetTextureBlockLayout(Prospero::GpuEnumValue(format),
|
||||
Prospero::GpuEnumValue(tile), false, texture),
|
||||
"non-render-target format admitted by an RT/depth tile family");
|
||||
}
|
||||
}
|
||||
{
|
||||
TileSurfaceLayout invalid {};
|
||||
const TileSurfaceDescription description {
|
||||
Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float),
|
||||
Prospero::GpuEnumValue(Prospero::TileMode::kStandard256B),
|
||||
TileSurfaceDimension::Dim3D,
|
||||
16,
|
||||
16,
|
||||
16,
|
||||
1,
|
||||
1,
|
||||
};
|
||||
Require(name, "3D tile policy", !TileGetTiledTextureLayout(description, invalid),
|
||||
"Standard256B volume silently fell back to a 2D array layout");
|
||||
}
|
||||
{
|
||||
constexpr u32 format =
|
||||
Prospero::GpuEnumValue(Prospero::BufferFormat::kFmask8_S4_F4);
|
||||
constexpr u32 tile = Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureSize(format, 128, 128, 1, tile, &total, nullptr, nullptr);
|
||||
const auto layout = TextureCalcUploadLayout(format, 128, 128, 1, 1, tile, total.size,
|
||||
false, false, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
Require(name, "FMASK policy",
|
||||
!TextureBuildGpuTileInfos(total.size, regions, layout, 1, infos),
|
||||
"FMASK entered the texel tiler through a non-depth family");
|
||||
}
|
||||
u32 format_cases = 0;
|
||||
for (u32 format = 1; format <= Prospero::GpuEnumValue(Prospero::BufferFormat::kBc7Srgb);
|
||||
++format) {
|
||||
@@ -7847,30 +7884,28 @@ public:
|
||||
continue;
|
||||
}
|
||||
for (const auto& mode: standard_modes) {
|
||||
if (!mode.supported(format)) {
|
||||
TileTextureBlockLayout texture {};
|
||||
if (!TileGetTextureBlockLayout(format, mode.tile, false, texture)) {
|
||||
continue;
|
||||
}
|
||||
const u32 bpe = std::max(Prospero::NumBytesPerElement(format),
|
||||
Prospero::BlockCompressedBytesPerBlock(format));
|
||||
TileBlockLayout block {};
|
||||
Require(name, "format block", TileGetBlockLayout(mode.family, bpe, block),
|
||||
"CPU-supported format has no GPU family/BPE mapping");
|
||||
const u32 bpe = texture.block.bytes_per_element;
|
||||
Require(name, "format block", texture.block.family == mode.family,
|
||||
"CPU-supported format selected the wrong block family");
|
||||
|
||||
constexpr u32 width = 67;
|
||||
constexpr u32 height = 51;
|
||||
const u32 pitch = TileGetTexturePitch(format, width, 1, mode.tile);
|
||||
const u32 pitch = TileGetTexturePitch(format, width, mode.tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureSize(format, width, height, pitch, 1, mode.tile, &total, nullptr,
|
||||
TileGetTextureSize(format, width, height, 1, mode.tile, &total, nullptr,
|
||||
nullptr);
|
||||
Require(name, "format size", total.size != 0,
|
||||
"supported format has an empty layout");
|
||||
|
||||
const auto layout = TextureCalcUploadLayout(
|
||||
format, width, height, 1, 1, pitch, mode.tile, total.size, false, false, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, 1, 1, false, false);
|
||||
format, width, height, 1, 1, mode.tile, total.size, false, false, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
if (!TextureBuildGpuTileInfos(total.size, regions, layout, format, 1, 1, infos)) {
|
||||
if (!TextureBuildGpuTileInfos(total.size, regions, layout, 1, infos)) {
|
||||
std::ostringstream out;
|
||||
out << "format=" << format << " tile=" << mode.tile << " size=" << total.size
|
||||
<< " pitch=" << pitch;
|
||||
@@ -7894,27 +7929,31 @@ public:
|
||||
Require(name, "format coverage", format_cases != 0,
|
||||
"no CPU-supported standard formats were tested");
|
||||
|
||||
{
|
||||
constexpr u32 format = Prospero::GpuEnumValue(Prospero::BufferFormat::k32_32_32Float);
|
||||
TileTextureElementLayout element {};
|
||||
Require(name, "RGB32 texture policy", !TileGetTextureElementLayout(format, element),
|
||||
"12-byte texel layouts must be rejected");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr u32 format = Prospero::GpuEnumValue(Prospero::BufferFormat::kBc1UNorm);
|
||||
constexpr u32 tile = Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB);
|
||||
constexpr u32 width = 256, height = 256, levels = 9;
|
||||
const u32 pitch = TileGetTexturePitch(format, width, levels, tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureSize(format, width, height, pitch, levels, tile, &total, nullptr,
|
||||
TileGetTextureSize(format, width, height, levels, tile, &total, nullptr,
|
||||
nullptr);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, 1, pitch,
|
||||
tile, total.size, false, false, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, 1, levels, false, false);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, 1, tile,
|
||||
total.size, false, false, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
const bool built =
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, format, 1, levels, infos);
|
||||
const bool built = TextureBuildGpuTileInfos(total.size, regions, layout, levels, infos);
|
||||
uint64_t linear_size = 0;
|
||||
for (const auto& info: infos) {
|
||||
linear_size = std::max(linear_size, info.linear_offset + info.linear_size);
|
||||
}
|
||||
Require(name, "BC1 mip-tail capacities",
|
||||
built && total.size == 0x10000 && layout.first_tail_level == 0 &&
|
||||
built && total.size == 0x10000 && layout.surface.first_tail_level == 0 &&
|
||||
linear_size == 0x15560 && linear_size > total.size,
|
||||
"BC1 mip tail conflated tiled and linear capacities");
|
||||
check_round_trip("BC1 mip tail", total.size, infos);
|
||||
@@ -7924,16 +7963,13 @@ public:
|
||||
constexpr u32 format = Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float);
|
||||
constexpr u32 tile = Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget);
|
||||
constexpr u32 width = 129, height = 65, layers = 3;
|
||||
const u32 pitch = TileGetTexturePitch(format, width, 1, tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureTotalSize(format, width, height, layers, pitch, 1, tile, false, total);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, 1, layers, pitch,
|
||||
tile, total.size, true, false, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, layers, 1, true, false);
|
||||
TileGetTextureTotalSize(format, width, height, layers, 1, tile, false, total);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, 1, layers, tile,
|
||||
total.size, true, false, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
const bool built =
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, format, layers, 1, infos);
|
||||
const bool built = TextureBuildGpuTileInfos(total.size, regions, layout, 1, infos);
|
||||
Require(name, "array infos",
|
||||
built && infos.size() == layers && infos[0].surface_z == 0 &&
|
||||
infos[1].surface_z == 1 && infos[2].surface_z == 2,
|
||||
@@ -7949,18 +7985,16 @@ public:
|
||||
"odd multi-mip format has no block layout");
|
||||
const u32 width = block.block_width * 2u + 1u;
|
||||
const u32 height = block.block_height * 2u + 1u;
|
||||
const u32 pitch = TileGetTexturePitch(format, width, levels, mode.tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureSize(format, width, height, pitch, levels, mode.tile, &total, nullptr,
|
||||
TileGetTextureSize(format, width, height, levels, mode.tile, &total, nullptr,
|
||||
nullptr);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, 1, pitch,
|
||||
mode.tile, total.size, false, false, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, 1, levels, false, false);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, 1, mode.tile,
|
||||
total.size, false, false, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
Require(
|
||||
name, "odd mip infos",
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, format, 1, levels, infos) &&
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, levels, infos) &&
|
||||
infos.size() == 2 && infos[1].tiled_width >= infos[1].pitch &&
|
||||
infos[1].tiled_height >= infos[1].height &&
|
||||
(mode.family == TileBlockFamily::Standard256B ||
|
||||
@@ -7992,19 +8026,16 @@ public:
|
||||
"2D tail mode has no block layout");
|
||||
const u32 width = block.block_width * 2u;
|
||||
const u32 height = block.block_height * 2u;
|
||||
const u32 pitch = TileGetTexturePitch(format, width, levels, mode.tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureSize(format, width, height, pitch, levels, mode.tile, &total, nullptr,
|
||||
TileGetTextureSize(format, width, height, levels, mode.tile, &total, nullptr,
|
||||
nullptr);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, 1, pitch,
|
||||
mode.tile, total.size, true, false, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, 1, levels, false, false);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, 1, mode.tile,
|
||||
total.size, true, false, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
Require(name, "2D mip tail seam",
|
||||
layout.first_tail_level == 2 &&
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, format, 1, levels,
|
||||
infos) &&
|
||||
layout.surface.first_tail_level == 2 &&
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, levels, infos) &&
|
||||
infos.size() == levels && !infos[0].tail && !infos[1].tail &&
|
||||
std::all_of(infos.begin() + 2, infos.end(),
|
||||
[](const auto& info) { return info.tail; }),
|
||||
@@ -8019,16 +8050,13 @@ public:
|
||||
constexpr u32 height = 129;
|
||||
constexpr u32 depth = 17;
|
||||
constexpr u32 levels = 2;
|
||||
const u32 pitch = TileGetTexturePitch(format, width, levels, tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureTotalSize(format, width, height, depth, pitch, levels, tile, true, total);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, depth, pitch,
|
||||
tile, total.size, false, true, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, depth, levels, false, true);
|
||||
TileGetTextureTotalSize(format, width, height, depth, levels, tile, true, total);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, depth, tile,
|
||||
total.size, false, true, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
const bool built =
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, format, depth, levels, infos);
|
||||
const bool built = TextureBuildGpuTileInfos(total.size, regions, layout, levels, infos);
|
||||
Require(name, "3D mip infos",
|
||||
regions.size() == depth + (depth >> 1u) && built && infos.size() == 4 &&
|
||||
infos[0].depth == 8 && infos[1].depth == 8 && infos[2].depth == 1 &&
|
||||
@@ -8048,17 +8076,14 @@ public:
|
||||
constexpr u32 height = 129;
|
||||
constexpr u32 depth = 17;
|
||||
constexpr u32 levels = 2;
|
||||
const u32 pitch = TileGetTexturePitch(format, width, levels, tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureTotalSize(format, width, height, depth, pitch, levels, tile, true, total);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, depth, pitch,
|
||||
tile, total.size, false, true, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, depth, levels, false, true);
|
||||
TileGetTextureTotalSize(format, width, height, depth, levels, tile, true, total);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, depth, tile,
|
||||
total.size, false, true, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
Require(name, "3D BC mip infos",
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, format, depth, levels,
|
||||
infos) &&
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, levels, infos) &&
|
||||
infos.size() == 4 && infos[3].pitch == 8 && infos[3].height == 16 &&
|
||||
infos[3].tiled_width == 16 && infos[3].tiled_height == 24,
|
||||
"block-compressed 3D mip lost its physical row or slice stride");
|
||||
@@ -8069,14 +8094,12 @@ public:
|
||||
constexpr u32 format = Prospero::GpuEnumValue(Prospero::BufferFormat::kBc3UNorm);
|
||||
constexpr u32 tile = Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||
constexpr u32 width = 8, height = 8, levels = 4;
|
||||
const u32 pitch = TileGetTexturePitch(format, width, levels, tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureSize(format, width, height, pitch, levels, tile, &total, nullptr,
|
||||
TileGetTextureSize(format, width, height, levels, tile, &total, nullptr,
|
||||
nullptr);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, 1, pitch,
|
||||
tile, total.size, false, false, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, 1, levels, false, false);
|
||||
const auto layout = TextureCalcUploadLayout(format, width, height, levels, 1, tile,
|
||||
total.size, false, false, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
Require(name, "linear BC native regions",
|
||||
regions.size() == levels &&
|
||||
std::all_of(regions.begin(), regions.end(),
|
||||
@@ -8114,18 +8137,15 @@ public:
|
||||
};
|
||||
for (const auto test: volume_modes) {
|
||||
constexpr u32 width = 65, height = 33, depth = 37, levels = 6;
|
||||
const u32 pitch = TileGetTexturePitch(test.format, width, levels, test.tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureTotalSize(test.format, width, height, depth, pitch, levels, test.tile,
|
||||
true, total);
|
||||
TileGetTextureTotalSize(test.format, width, height, depth, levels, test.tile, true,
|
||||
total);
|
||||
const auto layout =
|
||||
TextureCalcUploadLayout(test.format, width, height, levels, depth, pitch, test.tile,
|
||||
TextureCalcUploadLayout(test.format, width, height, levels, depth, test.tile,
|
||||
total.size, true, true, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, depth, levels, false, true);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
const bool built = TextureBuildGpuTileInfos(total.size, regions, layout, test.format,
|
||||
depth, levels, infos);
|
||||
const bool built = TextureBuildGpuTileInfos(total.size, regions, layout, levels, infos);
|
||||
const bool uses_z = test.family == TileBlockFamily::RenderTarget64KB ||
|
||||
test.family == TileBlockFamily::Depth64KB;
|
||||
Require(
|
||||
@@ -8168,21 +8188,18 @@ public:
|
||||
const u32 width = block.block_width * (compressed ? 4u : 1u);
|
||||
const u32 height = block.block_height / 2u * (compressed ? 4u : 1u);
|
||||
const u32 depth = block.block_depth + 1u;
|
||||
const u32 pitch = TileGetTexturePitch(tail.format, width, levels, tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureTotalSize(tail.format, width, height, depth, pitch, levels, tile, true,
|
||||
TileGetTextureTotalSize(tail.format, width, height, depth, levels, tile, true,
|
||||
total);
|
||||
const auto layout = TextureCalcUploadLayout(tail.format, width, height, levels, depth,
|
||||
pitch, tile, total.size, false, true, name);
|
||||
const auto regions =
|
||||
TextureBuildImageCopies(layout, width, height, depth, levels, false, true);
|
||||
tile, total.size, false, true, name);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
std::vector<GpuTileInfo> infos;
|
||||
bool valid =
|
||||
total.size == 8192 &&
|
||||
regions.size() == depth + std::max(depth >> 1u, 1u) + std::max(depth >> 2u, 1u) +
|
||||
std::max(depth >> 3u, 1u) + std::max(depth >> 4u, 1u) &&
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, tail.format, depth, levels,
|
||||
infos) &&
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, levels, infos) &&
|
||||
infos.size() == 6;
|
||||
const u32 table = std::countr_zero(tail.bytes);
|
||||
for (u32 level = 0; level < levels && valid; level++) {
|
||||
@@ -8280,15 +8297,14 @@ public:
|
||||
constexpr u32 volume_width = 8, volume_height = 4, volume_depth = 5;
|
||||
constexpr u32 volume_levels = 3;
|
||||
const u32 volume_pitch =
|
||||
TileGetTexturePitch(volume_format, volume_width, volume_levels, volume_tile);
|
||||
TileGetTexturePitch(volume_format, volume_width, volume_tile);
|
||||
TileSizeAlign volume_size {};
|
||||
TileGetTextureTotalSize(volume_format, volume_width, volume_height, volume_depth,
|
||||
volume_pitch, volume_levels, volume_tile, true, volume_size);
|
||||
volume_levels, volume_tile, true, volume_size);
|
||||
const auto volume_layout = TextureCalcUploadLayout(
|
||||
volume_format, volume_width, volume_height, volume_levels, volume_depth, volume_pitch,
|
||||
volume_tile, volume_size.size, true, true, name);
|
||||
const auto volume_copies = TextureBuildImageCopies(
|
||||
volume_layout, volume_width, volume_height, volume_depth, volume_levels, false, true);
|
||||
volume_format, volume_width, volume_height, volume_levels, volume_depth, volume_tile,
|
||||
volume_size.size, true, true, name);
|
||||
const auto volume_copies = TextureBuildImageCopies(volume_layout);
|
||||
std::vector<u32> volume_source(volume_size.size / sizeof(u32), 0);
|
||||
std::vector<std::pair<size_t, u32>> volume_probes;
|
||||
for (const auto& copy: volume_copies) {
|
||||
@@ -8323,9 +8339,10 @@ public:
|
||||
volume_info.bytes_per_block = sizeof(u32);
|
||||
volume_info.tile_mode = volume_tile;
|
||||
for (u32 level = 0; level < volume_levels; level++) {
|
||||
volume_info.mip_layout[level] = {
|
||||
volume_layout.level_sizes[level].offset, volume_layout.level_sizes[level].size,
|
||||
volume_layout.padded_sizes[level].width, volume_layout.padded_sizes[level].height};
|
||||
volume_info.mip_layout[level] = {volume_layout.mips[level].offset,
|
||||
volume_layout.mips[level].size,
|
||||
volume_layout.mips[level].row_length,
|
||||
volume_layout.mips[level].image_height};
|
||||
}
|
||||
Libs::Graphics::Image volume_image(m_runtime_context, scheduler, volume_info);
|
||||
volume_image.Upload(volume_copies, volume_upload.buffer, 0, volume_size.size);
|
||||
@@ -16988,12 +17005,10 @@ void CheckBasicStorageTextureDescriptor() {
|
||||
}};
|
||||
auto standard256b_resource = BasicBgraStorageTextureResource();
|
||||
standard256b_resource.kind = ShaderRecompiler::IR::ResourceKind::StorageImageUint;
|
||||
const auto standard256b_pitch = TileGetTexturePitch(
|
||||
standard256b.Format(), standard256b.Width5() + 1u, 1, standard256b.TileMode());
|
||||
TileSizeAlign standard256b_size {};
|
||||
TileGetTextureTotalSize(standard256b.Format(), standard256b.Width5() + 1u,
|
||||
standard256b.Height5() + 1u, standard256b.Depth() + 1u,
|
||||
standard256b_pitch, 1, standard256b.TileMode(), false,
|
||||
1, standard256b.TileMode(), false,
|
||||
standard256b_size);
|
||||
Require("BasicStorageTexture", "Standard256B uint 2D descriptor",
|
||||
standard256b.Width5() + 1u == 2 && standard256b.Height5() + 1u == 2 &&
|
||||
@@ -17009,10 +17024,8 @@ void CheckBasicStorageTextureDescriptor() {
|
||||
ValidateStorageTexture(standard256b_resource, standard256b, standard256b_size.size);
|
||||
|
||||
const auto standard4kb_array = Standard4KBUintArrayStorageTextureDescriptor();
|
||||
const auto standard4kb_pitch =
|
||||
TileGetTexturePitch(standard4kb_array.Format(), 1, 1, standard4kb_array.TileMode());
|
||||
TileSizeAlign standard4kb_size {};
|
||||
TileGetTextureTotalSize(standard4kb_array.Format(), 1, 1, 1, standard4kb_pitch, 1,
|
||||
TileGetTextureTotalSize(standard4kb_array.Format(), 1, 1, 1, 1,
|
||||
standard4kb_array.TileMode(), false, standard4kb_size);
|
||||
Require(
|
||||
"BasicStorageTexture", "Standard4KB uint 2D-array descriptor",
|
||||
@@ -17029,11 +17042,9 @@ void CheckBasicStorageTextureDescriptor() {
|
||||
auto based_standard4kb_array = standard4kb_array;
|
||||
based_standard4kb_array.fields[0] = 0x006c6800u;
|
||||
based_standard4kb_array.fields[4] = 0x00010001u;
|
||||
const auto based_standard4kb_pitch = TileGetTexturePitch(based_standard4kb_array.Format(), 1, 1,
|
||||
based_standard4kb_array.TileMode());
|
||||
TileSizeAlign based_standard4kb_size {};
|
||||
TileGetTextureTotalSize(based_standard4kb_array.Format(), 1, 1,
|
||||
based_standard4kb_array.Depth() + 1u, based_standard4kb_pitch, 1,
|
||||
based_standard4kb_array.Depth() + 1u, 1,
|
||||
based_standard4kb_array.TileMode(), false, based_standard4kb_size);
|
||||
Require("BasicStorageTexture", "based Standard4KB array view",
|
||||
based_standard4kb_array.Base40() == 0x6c680000ull &&
|
||||
@@ -17044,12 +17055,10 @@ void CheckBasicStorageTextureDescriptor() {
|
||||
based_standard4kb_size.size);
|
||||
|
||||
const auto standard64kb = Standard64KBStorageTextureDescriptor();
|
||||
const auto standard64kb_pitch = TileGetTexturePitch(
|
||||
standard64kb.Format(), standard64kb.Width5() + 1u, 1, standard64kb.TileMode());
|
||||
TileSizeAlign standard64kb_size {};
|
||||
TileGetTextureTotalSize(standard64kb.Format(), standard64kb.Width5() + 1u,
|
||||
standard64kb.Height5() + 1u, standard64kb.Depth() + 1u,
|
||||
standard64kb_pitch, 1, standard64kb.TileMode(), false,
|
||||
1, standard64kb.TileMode(), false,
|
||||
standard64kb_size);
|
||||
Require("BasicStorageTexture", "Standard64KB 2D descriptor",
|
||||
standard64kb.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) &&
|
||||
@@ -17109,11 +17118,11 @@ void CheckBasicStorageTextureDescriptor() {
|
||||
d16_depth_tile.DstSelXYZW() == DstSel(4, 0, 0, 1),
|
||||
"PPSA10112 writable D16 depth-plane descriptor fixture is malformed");
|
||||
const auto d16_pitch = TileGetTexturePitch(
|
||||
d16_depth_tile.Format(), d16_depth_tile.Width5() + 1u, 1, d16_depth_tile.TileMode());
|
||||
d16_depth_tile.Format(), d16_depth_tile.Width5() + 1u, d16_depth_tile.TileMode());
|
||||
TileSizeAlign d16_size {};
|
||||
TileGetTextureTotalSize(d16_depth_tile.Format(), d16_depth_tile.Width5() + 1u,
|
||||
d16_depth_tile.Height5() + 1u, d16_depth_tile.Depth() + 1u, d16_pitch,
|
||||
1, d16_depth_tile.TileMode(), false, d16_size);
|
||||
d16_depth_tile.Height5() + 1u, d16_depth_tile.Depth() + 1u, 1,
|
||||
d16_depth_tile.TileMode(), false, d16_size);
|
||||
Require("BasicStorageTexture", "PPSA10112 D16 depth-tile footprint",
|
||||
d16_pitch == 256 && d16_size.size == 0x20000 && d16_size.align == 0x10000,
|
||||
"PPSA10112 writable D16 depth-plane footprint is incorrect");
|
||||
@@ -17191,16 +17200,17 @@ void CheckStorageTextureLinearUploadLayout() {
|
||||
constexpr uint32_t height = 2160;
|
||||
constexpr uint32_t depth = 1;
|
||||
constexpr uint32_t tile = Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||
const auto pitch = TileGetTexturePitch(format, width, 1, tile);
|
||||
const auto pitch = TileGetTexturePitch(format, width, tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureTotalSize(format, width, height, depth, pitch, 1, tile, false, total);
|
||||
TileGetTextureTotalSize(format, width, height, depth, 1, tile, false, total);
|
||||
const auto layout =
|
||||
TextureCalcUploadLayout(format, width, height, 1, depth, pitch, tile, total.size, true,
|
||||
TextureCalcUploadLayout(format, width, height, 1, depth, tile, total.size, true,
|
||||
false, "StorageTextureLinearTest");
|
||||
const auto regions = TextureBuildImageCopies(layout, width, height, depth, 1, false, false);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
Require("StorageTextureLinearUpload", "layout",
|
||||
pitch == width && total.size == 0x1fa4000 && total.align == 256 &&
|
||||
layout.tile == tile && layout.pitch == width && layout.slice_stride == total.size &&
|
||||
layout.surface.description.tile_mode == tile && layout.pitch == width &&
|
||||
layout.slice_stride == total.size &&
|
||||
regions.size() == 1 && regions[0].bufferOffset == 0 &&
|
||||
regions[0].imageExtent.width == width && regions[0].imageExtent.height == height &&
|
||||
regions[0].bufferRowLength == width,
|
||||
@@ -17214,25 +17224,27 @@ void CheckStorageTextureDepthTileUploadLayout() {
|
||||
constexpr uint32_t height = 1;
|
||||
constexpr uint32_t depth = 1;
|
||||
constexpr uint32_t tile = Prospero::GpuEnumValue(Prospero::TileMode::kDepth);
|
||||
const auto pitch = TileGetTexturePitch(format, width, 1, tile);
|
||||
const auto pitch = TileGetTexturePitch(format, width, tile);
|
||||
TileSizeAlign slice {};
|
||||
TileSizeAlign total {};
|
||||
TileSizeOffset level {};
|
||||
TilePaddedSize padded {};
|
||||
TileGetTextureSize(format, width, height, pitch, 1, tile, &slice, &level, &padded);
|
||||
TileGetTextureTotalSize(format, width, height, depth, pitch, 1, tile, false, total);
|
||||
TileGetTextureSize(format, width, height, 1, tile, &slice, &level, &padded);
|
||||
TileGetTextureTotalSize(format, width, height, depth, 1, tile, false, total);
|
||||
const auto layout =
|
||||
TextureCalcUploadLayout(format, width, height, 1, depth, pitch, tile, total.size, true,
|
||||
TextureCalcUploadLayout(format, width, height, 1, depth, tile, total.size, true,
|
||||
false, "StorageTextureDepthTileTest");
|
||||
const auto regions = TextureBuildImageCopies(layout, width, height, depth, 1, true, false);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
Require("StorageTextureDepthTileUpload", "PPSA14053 layout",
|
||||
pitch == 256 && padded.width == 256 && padded.height == 256 && slice.size == 0x10000 &&
|
||||
slice.align == 0x10000 && level.size == slice.size && level.offset == 0 &&
|
||||
total.size == slice.size && total.align == slice.align && layout.tile == tile &&
|
||||
layout.tile_family == TileBlockFamily::Depth64KB && layout.pitch == pitch &&
|
||||
total.size == slice.size && total.align == slice.align &&
|
||||
layout.surface.description.tile_mode == tile &&
|
||||
layout.surface.texture.block.family == TileBlockFamily::Depth64KB &&
|
||||
layout.pitch == pitch &&
|
||||
layout.slice_stride == pitch && layout.source_slice_stride == total.size &&
|
||||
layout.level_sizes[0].size == pitch &&
|
||||
layout.level_sizes[0].src_size == total.size && regions.size() == 1 &&
|
||||
layout.mips[0].size == pitch &&
|
||||
layout.surface.mips[0].size == total.size && regions.size() == 1 &&
|
||||
regions[0].bufferOffset == 0 && regions[0].imageExtent.width == width &&
|
||||
regions[0].imageExtent.height == height && regions[0].bufferRowLength == pitch,
|
||||
"1x1 R8_UINT depth tile lost its 64 KiB source footprint");
|
||||
@@ -17274,24 +17286,24 @@ void CheckStorageTextureVolumeUploadLayout() {
|
||||
constexpr uint32_t height = 33;
|
||||
constexpr uint32_t depth = 33;
|
||||
const auto pitch = TileGetTexturePitch(
|
||||
format, width, 1, Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget));
|
||||
format, width, Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget));
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureTotalSize(format, width, height, depth, pitch, 1,
|
||||
TileGetTextureTotalSize(format, width, height, depth, 1,
|
||||
Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget), true, total);
|
||||
const auto layout =
|
||||
TextureCalcUploadLayout(format, width, height, 1, depth, pitch,
|
||||
TextureCalcUploadLayout(format, width, height, 1, depth,
|
||||
Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget),
|
||||
total.size, true, true, "StorageTextureVolumeTest");
|
||||
const auto regions = TextureBuildImageCopies(layout, width, height, depth, 1, false, true);
|
||||
const auto regions = TextureBuildImageCopies(layout);
|
||||
Require("StorageTextureVolumeUpload", "layout",
|
||||
pitch == 128 && total.size == 0x210000 && layout.slice_stride == 0x2208 &&
|
||||
layout.source_slice_stride == 0 && layout.level_sizes[0].size == 0x2208 &&
|
||||
layout.level_sizes[0].src_size == 0 && regions.size() == depth,
|
||||
layout.source_slice_stride == 0 && layout.mips[0].size == 0x2208 &&
|
||||
layout.surface.mips[0].size == 0x10000 && regions.size() == depth,
|
||||
"3D render-target upload did not preserve its compact linear layout");
|
||||
|
||||
std::vector<GpuTileInfo> infos;
|
||||
Require("StorageTextureVolumeUpload", "GPU records",
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, format, depth, 1, infos) &&
|
||||
TextureBuildGpuTileInfos(total.size, regions, layout, 1, infos) &&
|
||||
infos.size() == depth,
|
||||
"3D render-target GPU records were not built");
|
||||
for (const uint32_t z: {0u, 1u, depth - 1u}) {
|
||||
@@ -17311,13 +17323,12 @@ void CheckStorageTextureVolumeMipRegions() {
|
||||
constexpr uint32_t depth = 5;
|
||||
constexpr uint32_t levels = 3;
|
||||
constexpr uint32_t tile = Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||
const auto pitch = TileGetTexturePitch(format, width, levels, tile);
|
||||
TileSizeAlign total {};
|
||||
TileGetTextureTotalSize(format, width, height, depth, pitch, levels, tile, true, total);
|
||||
TileGetTextureTotalSize(format, width, height, depth, levels, tile, true, total);
|
||||
const auto layout =
|
||||
TextureCalcUploadLayout(format, width, height, levels, depth, pitch, tile, total.size, true,
|
||||
TextureCalcUploadLayout(format, width, height, levels, depth, tile, total.size, true,
|
||||
true, "StorageTextureVolumeMipTest");
|
||||
const auto copies = TextureBuildImageCopies(layout, width, height, depth, levels, false, true);
|
||||
const auto copies = TextureBuildImageCopies(layout);
|
||||
|
||||
bool valid = copies.size() == 8;
|
||||
size_t index = 0;
|
||||
@@ -17331,9 +17342,9 @@ void CheckStorageTextureVolumeMipRegions() {
|
||||
copy.imageSubresource.mipLevel == level &&
|
||||
copy.imageOffset.z == static_cast<int>(z) && copy.imageExtent.width == mip_width &&
|
||||
copy.imageExtent.height == mip_height &&
|
||||
copy.bufferOffset == layout.level_sizes[level].offset + z * layout.slice_stride &&
|
||||
copy.bufferRowLength == layout.padded_sizes[level].width &&
|
||||
copy.bufferImageHeight == layout.padded_sizes[level].height;
|
||||
copy.bufferOffset == layout.mips[level].offset + z * layout.slice_stride &&
|
||||
copy.bufferRowLength == layout.mips[level].row_length &&
|
||||
copy.bufferImageHeight == layout.mips[level].image_height;
|
||||
}
|
||||
}
|
||||
valid &= index == copies.size();
|
||||
@@ -17348,9 +17359,9 @@ void CheckStandard64RenderTargetTileRoundTrip() {
|
||||
|
||||
constexpr uint32_t observed_width = 3840;
|
||||
constexpr uint32_t observed_height = 2160;
|
||||
const auto observed_pitch = TileGetTexturePitch(format, observed_width, 1, tile);
|
||||
const auto observed_pitch = TileGetTexturePitch(format, observed_width, tile);
|
||||
TileSizeAlign observed {};
|
||||
TileGetTextureSize(format, observed_width, observed_height, observed_pitch, 1, tile, &observed,
|
||||
TileGetTextureSize(format, observed_width, observed_height, 1, tile, &observed,
|
||||
nullptr, nullptr);
|
||||
Require("Standard64RenderTarget", "observed layout",
|
||||
observed_pitch == 3840 && observed.size == 0x1fe0000 && observed.align == 0x10000,
|
||||
@@ -17358,9 +17369,9 @@ void CheckStandard64RenderTargetTileRoundTrip() {
|
||||
|
||||
constexpr uint32_t width = 257;
|
||||
constexpr uint32_t height = 131;
|
||||
const auto pitch = TileGetTexturePitch(format, width, 1, tile);
|
||||
const auto pitch = TileGetTexturePitch(format, width, tile);
|
||||
TileSizeAlign storage {};
|
||||
TileGetTextureSize(format, width, height, pitch, 1, tile, &storage, nullptr, nullptr);
|
||||
TileGetTextureSize(format, width, height, 1, tile, &storage, nullptr, nullptr);
|
||||
Require("Standard64RenderTarget", "partial layout",
|
||||
pitch == 384 && storage.size == 0x60000 && storage.align == 0x10000,
|
||||
"partial Standard64KB footprint was not padded in 128x128 blocks");
|
||||
@@ -17838,11 +17849,11 @@ void CheckDepthTargetFootprints() {
|
||||
"non-HTile depth/stencil footprint disagrees with Prospero block rules");
|
||||
|
||||
const auto depth_pitch =
|
||||
TileGetTexturePitch(Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float), 640, 1,
|
||||
TileGetTexturePitch(Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float), 640,
|
||||
Prospero::GpuEnumValue(Prospero::TileMode::kDepth));
|
||||
TileSizeAlign texture_depth {};
|
||||
TileGetTextureTotalSize(Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float), 640, 360, 1,
|
||||
depth_pitch, 1, Prospero::GpuEnumValue(Prospero::TileMode::kDepth),
|
||||
1, Prospero::GpuEnumValue(Prospero::TileMode::kDepth),
|
||||
false, texture_depth);
|
||||
Require("DepthTargetFootprints", "640x360 generic depth tile",
|
||||
depth_pitch == 640 && texture_depth.size == 0xf0000 && texture_depth.align == 0x10000,
|
||||
|
||||
Reference in new issue
Block a user