graphics: replace raw GPU enum values with typed formats

This commit is contained in:
nmzik committed 2026-08-11 16:12:38 +02:00
1 parent 11b95bed20
commit 21aa7b66ce
36 files changed
+903 -857

No files matched your search

@@ -526,9 +526,12 @@ KYTY_HW_CTX_PARSER(HwCtxSetColorInfo) {
// r.format = (buffer[4] >> 2u) & 0x1fu; // r.format = (buffer[4] >> 2u) & 0x1fu;
// r.channel_type = (buffer[4] >> 8u) & 0x7u; // r.channel_type = (buffer[4] >> 8u) & 0x7u;
// r.channel_order = (buffer[4] >> 11u) & 0x3u; // r.channel_order = (buffer[4] >> 11u) & 0x3u;
r.format = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, FORMAT); r.format =
r.channel_type = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, NUMBER_TYPE); static_cast<Prospero::ChannelLayout>(KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, FORMAT));
r.channel_order = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, COMP_SWAP); r.channel_type =
static_cast<Prospero::ChannelType>(KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, NUMBER_TYPE));
r.channel_order =
static_cast<Prospero::ChannelOrder>(KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, COMP_SWAP));
r.cmask_fast_clear_enable = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, FAST_CLEAR) != 0; r.cmask_fast_clear_enable = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, FAST_CLEAR) != 0;
r.fmask_compression_enable = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, COMPRESSION) != 0; r.fmask_compression_enable = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, COMPRESSION) != 0;
r.blend_clamp = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, BLEND_CLAMP) != 0; r.blend_clamp = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, BLEND_CLAMP) != 0;
@@ -1042,9 +1045,12 @@ KYTY_HW_CTX_PARSER(HwCtxSetRenderTarget) {
// info.format = (buffer[4] >> 2u) & 0x1fu; // info.format = (buffer[4] >> 2u) & 0x1fu;
// info.channel_type = (buffer[4] >> 8u) & 0x7u; // info.channel_type = (buffer[4] >> 8u) & 0x7u;
// info.channel_order = (buffer[4] >> 11u) & 0x3u; // info.channel_order = (buffer[4] >> 11u) & 0x3u;
info.format = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, FORMAT); info.format =
info.channel_type = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, NUMBER_TYPE); static_cast<Prospero::ChannelLayout>(KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, FORMAT));
info.channel_order = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, COMP_SWAP); info.channel_type =
static_cast<Prospero::ChannelType>(KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, NUMBER_TYPE));
info.channel_order =
static_cast<Prospero::ChannelOrder>(KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, COMP_SWAP));
info.cmask_fast_clear_enable = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, FAST_CLEAR) != 0; info.cmask_fast_clear_enable = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, FAST_CLEAR) != 0;
info.fmask_compression_enable = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, COMPRESSION) != 0; info.fmask_compression_enable = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, COMPRESSION) != 0;
info.blend_clamp = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, BLEND_CLAMP) != 0; info.blend_clamp = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, BLEND_CLAMP) != 0;
@@ -1066,8 +1072,10 @@ KYTY_HW_CTX_PARSER(HwCtxSetRenderTarget) {
// attrib.num_fragments = (buffer[5] >> 15u) & 0x3u; // attrib.num_fragments = (buffer[5] >> 15u) & 0x3u;
attrib.force_dest_alpha_to_one = attrib.force_dest_alpha_to_one =
KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, FORCE_DST_ALPHA_1) != 0; KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, FORCE_DST_ALPHA_1) != 0;
attrib.tile_mode = KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, TILE_MODE_INDEX); attrib.tile_mode =
attrib.fmask_tile_mode = KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, FMASK_TILE_MODE_INDEX); static_cast<Prospero::TileMode>(KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, TILE_MODE_INDEX));
attrib.fmask_tile_mode = static_cast<Prospero::TileMode>(
KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, FMASK_TILE_MODE_INDEX));
attrib.num_samples = KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, NUM_SAMPLES); attrib.num_samples = KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, NUM_SAMPLES);
attrib.num_fragments = KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, NUM_FRAGMENTS); attrib.num_fragments = KYTY_PM4_GET(buffer[5], CB_COLOR0_ATTRIB, NUM_FRAGMENTS);
@@ -1568,7 +1576,7 @@ KYTY_HW_UC_PARSER(HwUcSetPrimitiveType) {
uint32_t prim_type = KYTY_PM4_GET(buffer[0], VGT_PRIMITIVE_TYPE, PRIM_TYPE); uint32_t prim_type = KYTY_PM4_GET(buffer[0], VGT_PRIMITIVE_TYPE, PRIM_TYPE);
cp.GetUcfg().SetPrimitiveType(prim_type); cp.GetUcfg().SetPrimitiveType(static_cast<Prospero::PrimitiveType>(prim_type));
return 1; return 1;
} }
@@ -3106,9 +3114,12 @@ void GraphicsInitJmpTablesCxIndirect() {
g_hw_ctx_indirect_func[cmd_offset] = [](KYTY_HW_CTX_INDIRECT_ARGS) { g_hw_ctx_indirect_func[cmd_offset] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
uint32_t slot = (cmd_offset - Pm4::CB_COLOR0_INFO) / 15; uint32_t slot = (cmd_offset - Pm4::CB_COLOR0_INFO) / 15;
HW::ColorInfo info; HW::ColorInfo info;
info.format = KYTY_PM4_GET(value, CB_COLOR0_INFO, FORMAT); info.format =
info.channel_type = KYTY_PM4_GET(value, CB_COLOR0_INFO, NUMBER_TYPE); static_cast<Prospero::ChannelLayout>(KYTY_PM4_GET(value, CB_COLOR0_INFO, FORMAT));
info.channel_order = KYTY_PM4_GET(value, CB_COLOR0_INFO, COMP_SWAP); info.channel_type = static_cast<Prospero::ChannelType>(
KYTY_PM4_GET(value, CB_COLOR0_INFO, NUMBER_TYPE));
info.channel_order =
static_cast<Prospero::ChannelOrder>(KYTY_PM4_GET(value, CB_COLOR0_INFO, COMP_SWAP));
info.cmask_fast_clear_enable = KYTY_PM4_GET(value, CB_COLOR0_INFO, FAST_CLEAR) != 0; info.cmask_fast_clear_enable = KYTY_PM4_GET(value, CB_COLOR0_INFO, FAST_CLEAR) != 0;
info.fmask_compression_enable = KYTY_PM4_GET(value, CB_COLOR0_INFO, COMPRESSION) != 0; info.fmask_compression_enable = KYTY_PM4_GET(value, CB_COLOR0_INFO, COMPRESSION) != 0;
info.blend_clamp = KYTY_PM4_GET(value, CB_COLOR0_INFO, BLEND_CLAMP) != 0; info.blend_clamp = KYTY_PM4_GET(value, CB_COLOR0_INFO, BLEND_CLAMP) != 0;
@@ -3133,8 +3144,10 @@ void GraphicsInitJmpTablesCxIndirect() {
HW::ColorAttrib attrib; HW::ColorAttrib attrib;
attrib.force_dest_alpha_to_one = attrib.force_dest_alpha_to_one =
KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, FORCE_DST_ALPHA_1) != 0; KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, FORCE_DST_ALPHA_1) != 0;
attrib.tile_mode = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, TILE_MODE_INDEX); attrib.tile_mode = static_cast<Prospero::TileMode>(
attrib.fmask_tile_mode = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, FMASK_TILE_MODE_INDEX); KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, TILE_MODE_INDEX));
attrib.fmask_tile_mode = static_cast<Prospero::TileMode>(
KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, FMASK_TILE_MODE_INDEX));
attrib.num_samples = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, NUM_SAMPLES); attrib.num_samples = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, NUM_SAMPLES);
attrib.num_fragments = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, NUM_FRAGMENTS); attrib.num_fragments = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB, NUM_FRAGMENTS);
cp.GetCtx().SetColorAttrib(slot, attrib); cp.GetCtx().SetColorAttrib(slot, attrib);
@@ -3291,7 +3304,8 @@ void GraphicsInitJmpTablesCxIndirect() {
uint32_t slot = (cmd_offset - Pm4::CB_COLOR0_ATTRIB3); uint32_t slot = (cmd_offset - Pm4::CB_COLOR0_ATTRIB3);
HW::ColorAttrib3 attrib3; HW::ColorAttrib3 attrib3;
attrib3.depth = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, MIP0_DEPTH); attrib3.depth = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, MIP0_DEPTH);
attrib3.tile_mode = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, COLOR_SW_MODE); attrib3.tile_mode = static_cast<Prospero::TileMode>(
KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, COLOR_SW_MODE));
attrib3.dimension = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, RESOURCE_TYPE); attrib3.dimension = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, RESOURCE_TYPE);
attrib3.cmask_pipe_aligned = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, CMASK_PIPE_ALIGNED); attrib3.cmask_pipe_aligned = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, CMASK_PIPE_ALIGNED);
attrib3.dcc_pipe_aligned = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, DCC_PIPE_ALIGNED); attrib3.dcc_pipe_aligned = KYTY_PM4_GET(value, CB_COLOR0_ATTRIB3, DCC_PIPE_ALIGNED);
@@ -4467,7 +4481,7 @@ void GraphicsInitJmpTablesUcIndirect() {
g_hw_uc_indirect_func[Pm4::VGT_PRIMITIVE_TYPE] = [](KYTY_HW_UC_INDIRECT_ARGS) { g_hw_uc_indirect_func[Pm4::VGT_PRIMITIVE_TYPE] = [](KYTY_HW_UC_INDIRECT_ARGS) {
uint32_t prim_type = KYTY_PM4_GET(value, VGT_PRIMITIVE_TYPE, PRIM_TYPE); uint32_t prim_type = KYTY_PM4_GET(value, VGT_PRIMITIVE_TYPE, PRIM_TYPE);
cp.GetUcfg().SetPrimitiveType(prim_type); cp.GetUcfg().SetPrimitiveType(static_cast<Prospero::PrimitiveType>(prim_type));
}; };
g_hw_uc_indirect_func[Pm4::VGT_INDEX_TYPE] = [](KYTY_HW_UC_INDIRECT_ARGS) { g_hw_uc_indirect_func[Pm4::VGT_INDEX_TYPE] = [](KYTY_HW_UC_INDIRECT_ARGS) {
cp.SetIndexType(value & 0x3u); cp.SetIndexType(value & 0x3u);
-7
View File
@@ -3,15 +3,8 @@
#include "common/common.h" #include "common/common.h"
#include <type_traits>
namespace Libs::Graphics::Prospero { namespace Libs::Graphics::Prospero {
template <typename T>
constexpr auto GpuEnumValue(T value) {
return static_cast<std::underlying_type_t<T>>(value);
}
enum class PrimitiveType : uint32_t { enum class PrimitiveType : uint32_t {
kNone = 0, kNone = 0,
kPointList = 1, kPointList = 1,
+87 -87
View File
@@ -9,7 +9,7 @@ namespace Libs::Graphics::Prospero {
namespace { namespace {
struct FormatInfo { struct FormatInfo {
uint32_t format; BufferFormat format;
uint32_t bytes_per_element; uint32_t bytes_per_element;
uint32_t block_compressed_bytes_per_block; uint32_t block_compressed_bytes_per_block;
uint32_t render_target_bytes_per_element; uint32_t render_target_bytes_per_element;
@@ -18,74 +18,74 @@ struct FormatInfo {
}; };
constexpr FormatInfo kFormatInfo[] = { constexpr FormatInfo kFormatInfo[] = {
{GpuEnumValue(BufferFormat::k8UNorm), 1, 0, 1, true, false}, {BufferFormat::k8UNorm, 1, 0, 1, true, false},
{GpuEnumValue(BufferFormat::k8SNorm), 0, 0, 1, false, false}, {BufferFormat::k8SNorm, 0, 0, 1, false, false},
{GpuEnumValue(BufferFormat::k8UInt), 1, 0, 1, true, true}, {BufferFormat::k8UInt, 1, 0, 1, true, true},
{GpuEnumValue(BufferFormat::k16UNorm), 2, 0, 2, true, false}, {BufferFormat::k16UNorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k16SNorm), 2, 0, 2, true, false}, {BufferFormat::k16SNorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k16UInt), 2, 0, 2, true, true}, {BufferFormat::k16UInt, 2, 0, 2, true, true},
{GpuEnumValue(BufferFormat::k16SInt), 2, 0, 2, false, false}, {BufferFormat::k16SInt, 2, 0, 2, false, false},
{GpuEnumValue(BufferFormat::k16Float), 2, 0, 2, true, false}, {BufferFormat::k16Float, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8UNorm), 2, 0, 2, true, false}, {BufferFormat::k8_8UNorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8SNorm), 2, 0, 2, true, false}, {BufferFormat::k8_8SNorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8UInt), 2, 0, 2, true, true}, {BufferFormat::k8_8UInt, 2, 0, 2, true, true},
{GpuEnumValue(BufferFormat::k8_8SInt), 2, 0, 2, false, false}, {BufferFormat::k8_8SInt, 2, 0, 2, false, false},
{GpuEnumValue(BufferFormat::k32UInt), 4, 0, 4, true, true}, {BufferFormat::k32UInt, 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k32SInt), 4, 0, 4, false, false}, {BufferFormat::k32SInt, 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k32Float), 4, 0, 4, true, false}, {BufferFormat::k32Float, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16UNorm), 4, 0, 4, true, false}, {BufferFormat::k16_16UNorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16SNorm), 4, 0, 4, true, false}, {BufferFormat::k16_16SNorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16UInt), 4, 0, 4, true, true}, {BufferFormat::k16_16UInt, 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k16_16SInt), 4, 0, 4, false, false}, {BufferFormat::k16_16SInt, 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k16_16Float), 4, 0, 4, true, false}, {BufferFormat::k16_16Float, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k11_11_10Float), 4, 0, 4, true, false}, {BufferFormat::k11_11_10Float, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k10_10_10_2UNorm), 4, 0, 4, true, false}, {BufferFormat::k10_10_10_2UNorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k10_10_10_2UInt), 4, 0, 4, true, true}, {BufferFormat::k10_10_10_2UInt, 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k8_8_8_8UNorm), 4, 0, 4, true, false}, {BufferFormat::k8_8_8_8UNorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8SNorm), 4, 0, 4, true, false}, {BufferFormat::k8_8_8_8SNorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8UInt), 4, 0, 4, true, true}, {BufferFormat::k8_8_8_8UInt, 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k8_8_8_8SInt), 4, 0, 4, false, false}, {BufferFormat::k8_8_8_8SInt, 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k32_32UInt), 8, 0, 8, true, true}, {BufferFormat::k32_32UInt, 8, 0, 8, true, true},
{GpuEnumValue(BufferFormat::k32_32SInt), 8, 0, 8, false, false}, {BufferFormat::k32_32SInt, 8, 0, 8, false, false},
{GpuEnumValue(BufferFormat::k32_32Float), 8, 0, 8, true, false}, {BufferFormat::k32_32Float, 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k16_16_16_16UNorm), 8, 0, 8, true, false}, {BufferFormat::k16_16_16_16UNorm, 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k16_16_16_16SNorm), 8, 0, 8, true, false}, {BufferFormat::k16_16_16_16SNorm, 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k16_16_16_16UInt), 8, 0, 8, true, true}, {BufferFormat::k16_16_16_16UInt, 8, 0, 8, true, true},
{GpuEnumValue(BufferFormat::k16_16_16_16SInt), 8, 0, 8, false, false}, {BufferFormat::k16_16_16_16SInt, 8, 0, 8, false, false},
{GpuEnumValue(BufferFormat::k16_16_16_16Float), 8, 0, 8, true, false}, {BufferFormat::k16_16_16_16Float, 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k32_32_32UInt), 12, 0, 12, true, true}, {BufferFormat::k32_32_32UInt, 12, 0, 12, true, true},
{GpuEnumValue(BufferFormat::k32_32_32SInt), 12, 0, 12, false, false}, {BufferFormat::k32_32_32SInt, 12, 0, 12, false, false},
{GpuEnumValue(BufferFormat::k32_32_32Float), 12, 0, 12, true, false}, {BufferFormat::k32_32_32Float, 12, 0, 12, true, false},
{GpuEnumValue(BufferFormat::k32_32_32_32UInt), 16, 0, 16, true, true}, {BufferFormat::k32_32_32_32UInt, 16, 0, 16, true, true},
{GpuEnumValue(BufferFormat::k32_32_32_32SInt), 16, 0, 16, false, false}, {BufferFormat::k32_32_32_32SInt, 16, 0, 16, false, false},
{GpuEnumValue(BufferFormat::k32_32_32_32Float), 16, 0, 16, true, false}, {BufferFormat::k32_32_32_32Float, 16, 0, 16, true, false},
{GpuEnumValue(BufferFormat::k8Srgb), 1, 0, 0, true, false}, {BufferFormat::k8Srgb, 1, 0, 0, true, false},
{GpuEnumValue(BufferFormat::k8_8Srgb), 2, 0, 0, true, false}, {BufferFormat::k8_8Srgb, 2, 0, 0, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8Srgb), 4, 0, 4, true, false}, {BufferFormat::k8_8_8_8Srgb, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k9_9_9_5Float), 4, 0, 0, true, false}, {BufferFormat::k9_9_9_5Float, 4, 0, 0, true, false},
{GpuEnumValue(BufferFormat::k5_6_5UNorm), 2, 0, 2, true, false}, {BufferFormat::k5_6_5UNorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k5_5_5_1UNorm), 2, 0, 2, true, false}, {BufferFormat::k5_5_5_1UNorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k1_5_5_5UNorm), 0, 0, 2, false, false}, {BufferFormat::k1_5_5_5UNorm, 0, 0, 2, false, false},
{GpuEnumValue(BufferFormat::k4_4_4_4UNorm), 2, 0, 2, true, false}, {BufferFormat::k4_4_4_4UNorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::kFmask8_S4_F4), 1, 0, 1, true, false}, {BufferFormat::kFmask8_S4_F4, 1, 0, 1, true, false},
{GpuEnumValue(BufferFormat::kBc1UNorm), 0, 8, 0, true, false}, {BufferFormat::kBc1UNorm, 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc1Srgb), 0, 8, 0, true, false}, {BufferFormat::kBc1Srgb, 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc2UNorm), 0, 16, 0, true, false}, {BufferFormat::kBc2UNorm, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc2Srgb), 0, 16, 0, true, false}, {BufferFormat::kBc2Srgb, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc3UNorm), 0, 16, 0, true, false}, {BufferFormat::kBc3UNorm, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc3Srgb), 0, 16, 0, true, false}, {BufferFormat::kBc3Srgb, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc4UNorm), 0, 8, 0, true, false}, {BufferFormat::kBc4UNorm, 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc4SNorm), 0, 8, 0, true, false}, {BufferFormat::kBc4SNorm, 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc5UNorm), 0, 16, 0, true, false}, {BufferFormat::kBc5UNorm, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc5SNorm), 0, 16, 0, true, false}, {BufferFormat::kBc5SNorm, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc6UFloat), 0, 16, 0, true, false}, {BufferFormat::kBc6UFloat, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc6SFloat), 0, 16, 0, true, false}, {BufferFormat::kBc6SFloat, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc7UNorm), 0, 16, 0, true, false}, {BufferFormat::kBc7UNorm, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc7Srgb), 0, 16, 0, true, false}, {BufferFormat::kBc7Srgb, 0, 16, 0, true, false},
}; };
constexpr uint8_t RenderTargetTypeBit(ChannelType type) { constexpr uint8_t RenderTargetTypeBit(ChannelType type) {
return static_cast<uint8_t>(1u << GpuEnumValue(type)); return static_cast<uint8_t>(1u << static_cast<uint32_t>(type));
} }
constexpr auto kUNormType = RenderTargetTypeBit(ChannelType::kUNorm); constexpr auto kUNormType = RenderTargetTypeBit(ChannelType::kUNorm);
@@ -137,9 +137,9 @@ constexpr RenderTargetLayoutInfo kRenderTargetLayouts[] = {
ChannelType::kFloat, ChannelOrderSupport::kStandardOnly}, ChannelType::kFloat, ChannelOrderSupport::kStandardOnly},
}; };
const RenderTargetLayoutInfo* FindRenderTargetLayout(uint32_t layout) { const RenderTargetLayoutInfo* FindRenderTargetLayout(ChannelLayout layout) {
for (const auto& info: kRenderTargetLayouts) { for (const auto& info: kRenderTargetLayouts) {
if (GpuEnumValue(info.layout) == layout) { if (info.layout == layout) {
return &info; return &info;
} }
} }
@@ -147,38 +147,38 @@ const RenderTargetLayoutInfo* FindRenderTargetLayout(uint32_t layout) {
} }
constexpr auto MakeFormatInfoLookup() { constexpr auto MakeFormatInfoLookup() {
constexpr uint32_t kMaxFormat = GpuEnumValue(BufferFormat::kBc7Srgb); constexpr size_t kMaxFormat = static_cast<size_t>(BufferFormat::kBc7Srgb);
std::array<const FormatInfo*, kMaxFormat + 1> lookup {}; std::array<const FormatInfo*, kMaxFormat + 1> lookup {};
for (const auto& info: kFormatInfo) { for (const auto& info: kFormatInfo) {
lookup[info.format] = &info; lookup[static_cast<size_t>(info.format)] = &info;
} }
return lookup; return lookup;
} }
constexpr auto kFormatInfoLookup = MakeFormatInfoLookup(); constexpr auto kFormatInfoLookup = MakeFormatInfoLookup();
const FormatInfo* FindFormatInfo(uint32_t format) { const FormatInfo* FindFormatInfo(BufferFormat format) {
return format < kFormatInfoLookup.size() ? kFormatInfoLookup[format] : nullptr; const auto index = static_cast<size_t>(format);
return index < kFormatInfoLookup.size() ? kFormatInfoLookup[index] : nullptr;
} }
} // namespace } // namespace
RenderTargetFormatEncoding ResolveRenderTargetFormat(uint32_t layout, uint32_t type) { RenderTargetFormatEncoding ResolveRenderTargetFormat(ChannelLayout layout, ChannelType type) {
const auto* layout_info = FindRenderTargetLayout(layout); const auto* layout_info = FindRenderTargetLayout(layout);
if (layout_info == nullptr || type >= 8u) { const auto raw_type = static_cast<uint32_t>(type);
if (layout_info == nullptr || raw_type >= 8u) {
return {}; return {};
} }
const auto channel_type = static_cast<ChannelType>(type);
auto format = BufferFormat::kInvalid; auto format = BufferFormat::kInvalid;
if (layout_info->extra_format != BufferFormat::kInvalid && if (layout_info->extra_format != BufferFormat::kInvalid && type == layout_info->extra_type) {
channel_type == layout_info->extra_type) {
format = layout_info->extra_format; format = layout_info->extra_format;
} else if ((layout_info->linear_type_mask & (1u << type)) != 0) { } else if ((layout_info->linear_type_mask & (1u << raw_type)) != 0) {
const auto first_type = const auto first_type =
std::countr_zero(static_cast<uint32_t>(layout_info->linear_type_mask)); std::countr_zero(static_cast<uint32_t>(layout_info->linear_type_mask));
format = static_cast<BufferFormat>(GpuEnumValue(layout_info->first_linear_format) + type - format = static_cast<BufferFormat>(static_cast<uint32_t>(layout_info->first_linear_format) +
first_type); raw_type - first_type);
} }
if (format == BufferFormat::kInvalid) { if (format == BufferFormat::kInvalid) {
return {}; return {};
@@ -186,33 +186,33 @@ RenderTargetFormatEncoding ResolveRenderTargetFormat(uint32_t layout, uint32_t t
return {format, layout_info->components, layout_info->order_support}; return {format, layout_info->components, layout_info->order_support};
} }
uint32_t NumBytesPerElement(uint32_t format) { uint32_t NumBytesPerElement(BufferFormat format) {
const auto* info = FindFormatInfo(format); const auto* info = FindFormatInfo(format);
return info != nullptr ? info->bytes_per_element : 0; return info != nullptr ? info->bytes_per_element : 0;
} }
uint32_t BlockCompressedBytesPerBlock(uint32_t format) { uint32_t BlockCompressedBytesPerBlock(BufferFormat format) {
const auto* info = FindFormatInfo(format); const auto* info = FindFormatInfo(format);
return info != nullptr ? info->block_compressed_bytes_per_block : 0; return info != nullptr ? info->block_compressed_bytes_per_block : 0;
} }
uint32_t RenderTargetBytesPerElement(uint32_t format) { uint32_t RenderTargetBytesPerElement(BufferFormat format) {
const auto* info = FindFormatInfo(format); const auto* info = FindFormatInfo(format);
return info != nullptr ? info->render_target_bytes_per_element : 0; return info != nullptr ? info->render_target_bytes_per_element : 0;
} }
bool IsSupportedTextureFormat(uint32_t format) { bool IsSupportedTextureFormat(BufferFormat format) {
const auto* info = FindFormatInfo(format); const auto* info = FindFormatInfo(format);
return info != nullptr && info->supported_sampled_texture_format; return info != nullptr && info->supported_sampled_texture_format;
} }
bool IsUintTextureFormat(uint32_t format) { bool IsUintTextureFormat(BufferFormat format) {
const auto* info = FindFormatInfo(format); const auto* info = FindFormatInfo(format);
return info != nullptr && info->unsigned_integer_texture_format; return info != nullptr && info->unsigned_integer_texture_format;
} }
bool IsFmaskTextureFormat(uint32_t format) { bool IsFmaskTextureFormat(BufferFormat format) {
return format == GpuEnumValue(BufferFormat::kFmask8_S4_F4); return format == BufferFormat::kFmask8_S4_F4;
} }
} // namespace Libs::Graphics::Prospero } // namespace Libs::Graphics::Prospero
+16 -11
View File
@@ -21,24 +21,29 @@ struct RenderTargetFormatEncoding {
order_support != ChannelOrderSupport::kNone; order_support != ChannelOrderSupport::kNone;
} }
[[nodiscard]] constexpr bool SupportsOrder(uint32_t raw_order) const { [[nodiscard]] constexpr bool SupportsOrder(ChannelOrder order) const {
switch (order_support) { switch (order_support) {
case ChannelOrderSupport::kStandardOnly: case ChannelOrderSupport::kStandardOnly: return order == ChannelOrder::kStandard;
return raw_order == GpuEnumValue(ChannelOrder::kStandard);
case ChannelOrderSupport::kAll: case ChannelOrderSupport::kAll:
return raw_order <= GpuEnumValue(ChannelOrder::kAltReversed); switch (order) {
case ChannelOrder::kStandard:
case ChannelOrder::kAlt:
case ChannelOrder::kReversed:
case ChannelOrder::kAltReversed: return true;
}
return false;
default: return false; default: return false;
} }
} }
}; };
RenderTargetFormatEncoding ResolveRenderTargetFormat(uint32_t layout, uint32_t type); RenderTargetFormatEncoding ResolveRenderTargetFormat(ChannelLayout layout, ChannelType type);
uint32_t NumBytesPerElement(uint32_t format); uint32_t NumBytesPerElement(BufferFormat format);
uint32_t BlockCompressedBytesPerBlock(uint32_t format); uint32_t BlockCompressedBytesPerBlock(BufferFormat format);
uint32_t RenderTargetBytesPerElement(uint32_t format); uint32_t RenderTargetBytesPerElement(BufferFormat format);
bool IsSupportedTextureFormat(uint32_t format); bool IsSupportedTextureFormat(BufferFormat format);
bool IsUintTextureFormat(uint32_t format); bool IsUintTextureFormat(BufferFormat format);
bool IsFmaskTextureFormat(uint32_t format); bool IsFmaskTextureFormat(BufferFormat format);
} // namespace Libs::Graphics::Prospero } // namespace Libs::Graphics::Prospero
+16 -16
View File
@@ -39,15 +39,15 @@ struct ColorInfo {
uint32_t cmask_is_linear = 0; uint32_t cmask_is_linear = 0;
uint32_t cmask_addr_type = 0; uint32_t cmask_addr_type = 0;
bool alt_tile_mode = false; bool alt_tile_mode = false;
uint32_t format = 0; Prospero::ChannelLayout format = Prospero::ChannelLayout::kInvalid;
uint32_t channel_type = 0; Prospero::ChannelType channel_type = Prospero::ChannelType::kUNorm;
uint32_t channel_order = 0; Prospero::ChannelOrder channel_order = Prospero::ChannelOrder::kStandard;
}; };
struct ColorAttrib { struct ColorAttrib {
bool force_dest_alpha_to_one = false; bool force_dest_alpha_to_one = false;
uint32_t tile_mode = 0; Prospero::TileMode tile_mode = Prospero::TileMode::kLinear;
uint32_t fmask_tile_mode = 0; Prospero::TileMode fmask_tile_mode = Prospero::TileMode::kLinear;
uint32_t num_samples = 0; uint32_t num_samples = 0;
uint32_t num_fragments = 0; uint32_t num_fragments = 0;
}; };
@@ -60,7 +60,7 @@ struct ColorAttrib2 {
struct ColorAttrib3 { struct ColorAttrib3 {
uint32_t depth = 0; uint32_t depth = 0;
uint32_t tile_mode = 0; Prospero::TileMode tile_mode = Prospero::TileMode::kLinear;
uint32_t dimension = 0; uint32_t dimension = 0;
bool cmask_pipe_aligned = false; bool cmask_pipe_aligned = false;
bool dcc_pipe_aligned = false; bool dcc_pipe_aligned = false;
@@ -132,7 +132,7 @@ struct RenderTarget {
}; };
struct DepthZInfo { struct DepthZInfo {
uint32_t format = 0; Prospero::DepthFormat format = Prospero::DepthFormat::kInvalid;
uint32_t num_samples = 0; uint32_t num_samples = 0;
Prospero::TextureCompatiblePlaneCompression texture_compatibility = Prospero::TextureCompatiblePlaneCompression texture_compatibility =
Prospero::TextureCompatiblePlaneCompression::kDisable; Prospero::TextureCompatiblePlaneCompression::kDisable;
@@ -144,16 +144,16 @@ struct DepthZInfo {
[[nodiscard]] static DepthZInfo Decode(uint32_t value) { [[nodiscard]] static DepthZInfo Decode(uint32_t value) {
DepthZInfo info; DepthZInfo info;
info.format = value & 0x3u; info.format = static_cast<Prospero::DepthFormat>(value & 0x3u);
info.num_samples = (value >> 2u) & 0x3u; info.num_samples = (value >> 2u) & 0x3u;
info.texture_compatibility = static_cast<Prospero::TextureCompatiblePlaneCompression>( info.texture_compatibility = static_cast<Prospero::TextureCompatiblePlaneCompression>(
value & Prospero::GpuEnumValue(Prospero::TextureCompatiblePlaneCompression::kBitMask)); value & static_cast<uint32_t>(Prospero::TextureCompatiblePlaneCompression::kBitMask));
info.partially_resident = (value & 0x00001000u) != 0; info.partially_resident = (value & 0x00001000u) != 0;
info.max_mip_level = static_cast<uint8_t>((value >> 16u) & 0x0fu); info.max_mip_level = static_cast<uint8_t>((value >> 16u) & 0x0fu);
info.expclear_enabled = (value & 0x08000000u) != 0; info.expclear_enabled = (value & 0x08000000u) != 0;
info.htile_acceleration = (value & 0x20000000u) != 0; info.htile_acceleration = (value & 0x20000000u) != 0;
info.z_compare_base = static_cast<Prospero::ZCompareBase>( info.z_compare_base = static_cast<Prospero::ZCompareBase>(
value & Prospero::GpuEnumValue(Prospero::ZCompareBase::kBitMask)); value & static_cast<uint32_t>(Prospero::ZCompareBase::kBitMask));
return info; return info;
} }
@@ -167,7 +167,7 @@ struct DepthZInfo {
}; };
struct DepthStencilInfo { struct DepthStencilInfo {
uint32_t format = 0; Prospero::StencilFormat format = Prospero::StencilFormat::kInvalid;
Prospero::TextureCompatibleStencil texture_compatibility = Prospero::TextureCompatibleStencil texture_compatibility =
Prospero::TextureCompatibleStencil::kDisable; Prospero::TextureCompatibleStencil::kDisable;
bool expclear_enabled = false; bool expclear_enabled = false;
@@ -176,9 +176,9 @@ struct DepthStencilInfo {
[[nodiscard]] static DepthStencilInfo Decode(uint32_t value) { [[nodiscard]] static DepthStencilInfo Decode(uint32_t value) {
DepthStencilInfo info; DepthStencilInfo info;
info.format = value & 0x1u; info.format = static_cast<Prospero::StencilFormat>(value & 0x1u);
info.texture_compatibility = static_cast<Prospero::TextureCompatibleStencil>( info.texture_compatibility = static_cast<Prospero::TextureCompatibleStencil>(
value & Prospero::GpuEnumValue(Prospero::TextureCompatibleStencil::kBitMask)); value & static_cast<uint32_t>(Prospero::TextureCompatibleStencil::kBitMask));
info.partially_resident = (value & 0x00001000u) != 0; info.partially_resident = (value & 0x00001000u) != 0;
info.expclear_enabled = (value & 0x08000000u) != 0; info.expclear_enabled = (value & 0x08000000u) != 0;
info.htile_stencil_disabled = (value & 0x20000000u) != 0; info.htile_stencil_disabled = (value & 0x20000000u) != 0;
@@ -1029,8 +1029,8 @@ public:
void Reset() { *this = UserConfig(); } void Reset() { *this = UserConfig(); }
void SetPrimitiveType(uint32_t prim_type) { m_prim_type = prim_type; } void SetPrimitiveType(Prospero::PrimitiveType prim_type) { m_prim_type = prim_type; }
[[nodiscard]] uint32_t GetPrimType() const { return m_prim_type; } [[nodiscard]] Prospero::PrimitiveType GetPrimType() const { return m_prim_type; }
void SetIndexOffset(uint32_t index_offset) { m_index_offset = index_offset; } void SetIndexOffset(uint32_t index_offset) { m_index_offset = index_offset; }
[[nodiscard]] uint32_t GetIndexOffset() const { return m_index_offset; } [[nodiscard]] uint32_t GetIndexOffset() const { return m_index_offset; }
void SetObjectId(uint32_t object_id) { m_object_id = object_id; } void SetObjectId(uint32_t object_id) { m_object_id = object_id; }
@@ -1049,7 +1049,7 @@ public:
void SetGdsOaAddress(uint32_t value) { m_gds_oa.counters[m_gds_oa.GetIndex()].address = value; } void SetGdsOaAddress(uint32_t value) { m_gds_oa.counters[m_gds_oa.GetIndex()].address = value; }
private: private:
uint32_t m_prim_type = 0; Prospero::PrimitiveType m_prim_type = Prospero::PrimitiveType::kNone;
uint32_t m_index_offset = 0; uint32_t m_index_offset = 0;
uint32_t m_object_id = 0; uint32_t m_object_id = 0;
+38 -35
View File
@@ -265,7 +265,7 @@ static bool GetMipTailLayout(const TileBlockLayout& block, MipTailLayout& out) {
return false; return false;
} }
bool TileGetTextureElementLayout(uint32_t format, TileTextureElementLayout& out) { bool TileGetTextureElementLayout(Prospero::BufferFormat format, TileTextureElementLayout& out) {
if (const auto bytes = Prospero::NumBytesPerElement(format); std::has_single_bit(bytes)) { if (const auto bytes = Prospero::NumBytesPerElement(format); std::has_single_bit(bytes)) {
out = {bytes, 1, 1}; out = {bytes, 1, 1};
return true; return true;
@@ -277,10 +277,10 @@ bool TileGetTextureElementLayout(uint32_t format, TileTextureElementLayout& out)
return false; return false;
} }
bool TileGetTextureBlockLayout(uint32_t format, uint32_t tile, bool volume, bool TileGetTextureBlockLayout(Prospero::BufferFormat format, Prospero::TileMode tile, bool volume,
TileTextureBlockLayout& out) { TileTextureBlockLayout& out) {
TileBlockFamily family = TileBlockFamily::Count; TileBlockFamily family = TileBlockFamily::Count;
switch (static_cast<Prospero::TileMode>(tile)) { switch (tile) {
case Prospero::TileMode::kStandard256B: case Prospero::TileMode::kStandard256B:
if (!volume) family = TileBlockFamily::Standard256B; if (!volume) family = TileBlockFamily::Standard256B;
break; break;
@@ -1130,15 +1130,18 @@ static bool TileGetHtileSize(uint32_t width, uint32_t height, TileSizeAlign& hti
return true; return true;
} }
bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t z_format, bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch,
uint32_t stencil_format, bool htile, TileSizeAlign& stencil_size, Prospero::DepthFormat z_format, Prospero::StencilFormat stencil_format,
TileSizeAlign& htile_size, TileSizeAlign& depth_size, bool htile, TileSizeAlign& stencil_size, TileSizeAlign& htile_size,
uint32_t num_fragments_log2) { TileSizeAlign& depth_size, uint32_t num_fragments_log2) {
EXIT_IF(pitch != 0); EXIT_IF(pitch != 0);
// Prospero derives uncompressed depth/stencil as independent 64 KiB block surfaces. // Prospero derives uncompressed depth/stencil as independent 64 KiB block surfaces.
if (width > 0 && width <= 16384 && height > 0 && height <= 16384 && if (width > 0 && width <= 16384 && height > 0 && height <= 16384 &&
(z_format == 1 || z_format == 3) && stencil_format <= 1 && num_fragments_log2 <= 3) { (z_format == Prospero::DepthFormat::kZ16 || z_format == Prospero::DepthFormat::kZ32F) &&
const uint32_t depth_bytes = z_format == 1 ? 2u : 4u; (stencil_format == Prospero::StencilFormat::kInvalid ||
stencil_format == Prospero::StencilFormat::k8UInt) &&
num_fragments_log2 <= 3) {
const uint32_t depth_bytes = z_format == Prospero::DepthFormat::kZ16 ? 2u : 4u;
uint32_t depth_block_width = 0; uint32_t depth_block_width = 0;
uint32_t depth_block_height = 0; uint32_t depth_block_height = 0;
uint32_t stencil_block_width = 0; uint32_t stencil_block_width = 0;
@@ -1146,7 +1149,7 @@ bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t
const bool valid_blocks = const bool valid_blocks =
Gen5Msaa64KBBlockSizeFromElementBytes(depth_bytes, num_fragments_log2, Gen5Msaa64KBBlockSizeFromElementBytes(depth_bytes, num_fragments_log2,
&depth_block_width, &depth_block_height) && &depth_block_width, &depth_block_height) &&
(stencil_format == 0 || (stencil_format == Prospero::StencilFormat::kInvalid ||
Gen5Msaa64KBBlockSizeFromElementBytes(1, num_fragments_log2, &stencil_block_width, Gen5Msaa64KBBlockSizeFromElementBytes(1, num_fragments_log2, &stencil_block_width,
&stencil_block_height)); &stencil_block_height));
const uint32_t fragments = 1u << num_fragments_log2; const uint32_t fragments = 1u << num_fragments_log2;
@@ -1155,7 +1158,7 @@ bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t
AlignUp(height, depth_block_height) * depth_bytes * fragments AlignUp(height, depth_block_height) * depth_bytes * fragments
: 0; : 0;
const uint64_t stencil_bytes_total = const uint64_t stencil_bytes_total =
stencil_format == 1 && valid_blocks stencil_format == Prospero::StencilFormat::k8UInt && valid_blocks
? static_cast<uint64_t>(AlignUp(width, stencil_block_width)) * ? static_cast<uint64_t>(AlignUp(width, stencil_block_width)) *
AlignUp(height, stencil_block_height) * fragments AlignUp(height, stencil_block_height) * fragments
: 0; : 0;
@@ -1163,7 +1166,7 @@ bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t
const bool htile_valid = !htile || TileGetHtileSize(width, height, calculated_htile); const bool htile_valid = !htile || TileGetHtileSize(width, height, calculated_htile);
if (depth_bytes_total <= UINT32_MAX && stencil_bytes_total <= UINT32_MAX && htile_valid) { if (depth_bytes_total <= UINT32_MAX && stencil_bytes_total <= UINT32_MAX && htile_valid) {
depth_size = {static_cast<uint32_t>(depth_bytes_total), 65536}; depth_size = {static_cast<uint32_t>(depth_bytes_total), 65536};
stencil_size = stencil_format == 1 stencil_size = stencil_format == Prospero::StencilFormat::k8UInt
? TileSizeAlign {static_cast<uint32_t>(stencil_bytes_total), 65536} ? TileSizeAlign {static_cast<uint32_t>(stencil_bytes_total), 65536}
: TileSizeAlign {}; : TileSizeAlign {};
htile_size = calculated_htile; htile_size = calculated_htile;
@@ -1236,31 +1239,29 @@ bool TileGetRenderTargetMipLayout(uint32_t width, uint32_t height, uint32_t pitc
if (levels > max_levels) { if (levels > max_levels) {
return false; return false;
} }
uint32_t format = 0; auto format = Prospero::BufferFormat::kInvalid;
switch (bytes_per_element) { switch (bytes_per_element) {
case 1: format = Prospero::GpuEnumValue(Prospero::BufferFormat::k8UNorm); break; case 1: format = Prospero::BufferFormat::k8UNorm; break;
case 2: format = Prospero::GpuEnumValue(Prospero::BufferFormat::k16UNorm); break; case 2: format = Prospero::BufferFormat::k16UNorm; break;
case 4: format = Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float); break; case 4: format = Prospero::BufferFormat::k32Float; break;
case 8: format = Prospero::GpuEnumValue(Prospero::BufferFormat::k16_16_16_16Float); break; case 8: format = Prospero::BufferFormat::k16_16_16_16Float; break;
case 16: format = Prospero::GpuEnumValue(Prospero::BufferFormat::k32_32_32_32Float); break; case 16: format = Prospero::BufferFormat::k32_32_32_32Float; break;
default: return false; default: return false;
} }
TileGetTextureSize(format, width, height, levels, TileGetTextureSize(format, width, height, levels, Prospero::TileMode::kRenderTarget,
Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget), &total_size, &total_size, level_sizes, padded_size);
level_sizes, padded_size);
return total_size.size != 0 && total_size.align == 65536; return total_size.size != 0 && total_size.align == 65536;
} }
void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32_t levels, void TileGetTextureSize(Prospero::BufferFormat format, uint32_t width, uint32_t height,
uint32_t tile, TileSizeAlign* total_size, TileSizeOffset* level_sizes, uint32_t levels, Prospero::TileMode tile, TileSizeAlign* total_size,
TilePaddedSize* padded_size) { TileSizeOffset* level_sizes, TilePaddedSize* padded_size) {
KYTY_PROFILER_FUNCTION(); KYTY_PROFILER_FUNCTION();
EXIT_IF(levels == 0 || levels > 16); EXIT_IF(levels == 0 || levels > 16);
TileTextureElementLayout element {}; TileTextureElementLayout element {};
if (static_cast<Prospero::TileMode>(tile) == Prospero::TileMode::kLinear && if (tile == Prospero::TileMode::kLinear && TileGetTextureElementLayout(format, element)) {
TileGetTextureElementLayout(format, element)) {
uint32_t mip_pitch[16] {}; uint32_t mip_pitch[16] {};
uint32_t mip_height[16] {}; uint32_t mip_height[16] {};
uint32_t mip_size[16] {}; uint32_t mip_size[16] {};
@@ -1302,26 +1303,27 @@ void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32
} }
if (total_size != nullptr && total_size->size == 0) { if (total_size != nullptr && total_size->size == 0) {
std::vector<std::string> list; std::vector<std::string> list;
list.push_back(fmt::format("format = {}", format)); list.push_back(fmt::format("format = {}", static_cast<uint32_t>(format)));
list.push_back(fmt::format("width = {}", width)); list.push_back(fmt::format("width = {}", width));
list.push_back(fmt::format("height = {}", height)); list.push_back(fmt::format("height = {}", height));
list.push_back(fmt::format("levels = {}", levels)); list.push_back(fmt::format("levels = {}", levels));
list.push_back(fmt::format("tile = {}", tile)); list.push_back(fmt::format("tile = {}", static_cast<uint32_t>(tile)));
EXIT("unknown format:\n%s\n", Common::Concat(list, '\n').c_str()); EXIT("unknown format:\n%s\n", Common::Concat(list, '\n').c_str());
} }
} }
void TileGetTextureTotalSize(uint32_t format, uint32_t width, uint32_t height, uint32_t depth, void TileGetTextureTotalSize(Prospero::BufferFormat format, uint32_t width, uint32_t height,
uint32_t levels, uint32_t tile, bool volume_texture, uint32_t depth, uint32_t levels, Prospero::TileMode tile,
TileSizeAlign& total_size) { bool volume_texture, TileSizeAlign& total_size) {
EXIT_NOT_IMPLEMENTED(depth == 0); EXIT_NOT_IMPLEMENTED(depth == 0);
if (volume_texture && static_cast<Prospero::TileMode>(tile) != Prospero::TileMode::kLinear) { if (volume_texture && tile != Prospero::TileMode::kLinear) {
TileSurfaceLayout layout {}; TileSurfaceLayout layout {};
const TileSurfaceDescription description { const TileSurfaceDescription description {
format, tile, TileSurfaceDimension::Dim3D, width, height, depth, levels, 1}; format, tile, TileSurfaceDimension::Dim3D, width, height, depth, levels, 1};
if (!TileGetTiledTextureLayout(description, layout)) { if (!TileGetTiledTextureLayout(description, layout)) {
EXIT("unsupported 3D texture layout: format=%u tile=%u extent=%ux%ux%u levels=%u\n", EXIT("unsupported 3D texture layout: format=%u tile=%u extent=%ux%ux%u levels=%u\n",
format, tile, width, height, depth, levels); static_cast<uint32_t>(format), static_cast<uint32_t>(tile), width, height, depth,
levels);
} }
EXIT_NOT_IMPLEMENTED(layout.total_size > UINT32_MAX); EXIT_NOT_IMPLEMENTED(layout.total_size > UINT32_MAX);
total_size.size = static_cast<uint32_t>(layout.total_size); total_size.size = static_cast<uint32_t>(layout.total_size);
@@ -1337,9 +1339,10 @@ void TileGetTextureTotalSize(uint32_t format, uint32_t width, uint32_t height, u
total_size.size = static_cast<uint32_t>(total); total_size.size = static_cast<uint32_t>(total);
} }
uint32_t TileGetTexturePitch(uint32_t format, uint32_t width, uint32_t tile) { uint32_t TileGetTexturePitch(Prospero::BufferFormat format, uint32_t width,
Prospero::TileMode tile) {
uint32_t pitch = width; uint32_t pitch = width;
switch (static_cast<Prospero::TileMode>(tile)) { switch (tile) {
case Prospero::TileMode::kLinear: { case Prospero::TileMode::kLinear: {
TileTextureElementLayout element {}; TileTextureElementLayout element {};
if (TileGetTextureElementLayout(format, element) && element.texel_width == 1 && if (TileGetTextureElementLayout(format, element) && element.texel_width == 1 &&
+17 -15
View File
@@ -3,6 +3,7 @@
#include "common/abi.h" #include "common/abi.h"
#include "common/common.h" #include "common/common.h"
#include "graphics/guest_gpu/gpu_defs.h"
namespace Libs::Graphics { namespace Libs::Graphics {
@@ -65,8 +66,8 @@ enum class TileSurfaceDimension : uint32_t {
}; };
struct TileSurfaceDescription { struct TileSurfaceDescription {
uint32_t format = 0; Prospero::BufferFormat format = Prospero::BufferFormat::kInvalid;
uint32_t tile_mode = 0; Prospero::TileMode tile_mode = Prospero::TileMode::kLinear;
TileSurfaceDimension dimension = TileSurfaceDimension::Dim2D; TileSurfaceDimension dimension = TileSurfaceDimension::Dim2D;
uint32_t width = 0; uint32_t width = 0;
uint32_t height = 0; uint32_t height = 0;
@@ -98,8 +99,8 @@ struct TileSurfaceLayout {
bool TileGetBlockLayout(TileBlockFamily family, uint32_t bytes_per_element, bool TileGetBlockLayout(TileBlockFamily family, uint32_t bytes_per_element,
TileBlockLayout& layout); TileBlockLayout& layout);
bool TileGetTextureElementLayout(uint32_t format, TileTextureElementLayout& layout); bool TileGetTextureElementLayout(Prospero::BufferFormat format, TileTextureElementLayout& layout);
bool TileGetTextureBlockLayout(uint32_t format, uint32_t tile, bool volume, bool TileGetTextureBlockLayout(Prospero::BufferFormat format, Prospero::TileMode tile, bool volume,
TileTextureBlockLayout& layout); TileTextureBlockLayout& layout);
bool TileGetTiledTextureLayout(const TileSurfaceDescription& description, bool TileGetTiledTextureLayout(const TileSurfaceDescription& description,
TileSurfaceLayout& layout); TileSurfaceLayout& layout);
@@ -110,10 +111,10 @@ bool TileGetBlockXor(const TileBlockLayout& layout, uint32_t block_x, uint32_t b
bool TileGetBlockXor(const TileBlockLayout& layout, uint32_t block_x, uint32_t block_y, bool TileGetBlockXor(const TileBlockLayout& layout, uint32_t block_x, uint32_t block_y,
uint32_t block_z, uint32_t& byte_offset); uint32_t block_z, uint32_t& byte_offset);
bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t z_format, bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch,
uint32_t stencil_format, bool htile, TileSizeAlign& stencil_size, Prospero::DepthFormat z_format, Prospero::StencilFormat stencil_format,
TileSizeAlign& htile_size, TileSizeAlign& depth_size, bool htile, TileSizeAlign& stencil_size, TileSizeAlign& htile_size,
uint32_t num_fragments_log2 = 0); TileSizeAlign& depth_size, uint32_t num_fragments_log2 = 0);
uint32_t TileGetRenderTargetPitch(uint32_t width, uint32_t bytes_per_element, uint32_t TileGetRenderTargetPitch(uint32_t width, uint32_t bytes_per_element,
uint32_t num_fragments_log2 = 0); uint32_t num_fragments_log2 = 0);
uint32_t TileGetDepthPitch(uint32_t width, uint32_t bytes_per_element, uint32_t TileGetDepthPitch(uint32_t width, uint32_t bytes_per_element,
@@ -125,13 +126,14 @@ bool TileGetRenderTargetMipLayout(uint32_t width, uint32_t height, uint32_t
uint32_t bytes_per_element, uint32_t levels, uint32_t bytes_per_element, uint32_t levels,
TileSizeAlign& total_size, TileSizeOffset* level_sizes, TileSizeAlign& total_size, TileSizeOffset* level_sizes,
TilePaddedSize* padded_size); TilePaddedSize* padded_size);
void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32_t levels, void TileGetTextureSize(Prospero::BufferFormat format, uint32_t width, uint32_t height,
uint32_t tile, TileSizeAlign* total_size, TileSizeOffset* level_sizes, uint32_t levels, Prospero::TileMode tile, TileSizeAlign* total_size,
TilePaddedSize* padded_size); TileSizeOffset* level_sizes, TilePaddedSize* padded_size);
void TileGetTextureTotalSize(uint32_t format, uint32_t width, uint32_t height, uint32_t depth, void TileGetTextureTotalSize(Prospero::BufferFormat format, uint32_t width, uint32_t height,
uint32_t levels, uint32_t tile, bool volume_texture, uint32_t depth, uint32_t levels, Prospero::TileMode tile,
TileSizeAlign& total_size); bool volume_texture, TileSizeAlign& total_size);
uint32_t TileGetTexturePitch(uint32_t format, uint32_t width, uint32_t tile); uint32_t TileGetTexturePitch(Prospero::BufferFormat format, uint32_t width,
Prospero::TileMode tile);
} // namespace Libs::Graphics } // namespace Libs::Graphics
+7 -7
View File
@@ -516,7 +516,7 @@ ImageId TextureCache::GetNullImage(const ImageDesc& desc) {
info.pitch = 1; info.pitch = 1;
info.bytes_per_block = std::max(desc.info.bytes_per_block, 1u); info.bytes_per_block = std::max(desc.info.bytes_per_block, 1u);
info.samples = 1; info.samples = 1;
info.tile_mode = Prospero::GpuEnumValue(Prospero::TileMode::kLinear); info.tile_mode = Prospero::TileMode::kLinear;
info.mip_layout[0] = {0, info.bytes_per_block, 1, 1}; info.mip_layout[0] = {0, info.bytes_per_block, 1, 1};
const auto id = InsertImage(info); const auto id = InsertImage(info);
m_null_images.emplace(format, id); m_null_images.emplace(format, id);
@@ -822,7 +822,8 @@ TextureCache::OverlapResult TextureCache::ResolveOverlap(const ImageInfo& reques
requested.data.address, requested.resources.levels, requested.resources.layers, requested.data.address, requested.resources.levels, requested.resources.layers,
cached.info.resources.levels, cached.info.resources.layers, requested.data.size, cached.info.resources.levels, cached.info.resources.layers, requested.data.size,
cached.info.data.size, static_cast<uint32_t>(requested.type), cached.info.data.size, static_cast<uint32_t>(requested.type),
static_cast<uint32_t>(cached.info.type), requested.tile_mode, cached.info.tile_mode); static_cast<uint32_t>(cached.info.type), static_cast<uint32_t>(requested.tile_mode),
static_cast<uint32_t>(cached.info.tile_mode));
} }
if (requested.data.address > cached.info.data.address) { if (requested.data.address > cached.info.data.address) {
@@ -905,7 +906,7 @@ TextureCache::ColorTransferPlan
TextureCache::BuildColorTransfer(const Image& image, BindingType binding, TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
TransferDirection direction) const { TransferDirection direction) const {
const auto& info = image.info; const auto& info = image.info;
uint32_t format = info.guest_format; auto format = info.guest_format;
uint32_t layers = info.TransferLayers(); uint32_t layers = info.TransferLayers();
bool volume = info.IsVolume(); bool volume = info.IsVolume();
bool allow_depth_tile = direction == TransferDirection::Upload; bool allow_depth_tile = direction == TransferDirection::Upload;
@@ -957,8 +958,7 @@ TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
info.resources.levels, layers, info.tile_mode, info.resources.levels, layers, info.tile_mode,
info.data.size, allow_depth_tile, volume, owner); info.data.size, allow_depth_tile, volume, owner);
plan.regions = TextureBuildImageCopies(plan.layout); plan.regions = TextureBuildImageCopies(plan.layout);
plan.tiled = static_cast<Prospero::TileMode>(plan.layout.surface.description.tile_mode) != plan.tiled = plan.layout.surface.description.tile_mode != Prospero::TileMode::kLinear;
Prospero::TileMode::kLinear;
if (plan.tiled) { if (plan.tiled) {
if (!TextureBuildGpuTileInfos(info.data.size, plan.regions, plan.layout, if (!TextureBuildGpuTileInfos(info.data.size, plan.regions, plan.layout,
info.resources.levels, plan.tiles)) { info.resources.levels, plan.tiles)) {
@@ -1007,7 +1007,7 @@ void TextureCache::UploadImage(Image& image, const ImageDesc& desc, Buffer& sour
" size=0x%016" PRIx64 " format=%u tile=%u family=%u extent=%ux%ux%u " " size=0x%016" PRIx64 " format=%u tile=%u family=%u extent=%ux%ux%u "
"pitch=%u levels=%u layers=%u samples=%u\n", "pitch=%u levels=%u layers=%u samples=%u\n",
static_cast<uint32_t>(desc.type), info.data.address, info.data.size, static_cast<uint32_t>(desc.type), info.data.address, info.data.size,
info.guest_format, info.tile_mode, static_cast<uint32_t>(info.guest_format), static_cast<uint32_t>(info.tile_mode),
static_cast<uint32_t>(plan.layout.surface.texture.block.family), info.extent.width, 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.extent.height, info.extent.depth, info.pitch, info.resources.levels,
info.resources.layers, info.samples); info.resources.layers, info.samples);
@@ -1045,7 +1045,7 @@ void TextureCache::UploadImage(Image& image, const ImageDesc& desc, Buffer& sour
copy.bufferImageHeight = info.extent.height; copy.bufferImageHeight = info.extent.height;
copy.imageSubresource = {vk::ImageAspectFlagBits::eDepth, 0, layer, 1}; copy.imageSubresource = {vk::ImageAspectFlagBits::eDepth, 0, layer, 1};
copy.imageExtent = {info.extent.width, info.extent.height, 1}; copy.imageExtent = {info.extent.width, info.extent.height, 1};
if (static_cast<Prospero::TileMode>(info.tile_mode) != Prospero::TileMode::kLinear) { if (info.tile_mode != Prospero::TileMode::kLinear) {
tiles.push_back({block.family, block.bytes_per_element, offset, full_slice_size, offset, tiles.push_back({block.family, block.bytes_per_element, offset, full_slice_size, offset,
full_slice_size, 0, info.extent.width, info.extent.height, 1, full_slice_size, 0, info.extent.width, info.extent.height, 1,
info.pitch}); info.pitch});
@@ -101,8 +101,9 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
" attrib3_tile=0x%08" PRIx32 " attrib3_dim=0x%08" PRIx32 " fmt=0x%08" PRIx32 " attrib3_tile=0x%08" PRIx32 " attrib3_dim=0x%08" PRIx32 " fmt=0x%08" PRIx32
" nfmt=0x%08" PRIx32 " order=0x%08" PRIx32 "\n", " nfmt=0x%08" PRIx32 " order=0x%08" PRIx32 "\n",
rt_slot, rt.base.addr, mask, rt.attrib2.width, rt.attrib2.height, rt_slot, rt.base.addr, mask, rt.attrib2.width, rt.attrib2.height,
rt.attrib3.tile_mode, rt.attrib3.dimension, rt.info.format, rt.info.channel_type, static_cast<uint32_t>(rt.attrib3.tile_mode), rt.attrib3.dimension,
rt.info.channel_order); static_cast<uint32_t>(rt.info.format), static_cast<uint32_t>(rt.info.channel_type),
static_cast<uint32_t>(rt.info.channel_order));
} }
} }
@@ -130,16 +131,15 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
EXIT("multisampled 3D render targets are unsupported\n"); EXIT("multisampled 3D render targets are unsupported\n");
} }
const uint32_t depth = volume ? rt.attrib3.depth + 1u : 1u; const uint32_t depth = volume ? rt.attrib3.depth + 1u : 1u;
const bool standard64 = const bool standard64 = rt.attrib3.tile_mode == Prospero::TileMode::kStandard64KB;
rt.attrib3.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB);
switch (rt.attrib3.tile_mode) { switch (rt.attrib3.tile_mode) {
case Prospero::GpuEnumValue(Prospero::TileMode::kLinear): case Prospero::TileMode::kLinear:
case Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB): case Prospero::TileMode::kStandard64KB:
case Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget): case Prospero::TileMode::kRenderTarget:
tile = !RenderIsColorTileModeLinear(rt.attrib3.tile_mode); tile = !RenderIsColorTileModeLinear(rt.attrib3.tile_mode);
break; break;
default: EXIT("unknown tile mode: %u\n", rt.attrib3.tile_mode); default: EXIT("unknown tile mode: %u\n", static_cast<uint32_t>(rt.attrib3.tile_mode));
} }
if (!tile && levels > 1) { if (!tile && levels > 1) {
EXIT("linear mipmapped render targets are unsupported\n"); EXIT("linear mipmapped render targets are unsupported\n");
@@ -180,8 +180,8 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
if (volume) { if (volume) {
pitch = TileGetTexturePitch(transfer_format, width, rt.attrib3.tile_mode); pitch = TileGetTexturePitch(transfer_format, width, rt.attrib3.tile_mode);
} else if (standard64) { } else if (standard64) {
pitch = TileGetTexturePitch(Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float), pitch =
width, rt.attrib3.tile_mode); TileGetTexturePitch(Prospero::BufferFormat::k32Float, width, rt.attrib3.tile_mode);
} else { } else {
pitch = TileGetRenderTargetPitch(width, bytes_per_element, rt.attrib.num_fragments); pitch = TileGetRenderTargetPitch(width, bytes_per_element, rt.attrib.num_fragments);
} }
@@ -207,7 +207,7 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
1}; 1};
if (!tile || !TileGetTiledTextureLayout(description, volume_layout)) { if (!tile || !TileGetTiledTextureLayout(description, volume_layout)) {
EXIT("unsupported 3D render-target layout: %ux%ux%u levels=%u tile=%u\n", width, height, EXIT("unsupported 3D render-target layout: %ux%ux%u levels=%u tile=%u\n", width, height,
depth, levels, rt.attrib3.tile_mode); depth, levels, static_cast<uint32_t>(rt.attrib3.tile_mode));
} }
size = volume_layout.block_slice_size; size = volume_layout.block_slice_size;
backing_size = volume_layout.total_size; backing_size = volume_layout.total_size;
@@ -215,9 +215,8 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
TileSizeAlign layout {}; TileSizeAlign layout {};
bool valid_layout = false; bool valid_layout = false;
if (standard64) { if (standard64) {
TileGetTextureSize(Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float), width, TileGetTextureSize(Prospero::BufferFormat::k32Float, width, height, levels,
height, levels, rt.attrib3.tile_mode, &layout, mip_sizes, rt.attrib3.tile_mode, &layout, mip_sizes, mip_padded);
mip_padded);
valid_layout = layout.size != 0 && layout.align == 65536; valid_layout = layout.size != 0 && layout.align == 65536;
} else { } else {
valid_layout = valid_layout =
@@ -278,8 +277,9 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandB
" extent=%ux%ux%u view_mip=%u view_extent=%ux%u levels=%u pitch=%u" " extent=%ux%ux%u view_mip=%u view_extent=%ux%u levels=%u pitch=%u"
" fmt=0x%08" PRIx32 " nfmt=0x%08" PRIx32 " order=0x%08" PRIx32 " samples=%u tile=%s\n", " fmt=0x%08" PRIx32 " nfmt=0x%08" PRIx32 " order=0x%08" PRIx32 " samples=%u tile=%s\n",
rt_slot, rt.base.addr, backing_size, width, height, depth, rt.view.current_mip_level, rt_slot, rt.base.addr, backing_size, width, height, depth, rt.view.current_mip_level,
view_extent.width, view_extent.height, levels, pitch, rt.info.format, view_extent.width, view_extent.height, levels, pitch,
rt.info.channel_type, rt.info.channel_order, samples, tile ? "tiled" : "linear"); static_cast<uint32_t>(rt.info.format), static_cast<uint32_t>(rt.info.channel_type),
static_cast<uint32_t>(rt.info.channel_order), samples, tile ? "tiled" : "linear");
} }
TextureCache::ImageDesc desc {}; TextureCache::ImageDesc desc {};
+44 -37
View File
@@ -76,8 +76,8 @@ void uc_print(const char* func, const HW::UserConfig& uc) {
"\t en_user_vgpr1 = %s\n" "\t en_user_vgpr1 = %s\n"
"\t en_user_vgpr2 = %s\n" "\t en_user_vgpr2 = %s\n"
"\t en_user_vgpr3 = %s\n", "\t en_user_vgpr3 = %s\n",
uc.GetPrimType(), uc.GetIndexOffset(), uc.GetObjectId(), ge_cntl.primitive_group_size, static_cast<uint32_t>(uc.GetPrimType()), uc.GetIndexOffset(), uc.GetObjectId(),
ge_cntl.vertex_group_size, user_en.vgpr1 ? "true" : "false", ge_cntl.primitive_group_size, ge_cntl.vertex_group_size, user_en.vgpr1 ? "true" : "false",
user_en.vgpr2 ? "true" : "false", user_en.vgpr3 ? "true" : "false"); user_en.vgpr2 ? "true" : "false", user_en.vgpr3 ? "true" : "false");
} }
@@ -141,11 +141,12 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
fmt::format("\t info.cmask_addr_type = 0x{:08x}\n", rt.info.cmask_addr_type)); fmt::format("\t info.cmask_addr_type = 0x{:08x}\n", rt.info.cmask_addr_type));
dst.push_back(fmt::format("\t info.alt_tile_mode = {}\n", dst.push_back(fmt::format("\t info.alt_tile_mode = {}\n",
rt.info.alt_tile_mode ? "true" : "false")); rt.info.alt_tile_mode ? "true" : "false"));
dst.push_back(fmt::format("\t info.format = 0x{:08x}\n", rt.info.format)); dst.push_back(fmt::format("\t info.format = 0x{:08x}\n",
dst.push_back( static_cast<uint32_t>(rt.info.format)));
fmt::format("\t info.channel_type = 0x{:08x}\n", rt.info.channel_type)); dst.push_back(fmt::format("\t info.channel_type = 0x{:08x}\n",
dst.push_back( static_cast<uint32_t>(rt.info.channel_type)));
fmt::format("\t info.channel_order = 0x{:08x}\n", rt.info.channel_order)); dst.push_back(fmt::format("\t info.channel_order = 0x{:08x}\n",
static_cast<uint32_t>(rt.info.channel_order)));
dst.push_back(fmt::format("\t info.blend_bypa = {}\n", dst.push_back(fmt::format("\t info.blend_bypa = {}\n",
rt.info.blend_bypass ? "true" : "false")); rt.info.blend_bypass ? "true" : "false"));
dst.push_back(fmt::format("\t info.blend_clamp = {}\n", dst.push_back(fmt::format("\t info.blend_clamp = {}\n",
@@ -154,10 +155,10 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
rt.info.round_mode ? "true" : "false")); rt.info.round_mode ? "true" : "false"));
dst.push_back(fmt::format("\t attrib.force_dest_alpha_to_one = {}\n", dst.push_back(fmt::format("\t attrib.force_dest_alpha_to_one = {}\n",
rt.attrib.force_dest_alpha_to_one ? "true" : "false")); rt.attrib.force_dest_alpha_to_one ? "true" : "false"));
dst.push_back( dst.push_back(fmt::format("\t attrib.tile_mode = 0x{:08x}\n",
fmt::format("\t attrib.tile_mode = 0x{:08x}\n", rt.attrib.tile_mode)); static_cast<uint32_t>(rt.attrib.tile_mode)));
dst.push_back( dst.push_back(fmt::format("\t attrib.fmask_tile_mode = 0x{:08x}\n",
fmt::format("\t attrib.fmask_tile_mode = 0x{:08x}\n", rt.attrib.fmask_tile_mode)); static_cast<uint32_t>(rt.attrib.fmask_tile_mode)));
dst.push_back( dst.push_back(
fmt::format("\t attrib.num_samples = 0x{:08x}\n", rt.attrib.num_samples)); fmt::format("\t attrib.num_samples = 0x{:08x}\n", rt.attrib.num_samples));
dst.push_back( dst.push_back(
@@ -168,8 +169,8 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
dst.push_back( dst.push_back(
fmt::format("\t attrib2.num_mip_levels = 0x{:08x}\n", rt.attrib2.num_mip_levels)); fmt::format("\t attrib2.num_mip_levels = 0x{:08x}\n", rt.attrib2.num_mip_levels));
dst.push_back(fmt::format("\t attrib3.depth = 0x{:08x}\n", rt.attrib3.depth)); dst.push_back(fmt::format("\t attrib3.depth = 0x{:08x}\n", rt.attrib3.depth));
dst.push_back( dst.push_back(fmt::format("\t attrib3.tile_mode = 0x{:08x}\n",
fmt::format("\t attrib3.tile_mode = 0x{:08x}\n", rt.attrib3.tile_mode)); static_cast<uint32_t>(rt.attrib3.tile_mode)));
dst.push_back( dst.push_back(
fmt::format("\t attrib3.dimension = 0x{:08x}\n", rt.attrib3.dimension)); fmt::format("\t attrib3.dimension = 0x{:08x}\n", rt.attrib3.dimension));
dst.push_back(fmt::format("\t attrib3.cmask_pipe_aligned = {}\n", dst.push_back(fmt::format("\t attrib3.cmask_pipe_aligned = {}\n",
@@ -212,22 +213,22 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
return dst; return dst;
} }
static bool RenderIsColorTileMode(uint32_t tile_mode) { static bool RenderIsColorTileMode(Prospero::TileMode tile_mode) {
// AGC CxRenderTarget::TileMode shifted by CB_COLOR*_ATTRIB3.COLOR_SW_MODE. // AGC CxRenderTarget::TileMode shifted by CB_COLOR*_ATTRIB3.COLOR_SW_MODE.
switch (tile_mode) { switch (tile_mode) {
case Prospero::GpuEnumValue(Prospero::TileMode::kLinear): case Prospero::TileMode::kLinear:
case Prospero::GpuEnumValue(Prospero::TileMode::kStandard256B): case Prospero::TileMode::kStandard256B:
case Prospero::GpuEnumValue(Prospero::TileMode::kStandard4KB): case Prospero::TileMode::kStandard4KB:
case Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB): case Prospero::TileMode::kStandard64KB:
case Prospero::GpuEnumValue(Prospero::TileMode::kPrt): case Prospero::TileMode::kPrt:
case Prospero::GpuEnumValue(Prospero::TileMode::kDepth): case Prospero::TileMode::kDepth:
case Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget): return true; case Prospero::TileMode::kRenderTarget: return true;
default: return false; default: return false;
} }
} }
bool RenderIsColorTileModeLinear(uint32_t tile_mode) { bool RenderIsColorTileModeLinear(Prospero::TileMode tile_mode) {
return tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear); return tile_mode == Prospero::TileMode::kLinear;
} }
static bool RenderIsColorDimension(uint32_t dimension) { static bool RenderIsColorDimension(uint32_t dimension) {
@@ -361,7 +362,8 @@ static void RtCheck(const HW::RenderTarget& rt) {
} }
} }
if (!RenderIsColorTileMode(rt.attrib3.tile_mode)) { if (!RenderIsColorTileMode(rt.attrib3.tile_mode)) {
EXIT("unknown PS5 render-target tile mode: 0x%08" PRIx32 "\n", rt.attrib3.tile_mode); EXIT("unknown PS5 render-target tile mode: 0x%08" PRIx32 "\n",
static_cast<uint32_t>(rt.attrib3.tile_mode));
} }
if (!RenderIsColorDimension(rt.attrib3.dimension)) { if (!RenderIsColorDimension(rt.attrib3.dimension)) {
EXIT("unknown PS5 render-target dimension: 0x%08" PRIx32 "\n", rt.attrib3.dimension); EXIT("unknown PS5 render-target dimension: 0x%08" PRIx32 "\n", rt.attrib3.dimension);
@@ -456,13 +458,14 @@ static void ZPrint(const char* func, const HW::DepthRenderTarget& z) {
"\t height = 0x%08" PRIx32 "\n" "\t height = 0x%08" PRIx32 "\n"
"\t size.x_max = 0x%04" PRIx16 "\n" "\t size.x_max = 0x%04" PRIx16 "\n"
"\t size.y_max = 0x%04" PRIx16 "\n", "\t size.y_max = 0x%04" PRIx16 "\n",
z.z_info.format, z.z_info.num_samples, static_cast<uint32_t>(z.z_info.format), z.z_info.num_samples,
Prospero::GpuEnumValue(z.z_info.texture_compatibility), static_cast<uint32_t>(z.z_info.texture_compatibility),
z.z_info.htile_acceleration ? "true" : "false", z.z_info.htile_acceleration ? "true" : "false",
z.z_info.expclear_enabled ? "true" : "false", z.z_info.expclear_enabled ? "true" : "false",
Prospero::GpuEnumValue(z.z_info.z_compare_base), static_cast<uint32_t>(z.z_info.z_compare_base),
z.z_info.partially_resident ? "true" : "false", z.z_info.max_mip_level, z.z_info.partially_resident ? "true" : "false", z.z_info.max_mip_level,
z.stencil_info.format, Prospero::GpuEnumValue(z.stencil_info.texture_compatibility), static_cast<uint32_t>(z.stencil_info.format),
static_cast<uint32_t>(z.stencil_info.texture_compatibility),
z.stencil_info.htile_stencil_disabled ? "true" : "false", z.stencil_info.htile_stencil_disabled ? "true" : "false",
z.stencil_info.expclear_enabled ? "true" : "false", z.stencil_info.expclear_enabled ? "true" : "false",
z.stencil_info.partially_resident ? "true" : "false", z.depth_info.addr5_swizzle_mask, z.stencil_info.partially_resident ? "true" : "false", z.depth_info.addr5_swizzle_mask,
@@ -491,15 +494,16 @@ static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
EXIT_NOT_IMPLEMENTED(!z.z_info.HasValidTextureCompatibility()); EXIT_NOT_IMPLEMENTED(!z.z_info.HasValidTextureCompatibility());
EXIT_NOT_IMPLEMENTED(!z.stencil_info.HasValidTextureCompatibility()); EXIT_NOT_IMPLEMENTED(!z.stencil_info.HasValidTextureCompatibility());
if (z.z_info.format == 0) { if (z.z_info.format == Prospero::DepthFormat::kInvalid) {
EXIT_NOT_IMPLEMENTED(z.z_info.format != 0); EXIT_NOT_IMPLEMENTED(z.z_info.format != Prospero::DepthFormat::kInvalid);
EXIT_NOT_IMPLEMENTED(z.z_info.num_samples != 0); EXIT_NOT_IMPLEMENTED(z.z_info.num_samples != 0);
EXIT_NOT_IMPLEMENTED(z.z_info.htile_acceleration != false); EXIT_NOT_IMPLEMENTED(z.z_info.htile_acceleration != false);
EXIT_NOT_IMPLEMENTED(z.z_info.expclear_enabled != false); EXIT_NOT_IMPLEMENTED(z.z_info.expclear_enabled != false);
EXIT_NOT_IMPLEMENTED(z.z_info.partially_resident != false); EXIT_NOT_IMPLEMENTED(z.z_info.partially_resident != false);
EXIT_NOT_IMPLEMENTED(z.z_info.max_mip_level != 0); EXIT_NOT_IMPLEMENTED(z.z_info.max_mip_level != 0);
} else { } else {
EXIT_NOT_IMPLEMENTED(z.z_info.format != 0x00000001 && z.z_info.format != 0x00000003); EXIT_NOT_IMPLEMENTED(z.z_info.format != Prospero::DepthFormat::kZ16 &&
z.z_info.format != Prospero::DepthFormat::kZ32F);
if (z.z_info.num_samples != 0x00000000) { if (z.z_info.num_samples != 0x00000000) {
static bool logged = false; static bool logged = false;
if (!logged) { if (!logged) {
@@ -513,16 +517,17 @@ static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
EXIT_NOT_IMPLEMENTED(z.z_info.max_mip_level != 0); EXIT_NOT_IMPLEMENTED(z.z_info.max_mip_level != 0);
} }
if (z.stencil_info.format == 0) { if (z.stencil_info.format == Prospero::StencilFormat::kInvalid) {
EXIT_NOT_IMPLEMENTED(z.stencil_info.expclear_enabled != false); EXIT_NOT_IMPLEMENTED(z.stencil_info.expclear_enabled != false);
EXIT_NOT_IMPLEMENTED(z.stencil_info.partially_resident != false); EXIT_NOT_IMPLEMENTED(z.stencil_info.partially_resident != false);
} else { } else {
EXIT_NOT_IMPLEMENTED(z.stencil_info.format != 0x00000001); EXIT_NOT_IMPLEMENTED(z.stencil_info.format != Prospero::StencilFormat::k8UInt);
EXIT_NOT_IMPLEMENTED(z.stencil_info.expclear_enabled != false); EXIT_NOT_IMPLEMENTED(z.stencil_info.expclear_enabled != false);
EXIT_NOT_IMPLEMENTED(z.stencil_info.partially_resident != false); EXIT_NOT_IMPLEMENTED(z.stencil_info.partially_resident != false);
} }
if (z.z_info.format != 0 || z.stencil_info.format != 0) { if (z.z_info.format != Prospero::DepthFormat::kInvalid ||
z.stencil_info.format != Prospero::StencilFormat::kInvalid) {
EXIT_NOT_IMPLEMENTED(z.depth_info.addr5_swizzle_mask != 0x00000000); EXIT_NOT_IMPLEMENTED(z.depth_info.addr5_swizzle_mask != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.depth_info.array_mode != 0x00000000); EXIT_NOT_IMPLEMENTED(z.depth_info.array_mode != 0x00000000);
@@ -557,7 +562,8 @@ static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
EXIT_NOT_IMPLEMENTED(z.z_read_base_addr != z.z_write_base_addr); EXIT_NOT_IMPLEMENTED(z.z_read_base_addr != z.z_write_base_addr);
EXIT_NOT_IMPLEMENTED(z.stencil_read_base_addr != z.stencil_write_base_addr); EXIT_NOT_IMPLEMENTED(z.stencil_read_base_addr != z.stencil_write_base_addr);
EXIT_NOT_IMPLEMENTED(z.z_write_base_addr == 0); EXIT_NOT_IMPLEMENTED(z.z_write_base_addr == 0);
if (z.stencil_info.format != 0 && z.stencil_write_base_addr == 0) { if (z.stencil_info.format != Prospero::StencilFormat::kInvalid &&
z.stencil_write_base_addr == 0) {
LOGF("\t warning: stencil format is set without a stencil base address, continuing " LOGF("\t warning: stencil format is set without a stencil base address, continuing "
"without stencil attachment\n"); "without stencil attachment\n");
} }
@@ -1218,8 +1224,9 @@ void hw_check(const RenderCommandBuffer& buffer) {
const auto& mrt = hw.GetRenderTarget(i); const auto& mrt = hw.GetRenderTarget(i);
LOGF("\t RT%u addr=0x%010" PRIx64 " mask=0x%x fmt=0x%08" PRIx32 LOGF("\t RT%u addr=0x%010" PRIx64 " mask=0x%x fmt=0x%08" PRIx32
" width=%u height=%u tile=%u\n", " width=%u height=%u tile=%u\n",
i, mrt.base.addr, (hw.GetRenderTargetMask() >> (i * 4u)) & 0x0fu, mrt.info.format, i, mrt.base.addr, (hw.GetRenderTargetMask() >> (i * 4u)) & 0x0fu,
mrt.attrib2.width + 1, mrt.attrib2.height + 1, mrt.attrib3.tile_mode); static_cast<uint32_t>(mrt.info.format), mrt.attrib2.width + 1,
mrt.attrib2.height + 1, static_cast<uint32_t>(mrt.attrib3.tile_mode));
} }
} }
if (rc.depth_clear_enable && hw.GetDepthClearValue() != 0.0f && if (rc.depth_clear_enable && hw.GetDepthClearValue() != 0.0f &&
+1 -1
View File
@@ -34,7 +34,7 @@ void uc_print(const char* func, const HW::UserConfig& uc);
void uc_check(const HW::UserConfig& uc); void uc_check(const HW::UserConfig& uc);
void sh_print(const char* func, const HW::Shader& uc); void sh_print(const char* func, const HW::Shader& uc);
std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt); std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt);
bool RenderIsColorTileModeLinear(uint32_t tile_mode); bool RenderIsColorTileModeLinear(Prospero::TileMode tile_mode);
void hw_print(const RenderCommandBuffer& buffer); void hw_print(const RenderCommandBuffer& buffer);
void hw_check(const RenderCommandBuffer& buffer); void hw_check(const RenderCommandBuffer& buffer);
void LogDrawPhase(const char* draw_name, const char* phase); void LogDrawPhase(const char* draw_name, const char* phase);
@@ -67,9 +67,8 @@ static vk::StencilOp ConvertStencilOp(uint8_t value, uint8_t write_mask, uint8_t
} }
static bool UsesStencilOpValue(uint8_t fail, uint8_t pass, uint8_t depth_fail) { static bool UsesStencilOpValue(uint8_t fail, uint8_t pass, uint8_t depth_fail) {
return fail == Prospero::GpuEnumValue(Prospero::StencilOp::kReplaceOp) || constexpr auto replace_op = static_cast<uint8_t>(Prospero::StencilOp::kReplaceOp);
pass == Prospero::GpuEnumValue(Prospero::StencilOp::kReplaceOp) || return fail == replace_op || pass == replace_op || depth_fail == replace_op;
depth_fail == Prospero::GpuEnumValue(Prospero::StencilOp::kReplaceOp);
} }
[[nodiscard]] static vk::Format ResolveHostDepthAttachmentFormat(const RenderCommandBuffer& buffer, [[nodiscard]] static vk::Format ResolveHostDepthAttachmentFormat(const RenderCommandBuffer& buffer,
@@ -109,8 +108,7 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
const auto& dc = hw.GetDepthControl(); const auto& dc = hw.GetDepthControl();
const auto& sc = hw.GetStencilControl(); const auto& sc = hw.GetStencilControl();
const auto& sm = hw.GetStencilMask(); const auto& sm = hw.GetStencilMask();
const bool has_stencil = const bool has_stencil = z.stencil_info.format != Prospero::StencilFormat::kInvalid;
z.stencil_info.format != Prospero::GpuEnumValue(Prospero::StencilFormat::kInvalid);
const bool depth_active = const bool depth_active =
dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable || rc.depth_clear_enable; dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable || rc.depth_clear_enable;
const bool stencil_active = has_stencil && (dc.stencil_enable || rc.stencil_clear_enable); const bool stencil_active = has_stencil && (dc.stencil_enable || rc.stencil_clear_enable);
@@ -122,9 +120,8 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
DepthFatal("invalid PS5 depth texture-compatibility encoding"); DepthFatal("invalid PS5 depth texture-compatibility encoding");
} }
const bool attachment_unbound = const bool attachment_unbound =
z.z_info.format == Prospero::GpuEnumValue(Prospero::DepthFormat::kInvalid) && z.z_info.format == Prospero::DepthFormat::kInvalid &&
z.stencil_info.format == Prospero::GpuEnumValue(Prospero::StencilFormat::kInvalid) && z.stencil_info.format == Prospero::StencilFormat::kInvalid && z.z_info.num_samples == 0 &&
z.z_info.num_samples == 0 &&
z.z_info.texture_compatibility == Prospero::TextureCompatiblePlaneCompression::kDisable && z.z_info.texture_compatibility == Prospero::TextureCompatiblePlaneCompression::kDisable &&
!z.z_info.expclear_enabled && !z.z_info.partially_resident && z.z_info.max_mip_level == 0 && !z.z_info.expclear_enabled && !z.z_info.partially_resident && z.z_info.max_mip_level == 0 &&
z.stencil_info.texture_compatibility == Prospero::TextureCompatibleStencil::kDisable && z.stencil_info.texture_compatibility == Prospero::TextureCompatibleStencil::kDisable &&
@@ -186,8 +183,8 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
DepthFatal("unsupported depth register state"); DepthFatal("unsupported depth register state");
} }
if (has_stencil) { if (has_stencil) {
if (z.stencil_info.format != Prospero::GpuEnumValue(Prospero::StencilFormat::k8UInt) || if (z.stencil_info.format != Prospero::StencilFormat::k8UInt || !htile_stencil_compat ||
!htile_stencil_compat || z.stencil_read_base_addr == 0 || z.stencil_read_base_addr == 0 ||
z.stencil_write_base_addr != z.stencil_read_base_addr || z.stencil_write_base_addr != z.stencil_read_base_addr ||
(z.stencil_read_base_addr & 0xffffu) != 0 || z.depth_view.stencil_write_disable) { (z.stencil_read_base_addr & 0xffffu) != 0 || z.depth_view.stencil_write_disable) {
DepthFatal("unsupported stencil attachment state"); DepthFatal("unsupported stencil attachment state");
@@ -229,7 +226,7 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
DepthFatal("no host depth/stencil format supports required usage for %s", DepthFatal("no host depth/stencil format supports required usage for %s",
VulkanToString(ideal_format).c_str()); VulkanToString(ideal_format).c_str());
} }
const uint32_t guest_format = Prospero::GpuEnumValue(policy->guest_format); const auto guest_format = policy->guest_format;
const uint32_t bytes = policy->bytes_per_element; const uint32_t bytes = policy->bytes_per_element;
const auto pitch = TileGetDepthPitch(width, bytes, z.z_info.num_samples); const auto pitch = TileGetDepthPitch(width, bytes, z.z_info.num_samples);
if (z.pitch_height_valid && ((static_cast<uint64_t>(z.pitch_div8_minus1) + 1u) * 8u != pitch || if (z.pitch_height_valid && ((static_cast<uint64_t>(z.pitch_div8_minus1) + 1u) * 8u != pitch ||
@@ -343,7 +340,7 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
desc.info.pitch = pitch; desc.info.pitch = pitch;
desc.info.bytes_per_block = bytes; desc.info.bytes_per_block = bytes;
desc.info.samples = samples; desc.info.samples = samples;
desc.info.tile_mode = Prospero::GpuEnumValue(Prospero::TileMode::kDepth); desc.info.tile_mode = Prospero::TileMode::kDepth;
desc.info.mip_layout[0] = {0, r.depth_buffer_size, pitch, height}; desc.info.mip_layout[0] = {0, r.depth_buffer_size, pitch, height};
desc.info.metadata.range = {r.htile_buffer_vaddr, r.htile_buffer_size}; desc.info.metadata.range = {r.htile_buffer_vaddr, r.htile_buffer_size};
desc.info.metadata.kind = has_htile ? ImageMetadataKind::Htile : ImageMetadataKind::None; desc.info.metadata.kind = has_htile ? ImageMetadataKind::Htile : ImageMetadataKind::None;
@@ -646,13 +646,13 @@ void Validate(const ImageInfo& info) {
} }
} }
uint32_t RenderTargetTransferFormat(uint32_t bytes_per_element) { Prospero::BufferFormat RenderTargetTransferFormat(uint32_t bytes_per_element) {
switch (bytes_per_element) { switch (bytes_per_element) {
case 1: return Prospero::GpuEnumValue(Prospero::BufferFormat::k8UNorm); case 1: return Prospero::BufferFormat::k8UNorm;
case 2: return Prospero::GpuEnumValue(Prospero::BufferFormat::k16UNorm); case 2: return Prospero::BufferFormat::k16UNorm;
case 4: return Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float); case 4: return Prospero::BufferFormat::k32Float;
case 8: return Prospero::GpuEnumValue(Prospero::BufferFormat::k16_16_16_16Float); case 8: return Prospero::BufferFormat::k16_16_16_16Float;
case 16: return Prospero::GpuEnumValue(Prospero::BufferFormat::k32_32_32_32Float); case 16: return Prospero::BufferFormat::k32_32_32_32Float;
default: EXIT("unsupported render-target element size: %u\n", bytes_per_element); default: EXIT("unsupported render-target element size: %u\n", bytes_per_element);
} }
} }
+1 -1
View File
@@ -189,7 +189,7 @@ private:
namespace ImageOps { namespace ImageOps {
void Validate(const ImageInfo& info); void Validate(const ImageInfo& info);
[[nodiscard]] uint32_t RenderTargetTransferFormat(uint32_t bytes_per_element); [[nodiscard]] Prospero::BufferFormat RenderTargetTransferFormat(uint32_t bytes_per_element);
} // namespace ImageOps } // namespace ImageOps
@@ -67,14 +67,14 @@ struct ImageInfo {
ImageMetadataInfo metadata; ImageMetadataInfo metadata;
uint32_t htile_clear_mask = UINT32_MAX; uint32_t htile_clear_mask = UINT32_MAX;
vk::Format pixel_format = vk::Format::eUndefined; vk::Format pixel_format = vk::Format::eUndefined;
uint32_t guest_format = 0; Prospero::BufferFormat guest_format = Prospero::BufferFormat::kInvalid;
Prospero::ImageType type = Prospero::ImageType::kColor2D; Prospero::ImageType type = Prospero::ImageType::kColor2D;
vk::Extent3D extent = {1, 1, 1}; vk::Extent3D extent = {1, 1, 1};
ImageSubresources resources; ImageSubresources resources;
uint32_t pitch = 0; uint32_t pitch = 0;
uint32_t bytes_per_block = 0; uint32_t bytes_per_block = 0;
uint32_t samples = 1; uint32_t samples = 1;
uint32_t tile_mode = 0; Prospero::TileMode tile_mode = Prospero::TileMode::kLinear;
bool bgra16 = false; bool bgra16 = false;
std::array<ImageMipInfo, 16> mip_layout {}; std::array<ImageMipInfo, 16> mip_layout {};
@@ -86,9 +86,7 @@ struct ImageInfo {
[[nodiscard]] bool IsBlock() const noexcept { [[nodiscard]] bool IsBlock() const noexcept {
return Prospero::BlockCompressedBytesPerBlock(guest_format) != 0; return Prospero::BlockCompressedBytesPerBlock(guest_format) != 0;
} }
[[nodiscard]] bool IsTiled() const noexcept { [[nodiscard]] bool IsTiled() const noexcept { return tile_mode != Prospero::TileMode::kLinear; }
return tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
}
[[nodiscard]] constexpr bool IsVolume() const noexcept { [[nodiscard]] constexpr bool IsVolume() const noexcept {
return type == Prospero::ImageType::kColor3D; return type == Prospero::ImageType::kColor3D;
} }
@@ -235,9 +233,9 @@ inline constexpr std::array<DepthFormatPolicy, 2> DEPTH_FORMAT_POLICIES {{
}}; }};
[[nodiscard]] inline constexpr const DepthFormatPolicy* [[nodiscard]] inline constexpr const DepthFormatPolicy*
FindDepthFormatPolicy(uint32_t depth_format) noexcept { FindDepthFormatPolicy(Prospero::DepthFormat depth_format) noexcept {
for (const auto& policy: DEPTH_FORMAT_POLICIES) { for (const auto& policy: DEPTH_FORMAT_POLICIES) {
if (Prospero::GpuEnumValue(policy.depth_format) == depth_format) { if (policy.depth_format == depth_format) {
return &policy; return &policy;
} }
} }
@@ -245,9 +243,9 @@ FindDepthFormatPolicy(uint32_t depth_format) noexcept {
} }
[[nodiscard]] inline constexpr const DepthFormatPolicy* [[nodiscard]] inline constexpr const DepthFormatPolicy*
FindGuestDepthFormatPolicy(uint32_t guest_format) noexcept { FindGuestDepthFormatPolicy(Prospero::BufferFormat guest_format) noexcept {
for (const auto& policy: DEPTH_FORMAT_POLICIES) { for (const auto& policy: DEPTH_FORMAT_POLICIES) {
if (Prospero::GpuEnumValue(policy.guest_format) == guest_format) { if (policy.guest_format == guest_format) {
return &policy; return &policy;
} }
} }
@@ -269,10 +267,11 @@ FindGuestDepthFormatPolicy(uint32_t guest_format) noexcept {
return has_stencil ? policy.stencil_attachment_formats.front() : policy.depth_attachment_format; return has_stencil ? policy.stencil_attachment_formats.front() : policy.depth_attachment_format;
} }
[[nodiscard]] inline constexpr vk::Format DepthAttachmentFormat(uint32_t depth_format, [[nodiscard]] inline constexpr vk::Format
uint32_t stencil_format) noexcept { DepthAttachmentFormat(Prospero::DepthFormat depth_format,
Prospero::StencilFormat stencil_format) noexcept {
bool has_stencil = false; bool has_stencil = false;
switch (static_cast<Prospero::StencilFormat>(stencil_format)) { switch (stencil_format) {
case Prospero::StencilFormat::kInvalid: break; case Prospero::StencilFormat::kInvalid: break;
case Prospero::StencilFormat::k8UInt: has_stencil = true; break; case Prospero::StencilFormat::k8UInt: has_stencil = true; break;
default: return vk::Format::eUndefined; default: return vk::Format::eUndefined;
@@ -318,8 +317,8 @@ inline bool ImageInfo::IsDepth() const noexcept {
return std::bit_cast<uint32_t>(static_cast<float>(value) / 65535.0f); return std::bit_cast<uint32_t>(static_cast<float>(value) / 65535.0f);
} }
[[nodiscard]] inline constexpr bool IsSupportedSampledDepthFormat(vk::Format image_format, [[nodiscard]] inline constexpr bool
uint32_t guest_format, IsSupportedSampledDepthFormat(vk::Format image_format, Prospero::BufferFormat guest_format,
vk::Format view_format) noexcept { vk::Format view_format) noexcept {
const auto* policy = FindGuestDepthFormatPolicy(guest_format); const auto* policy = FindGuestDepthFormatPolicy(guest_format);
return policy != nullptr && view_format == policy->sampled_view_format && return policy != nullptr && view_format == policy->sampled_view_format &&
@@ -330,8 +329,7 @@ inline bool ImageInfo::IsDepth() const noexcept {
[[nodiscard]] inline constexpr bool IsSupportedSampledDepthFormat(vk::Format image_format, [[nodiscard]] inline constexpr bool IsSupportedSampledDepthFormat(vk::Format image_format,
vk::Format view_format) noexcept { vk::Format view_format) noexcept {
for (const auto& policy: DEPTH_FORMAT_POLICIES) { for (const auto& policy: DEPTH_FORMAT_POLICIES) {
if (IsSupportedSampledDepthFormat(image_format, Prospero::GpuEnumValue(policy.guest_format), if (IsSupportedSampledDepthFormat(image_format, policy.guest_format, view_format)) {
view_format)) {
return true; return true;
} }
} }
@@ -384,7 +382,7 @@ CanUseVideoOutNativeWithoutUpload(VideoOutCompression compression, bool render_t
struct VideoOutPixelFormatInfo { struct VideoOutPixelFormatInfo {
vk::Format format = vk::Format::eUndefined; vk::Format format = vk::Format::eUndefined;
uint32_t guest_format = 0; Prospero::BufferFormat guest_format = Prospero::BufferFormat::kInvalid;
uint32_t bytes_per_element = 0; uint32_t bytes_per_element = 0;
bool bgra16 = false; bool bgra16 = false;
}; };
@@ -396,23 +394,17 @@ struct VideoOutFormatPolicy {
inline constexpr std::array<VideoOutFormatPolicy, 6> VIDEO_OUT_FORMAT_POLICIES {{ inline constexpr std::array<VideoOutFormatPolicy, 6> VIDEO_OUT_FORMAT_POLICIES {{
{0x8000000022000000ull, {0x8000000022000000ull,
{vk::Format::eR8G8B8A8Srgb, Prospero::GpuEnumValue(Prospero::BufferFormat::k8_8_8_8Srgb), 4, {vk::Format::eR8G8B8A8Srgb, Prospero::BufferFormat::k8_8_8_8Srgb, 4, false}},
false}},
{0x8000000000000000ull, {0x8000000000000000ull,
{vk::Format::eB8G8R8A8Srgb, Prospero::GpuEnumValue(Prospero::BufferFormat::k8_8_8_8Srgb), 4, {vk::Format::eB8G8R8A8Srgb, Prospero::BufferFormat::k8_8_8_8Srgb, 4, false}},
false}},
{0x8100000022000000ull, {0x8100000022000000ull,
{vk::Format::eA2B10G10R10UnormPack32, {vk::Format::eA2B10G10R10UnormPack32, Prospero::BufferFormat::k10_10_10_2UNorm, 4, false}},
Prospero::GpuEnumValue(Prospero::BufferFormat::k10_10_10_2UNorm), 4, false}},
{0x8100000000000000ull, {0x8100000000000000ull,
{vk::Format::eA2R10G10B10UnormPack32, {vk::Format::eA2R10G10B10UnormPack32, Prospero::BufferFormat::k10_10_10_2UNorm, 4, false}},
Prospero::GpuEnumValue(Prospero::BufferFormat::k10_10_10_2UNorm), 4, false}},
{0xc001000622000000ull, {0xc001000622000000ull,
{vk::Format::eR16G16B16A16Sfloat, {vk::Format::eR16G16B16A16Sfloat, Prospero::BufferFormat::k16_16_16_16Float, 8, false}},
Prospero::GpuEnumValue(Prospero::BufferFormat::k16_16_16_16Float), 8, false}},
{0xc001000600000000ull, {0xc001000600000000ull,
{vk::Format::eR16G16B16A16Sfloat, {vk::Format::eR16G16B16A16Sfloat, Prospero::BufferFormat::k16_16_16_16Float, 8, true}},
Prospero::GpuEnumValue(Prospero::BufferFormat::k16_16_16_16Float), 8, true}},
}}; }};
[[nodiscard]] inline bool DecodeVideoOutPixelFormat(uint64_t pixel_format, [[nodiscard]] inline bool DecodeVideoOutPixelFormat(uint64_t pixel_format,
@@ -439,15 +431,15 @@ inline constexpr std::array<VideoOutFormatPolicy, 6> VIDEO_OUT_FORMAT_POLICIES {
} }
[[nodiscard]] inline constexpr bool [[nodiscard]] inline constexpr bool
IsSupportedDisplayRenderTargetTileMode(uint32_t tile_mode) noexcept { IsSupportedDisplayRenderTargetTileMode(Prospero::TileMode tile_mode) noexcept {
return tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget); return tile_mode == Prospero::TileMode::kRenderTarget;
} }
[[nodiscard]] inline constexpr bool IsSupportedStandard64RenderTarget(const ImageInfo& info) { [[nodiscard]] inline constexpr bool IsSupportedStandard64RenderTarget(const ImageInfo& info) {
if (info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB) || if (info.tile_mode != Prospero::TileMode::kStandard64KB || info.data.address == 0 ||
info.data.address == 0 || (info.data.address & 0xffffu) != 0 || info.extent.width == 0 || (info.data.address & 0xffffu) != 0 || info.extent.width == 0 || info.extent.height == 0 ||
info.extent.height == 0 || info.bytes_per_block != 4 || info.resources.levels != 1 || info.bytes_per_block != 4 || info.resources.levels != 1 || info.resources.layers != 1 ||
info.resources.layers != 1 || info.samples != 1) { info.samples != 1) {
return false; return false;
} }
const auto expected_pitch = const auto expected_pitch =
@@ -460,7 +452,7 @@ IsSupportedDisplayRenderTargetTileMode(uint32_t tile_mode) noexcept {
} }
[[nodiscard]] inline constexpr bool IsTiledRenderTarget(const ImageInfo& info) noexcept { [[nodiscard]] inline constexpr bool IsTiledRenderTarget(const ImageInfo& info) noexcept {
return info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) || return info.tile_mode == Prospero::TileMode::kRenderTarget ||
IsSupportedStandard64RenderTarget(info); IsSupportedStandard64RenderTarget(info);
} }
@@ -54,28 +54,27 @@ RenderTargetHostFormatInfo ResolveRenderTargetHostFormat(Prospero::BufferFormat
return {vk::Format::eR5G5B5A1UnormPack16, Prospero::ColorMappingAbgr}; return {vk::Format::eR5G5B5A1UnormPack16, Prospero::ColorMappingAbgr};
case Prospero::BufferFormat::k4_4_4_4UNorm: case Prospero::BufferFormat::k4_4_4_4UNorm:
return {vk::Format::eR4G4B4A4UnormPack16, Prospero::ColorMappingAbgr}; return {vk::Format::eR4G4B4A4UnormPack16, Prospero::ColorMappingAbgr};
default: return {VulkanFormat(Prospero::GpuEnumValue(guest_format)), {}}; default: return {VulkanFormat(guest_format), {}};
} }
} }
} // namespace } // namespace
RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t raw_layout, uint32_t raw_type, RenderTargetFormatInfo TextureGetRenderTargetFormat(Prospero::ChannelLayout layout,
uint32_t raw_order) { Prospero::ChannelType type,
const auto encoding = Prospero::ResolveRenderTargetFormat(raw_layout, raw_type); Prospero::ChannelOrder order) {
if (encoding.IsValid() && encoding.SupportsOrder(raw_order)) { const auto encoding = Prospero::ResolveRenderTargetFormat(layout, type);
const auto order = static_cast<Prospero::ChannelOrder>(raw_order); if (encoding.IsValid() && encoding.SupportsOrder(order)) {
const auto host = ResolveRenderTargetHostFormat(encoding.buffer_format, order); const auto host = ResolveRenderTargetHostFormat(encoding.buffer_format, order);
const auto bytes = const auto bytes = Prospero::RenderTargetBytesPerElement(encoding.buffer_format);
Prospero::RenderTargetBytesPerElement(Prospero::GpuEnumValue(encoding.buffer_format));
if (host.format != vk::Format::eUndefined && bytes != 0) { if (host.format != vk::Format::eUndefined && bytes != 0) {
const auto order_mapping = const auto order_mapping =
kRenderTargetColorMappings[raw_order][encoding.components - 1u]; kRenderTargetColorMappings[static_cast<size_t>(order)][encoding.components - 1u];
return {host.format, bytes, host.host_to_storage.Then(order_mapping)}; return {host.format, bytes, host.host_to_storage.Then(order_mapping)};
} }
} }
EXIT("unsupported render-target format combination: layout=%u type=%u order=%u\n", raw_layout, EXIT("unsupported render-target format combination: layout=%u type=%u order=%u\n",
raw_type, raw_order); static_cast<uint32_t>(layout), static_cast<uint32_t>(type), static_cast<uint32_t>(order));
} }
namespace { namespace {
@@ -120,12 +119,12 @@ vk::ComponentMapping TextureGetComponentMapping(uint32_t swizzle) {
return components; return components;
} }
vk::Format TextureGetFormat(uint32_t fmt) { vk::Format TextureGetFormat(Prospero::BufferFormat format) {
const auto vk_format = VulkanFormat(fmt); const auto vk_format = VulkanFormat(format);
if (vk_format != vk::Format::eUndefined) { if (vk_format != vk::Format::eUndefined) {
return vk_format; return vk_format;
} }
EXIT("unknown format: fmt = %u\n", fmt); EXIT("unknown format: fmt = %u\n", static_cast<uint32_t>(format));
return vk::Format::eUndefined; return vk::Format::eUndefined;
} }
@@ -183,13 +182,14 @@ uint64_t SetLinearUploadLevels(TextureUploadMipLayout* mips,
} // namespace } // namespace
TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint32_t width, uint32_t height, TextureUploadLayout TextureCalcUploadLayout(Prospero::BufferFormat format, uint32_t width,
uint32_t levels, uint32_t depth, uint32_t tile, uint32_t height, uint32_t levels, uint32_t depth,
uint64_t upload_size, bool allow_depth_tile, Prospero::TileMode tile, uint64_t upload_size,
bool volume_texture, const char* owner) { bool allow_depth_tile, bool volume_texture,
const char* owner) {
TextureUploadLayout layout {}; TextureUploadLayout layout {};
layout.surface.description = { layout.surface.description = {
fmt, format,
tile, tile,
volume_texture ? TileSurfaceDimension::Dim3D : TileSurfaceDimension::Dim2D, volume_texture ? TileSurfaceDimension::Dim3D : TileSurfaceDimension::Dim2D,
width, width,
@@ -199,35 +199,39 @@ TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint32_t width, uint32
volume_texture ? 1u : depth, volume_texture ? 1u : depth,
}; };
const auto& description = layout.surface.description; const auto& description = layout.surface.description;
const auto tile_mode = static_cast<Prospero::TileMode>(description.tile_mode); const auto tile_mode = description.tile_mode;
TileTextureElementLayout element {}; TileTextureElementLayout element {};
if (fmt == 0) { if (format == Prospero::BufferFormat::kInvalid) {
EXIT("%s: legacy texture upload format unsupported: fmt=0 tile=%u size=%" PRIu64 EXIT("%s: legacy texture upload format unsupported: fmt=0 tile=%u size=%" PRIu64
" extent=%ux%u levels=%u\n", " extent=%ux%u levels=%u\n",
owner, description.tile_mode, upload_size, width, height, levels); owner, static_cast<uint32_t>(description.tile_mode), upload_size, width, height,
levels);
} }
switch (tile_mode) { switch (tile_mode) {
case Prospero::TileMode::kLinear: case Prospero::TileMode::kLinear:
if (!TileGetTextureElementLayout(fmt, element)) { if (!TileGetTextureElementLayout(format, element)) {
EXIT("%s: unsupported linear texture format: fmt=%u\n", owner, fmt); EXIT("%s: unsupported linear texture format: fmt=%u\n", owner,
static_cast<uint32_t>(format));
} }
break; break;
case Prospero::TileMode::kDepth: case Prospero::TileMode::kDepth:
if (!allow_depth_tile || !TileGetTiledTextureLayout(description, layout.surface)) { if (!allow_depth_tile || !TileGetTiledTextureLayout(description, layout.surface)) {
EXIT("%s: unsupported typed tiled upload: fmt=%u tile=%u " EXIT("%s: unsupported typed tiled upload: fmt=%u tile=%u "
"size=%" PRIu64 " extent=%ux%u levels=%u\n", "size=%" PRIu64 " extent=%ux%u levels=%u\n",
owner, static_cast<uint32_t>(fmt), description.tile_mode, upload_size, width, owner, static_cast<uint32_t>(format),
height, levels); static_cast<uint32_t>(description.tile_mode), upload_size, width, height,
levels);
} }
break; break;
default: default:
if (!TileGetTiledTextureLayout(description, layout.surface)) { if (!TileGetTiledTextureLayout(description, layout.surface)) {
EXIT("%s: unsupported typed tiled upload: fmt=%u tile=%u " EXIT("%s: unsupported typed tiled upload: fmt=%u tile=%u "
"size=%" PRIu64 " extent=%ux%u levels=%u\n", "size=%" PRIu64 " extent=%ux%u levels=%u\n",
owner, static_cast<uint32_t>(fmt), description.tile_mode, upload_size, width, owner, static_cast<uint32_t>(format),
height, levels); static_cast<uint32_t>(description.tile_mode), upload_size, width, height,
levels);
} }
break; break;
} }
@@ -236,12 +240,12 @@ TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint32_t width, uint32
element = {layout.surface.texture.block.bytes_per_element, element = {layout.surface.texture.block.bytes_per_element,
layout.surface.texture.texel_width, layout.surface.texture.texel_height}; layout.surface.texture.texel_width, layout.surface.texture.texel_height};
} }
layout.pitch = TileGetTexturePitch(fmt, width, description.tile_mode); layout.pitch = TileGetTexturePitch(format, width, description.tile_mode);
if (tile_mode == Prospero::TileMode::kLinear) { if (tile_mode == Prospero::TileMode::kLinear) {
TileSizeOffset level_sizes[16] {}; TileSizeOffset level_sizes[16] {};
TilePaddedSize padded_sizes[16] {}; TilePaddedSize padded_sizes[16] {};
TileGetTextureSize(fmt, width, height, levels, description.tile_mode, nullptr, level_sizes, TileGetTextureSize(format, width, height, levels, description.tile_mode, nullptr,
padded_sizes); level_sizes, padded_sizes);
for (uint32_t level = 0; level < levels; ++level) { for (uint32_t level = 0; level < levels; ++level) {
layout.mips[level] = {level_sizes[level].offset, level_sizes[level].size, layout.mips[level] = {level_sizes[level].offset, level_sizes[level].size,
padded_sizes[level].width, padded_sizes[level].height}; padded_sizes[level].width, padded_sizes[level].height};
@@ -268,8 +272,7 @@ std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayo
const auto depth = volume_texture ? description.depth : description.layers; const auto depth = volume_texture ? description.depth : description.layers;
uint32_t mip_width = description.width; uint32_t mip_width = description.width;
uint32_t mip_height = description.height; uint32_t mip_height = description.height;
uint32_t mip_pitch = volume_texture && static_cast<Prospero::TileMode>(description.tile_mode) != uint32_t mip_pitch = volume_texture && description.tile_mode != Prospero::TileMode::kLinear
Prospero::TileMode::kLinear
? description.width ? description.width
: layout.pitch; : layout.pitch;
@@ -288,8 +291,7 @@ std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayo
1}; 1};
region.imageOffset.z = volume_texture ? static_cast<int>(z) : 0; region.imageOffset.z = volume_texture ? static_cast<int>(z) : 0;
region.imageExtent = {mip_width, mip_height, 1}; region.imageExtent = {mip_width, mip_height, 1};
const bool linear = static_cast<Prospero::TileMode>(description.tile_mode) == const bool linear = description.tile_mode == Prospero::TileMode::kLinear;
Prospero::TileMode::kLinear;
if (linear) { if (linear) {
region.bufferRowLength = layout.mips[i].row_length; region.bufferRowLength = layout.mips[i].row_length;
region.bufferImageHeight = layout.mips[i].image_height; region.bufferImageHeight = layout.mips[i].image_height;
@@ -35,12 +35,15 @@ struct TextureUploadLayout {
}; };
vk::ComponentMapping TextureGetComponentMapping(uint32_t swizzle); vk::ComponentMapping TextureGetComponentMapping(uint32_t swizzle);
vk::Format TextureGetFormat(uint32_t fmt); vk::Format TextureGetFormat(Prospero::BufferFormat format);
RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t layout, uint32_t type, uint32_t order); RenderTargetFormatInfo TextureGetRenderTargetFormat(Prospero::ChannelLayout layout,
TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint32_t width, uint32_t height, Prospero::ChannelType type,
uint32_t levels, uint32_t depth, uint32_t tile, Prospero::ChannelOrder order);
uint64_t upload_size, bool allow_depth_tile, TextureUploadLayout TextureCalcUploadLayout(Prospero::BufferFormat format, uint32_t width,
bool volume_texture, const char* owner); uint32_t height, uint32_t levels, uint32_t depth,
Prospero::TileMode tile, uint64_t upload_size,
bool allow_depth_tile, bool volume_texture,
const char* owner);
std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayout& layout); std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayout& layout);
bool TextureBuildGpuTileInfos(uint64_t tiled_size, const std::vector<vk::BufferImageCopy>& regions, bool TextureBuildGpuTileInfos(uint64_t tiled_size, const std::vector<vk::BufferImageCopy>& regions,
const TextureUploadLayout& layout, uint32_t levels, const TextureUploadLayout& layout, uint32_t levels,
@@ -59,7 +59,7 @@ static void CopyNativeDescriptor(const ShaderRecompiler::IR::DescriptorValue& so
} }
static Prospero::ImageType TextureType(const ShaderTextureResource& descriptor) { static Prospero::ImageType TextureType(const ShaderTextureResource& descriptor) {
const auto type = static_cast<Prospero::ImageType>(descriptor.Type()); const auto type = descriptor.Type();
return type == Prospero::ImageType::kCube ? Prospero::ImageType::kColor2DArray : type; return type == Prospero::ImageType::kCube ? Prospero::ImageType::kColor2DArray : type;
} }
@@ -227,14 +227,14 @@ bool IsSupportedSampledVideoOutView(const ShaderRecompiler::IR::ImageResource& r
return image.usage.video_out && image.info.resources.layers == 1 && return image.usage.video_out && image.info.resources.layers == 1 &&
IsSupportedSampledColorResource(resource) && IsSupportedSampledColorResource(resource) &&
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D && resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D &&
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) && descriptor.Type() == Prospero::ImageType::kColor2D && descriptor.Depth() == 0 &&
descriptor.Depth() == 0 && descriptor.BaseArray5() == 0; descriptor.BaseArray5() == 0;
} }
bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, const Image& image) { bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, const Image& image) {
const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u; const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u;
const auto height = static_cast<uint32_t>(descriptor.Height5()) + 1u; const auto height = static_cast<uint32_t>(descriptor.Height5()) + 1u;
const auto type = static_cast<Prospero::ImageType>(descriptor.Type()); const auto type = descriptor.Type();
const bool multisampled = IsMultisampledTexture(type); const bool multisampled = IsMultisampledTexture(type);
const auto samples = multisampled ? 1u << descriptor.LastLevel() : 1u; const auto samples = multisampled ? 1u << descriptor.LastLevel() : 1u;
const auto pitch = const auto pitch =
@@ -269,9 +269,8 @@ bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, c
(supported_2d || supported_array || supported_cube || supported_msaa_2d || (supported_2d || supported_array || supported_cube || supported_msaa_2d ||
supported_msaa_array) && supported_msaa_array) &&
levels_ok && descriptor.MinLod() == 0 && levels_ok && descriptor.MinLod() == 0 &&
descriptor.TileMode() == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && descriptor.TileMode() == Prospero::TileMode::kDepth && descriptor.BCSwizzle() == 0 &&
descriptor.BCSwizzle() == 0 && (!descriptor.MsaaDepth() || multisampled) && (!descriptor.MsaaDepth() || multisampled) && pitch >= width && pitch == image.info.pitch;
pitch >= width && pitch == image.info.pitch;
} }
bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor, const Image& image) { bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor, const Image& image) {
@@ -300,8 +299,8 @@ bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor, co
const uint32_t expected_control = htile_control | (descriptor.MsaaDepth() ? (1u << 10u) : 0u); const uint32_t expected_control = htile_control | (descriptor.MsaaDepth() ? (1u << 10u) : 0u);
const auto metadata_addr = descriptor.MetaAddr() << 8u; const auto metadata_addr = descriptor.MetaAddr() << 8u;
return (descriptor.fields[6] & 0x00ffffffu) == expected_control && metadata_addr != 0 && return (descriptor.fields[6] & 0x00ffffffu) == expected_control && metadata_addr != 0 &&
descriptor.TileMode() == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && descriptor.TileMode() == Prospero::TileMode::kDepth &&
image.info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && image.info.tile_mode == Prospero::TileMode::kDepth &&
image.info.metadata.kind == ImageMetadataKind::Htile && image.info.metadata.kind == ImageMetadataKind::Htile &&
image.info.metadata.range.Valid() && image.info.metadata.range.address == metadata_addr; image.info.metadata.range.Valid() && image.info.metadata.range.address == metadata_addr;
} }
@@ -332,23 +331,21 @@ static void ValidateDepthTargetBinding(const ShaderRecompiler::IR::ImageResource
resource_ok, descriptor_ok, encoding_ok, format_ok, static_cast<uint32_t>(resource.kind), resource_ok, descriptor_ok, encoding_ok, format_ok, static_cast<uint32_t>(resource.kind),
static_cast<uint32_t>(resource.dimension), static_cast<uint32_t>(resource.mip_mode), static_cast<uint32_t>(resource.dimension), static_cast<uint32_t>(resource.mip_mode),
resource.read, resource.written, resource.atomic, resource.depth_compare, resource.read, resource.written, resource.atomic, resource.depth_compare,
descriptor.Format(), descriptor.DstSelXYZW(), static_cast<uint32_t>(descriptor.Format()), descriptor.DstSelXYZW(),
image == nullptr ? static_cast<int>(vk::Format::eUndefined) image == nullptr ? static_cast<int>(vk::Format::eUndefined)
: static_cast<int>(image->info.pixel_format), : static_cast<int>(image->info.pixel_format),
static_cast<int>(view_format), image == nullptr ? 0u : image->info.resources.layers, static_cast<int>(view_format), image == nullptr ? 0u : image->info.resources.layers,
descriptor.Type(), descriptor.BaseArray5(), descriptor.Depth(), descriptor_pitch, static_cast<uint32_t>(descriptor.Type()), descriptor.BaseArray5(), descriptor.Depth(),
image == nullptr ? 0u : image->info.pitch, descriptor.Base40(), size, descriptor.fields[0], descriptor_pitch, image == nullptr ? 0u : image->info.pitch, descriptor.Base40(), size,
descriptor.fields[1], descriptor.fields[2], descriptor.fields[3], descriptor.fields[4], descriptor.fields[0], descriptor.fields[1], descriptor.fields[2], descriptor.fields[3],
descriptor.fields[5], descriptor.fields[6], descriptor.fields[7]); descriptor.fields[4], descriptor.fields[5], descriptor.fields[6], descriptor.fields[7]);
} }
static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::ImageResource& resource, static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::ImageResource& resource,
const ShaderTextureResource& descriptor) { const ShaderTextureResource& descriptor) {
const auto tile = descriptor.TileMode(); const auto tile = descriptor.TileMode();
const bool is_color_1d = const bool is_color_1d = descriptor.Type() == Prospero::ImageType::kColor1D;
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor1D); const bool is_color_1d_array = descriptor.Type() == Prospero::ImageType::kColor1DArray;
const bool is_color_1d_array =
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor1DArray);
const bool valid_1d_slice = const bool valid_1d_slice =
(is_color_1d && descriptor.Depth() == 0 && descriptor.BaseArray5() == 0) || (is_color_1d && descriptor.Depth() == 0 && descriptor.BaseArray5() == 0) ||
(is_color_1d_array && descriptor.BaseArray5() <= descriptor.Depth()); (is_color_1d_array && descriptor.BaseArray5() <= descriptor.Depth());
@@ -358,10 +355,8 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim1DArray && resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim1DArray &&
is_color_1d_array && descriptor.Height5() == 0 && is_color_1d_array && descriptor.Height5() == 0 &&
descriptor.BaseArray5() <= descriptor.Depth(); descriptor.BaseArray5() <= descriptor.Depth();
const bool is_color_2d = const bool is_color_2d = descriptor.Type() == Prospero::ImageType::kColor2D;
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D); const bool is_color_2d_array = descriptor.Type() == Prospero::ImageType::kColor2DArray;
const bool is_color_2d_array =
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray);
const bool valid_2d_slice = const bool valid_2d_slice =
(is_color_2d && descriptor.Depth() == 0 && descriptor.BaseArray5() == 0) || (is_color_2d && descriptor.Depth() == 0 && descriptor.BaseArray5() == 0) ||
(is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth()); (is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth());
@@ -371,11 +366,11 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray && resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray &&
is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth(); is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth();
const bool is_3d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D && const bool is_3d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D &&
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D) && descriptor.Type() == Prospero::ImageType::kColor3D &&
descriptor.BaseArray5() == 0; descriptor.BaseArray5() == 0;
TileTextureBlockLayout tile_layout {}; TileTextureBlockLayout tile_layout {};
bool supported_tile = false; bool supported_tile = false;
switch (static_cast<Prospero::TileMode>(tile)) { switch (tile) {
case Prospero::TileMode::kLinear: supported_tile = true; break; case Prospero::TileMode::kLinear: supported_tile = true; break;
case Prospero::TileMode::kDepth: case Prospero::TileMode::kDepth:
supported_tile = supported_tile =
@@ -435,14 +430,12 @@ void ValidateStorageTexture(const ShaderRecompiler::IR::ImageResource& resource,
const bool encoding_ok = IsSupportedStorageTextureEncoding(descriptor); const bool encoding_ok = IsSupportedStorageTextureEncoding(descriptor);
const bool uint_resource = const bool uint_resource =
resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint; resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint;
const bool raw_sint_storage = const bool raw_sint_storage = format == Prospero::BufferFormat::k32SInt && uint_resource &&
format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) && uint_resource &&
resource.written && !resource.read && !resource.atomic; resource.written && !resource.read && !resource.atomic;
const bool format_ok = const bool format_ok =
raw_sint_storage || raw_sint_storage || (Prospero::IsSupportedTextureFormat(format) &&
(Prospero::IsSupportedTextureFormat(format) &&
uint_resource == Prospero::IsUintTextureFormat(format) && uint_resource == Prospero::IsUintTextureFormat(format) &&
(!resource.atomic || format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt))); (!resource.atomic || format == Prospero::BufferFormat::k32UInt));
if (resource_ok && descriptor_ok && encoding_ok && format_ok && size != 0) { if (resource_ok && descriptor_ok && encoding_ok && format_ok && size != 0) {
return; return;
} }
@@ -461,24 +454,23 @@ void ValidateStorageTexture(const ShaderRecompiler::IR::ImageResource& resource,
IsValidImageSwizzle(descriptor.DstSelXYZW()), descriptor.Base40(), size, IsValidImageSwizzle(descriptor.DstSelXYZW()), descriptor.Base40(), size,
static_cast<uint32_t>(descriptor.Width5()) + 1u, static_cast<uint32_t>(descriptor.Width5()) + 1u,
static_cast<uint32_t>(descriptor.Height5()) + 1u, static_cast<uint32_t>(descriptor.Height5()) + 1u,
static_cast<uint32_t>(descriptor.Depth()) + 1u, descriptor.Type(), format, static_cast<uint32_t>(descriptor.Depth()) + 1u, static_cast<uint32_t>(descriptor.Type()),
descriptor.TileMode(), descriptor.DstSelXYZW(), resource.read, resource.written, static_cast<uint32_t>(format), static_cast<uint32_t>(descriptor.TileMode()),
descriptor.fields[0], descriptor.fields[1], descriptor.fields[2], descriptor.fields[3], descriptor.DstSelXYZW(), resource.read, resource.written, descriptor.fields[0],
descriptor.fields[4], descriptor.fields[5], descriptor.fields[6], descriptor.fields[7]); descriptor.fields[1], descriptor.fields[2], descriptor.fields[3], descriptor.fields[4],
descriptor.fields[5], descriptor.fields[6], descriptor.fields[7]);
} }
struct NullImageSpec { struct NullImageSpec {
vk::Format format; vk::Format format;
uint32_t guest_format; Prospero::BufferFormat guest_format;
}; };
static NullImageSpec NullTextureSpec(const ShaderRecompiler::IR::ImageResource& resource) { static NullImageSpec NullTextureSpec(const ShaderRecompiler::IR::ImageResource& resource) {
const bool uint_image = resource.kind == ShaderRecompiler::IR::ResourceKind::ImageUint || const bool uint_image = resource.kind == ShaderRecompiler::IR::ResourceKind::ImageUint ||
resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint; resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint;
return uint_image ? NullImageSpec {vk::Format::eR32Uint, return uint_image ? NullImageSpec {vk::Format::eR32Uint, Prospero::BufferFormat::k32UInt}
Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt)} : NullImageSpec {vk::Format::eR32Sfloat, Prospero::BufferFormat::k32Float};
: NullImageSpec {vk::Format::eR32Sfloat,
Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float)};
} }
static TextureCache::ImageDesc NullTextureDesc(const ShaderRecompiler::IR::ImageResource& resource, static TextureCache::ImageDesc NullTextureDesc(const ShaderRecompiler::IR::ImageResource& resource,
@@ -504,7 +496,7 @@ static TextureCache::ImageDesc NullTextureDesc(const ShaderRecompiler::IR::Image
} }
static void PopulateTextureMipLayout(ImageInfo& info) { static void PopulateTextureMipLayout(ImageInfo& info) {
if (info.IsVolume() && info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kLinear)) { if (info.IsVolume() && info.tile_mode != Prospero::TileMode::kLinear) {
TileSurfaceLayout surface {}; TileSurfaceLayout surface {};
const TileSurfaceDescription description { const TileSurfaceDescription description {
info.guest_format, info.tile_mode, TileSurfaceDimension::Dim3D, info.extent.width, info.guest_format, info.tile_mode, TileSurfaceDimension::Dim3D, info.extent.width,
@@ -631,9 +623,8 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
const bool multisampled = IsMultisampledTexture(type); const bool multisampled = IsMultisampledTexture(type);
const auto levels = multisampled ? 1u : static_cast<uint32_t>(descriptor.MaxMip()) + 1u; const auto levels = multisampled ? 1u : static_cast<uint32_t>(descriptor.MaxMip()) + 1u;
const auto tile = descriptor.TileMode(); const auto tile = descriptor.TileMode();
const bool depth_tile = tile == Prospero::GpuEnumValue(Prospero::TileMode::kDepth); const bool depth_tile = tile == Prospero::TileMode::kDepth;
const bool msaa_tile = const bool msaa_tile = depth_tile || tile == Prospero::TileMode::kRenderTarget;
depth_tile || tile == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget);
const bool msaa_array = type == Prospero::ImageType::kColor2DMsaaArray; const bool msaa_array = type == Prospero::ImageType::kColor2DMsaaArray;
if ((!multisampled && (base_level > last_level || last_level >= levels)) || if ((!multisampled && (base_level > last_level || last_level >= levels)) ||
(multisampled && (multisampled &&
@@ -644,7 +635,8 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
EXIT("unsupported texture mip view: base=%u last=%u levels=%u max=%u type=%u tile=%u " EXIT("unsupported texture mip view: base=%u last=%u levels=%u max=%u type=%u tile=%u "
"kind=%u dimension=%u mip_mode=%u read=%d written=%d " "kind=%u dimension=%u mip_mode=%u read=%d written=%d "
"dwords=%08x,%08x,%08x,%08x,%08x,%08x,%08x,%08x\n", "dwords=%08x,%08x,%08x,%08x,%08x,%08x,%08x,%08x\n",
base_level, last_level, levels, descriptor.MaxMip(), descriptor.Type(), tile, base_level, last_level, levels, descriptor.MaxMip(),
static_cast<uint32_t>(descriptor.Type()), static_cast<uint32_t>(tile),
static_cast<uint32_t>(resource.kind), static_cast<uint32_t>(resource.dimension), static_cast<uint32_t>(resource.kind), static_cast<uint32_t>(resource.dimension),
static_cast<uint32_t>(resource.mip_mode), resource.read, resource.written, static_cast<uint32_t>(resource.mip_mode), resource.read, resource.written,
descriptor.fields[0], descriptor.fields[1], descriptor.fields[2], descriptor.fields[3], descriptor.fields[0], descriptor.fields[1], descriptor.fields[2], descriptor.fields[3],
@@ -664,7 +656,7 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
resource.kind == ShaderRecompiler::IR::ResourceKind::ImageUint) && resource.kind == ShaderRecompiler::IR::ResourceKind::ImageUint) &&
!sampled_numeric_class) { !sampled_numeric_class) {
EXIT("sampled image numeric class mismatch: kind=%u format=%u addr=0x%016" PRIx64 "\n", EXIT("sampled image numeric class mismatch: kind=%u format=%u addr=0x%016" PRIx64 "\n",
static_cast<uint32_t>(resource.kind), format, address); static_cast<uint32_t>(resource.kind), static_cast<uint32_t>(format), address);
} }
const bool volume = type == Prospero::ImageType::kColor3D; const bool volume = type == Prospero::ImageType::kColor3D;
@@ -695,8 +687,7 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
} }
const auto pixel_format = TextureGetFormat(format); const auto pixel_format = TextureGetFormat(format);
const auto storage_view_format = const auto storage_view_format = storage && format == Prospero::BufferFormat::k32SInt
storage && format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt)
? vk::Format::eR32Uint ? vk::Format::eR32Uint
: SrgbStorageViewFormat(pixel_format); : SrgbStorageViewFormat(pixel_format);
const auto view_format = storage && storage_view_format != vk::Format::eUndefined const auto view_format = storage && storage_view_format != vk::Format::eUndefined
@@ -24,6 +24,8 @@
namespace Libs::Graphics { namespace Libs::Graphics {
// IDK: maybe we can remove it? // IDK: maybe we can remove it?
constexpr uint8_t kTemporaryVertexAttribFormat113 =
static_cast<uint8_t>(Prospero::VertexAttribFormat::k16_16SInt);
constexpr uint32_t kTemporaryPs5BufferFormat121 = 121u; constexpr uint32_t kTemporaryPs5BufferFormat121 = 121u;
static bool NarrowInputFormat(vk::Format& format, uint32_t& size, uint32_t used_components) { static bool NarrowInputFormat(vk::Format& format, uint32_t& size, uint32_t used_components) {
@@ -88,8 +90,9 @@ static bool NarrowInputFormat(vk::Format& format, uint32_t& size, uint32_t used_
static void GetInputFormat(const ShaderBufferResource& res, vk::Format& format, uint32_t& size, static void GetInputFormat(const ShaderBufferResource& res, vk::Format& format, uint32_t& size,
uint32_t used_components) { uint32_t used_components) {
auto fmt = res.Format(); const auto fmt = res.Format();
if (fmt == Prospero::GpuEnumValue(Prospero::VertexAttribFormat::k16_16SInt)) { const auto raw_format = res.RawFormat();
if (raw_format == kTemporaryVertexAttribFormat113) {
static bool logged_113 = false; static bool logged_113 = false;
if (!logged_113) { if (!logged_113) {
LOGF("InputFormat: temporary: accepting invalid PS5 buffer format 113 as " LOGF("InputFormat: temporary: accepting invalid PS5 buffer format 113 as "
@@ -99,12 +102,12 @@ static void GetInputFormat(const ShaderBufferResource& res, vk::Format& format,
format = vk::Format::eR32G32B32A32Sfloat; format = vk::Format::eR32G32B32A32Sfloat;
size = 4; size = 4;
if (NarrowInputFormat(format, size, used_components)) { if (NarrowInputFormat(format, size, used_components)) {
LOGF("InputFormat: narrowing fmt=%u to %s for used_components=%u\n", fmt, LOGF("InputFormat: narrowing fmt=%u to %s for used_components=%u\n", raw_format,
VulkanToString(format).c_str(), used_components); VulkanToString(format).c_str(), used_components);
} }
return; return;
} }
if (fmt == kTemporaryPs5BufferFormat121) { if (raw_format == kTemporaryPs5BufferFormat121) {
static bool logged_121 = false; static bool logged_121 = false;
if (!logged_121) { if (!logged_121) {
LOGF("InputFormat: accepting PS5 buffer format 121 as vk::Format::eR16G16Sfloat\n"); LOGF("InputFormat: accepting PS5 buffer format 121 as vk::Format::eR16G16Sfloat\n");
@@ -113,13 +116,13 @@ static void GetInputFormat(const ShaderBufferResource& res, vk::Format& format,
format = vk::Format::eR16G16Sfloat; format = vk::Format::eR16G16Sfloat;
size = 2; size = 2;
if (NarrowInputFormat(format, size, used_components)) { if (NarrowInputFormat(format, size, used_components)) {
LOGF("InputFormat: narrowing fmt=%u to %s for used_components=%u\n", fmt, LOGF("InputFormat: narrowing fmt=%u to %s for used_components=%u\n", raw_format,
VulkanToString(format).c_str(), used_components); VulkanToString(format).c_str(), used_components);
} }
return; return;
} }
switch (static_cast<Prospero::BufferFormat>(fmt)) { switch (fmt) {
case Prospero::BufferFormat::k32_32_32_32Float: case Prospero::BufferFormat::k32_32_32_32Float:
format = vk::Format::eR32G32B32A32Sfloat; format = vk::Format::eR32G32B32A32Sfloat;
size = 4; size = 4;
@@ -329,7 +332,7 @@ static void GetInputFormat(const ShaderBufferResource& res, vk::Format& format,
size = 1; size = 1;
break; break;
default: default:
EXIT("unknown format: fmt = %u\n", fmt); EXIT("unknown format: fmt = %u\n", raw_format);
format = vk::Format::eUndefined; format = vk::Format::eUndefined;
size = 4; size = 4;
break; break;
@@ -93,7 +93,7 @@ bool ResolveComputeImageClear(const ShaderComputeInputInfo& input, uint32_t grou
const auto descriptor = DecodeNativeDescriptor<ShaderBufferResource>(raw); const auto descriptor = DecodeNativeDescriptor<ShaderBufferResource>(raw);
if (!resource.formatted || !resource.written || resource.read || resource.atomic || if (!resource.formatted || !resource.written || resource.read || resource.atomic ||
resource.scalar || resource.max_byte_extent != 16 || descriptor.Stride() != 16 || resource.scalar || resource.max_byte_extent != 16 || descriptor.Stride() != 16 ||
descriptor.Format() != Prospero::GpuEnumValue(Prospero::BufferFormat::k32_32_32_32UInt) || descriptor.Format() != Prospero::BufferFormat::k32_32_32_32UInt ||
descriptor.SwizzleEnabled() || descriptor.IndexStride() != 0 || descriptor.AddTid() || descriptor.SwizzleEnabled() || descriptor.IndexStride() != 0 || descriptor.AddTid() ||
resource.packed_stride != descriptor.PackedStride() || raw.dword_count != 4 || resource.packed_stride != descriptor.PackedStride() || raw.dword_count != 4 ||
program.user_data_base != 0 || resources.user_data.size() != 8) { program.user_data_base != 0 || resources.user_data.size() != 8) {
@@ -246,7 +246,7 @@ void RenderExecutor::DispatchDirect(uint64_t submit_id, RenderCommandBuffer& buf
LOGF(" CS buffer[%u]: source=%u usage=%s addr=0x%012" PRIx64 LOGF(" CS buffer[%u]: source=%u usage=%s addr=0x%012" PRIx64
" stride=%u records=%u format=%u\n", " stride=%u records=%u format=%u\n",
i, buffer.source, buffer.written ? "read-write" : "read-only", r.Base48(), i, buffer.source, buffer.written ? "read-write" : "read-only", r.Base48(),
r.Stride(), r.NumRecords(), r.Format()); r.Stride(), r.NumRecords(), r.RawFormat());
} }
for (uint32_t i = 0; i < program.info.images.size(); i++) { for (uint32_t i = 0; i < program.info.images.size(); i++) {
const auto& image = program.info.images[i]; const auto& image = program.info.images[i];
@@ -258,13 +258,13 @@ void RenderExecutor::DispatchDirect(uint64_t submit_id, RenderCommandBuffer& buf
image.kind == ShaderRecompiler::IR::ResourceKind::ImageUint) image.kind == ShaderRecompiler::IR::ResourceKind::ImageUint)
? "true" ? "true"
: "false", : "false",
r.Base40(), static_cast<uint32_t>(r.Type()), r.Format(), r.Base40(), static_cast<uint32_t>(r.Type()), static_cast<uint32_t>(r.Format()),
static_cast<uint32_t>(r.Width5()) + 1u, static_cast<uint32_t>(r.Height5()) + 1u, static_cast<uint32_t>(r.Width5()) + 1u, static_cast<uint32_t>(r.Height5()) + 1u,
static_cast<uint32_t>(r.Depth()) + 1u, static_cast<uint32_t>(r.Depth()) + 1u,
std::max<uint32_t>(static_cast<uint32_t>(r.LastLevel()), std::max<uint32_t>(static_cast<uint32_t>(r.LastLevel()),
static_cast<uint32_t>(r.MaxMip())) + static_cast<uint32_t>(r.MaxMip())) +
1u, 1u,
r.TileMode()); static_cast<uint32_t>(r.TileMode()));
} }
for (uint32_t i = 0; i < program.info.samplers.size(); i++) { for (uint32_t i = 0; i < program.info.samplers.size(); i++) {
const auto r = DecodeNativeDescriptor<ShaderSamplerResource>(resources.samplers[i]); const auto r = DecodeNativeDescriptor<ShaderSamplerResource>(resources.samplers[i]);
+17 -17
View File
@@ -123,7 +123,7 @@ static void LogFramebufferSkip(const char* draw_name, const RenderColorInfo& col
log_id, draw_name, RenderColorTypeName(color.type), color.base_addr, color.buffer_size, log_id, draw_name, RenderColorTypeName(color.type), color.base_addr, color.buffer_size,
color.image_id ? "yes" : "no", VulkanToString(depth.format).c_str(), color.image_id ? "yes" : "no", VulkanToString(depth.format).c_str(),
depth.image_id ? "yes" : "no", depth.vaddr_num, ctx.GetRenderTargetMask(), depth.image_id ? "yes" : "no", depth.vaddr_num, ctx.GetRenderTargetMask(),
ucfg.GetPrimType(), index_count, flags); static_cast<uint32_t>(ucfg.GetPrimType()), index_count, flags);
} }
static void LogMrtState(const char* draw_name, const RenderCommandBuffer& buffer, static void LogMrtState(const char* draw_name, const RenderCommandBuffer& buffer,
@@ -179,10 +179,12 @@ static void LogMrtState(const char* draw_name, const RenderCommandBuffer& buffer
" fmt=0x%08" PRIx32 " nfmt=0x%08" PRIx32 " order=0x%08" PRIx32 " fmt=0x%08" PRIx32 " nfmt=0x%08" PRIx32 " order=0x%08" PRIx32
" width=%u height=%u tile=%u" " width=%u height=%u tile=%u"
" blend=%s src=%u dst=%u alpha_src=%u alpha_dst=%u\n", " blend=%s src=%u dst=%u alpha_src=%u alpha_dst=%u\n",
log_id, i, rt.base.addr, ctm, csm, ps_input_info.target_output_mode[i], rt.info.format, log_id, i, rt.base.addr, ctm, csm, ps_input_info.target_output_mode[i],
rt.info.channel_type, rt.info.channel_order, rt.attrib2.width + 1, static_cast<uint32_t>(rt.info.format), static_cast<uint32_t>(rt.info.channel_type),
rt.attrib2.height + 1, rt.attrib3.tile_mode, bc.enable ? "true" : "false", static_cast<uint32_t>(rt.info.channel_order), rt.attrib2.width + 1,
bc.color_srcblend, bc.color_destblend, bc.alpha_srcblend, bc.alpha_destblend); rt.attrib2.height + 1, static_cast<uint32_t>(rt.attrib3.tile_mode),
bc.enable ? "true" : "false", bc.color_srcblend, bc.color_destblend, bc.alpha_srcblend,
bc.alpha_destblend);
} }
} }
@@ -225,7 +227,7 @@ static void LogDrawTargetState(const char* draw_name, const RenderColorInfo& col
"scissor=(%d,%d)-(%d,%d)\n", "scissor=(%d,%d)-(%d,%d)\n",
log_id, buffer.GetContext().GetGpu().GetFrameNum(), draw_name, log_id, buffer.GetContext().GetGpu().GetFrameNum(), draw_name,
RenderColorTypeName(color.type), color.base_addr, extent.width, extent.height, RenderColorTypeName(color.type), color.base_addr, extent.width, extent.height,
ucfg.GetPrimType(), index_count, flags, ctx.GetRenderTargetMask(), static_cast<uint32_t>(ucfg.GetPrimType()), index_count, flags, ctx.GetRenderTargetMask(),
color.color_clear_enable ? "true" : "false", color.color_clear_value.float32[0], color.color_clear_enable ? "true" : "false", color.color_clear_value.float32[0],
color.color_clear_value.float32[1], color.color_clear_value.float32[2], color.color_clear_value.float32[1], color.color_clear_value.float32[2],
color.color_clear_value.float32[3], cc.mode, cc.op, bc.enable ? "true" : "false", color.color_clear_value.float32[3], cc.mode, cc.op, bc.enable ? "true" : "false",
@@ -289,8 +291,7 @@ static void LogDrawInputState(const RenderCommandBuffer& buffer, const RenderCol
const auto& rd = vs_input_info.resources_dst[res_index]; const auto& rd = vs_input_info.resources_dst[res_index];
const auto offset = b.attr_offsets[ai]; const auto offset = b.attr_offsets[ai];
if (offset + 4u <= b.stride && if (offset + 4u <= b.stride &&
r.Format() == r.Format() == Prospero::BufferFormat::k8_8_8_8UNorm) {
Prospero::GpuEnumValue(Prospero::BufferFormat::k8_8_8_8UNorm)) {
uint32_t packed = 0; uint32_t packed = 0;
std::memcpy(&packed, rec_bytes + offset, sizeof(packed)); std::memcpy(&packed, rec_bytes + offset, sizeof(packed));
const auto r8 = (packed >> 0u) & 0xffu; const auto r8 = (packed >> 0u) & 0xffu;
@@ -844,7 +845,7 @@ static bool GetDrawTopology(const HW::UserConfig& ucfg, bool auto_draw,
topology = vk::PrimitiveTopology::ePointList; topology = vk::PrimitiveTopology::ePointList;
switch (static_cast<Prospero::PrimitiveType>(ucfg.GetPrimType())) { switch (ucfg.GetPrimType()) {
case Prospero::PrimitiveType::kNone: return false; case Prospero::PrimitiveType::kNone: return false;
case Prospero::PrimitiveType::kPointList: case Prospero::PrimitiveType::kPointList:
topology = vk::PrimitiveTopology::ePointList; topology = vk::PrimitiveTopology::ePointList;
@@ -867,14 +868,14 @@ static bool GetDrawTopology(const HW::UserConfig& ucfg, bool auto_draw,
break; break;
case Prospero::PrimitiveType::kRectListLegacy: case Prospero::PrimitiveType::kRectListLegacy:
if (!auto_draw) { if (!auto_draw) {
EXIT("unknown primitive type: %u\n", ucfg.GetPrimType()); EXIT("unknown primitive type: %u\n", static_cast<uint32_t>(ucfg.GetPrimType()));
} }
topology = vk::PrimitiveTopology::eTriangleStrip; topology = vk::PrimitiveTopology::eTriangleStrip;
break; break;
case Prospero::PrimitiveType::kQuadListLegacy: case Prospero::PrimitiveType::kQuadListLegacy:
topology = vk::PrimitiveTopology::eTriangleFan; topology = vk::PrimitiveTopology::eTriangleFan;
break; break;
default: EXIT("unknown primitive type: %u\n", ucfg.GetPrimType()); default: EXIT("unknown primitive type: %u\n", static_cast<uint32_t>(ucfg.GetPrimType()));
} }
return true; return true;
@@ -1051,7 +1052,7 @@ static void EmitDrawPrimitives(const HW::UserConfig& ucfg, vk::CommandBuffer vk_
const DrawEmitInfo& emit) { const DrawEmitInfo& emit) {
EXIT_IF(draw.name == nullptr); EXIT_IF(draw.name == nullptr);
switch (static_cast<Prospero::PrimitiveType>(ucfg.GetPrimType())) { switch (ucfg.GetPrimType()) {
case Prospero::PrimitiveType::kPointList: case Prospero::PrimitiveType::kPointList:
case Prospero::PrimitiveType::kLineList: case Prospero::PrimitiveType::kLineList:
case Prospero::PrimitiveType::kLineStrip: case Prospero::PrimitiveType::kLineStrip:
@@ -1069,7 +1070,7 @@ static void EmitDrawPrimitives(const HW::UserConfig& ucfg, vk::CommandBuffer vk_
break; break;
case Prospero::PrimitiveType::kRectListLegacy: case Prospero::PrimitiveType::kRectListLegacy:
if (emit.indexed) { if (emit.indexed) {
EXIT("unknown primitive type: %u\n", ucfg.GetPrimType()); EXIT("unknown primitive type: %u\n", static_cast<uint32_t>(ucfg.GetPrimType()));
} }
// Sarah // Sarah
EXIT_NOT_IMPLEMENTED(!(draw.index_count == 3 && vs_input_info.buffers_num == 0)); EXIT_NOT_IMPLEMENTED(!(draw.index_count == 3 && vs_input_info.buffers_num == 0));
@@ -1087,7 +1088,7 @@ static void EmitDrawPrimitives(const HW::UserConfig& ucfg, vk::CommandBuffer vk_
} }
} }
break; break;
default: EXIT("unknown primitive type: %u\n", ucfg.GetPrimType()); default: EXIT("unknown primitive type: %u\n", static_cast<uint32_t>(ucfg.GetPrimType()));
} }
} }
@@ -1387,9 +1388,8 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, RenderCommandBuffer& buffer, u
} }
LogDrawStateIfNeeded(buffer, draw, state, false, LogDrawStateIfNeeded(buffer, draw, state, false,
ucfg.GetPrimType() == ucfg.GetPrimType() == Prospero::PrimitiveType::kRectListLegacy, 0,
Prospero::GpuEnumValue(Prospero::PrimitiveType::kRectListLegacy), nullptr);
0, nullptr);
const auto vertex_offset = ResolveVertexOffset(ucfg.GetIndexOffset(), state.vs_input_info) + const auto vertex_offset = ResolveVertexOffset(ucfg.GetIndexOffset(), state.vs_input_info) +
static_cast<int32_t>(first_vertex); static_cast<int32_t>(first_vertex);
+5 -5
View File
@@ -83,11 +83,11 @@ constexpr FormatMapping kFormatMappings[] = {
}; };
constexpr auto MakeFormatLookup() { constexpr auto MakeFormatLookup() {
constexpr auto kMaxFormat = Prospero::GpuEnumValue(Prospero::BufferFormat::kBc7Srgb); constexpr auto kMaxFormat = static_cast<size_t>(Prospero::BufferFormat::kBc7Srgb);
std::array<vk::Format, kMaxFormat + 1> lookup {}; std::array<vk::Format, kMaxFormat + 1> lookup {};
lookup.fill(vk::Format::eUndefined); lookup.fill(vk::Format::eUndefined);
for (const auto& mapping: kFormatMappings) { for (const auto& mapping: kFormatMappings) {
lookup[Prospero::GpuEnumValue(mapping.guest)] = mapping.host; lookup[static_cast<size_t>(mapping.guest)] = mapping.host;
} }
return lookup; return lookup;
} }
@@ -112,9 +112,9 @@ std::string VulkanToString(vk::QueueFlags value) {
return vk::to_string(value); return vk::to_string(value);
} }
vk::Format VulkanFormat(uint32_t guest_format) { vk::Format VulkanFormat(Prospero::BufferFormat guest_format) {
return guest_format < kFormatLookup.size() ? kFormatLookup[guest_format] const auto index = static_cast<size_t>(guest_format);
: vk::Format::eUndefined; return index < kFormatLookup.size() ? kFormatLookup[index] : vk::Format::eUndefined;
} }
void RequireVulkanSuccess(vk::Result result, const char* operation) { void RequireVulkanSuccess(vk::Result result, const char* operation) {
+3 -1
View File
@@ -10,6 +10,8 @@
#define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_STATIC_VULKAN_FUNCTIONS 0
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
#include "graphics/guest_gpu/gpu_defs.h"
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -29,7 +31,7 @@ std::string VulkanToString(vk::Result value);
std::string VulkanToString(vk::Format value); std::string VulkanToString(vk::Format value);
std::string VulkanToString(vk::ImageLayout value); std::string VulkanToString(vk::ImageLayout value);
std::string VulkanToString(vk::QueueFlags value); std::string VulkanToString(vk::QueueFlags value);
vk::Format VulkanFormat(uint32_t guest_format); vk::Format VulkanFormat(Prospero::BufferFormat guest_format);
void RequireVulkanSuccess(vk::Result result, const char* operation); void RequireVulkanSuccess(vk::Result result, const char* operation);
template <typename T, typename Enumerator> template <typename T, typename Enumerator>
+1 -2
View File
@@ -534,8 +534,7 @@ Graphics::ImageInfo BufferAttributeGroup::ImageInfo(const VideoOutBuffer& buffer
if (!Graphics::DecodeVideoOutPixelFormat(attribute.pixel_format, pixel_format)) { if (!Graphics::DecodeVideoOutPixelFormat(attribute.pixel_format, pixel_format)) {
EXIT("unsupported video-out pixel format: 0x%016" PRIx64 "\n", attribute.pixel_format); EXIT("unsupported video-out pixel format: 0x%016" PRIx64 "\n", attribute.pixel_format);
} }
const auto tile_mode = const auto tile_mode = Graphics::Prospero::TileMode::kRenderTarget;
Graphics::Prospero::GpuEnumValue(Graphics::Prospero::TileMode::kRenderTarget);
const auto pitch = const auto pitch =
Graphics::TileGetTexturePitch(pixel_format.guest_format, attribute.width, tile_mode); Graphics::TileGetTexturePitch(pixel_format.guest_format, attribute.width, tile_mode);
Graphics::TileSizeAlign total {}; Graphics::TileSizeAlign total {};
@@ -893,7 +893,8 @@ uint32_t EmitByteAddress(EmitterState& state, const IR::Instruction& inst, uint3
uint32_t StorageBufferPackedStride(const EmitterState& state, const IR::MemoryInfo& mem, uint32_t StorageBufferPackedStride(const EmitterState& state, const IR::MemoryInfo& mem,
uint32_t use_pc); uint32_t use_pc);
uint32_t StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem, uint32_t use_pc); Prospero::BufferFormat StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem,
uint32_t use_pc);
bool ShouldApplyBufferAddTid(const IR::Instruction& inst); bool ShouldApplyBufferAddTid(const IR::Instruction& inst);
@@ -153,7 +153,7 @@ uint32_t StorageBufferPackedStride(const EmitterState& state, const IR::MemoryIn
return state.program.info.buffers[mem.resource].packed_stride; return state.program.info.buffers[mem.resource].packed_stride;
} }
uint32_t StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem, Prospero::BufferFormat StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem,
uint32_t use_pc) { uint32_t use_pc) {
(void)use_pc; (void)use_pc;
if (mem.resource >= state.program.info.buffers.size()) { if (mem.resource >= state.program.info.buffers.size()) {
@@ -749,8 +749,7 @@ Prospero::BufferFormat FormattedBufferFormat(const EmitterState& state,
const IR::Instruction& inst) { const IR::Instruction& inst) {
return inst.memory.typed return inst.memory.typed
? Format::DecodeTBufferFormat(inst.memory.data_format, inst.memory.number_format) ? Format::DecodeTBufferFormat(inst.memory.data_format, inst.memory.number_format)
: static_cast<Prospero::BufferFormat>( : StorageBufferFormat(state, inst.memory, inst.pc);
StorageBufferFormat(state, inst.memory, inst.pc));
} }
IR::Instruction WithFormatComponentByteOffset(const IR::Instruction& inst, IR::Instruction WithFormatComponentByteOffset(const IR::Instruction& inst,
@@ -64,26 +64,26 @@ VertexInputScalarKind VertexParameterScalarKind(const EmitterState& state, uint3
} }
switch (state.vertex_input_info->resources[location].Format()) { switch (state.vertex_input_info->resources[location].Format()) {
case 5: case Prospero::BufferFormat::k8UInt:
case 11: case Prospero::BufferFormat::k16UInt:
case 18: case Prospero::BufferFormat::k8_8UInt:
case 20: case Prospero::BufferFormat::k32UInt:
case 27: case Prospero::BufferFormat::k16_16UInt:
case 60: case Prospero::BufferFormat::k8_8_8_8UInt:
case 62: case Prospero::BufferFormat::k32_32UInt:
case 69: case Prospero::BufferFormat::k16_16_16_16UInt:
case 72: case Prospero::BufferFormat::k32_32_32UInt:
case 75: return VertexInputScalarKind::Uint; case Prospero::BufferFormat::k32_32_32_32UInt: return VertexInputScalarKind::Uint;
case 6: case Prospero::BufferFormat::k8SInt:
case 12: case Prospero::BufferFormat::k16SInt:
case 19: case Prospero::BufferFormat::k8_8SInt:
case 21: case Prospero::BufferFormat::k32SInt:
case 28: case Prospero::BufferFormat::k16_16SInt:
case 61: case Prospero::BufferFormat::k8_8_8_8SInt:
case 63: case Prospero::BufferFormat::k32_32SInt:
case 70: case Prospero::BufferFormat::k16_16_16_16SInt:
case 73: case Prospero::BufferFormat::k32_32_32SInt:
case 76: return VertexInputScalarKind::Sint; case Prospero::BufferFormat::k32_32_32_32SInt: return VertexInputScalarKind::Sint;
default: return VertexInputScalarKind::Float; default: return VertexInputScalarKind::Float;
} }
} }
@@ -220,9 +220,9 @@ bool ValidateResourceSpecialization(const Program& program, const ResourceSnapsh
} }
return false; return false;
} }
const auto format = (descriptor.dwords[1] >> 20u) & 0x1ffu; const auto format =
const bool raw_sint_storage = static_cast<Prospero::BufferFormat>((descriptor.dwords[1] >> 20u) & 0x1ffu);
storage && format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) && const bool raw_sint_storage = storage && format == Prospero::BufferFormat::k32SInt &&
!image.read && !image.atomic; !image.read && !image.atomic;
const bool uint_descriptor = Prospero::IsUintTextureFormat(format) || raw_sint_storage; const bool uint_descriptor = Prospero::IsUintTextureFormat(format) || raw_sint_storage;
const auto uint_program = image.kind == ResourceKind::ImageUint || const auto uint_program = image.kind == ResourceKind::ImageUint ||
@@ -415,12 +415,12 @@ bool SpecializeResources(Program& program, const ResourceSnapshot& snapshot, std
image.kind == ResourceKind::StorageImageUint) { image.kind == ResourceKind::StorageImageUint) {
image.storage_swizzle = DescriptorImageSwizzle(descriptor); image.storage_swizzle = DescriptorImageSwizzle(descriptor);
} }
const auto format = (descriptor.dwords[1] >> 20u) & 0x1ffu; const auto format =
static_cast<Prospero::BufferFormat>((descriptor.dwords[1] >> 20u) & 0x1ffu);
const bool storage = image.kind == ResourceKind::StorageImage || const bool storage = image.kind == ResourceKind::StorageImage ||
image.kind == ResourceKind::StorageImageUint; image.kind == ResourceKind::StorageImageUint;
const bool raw_sint_storage = const bool raw_sint_storage =
storage && format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) && storage && format == Prospero::BufferFormat::k32SInt && !image.read && !image.atomic;
!image.read && !image.atomic;
const bool uint_image = Prospero::IsUintTextureFormat(format) || raw_sint_storage; const bool uint_image = Prospero::IsUintTextureFormat(format) || raw_sint_storage;
if (uint_image) { if (uint_image) {
switch (image.kind) { switch (image.kind) {
+2 -1
View File
@@ -3,6 +3,7 @@
#include "common/common.h" #include "common/common.h"
#include "common/stringUtils.h" #include "common/stringUtils.h"
#include "graphics/guest_gpu/gpu_defs.h"
#include "graphics/shader/recompiler/cfg/ShaderCFG.h" #include "graphics/shader/recompiler/cfg/ShaderCFG.h"
#include "graphics/shader/recompiler/decompiler/ShaderDecoder.h" #include "graphics/shader/recompiler/decompiler/ShaderDecoder.h"
#include "graphics/shader/shader.h" #include "graphics/shader/shader.h"
@@ -280,7 +281,7 @@ struct BufferResource {
uint32_t first_use_pc = 0; uint32_t first_use_pc = 0;
uint32_t max_byte_extent = 0; uint32_t max_byte_extent = 0;
uint32_t packed_stride = 0; uint32_t packed_stride = 0;
uint32_t descriptor_format = 0; Prospero::BufferFormat descriptor_format = Prospero::BufferFormat::kInvalid;
uint32_t image_alias = NoImageAlias; uint32_t image_alias = NoImageAlias;
bool read = false; bool read = false;
bool written = false; bool written = false;
+16 -12
View File
@@ -535,7 +535,8 @@ static void ShaderDetectBuffers(ShaderVertexInputInfo& info) {
} }
} }
static uint32_t VertexAttribFormatToBufferFormat(uint32_t format) { static Prospero::BufferFormat
VertexAttribFormatToBufferFormat(Prospero::VertexAttribFormat format) {
struct FormatMap { struct FormatMap {
Prospero::VertexAttribFormat vertex; Prospero::VertexAttribFormat vertex;
Prospero::BufferFormat buffer; Prospero::BufferFormat buffer;
@@ -633,12 +634,12 @@ static uint32_t VertexAttribFormatToBufferFormat(uint32_t format) {
}; };
for (const auto& entry: format_map) { for (const auto& entry: format_map) {
if (format == Prospero::GpuEnumValue(entry.vertex)) { if (format == entry.vertex) {
return Prospero::GpuEnumValue(entry.buffer); return entry.buffer;
} }
} }
return format; return static_cast<Prospero::BufferFormat>(static_cast<uint32_t>(format));
} }
static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info, static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
@@ -660,7 +661,8 @@ static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
LOGF("reg = %u, size = %u, va[%u] = 0x%08" PRIx32 "\n", reg, size, i, attrib[in.semantic]); LOGF("reg = %u, size = %u, va[%u] = 0x%08" PRIx32 "\n", reg, size, i, attrib[in.semantic]);
size_t index = attrib[in.semantic] & 0x1fu; size_t index = attrib[in.semantic] & 0x1fu;
uint32_t format = (attrib[in.semantic] >> 5u) & 0x1ffu; auto format =
static_cast<Prospero::VertexAttribFormat>((attrib[in.semantic] >> 5u) & 0x1ffu);
uint32_t offset = (attrib[in.semantic] >> 14u) & 0xfffu; uint32_t offset = (attrib[in.semantic] >> 14u) & 0xfffu;
uint32_t fetch_index = (attrib[in.semantic] >> 26u) & 0x1u; uint32_t fetch_index = (attrib[in.semantic] >> 26u) & 0x1u;
@@ -690,17 +692,19 @@ static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
r.fields[1] = sharp[1]; r.fields[1] = sharp[1];
r.fields[2] = sharp[2]; r.fields[2] = sharp[2];
r.fields[3] = sharp[3]; r.fields[3] = sharp[3];
if (format != 0) { if (format != Prospero::VertexAttribFormat::kInvalid) {
auto buffer_format = VertexAttribFormatToBufferFormat(format); auto buffer_format = VertexAttribFormatToBufferFormat(format);
static std::atomic<uint64_t> log_count = 0; static std::atomic<uint64_t> log_count = 0;
auto log_id = log_count.fetch_add(1); auto log_id = log_count.fetch_add(1);
if (log_id < 64) { if (log_id < 64) {
LOGF("\t temporary: PS5 vertex attrib semantic %u uses attrib format %u -> buffer " LOGF("\t temporary: PS5 vertex attrib semantic %u uses attrib format %u -> buffer "
"format %u, offset %u, buffer index %zu\n", "format %u, offset %u, buffer index %zu\n",
static_cast<uint32_t>(in.semantic), format, buffer_format, offset, index); static_cast<uint32_t>(in.semantic), static_cast<uint32_t>(format),
static_cast<uint32_t>(buffer_format), offset, index);
} }
const auto buffer_format_raw = static_cast<uint32_t>(buffer_format);
r.fields[3] = (r.fields[3] & ~((0x7fu << 12u) | 0xfffu)) | r.fields[3] = (r.fields[3] & ~((0x7fu << 12u) | 0xfffu)) |
((buffer_format & 0x7fu) << 12u) | DstSel(4, 5, 6, 7); ((buffer_format_raw & 0x7fu) << 12u) | DstSel(4, 5, 6, 7);
} }
if (offset != 0) { if (offset != 0) {
r.UpdateAddress48(r.Base48() + offset); r.UpdateAddress48(r.Base48() + offset);
@@ -1011,7 +1015,7 @@ static std::string ShaderDescribeSpecialization(const ShaderRecompiler::IR::Prog
for (uint32_t i = 0; i < program.info.buffers.size(); i++) { for (uint32_t i = 0; i < program.info.buffers.size(); i++) {
const auto& buffer = program.info.buffers[i]; const auto& buffer = program.info.buffers[i];
ret += fmt::format(" b{}[stride={} format={}]", i, buffer.packed_stride, ret += fmt::format(" b{}[stride={} format={}]", i, buffer.packed_stride,
buffer.descriptor_format); static_cast<uint32_t>(buffer.descriptor_format));
} }
for (uint32_t i = 0; i < program.info.images.size(); i++) { for (uint32_t i = 0; i < program.info.images.size(); i++) {
const auto& image = program.info.images[i]; const auto& image = program.info.images[i];
@@ -1047,7 +1051,7 @@ static void ShaderAppendNativeSpecialization(std::vector<uint32_t>&
ids.push_back(static_cast<uint32_t>(program.info.buffers.size())); ids.push_back(static_cast<uint32_t>(program.info.buffers.size()));
for (const auto& buffer: program.info.buffers) { for (const auto& buffer: program.info.buffers) {
ids.push_back(buffer.packed_stride); ids.push_back(buffer.packed_stride);
ids.push_back(buffer.descriptor_format); ids.push_back(static_cast<uint32_t>(buffer.descriptor_format));
} }
ids.push_back(static_cast<uint32_t>(program.info.images.size())); ids.push_back(static_cast<uint32_t>(program.info.images.size()));
for (const auto& image: program.info.images) { for (const auto& image: program.info.images) {
@@ -1250,7 +1254,7 @@ void ShaderDbgDumpInputInfo(const ShaderVertexInputInfo& info) {
r.DstSelX(), r.DstSelY(), r.DstSelZ(), r.DstSelW()); r.DstSelX(), r.DstSelY(), r.DstSelZ(), r.DstSelW());
LOGF("\t\t Format() = %" PRIu8 "\n" LOGF("\t\t Format() = %" PRIu8 "\n"
"\t\t OutOfBounds() = %" PRIu8 "\n", "\t\t OutOfBounds() = %" PRIu8 "\n",
r.Format(), r.OutOfBounds()); r.RawFormat(), r.OutOfBounds());
LOGF("\t\t AddTid() = %s\n", r.AddTid() ? "true" : "false"); LOGF("\t\t AddTid() = %s\n", r.AddTid() ? "true" : "false");
} }
@@ -1596,7 +1600,7 @@ ShaderId ShaderGetIdVS(const HW::VertexShaderInfo& regs, const ShaderVertexInput
ret.ids.push_back(r.DstSelY()); ret.ids.push_back(r.DstSelY());
ret.ids.push_back(r.DstSelZ()); ret.ids.push_back(r.DstSelZ());
ret.ids.push_back(r.DstSelW()); ret.ids.push_back(r.DstSelW());
ret.ids.push_back(r.Format()); ret.ids.push_back(r.RawFormat());
ret.ids.push_back(r.OutOfBounds()); ret.ids.push_back(r.OutOfBounds());
ret.ids.push_back(static_cast<uint32_t>(r.AddTid())); ret.ids.push_back(static_cast<uint32_t>(r.AddTid()));
} }
+1 -1
View File
@@ -29,7 +29,7 @@ ResourceDescriptorType ShaderClassifyResourceDescriptor(const uint32_t* desc) {
default: break; default: break;
} }
return (raw_type & Prospero::GpuEnumValue(Prospero::ImageType::kColor1D)) == 0 return (raw_type & static_cast<uint32_t>(Prospero::ImageType::kColor1D)) == 0
? ResourceDescriptorType::Buffer ? ResourceDescriptorType::Buffer
: ResourceDescriptorType::Unused; : ResourceDescriptorType::Unused;
} }
+14 -4
View File
@@ -3,6 +3,7 @@
#include "common/abi.h" #include "common/abi.h"
#include "common/common.h" #include "common/common.h"
#include "graphics/guest_gpu/gpu_defs.h"
namespace Libs::Graphics { namespace Libs::Graphics {
@@ -61,7 +62,10 @@ struct ShaderBufferResource {
[[nodiscard]] uint64_t Base48() const { [[nodiscard]] uint64_t Base48() const {
return (fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)) & 0xFFFFFFFFFFFFu; return (fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)) & 0xFFFFFFFFFFFFu;
} }
[[nodiscard]] uint8_t Format() const { return (fields[3] >> 12u) & 0x7Fu; } [[nodiscard]] uint8_t RawFormat() const { return (fields[3] >> 12u) & 0x7Fu; }
[[nodiscard]] Prospero::BufferFormat Format() const {
return static_cast<Prospero::BufferFormat>(RawFormat());
}
[[nodiscard]] uint8_t OutOfBounds() const { return (fields[3] >> 28u) & 0x3u; } [[nodiscard]] uint8_t OutOfBounds() const { return (fields[3] >> 28u) & 0x3u; }
[[nodiscard]] uint8_t Type() const { return (fields[3] >> 30u) & 0x3u; } [[nodiscard]] uint8_t Type() const { return (fields[3] >> 30u) & 0x3u; }
}; };
@@ -79,15 +83,21 @@ struct ShaderTextureResource {
[[nodiscard]] uint32_t DstSelXYZW() const { return (fields[3] >> 0u) & 0xFFFu; } [[nodiscard]] uint32_t DstSelXYZW() const { return (fields[3] >> 0u) & 0xFFFu; }
[[nodiscard]] uint8_t BaseLevel() const { return (fields[3] >> 12u) & 0xFu; } [[nodiscard]] uint8_t BaseLevel() const { return (fields[3] >> 12u) & 0xFu; }
[[nodiscard]] uint8_t LastLevel() const { return (fields[3] >> 16u) & 0xFu; } [[nodiscard]] uint8_t LastLevel() const { return (fields[3] >> 16u) & 0xFu; }
[[nodiscard]] uint8_t TileMode() const { return (fields[3] >> 20u) & 0x1Fu; } [[nodiscard]] Prospero::TileMode TileMode() const {
[[nodiscard]] uint8_t Type() const { return (fields[3] >> 28u) & 0xFu; } return static_cast<Prospero::TileMode>((fields[3] >> 20u) & 0x1Fu);
}
[[nodiscard]] Prospero::ImageType Type() const {
return static_cast<Prospero::ImageType>((fields[3] >> 28u) & 0xFu);
}
[[nodiscard]] uint16_t Depth() const { return (fields[4] >> 0u) & 0x1FFFu; } [[nodiscard]] uint16_t Depth() const { return (fields[4] >> 0u) & 0x1FFFu; }
[[nodiscard]] uint64_t Base40() const { [[nodiscard]] uint64_t Base40() const {
return ((fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)) & 0xFFFFFFFFFFu) << 8u; return ((fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)) & 0xFFFFFFFFFFu) << 8u;
} }
[[nodiscard]] bool IsNull() const { return Base40() == 0; } [[nodiscard]] bool IsNull() const { return Base40() == 0; }
[[nodiscard]] uint16_t Format() const { return (fields[1] >> 20u) & 0x1FFu; } [[nodiscard]] Prospero::BufferFormat Format() const {
return static_cast<Prospero::BufferFormat>((fields[1] >> 20u) & 0x1FFu);
}
[[nodiscard]] uint16_t Width5() const { [[nodiscard]] uint16_t Width5() const {
return ((fields[1] >> 30u) & 0x3u) | (((fields[2] >> 0u) & 0xFFFu) << 2u); return ((fields[1] >> 30u) & 0x3u) | (((fields[2] >> 0u) & 0xFFFu) << 2u);
} }
+5 -5
View File
@@ -1076,18 +1076,18 @@ int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchAddRegisters(uint32_t* cmd, uint3
static uint32_t GraphicsPrimitiveTypeToGsOut(uint32_t prim_type) { static uint32_t GraphicsPrimitiveTypeToGsOut(uint32_t prim_type) {
switch (static_cast<Prospero::PrimitiveType>(prim_type)) { switch (static_cast<Prospero::PrimitiveType>(prim_type)) {
case Prospero::PrimitiveType::kPointList: case Prospero::PrimitiveType::kPointList:
return Prospero::GpuEnumValue(Prospero::GsOutputPrimitiveType::kPoints); return static_cast<uint32_t>(Prospero::GsOutputPrimitiveType::kPoints);
case Prospero::PrimitiveType::kLineList: case Prospero::PrimitiveType::kLineList:
case Prospero::PrimitiveType::kLineStrip: case Prospero::PrimitiveType::kLineStrip:
case Prospero::PrimitiveType::kLineListAdjacency: case Prospero::PrimitiveType::kLineListAdjacency:
case Prospero::PrimitiveType::kLineStripAdjacency: case Prospero::PrimitiveType::kLineStripAdjacency:
case Prospero::PrimitiveType::kLineLoop: case Prospero::PrimitiveType::kLineLoop:
return Prospero::GpuEnumValue(Prospero::GsOutputPrimitiveType::kLines); return static_cast<uint32_t>(Prospero::GsOutputPrimitiveType::kLines);
case Prospero::PrimitiveType::kRectList: case Prospero::PrimitiveType::kRectList:
return Prospero::GpuEnumValue(Prospero::GsOutputPrimitiveType::k2dRectangle); return static_cast<uint32_t>(Prospero::GsOutputPrimitiveType::k2dRectangle);
case Prospero::PrimitiveType::kRectListLegacy: case Prospero::PrimitiveType::kRectListLegacy:
return Prospero::GpuEnumValue(Prospero::GsOutputPrimitiveType::kRectList); return static_cast<uint32_t>(Prospero::GsOutputPrimitiveType::kRectList);
default: return Prospero::GpuEnumValue(Prospero::GsOutputPrimitiveType::kTriangles); default: return static_cast<uint32_t>(Prospero::GsOutputPrimitiveType::kTriangles);
} }
} }
+15 -15
View File
@@ -870,8 +870,8 @@ void TestMaterializationSharesReadConstEvaluation() {
for (uint32_t i = 0; i < memory.words.size(); i++) { for (uint32_t i = 0; i < memory.words.size(); i++) {
memory.words[i] = 0x100 + i; memory.words[i] = 0x100 + i;
} }
memory.words[1] |= Prospero::GpuEnumValue(Prospero::BufferFormat::k8UNorm) << 20u; memory.words[1] |= static_cast<uint32_t>(Prospero::BufferFormat::k8UNorm) << 20u;
memory.words[3] |= Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) << 28u; memory.words[3] |= static_cast<uint32_t>(Prospero::ImageType::kColor2D) << 28u;
std::array<uint32_t, 32> user_data {}; std::array<uint32_t, 32> user_data {};
user_data[16] = static_cast<uint32_t>(memory.base); user_data[16] = static_cast<uint32_t>(memory.base);
user_data[17] = static_cast<uint32_t>(memory.base >> 32u); user_data[17] = static_cast<uint32_t>(memory.base >> 32u);
@@ -911,7 +911,7 @@ void TestInvalidImagesMaterializeAsNull() {
std::string error; std::string error;
for (uint32_t type = 0; type < 8; type++) { for (uint32_t type = 0; type < 8; type++) {
auto descriptor = stale; auto descriptor = stale;
descriptor[1] |= Prospero::GpuEnumValue(Prospero::BufferFormat::k8UNorm) << 20u; descriptor[1] |= static_cast<uint32_t>(Prospero::BufferFormat::k8UNorm) << 20u;
descriptor[3] = (descriptor[3] & 0x0fffffffu) | (type << 28u); descriptor[3] = (descriptor[3] & 0x0fffffffu) | (type << 28u);
ResourceSnapshot snapshot; ResourceSnapshot snapshot;
Check(MaterializeResources(sampled, {descriptor}, snapshot, &error) && Check(MaterializeResources(sampled, {descriptor}, snapshot, &error) &&
@@ -951,7 +951,7 @@ void TestInvalidImagesMaterializeAsNull() {
std::array<uint32_t, 8> msaa {}; std::array<uint32_t, 8> msaa {};
msaa[0] = 1; msaa[0] = 1;
msaa[1] = 36u << 20u; msaa[1] = 36u << 20u;
msaa[3] = (Prospero::GpuEnumValue(type) << 28u) | (test.base_level << 12u) | msaa[3] = (static_cast<uint32_t>(type) << 28u) | (test.base_level << 12u) |
(test.fragments << 16u); (test.fragments << 16u);
msaa[5] = test.max_mip << 4u; msaa[5] = test.max_mip << 4u;
ResourceSnapshot msaa_snapshot; ResourceSnapshot msaa_snapshot;
@@ -970,7 +970,7 @@ void TestInvalidImagesMaterializeAsNull() {
std::array<uint32_t, 8> invalid_format {}; std::array<uint32_t, 8> invalid_format {};
invalid_format[0] = 1; invalid_format[0] = 1;
invalid_format[3] = Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) << 28u; invalid_format[3] = static_cast<uint32_t>(Prospero::ImageType::kColor2D) << 28u;
ResourceSnapshot invalid_format_snapshot; ResourceSnapshot invalid_format_snapshot;
Check(MaterializeResources(sampled, {invalid_format}, invalid_format_snapshot, &error) && Check(MaterializeResources(sampled, {invalid_format}, invalid_format_snapshot, &error) &&
std::all_of(invalid_format_snapshot.images[0].dwords.begin(), std::all_of(invalid_format_snapshot.images[0].dwords.begin(),
@@ -979,9 +979,9 @@ void TestInvalidImagesMaterializeAsNull() {
"invalid-format image descriptor was not normalized to null"); "invalid-format image descriptor was not normalized to null");
auto valid = stale; auto valid = stale;
valid[1] |= Prospero::GpuEnumValue(Prospero::BufferFormat::k8UNorm) << 20u; valid[1] |= static_cast<uint32_t>(Prospero::BufferFormat::k8UNorm) << 20u;
valid[3] = valid[3] =
(valid[3] & 0x0fffffffu) | (Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) << 28u); (valid[3] & 0x0fffffffu) | (static_cast<uint32_t>(Prospero::ImageType::kColor2D) << 28u);
ResourceSnapshot valid_snapshot; ResourceSnapshot valid_snapshot;
Check(MaterializeResources(sampled, {valid}, valid_snapshot, &error) && Check(MaterializeResources(sampled, {valid}, valid_snapshot, &error) &&
std::equal(valid.begin(), valid.end(), valid_snapshot.images[0].dwords.begin()), std::equal(valid.begin(), valid.end(), valid_snapshot.images[0].dwords.begin()),
@@ -1099,7 +1099,7 @@ void TestResourceSpecializationIsTypedAndTransactional() {
array_snapshot.images.resize(1); array_snapshot.images.resize(1);
array_snapshot.images[0].dword_count = 8; array_snapshot.images[0].dword_count = 8;
array_snapshot.images[0].dwords[0] = 0x1000; array_snapshot.images[0].dwords[0] = 0x1000;
array_snapshot.images[0].dwords[3] = Prospero::GpuEnumValue(Prospero::ImageType::kColor1DArray) array_snapshot.images[0].dwords[3] = static_cast<uint32_t>(Prospero::ImageType::kColor1DArray)
<< 28u; << 28u;
Check(SpecializeResources(array_view, array_snapshot, &error) && Check(SpecializeResources(array_view, array_snapshot, &error) &&
array_view.info.images[0].dimension == Decoder::ImageDimension::Dim1D && array_view.info.images[0].dimension == Decoder::ImageDimension::Dim1D &&
@@ -1132,7 +1132,7 @@ void TestResourceSpecializationIsTypedAndTransactional() {
Prepare(cross_family_2d_array); Prepare(cross_family_2d_array);
auto array_2d_snapshot = array_snapshot; auto array_2d_snapshot = array_snapshot;
array_2d_snapshot.images[0].dwords[3] = array_2d_snapshot.images[0].dwords[3] =
Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) << 28u; static_cast<uint32_t>(Prospero::ImageType::kColor2DArray) << 28u;
Check(SpecializeResources(cross_family_2d_array, array_2d_snapshot, &error) && Check(SpecializeResources(cross_family_2d_array, array_2d_snapshot, &error) &&
cross_family_2d_array.info.images[0].dimension == Decoder::ImageDimension::Dim2DArray, cross_family_2d_array.info.images[0].dimension == Decoder::ImageDimension::Dim2DArray,
"array MIMG intent did not produce a 2D-array view"); "array MIMG intent did not produce a 2D-array view");
@@ -1144,7 +1144,7 @@ void TestResourceSpecializationIsTypedAndTransactional() {
Decoder::ImageDimension::Dim2DArray)}; Decoder::ImageDimension::Dim2DArray)};
Prepare(cube_view); Prepare(cube_view);
auto cube_snapshot = array_2d_snapshot; auto cube_snapshot = array_2d_snapshot;
cube_snapshot.images[0].dwords[3] = Prospero::GpuEnumValue(Prospero::ImageType::kCube) << 28u; cube_snapshot.images[0].dwords[3] = static_cast<uint32_t>(Prospero::ImageType::kCube) << 28u;
Check(SpecializeResources(cube_view, cube_snapshot, &error) && Check(SpecializeResources(cube_view, cube_snapshot, &error) &&
ValidateResourceSpecialization(cube_view, cube_snapshot, &error) && ValidateResourceSpecialization(cube_view, cube_snapshot, &error) &&
cube_view.info.images[0].cube && cube_view.info.images[0].cube &&
@@ -1152,7 +1152,7 @@ void TestResourceSpecializationIsTypedAndTransactional() {
"cube descriptor identity did not reach the specialized image and IR"); "cube descriptor identity did not reach the specialized image and IR");
auto array_after_cube = cube_snapshot; auto array_after_cube = cube_snapshot;
array_after_cube.images[0].dwords[3] = array_after_cube.images[0].dwords[3] =
Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) << 28u; static_cast<uint32_t>(Prospero::ImageType::kColor2DArray) << 28u;
Check(!ValidateResourceSpecialization(cube_view, array_after_cube, &error), Check(!ValidateResourceSpecialization(cube_view, array_after_cube, &error),
"2D-array descriptor reused a cube-coordinate specialization"); "2D-array descriptor reused a cube-coordinate specialization");
auto null_after_cube = cube_snapshot; auto null_after_cube = cube_snapshot;
@@ -1185,9 +1185,9 @@ void TestResourceSpecializationIsTypedAndTransactional() {
snapshot.images[0].dword_count = 8; snapshot.images[0].dword_count = 8;
snapshot.images[0].dwords[0] = 0x1000; snapshot.images[0].dwords[0] = 0x1000;
snapshot.images[0].dwords[1] = Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt) << 20u; snapshot.images[0].dwords[1] = static_cast<uint32_t>(Prospero::BufferFormat::k32UInt) << 20u;
snapshot.images[0].dwords[3] = snapshot.images[0].dwords[3] =
(Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) << 28u) | 0x3acu; (static_cast<uint32_t>(Prospero::ImageType::kColor2D) << 28u) | 0x3acu;
Check(SpecializeResources(program, snapshot, &error), error.c_str()); Check(SpecializeResources(program, snapshot, &error), error.c_str());
const auto& image = program.info.images[0]; const auto& image = program.info.images[0];
const auto& inst = program.blocks[0].instructions[0]; const auto& inst = program.blocks[0].instructions[0];
@@ -1235,7 +1235,7 @@ void TestRuntimeSpecializationCoversBakedBufferAndAddressFields() {
buffer_snapshot.buffers[0].dword_count = 4; buffer_snapshot.buffers[0].dword_count = 4;
buffer_snapshot.buffers[0].dwords[1] = (16u << 16u) | (1u << 31u); buffer_snapshot.buffers[0].dwords[1] = (16u << 16u) | (1u << 31u);
buffer_snapshot.buffers[0].dwords[3] = buffer_snapshot.buffers[0].dwords[3] =
(Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt) << 12u) | (2u << 21u) | (static_cast<uint32_t>(Prospero::BufferFormat::k32UInt) << 12u) | (2u << 21u) |
(1u << 23u); (1u << 23u);
std::string error; std::string error;
Check(SpecializeResources(buffer_program, buffer_snapshot, &error) && Check(SpecializeResources(buffer_program, buffer_snapshot, &error) &&
@@ -1244,7 +1244,7 @@ void TestRuntimeSpecializationCoversBakedBufferAndAddressFields() {
Check(buffer_program.info.buffers[0].packed_stride == Check(buffer_program.info.buffers[0].packed_stride ==
(16u | (1u << 14u) | (2u << 16u) | (1u << 20u)) && (16u | (1u << 14u) | (2u << 16u) | (1u << 20u)) &&
buffer_program.info.buffers[0].descriptor_format == buffer_program.info.buffers[0].descriptor_format ==
Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt), Prospero::BufferFormat::k32UInt,
"buffer specialization omitted SPIR-V-baked descriptor fields"); "buffer specialization omitted SPIR-V-baked descriptor fields");
auto stale_buffer = buffer_snapshot; auto stale_buffer = buffer_snapshot;
stale_buffer.buffers[0].dwords[1] ^= 4u << 16u; stale_buffer.buffers[0].dwords[1] ^= 4u << 16u;
File diff suppressed because it is too large. Load diff
+38 -38
View File
@@ -463,14 +463,14 @@ void TestNormalizedImageContracts() {
ImageInfo container {}; ImageInfo container {};
container.data = {0x10000, 0x15000}; container.data = {0x10000, 0x15000};
container.pixel_format = vk::Format::eR8G8B8A8Unorm; container.pixel_format = vk::Format::eR8G8B8A8Unorm;
container.guest_format = Prospero::GpuEnumValue(Prospero::BufferFormat::k8_8_8_8UNorm); container.guest_format = Prospero::BufferFormat::k8_8_8_8UNorm;
container.type = Prospero::ImageType::kColor2D; container.type = Prospero::ImageType::kColor2D;
container.extent = {64, 64, 1}; container.extent = {64, 64, 1};
container.resources = {3, 4}; container.resources = {3, 4};
container.pitch = 64; container.pitch = 64;
container.bytes_per_block = 4; container.bytes_per_block = 4;
container.samples = 1; container.samples = 1;
container.tile_mode = Prospero::GpuEnumValue(Prospero::TileMode::kStandard64KB); container.tile_mode = Prospero::TileMode::kStandard64KB;
container.mip_layout[0] = {0, 0x10000, 64, 64}; container.mip_layout[0] = {0, 0x10000, 64, 64};
container.mip_layout[1] = {0x10000, 0x4000, 32, 32}; container.mip_layout[1] = {0x10000, 0x4000, 32, 32};
container.mip_layout[2] = {0x14000, 0x1000, 16, 16}; container.mip_layout[2] = {0x14000, 0x1000, 16, 16};
@@ -495,7 +495,7 @@ void TestNormalizedImageContracts() {
"sample-count mismatch was accepted as a compatible image"); "sample-count mismatch was accepted as a compatible image");
auto compressed = container; auto compressed = container;
compressed.guest_format = Prospero::GpuEnumValue(Prospero::BufferFormat::kBc3UNorm); compressed.guest_format = Prospero::BufferFormat::kBc3UNorm;
compressed.pitch = 128; compressed.pitch = 128;
compressed.extent.height = 64; compressed.extent.height = 64;
Check(compressed.BlockExtent() == vk::Extent2D {32, 16}, Check(compressed.BlockExtent() == vk::Extent2D {32, 16},
@@ -623,9 +623,9 @@ ImageTestUserData(Prospero::ImageType type = Prospero::ImageType::kColor2D) {
std::array<uint32_t, 64> data {}; std::array<uint32_t, 64> data {};
for (uint32_t start = 0; start + 3u < data.size(); start += 4u) { for (uint32_t start = 0; start + 3u < data.size(); start += 4u) {
data[start] = 0x1000u + start * 0x100u; data[start] = 0x1000u + start * 0x100u;
data[start + 1u] = Prospero::GpuEnumValue(Prospero::BufferFormat::k8UNorm) << 20u; data[start + 1u] = static_cast<uint32_t>(Prospero::BufferFormat::k8UNorm) << 20u;
data[start + 2u] = UINT32_MAX; data[start + 2u] = UINT32_MAX;
data[start + 3u] = Prospero::GpuEnumValue(type) << 28u; data[start + 3u] = static_cast<uint32_t>(type) << 28u;
} }
return data; return data;
} }
@@ -633,14 +633,14 @@ ImageTestUserData(Prospero::ImageType type = Prospero::ImageType::kColor2D) {
void SetImageTestType(std::array<uint32_t, 64>* data, uint32_t srsrc, Prospero::ImageType type) { void SetImageTestType(std::array<uint32_t, 64>* data, uint32_t srsrc, Prospero::ImageType type) {
const auto type_dword = srsrc * 4u + 3u; const auto type_dword = srsrc * 4u + 3u;
Check(data != nullptr && type_dword < data->size(), "invalid image test descriptor source"); Check(data != nullptr && type_dword < data->size(), "invalid image test descriptor source");
(*data)[type_dword] = Prospero::GpuEnumValue(type) << 28u; (*data)[type_dword] = static_cast<uint32_t>(type) << 28u;
} }
void SetImageTestFormat(std::array<uint32_t, 64>* data, uint32_t srsrc, void SetImageTestFormat(std::array<uint32_t, 64>* data, uint32_t srsrc,
Prospero::BufferFormat format) { Prospero::BufferFormat format) {
const auto format_dword = srsrc * 4u + 1u; const auto format_dword = srsrc * 4u + 1u;
Check(data != nullptr && format_dword < data->size(), "invalid image test descriptor source"); Check(data != nullptr && format_dword < data->size(), "invalid image test descriptor source");
(*data)[format_dword] = Prospero::GpuEnumValue(format) << 20u; (*data)[format_dword] = static_cast<uint32_t>(format) << 20u;
} }
bool ReadZeroTestMemory(void*, uint64_t, uint32_t* value) { bool ReadZeroTestMemory(void*, uint64_t, uint32_t* value) {
@@ -4518,7 +4518,7 @@ void TestNewShaderRecompilerFormattedStoreUsesRuntimeArrayLengthOnly() {
std::array<uint32_t, 64> user_data {}; std::array<uint32_t, 64> user_data {};
user_data[1] = 4u << 16u; user_data[1] = 4u << 16u;
user_data[2] = 5u; user_data[2] = 5u;
user_data[3] = Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt) << 12u; user_data[3] = static_cast<uint32_t>(Prospero::BufferFormat::k32UInt) << 12u;
ShaderRecompiler::CompileOptions options; ShaderRecompiler::CompileOptions options;
options.stage = ShaderType::Compute; options.stage = ShaderType::Compute;
@@ -6486,9 +6486,9 @@ void TestNewShaderRecompilerExpPixelOutputs() {
void TestRenderTargetReverseExportMapping() { void TestRenderTargetReverseExportMapping() {
const auto format = const auto format =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k16_16_16_16), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k16_16_16_16,
Prospero::GpuEnumValue(Prospero::ChannelType::kFloat), Prospero::ChannelType::kFloat,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kReversed)); Prospero::ChannelOrder::kReversed);
Check(format.format == vk::Format::eR16G16B16A16Sfloat && format.bytes_per_element == 8u, Check(format.format == vk::Format::eR16G16B16A16Sfloat && format.bytes_per_element == 8u,
"reverse RGBA16F render target did not retain its native host format " "reverse RGBA16F render target did not retain its native host format "
"and size"); "and size");
@@ -6501,15 +6501,15 @@ void TestRenderTargetReverseExportMapping() {
"reverse RGBA16F render-target export or write-mask mapping is " "reverse RGBA16F render-target export or write-mask mapping is "
"incorrect"); "incorrect");
const auto legacy_alt = const auto legacy_alt =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k8_8_8_8), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k8_8_8_8,
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm), Prospero::ChannelType::kUNorm,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kAlt)); Prospero::ChannelOrder::kAlt);
Check(legacy_alt.format == vk::Format::eB8G8R8A8Unorm && legacy_alt.export_mapping.IsIdentity(), Check(legacy_alt.format == vk::Format::eB8G8R8A8Unorm && legacy_alt.export_mapping.IsIdentity(),
"legacy BGRA render target acquired a duplicate shader export mapping"); "legacy BGRA render target acquired a duplicate shader export mapping");
const auto gr32 = const auto gr32 =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k32_32), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k32_32,
Prospero::GpuEnumValue(Prospero::ChannelType::kFloat), Prospero::ChannelType::kFloat,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kReversed)); Prospero::ChannelOrder::kReversed);
Check(gr32.format == vk::Format::eR32G32Sfloat && gr32.bytes_per_element == 8u && Check(gr32.format == vk::Format::eR32G32Sfloat && gr32.bytes_per_element == 8u &&
gr32.export_mapping == Prospero::ColorMappingGr, gr32.export_mapping == Prospero::ColorMappingGr,
"reverse GR32F render target did not retain its native host format, " "reverse GR32F render target did not retain its native host format, "
@@ -6550,9 +6550,9 @@ void TestRenderTargetReverseExportMapping() {
}; };
for (const auto& mapping_case: mapping_cases) { for (const auto& mapping_case: mapping_cases) {
for (uint32_t order = 0; order < 4u; order++) { for (uint32_t order = 0; order < 4u; order++) {
const auto info = const auto info = TextureGetRenderTargetFormat(
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(mapping_case.layout), mapping_case.layout, mapping_case.type,
Prospero::GpuEnumValue(mapping_case.type), order); static_cast<Prospero::ChannelOrder>(order));
Check(info.format == mapping_case.format && Check(info.format == mapping_case.format &&
info.bytes_per_element == mapping_case.bytes && info.bytes_per_element == mapping_case.bytes &&
info.export_mapping == mapping_case.mappings[order], info.export_mapping == mapping_case.mappings[order],
@@ -6568,47 +6568,47 @@ void TestRenderTargetReverseExportMapping() {
} }
const auto alt_1010102 = const auto alt_1010102 =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k10_10_10_2), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k10_10_10_2,
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm), Prospero::ChannelType::kUNorm,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kAlt)); Prospero::ChannelOrder::kAlt);
Check(alt_1010102.format == vk::Format::eA2R10G10B10UnormPack32 && Check(alt_1010102.format == vk::Format::eA2R10G10B10UnormPack32 &&
alt_1010102.export_mapping.IsIdentity(), alt_1010102.export_mapping.IsIdentity(),
"native alternate 10:10:10:2 render target acquired a shader mapping"); "native alternate 10:10:10:2 render target acquired a shader mapping");
const auto reversed_4444 = const auto reversed_4444 =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k4_4_4_4), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k4_4_4_4,
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm), Prospero::ChannelType::kUNorm,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kReversed)); Prospero::ChannelOrder::kReversed);
Check(reversed_4444.format == vk::Format::eR4G4B4A4UnormPack16 && Check(reversed_4444.format == vk::Format::eR4G4B4A4UnormPack16 &&
reversed_4444.export_mapping.IsIdentity(), reversed_4444.export_mapping.IsIdentity(),
"reversed 4:4:4:4 render target did not compose storage and channel " "reversed 4:4:4:4 render target did not compose storage and channel "
"order"); "order");
const auto standard_4444 = const auto standard_4444 =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k4_4_4_4), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k4_4_4_4,
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm), Prospero::ChannelType::kUNorm,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kStandard)); Prospero::ChannelOrder::kStandard);
Check(standard_4444.format == vk::Format::eR4G4B4A4UnormPack16 && Check(standard_4444.format == vk::Format::eR4G4B4A4UnormPack16 &&
standard_4444.export_mapping == Prospero::ColorMappingAbgr, standard_4444.export_mapping == Prospero::ColorMappingAbgr,
"standard 4:4:4:4 render target did not compensate host packed-bit " "standard 4:4:4:4 render target did not compensate host packed-bit "
"order"); "order");
const auto standard_5551 = const auto standard_5551 =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k5_5_5_1), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k5_5_5_1,
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm), Prospero::ChannelType::kUNorm,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kStandard)); Prospero::ChannelOrder::kStandard);
Check(standard_5551.format == vk::Format::eA1R5G5B5UnormPack16 && Check(standard_5551.format == vk::Format::eA1R5G5B5UnormPack16 &&
standard_5551.export_mapping == Prospero::ColorMappingBgra, standard_5551.export_mapping == Prospero::ColorMappingBgra,
"5:5:5:1 render target did not preserve its high one-bit component"); "5:5:5:1 render target did not preserve its high one-bit component");
const auto standard_1555 = const auto standard_1555 =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k1_5_5_5), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k1_5_5_5,
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm), Prospero::ChannelType::kUNorm,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kStandard)); Prospero::ChannelOrder::kStandard);
Check(standard_1555.format == vk::Format::eR5G5B5A1UnormPack16 && Check(standard_1555.format == vk::Format::eR5G5B5A1UnormPack16 &&
standard_1555.export_mapping == Prospero::ColorMappingAbgr, standard_1555.export_mapping == Prospero::ColorMappingAbgr,
"1:5:5:5 render target did not preserve its low one-bit component"); "1:5:5:5 render target did not preserve its low one-bit component");
const auto argb = const auto argb =
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k16_16_16_16), TextureGetRenderTargetFormat(Prospero::ChannelLayout::k16_16_16_16,
Prospero::GpuEnumValue(Prospero::ChannelType::kFloat), Prospero::ChannelType::kFloat,
Prospero::GpuEnumValue(Prospero::ChannelOrder::kAltReversed)); Prospero::ChannelOrder::kAltReversed);
Check(argb.export_mapping == Prospero::ColorMappingArgb && Check(argb.export_mapping == Prospero::ColorMappingArgb &&
argb.export_mapping.ApplyMask(0x1u) == 0x2u && argb.export_mapping.ApplyMask(0x1u) == 0x2u &&
argb.export_mapping.ApplyMask(0x2u) == 0x4u && argb.export_mapping.ApplyMask(0x2u) == 0x4u &&