Compare commits

...
Author SHA1 Message Date
CheesyPoofs3460andnmzik e0c055fd74 renderer: decode R32_SFLOAT packed colour clears (#436)
* renderer: decode R32_SFLOAT packed colour clears

DecodePackedColorClear handled R32Uint, R32Sint and the 8/10-bit formats but fell through to the default false case for R32Sfloat. metadata_clear_supported then went false, the clear value was discarded, and the target kept its previous contents. Decode the packed word as float bits, matching DecodePackedDepthClear directly below, and reject non-finite patterns rather than materializing them.

* renderer: preserve all R32_SFLOAT clear bits

---------

Co-authored-by: nmzik <Nmzik@mail.ru>
2026-09-01 03:37:55 +04:00
nmzik d1eee7b3a9 emulate dualsense touchpad + refactor (ps1 emulation) 2026-09-01 02:21:47 +04:00
nmzikandMac 1342c6f1e1 shader: took fixes from PR 427
- apply c8f34f9's ResourceTracking portability fix
- complete V_CMP_LT_U64 and S_FLBIT_I32_B32 support
- add the sceAmprCommandBufferWaitOnAddress NID from f625a47
- add decoder and compute tests for both shader operations

Co-authored-by: Mac <me@itsmemac.com>
2026-08-31 23:49:21 +04:00
GodsWill Devandnmzik 6453bafd1d renderer: ignore inactive stencil registers for depth-only targets (#425)
graphics: ignore inactive Hi-Stencil state

Co-authored-by: nmzik <Nmzik@mail.ru>
2026-08-31 22:39:44 +04:00
nmzik beb8047083 remove truly unknown Kyty era abi 2026-08-31 21:01:24 +04:00
nmzik 1df06e230d guest_gpu: remove stale PS4/GCN era gpu registers 2026-08-31 20:58:35 +04:00
nmzik 39a34fa343 graphics: consolidate validation guest checks 2026-08-31 11:06:51 +04:00
nmzik 96c64d113e shader: trust recompiler stage metadata 2026-08-31 10:30:58 +04:00
nmzik 66ca225c76 shader: require explicit recompiler resource data 2026-08-31 10:26:08 +04:00
nmzik 0de4cfbf80 graphics: add PS5 FMASK texture formats 2026-08-31 10:11:02 +04:00
nmzik 42980fe6df graphics: accept texture-compatible FMASK compression 2026-08-31 10:01:16 +04:00
nmzik 1592cf2b1b shader: accept SDWA byte source for reverse shift 2026-08-31 09:53:26 +04:00
nmzik a9166f8546 shader: canonicalize out-of-range image formats 2026-08-31 08:16:05 +04:00
nmzik b77978fd1e agc: correct Trinity mode ABI 2026-08-31 08:16:00 +04:00
nmzik 4330cb9462 agc: preserve caller state during initialization 2026-08-31 08:15:36 +04:00
43 changed files with 926 additions and 1579 deletions

No files matched your search

@@ -23,9 +23,8 @@ constexpr auto MakeContextDispatchTable() {
g_hw_ctx_func[Pm4::DB_STENCIL_CLEAR] = HwCtxSetStencilClear;
g_hw_ctx_func[Pm4::DB_DEPTH_CLEAR] = HwCtxSetDepthClear;
g_hw_ctx_func[Pm4::PA_SC_SCREEN_SCISSOR_TL] = HwCtxSetScreenScissor;
g_hw_ctx_func[Pm4::DB_Z_INFO] = HwCtxSetDepthRenderTarget;
g_hw_ctx_func[Pm4::DB_STENCIL_INFO] = HwCtxSetStencilInfo;
g_hw_ctx_func[Pm4::DB_HTILE_SURFACE] = HwCtxSetDepthHtileSurface;
g_hw_ctx_func[Pm4::DB_SHADING_RATE_ENCODING] = HwCtxSetDepthShadingRateEncoding;
g_hw_ctx_func[Pm4::PA_SU_HARDWARE_SCREEN_OFFSET] = HwCtxSetHardwareScreenOffset;
g_hw_ctx_func[Pm4::PA_SC_WINDOW_OFFSET] = HwCtxSetWindowOffset;
g_hw_ctx_func[Pm4::PA_SC_WINDOW_SCISSOR_TL] = HwCtxSetWindowScissor;
@@ -75,7 +74,6 @@ constexpr auto MakeContextDispatchTable() {
g_hw_ctx_func[Pm4::PA_SC_BINNER_CNTL_0] = HwCtxSetPaScExtendedControl;
g_hw_ctx_func[Pm4::PA_SC_BINNER_CNTL_1] = HwCtxSetPaScExtendedControl;
g_hw_ctx_func[Pm4::PA_SC_CONSERVATIVE_RASTERIZATION_CNTL] = HwCtxSetPaScExtendedControl;
g_hw_ctx_func[Pm4::PA_SC_NGG_MODE_CNTL] = HwCtxSetPaScExtendedControl;
g_hw_ctx_func[Pm4::DB_ALPHA_TO_MASK] = HwCtxSetAlphaToMask;
g_hw_ctx_func[Pm4::VGT_DRAW_PAYLOAD_CNTL] = HwCtxSetDrawPayloadControl;
g_hw_ctx_func[Pm4::VGT_PRIMITIVEID_RESET] = HwCtxSetPrimitiveIdReset;
@@ -83,7 +81,6 @@ constexpr auto MakeContextDispatchTable() {
g_hw_ctx_func[Pm4::VGT_SHADER_STAGES_EN] = HwCtxSetShaderStages;
for (uint32_t slot = 0; slot < 8; slot++) {
g_hw_ctx_func[Pm4::CB_COLOR0_BASE + slot * 15] = HwCtxSetRenderTarget;
g_hw_ctx_func[Pm4::CB_COLOR0_INFO + slot * 15] = HwCtxSetColorInfo;
g_hw_ctx_func[Pm4::CB_BLEND0_CONTROL + slot * 1] = HwCtxSetBlendControl;
@@ -116,25 +113,21 @@ constexpr auto MakeShaderDispatchTable() {
}
for (uint32_t slot = 0; slot < 4; slot++) {
g_hw_sh_func[Pm4::SPI_SHADER_USER_ACCUM_PS_0 + slot] = HwShSetPsUserAccumSgpr;
g_hw_sh_func[Pm4::SPI_SHADER_USER_ACCUM_PS_0 + slot] = HwShIgnoreUserAccumulator;
}
for (uint32_t slot = 0; slot < 4; slot++) {
g_hw_sh_func[Pm4::SPI_SHADER_USER_ACCUM_ESGS_0 + slot] = HwShSetGsUserAccumSgpr;
g_hw_sh_func[Pm4::SPI_SHADER_USER_ACCUM_ESGS_0 + slot] = HwShIgnoreUserAccumulator;
}
for (uint32_t slot = 0; slot < 4; slot++) {
g_hw_sh_func[Pm4::SPI_SHADER_USER_ACCUM_LSHS_0 + slot] = HwShSetHsUserAccumSgpr;
g_hw_sh_func[Pm4::SPI_SHADER_USER_ACCUM_LSHS_0 + slot] = HwShIgnoreUserAccumulator;
}
for (uint32_t slot = 0; Pm4::COMPUTE_USER_ACCUM_0 + slot < Pm4::COMPUTE_USER_DATA_0; slot++) {
g_hw_sh_func[Pm4::COMPUTE_USER_ACCUM_0 + slot] = HwShSetCsUserAccumSgpr;
for (uint32_t slot = 0; slot < 4; slot++) {
g_hw_sh_func[Pm4::COMPUTE_USER_ACCUM_0 + slot] = HwShIgnoreUserAccumulator;
}
g_hw_sh_func[Pm4::COMPUTE_PGM_LO] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_PGM_HI] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_TBA_LO] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_TBA_HI] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_TMA_LO] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_TMA_HI] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_PGM_RSRC1] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_PGM_RSRC2] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_START_X] = HwShSetCsRegisters;
@@ -144,30 +137,16 @@ constexpr auto MakeShaderDispatchTable() {
g_hw_sh_func[Pm4::COMPUTE_NUM_THREAD_Y] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_NUM_THREAD_Z] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_RESOURCE_LIMITS] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_DESTINATION_EN_SE0] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_DESTINATION_EN_SE1] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_TMPRING_SIZE] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_DESTINATION_EN_SE2] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_DESTINATION_EN_SE3] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_PGM_RSRC3] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_SHADER_CHKSUM] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::COMPUTE_DISPATCH_TUNNEL] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_TBA_LO_PS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_PGM_RSRC3_PS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_PGM_RSRC4_PS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_TMA_LO_PS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_TMA_HI_PS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_REQ_CTRL_PS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_PGM_RSRC3_GS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_PGM_RSRC4_GS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::COMPUTE_PACE_ID] = HwShSetCsRegisters;
g_hw_sh_func[Pm4::SPI_GRAPHICS_SHADER_CONTROL_PS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_GRAPHICS_SHADER_CONTROL_GS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_USER_DATA_ADDR_LO_GS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_USER_DATA_ADDR_HI_GS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_REQ_CTRL_ESGS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_PGM_RSRC3_HS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_PGM_RSRC4_HS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_GRAPHICS_SHADER_CONTROL_HS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_USER_DATA_ADDR_LO_HS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_USER_DATA_ADDR_HI_HS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_REQ_CTRL_LSHS] = HwShIgnoreRegisters;
return g_hw_sh_func;
}
@@ -179,6 +158,7 @@ constexpr auto MakeUconfigDispatchTable() {
g_hw_uc_func[Pm4::VGT_INDEX_TYPE] = HwUcSetIndexType;
g_hw_uc_func[Pm4::VGT_OBJECT_ID] = HwUcSetObjectId;
g_hw_uc_func[Pm4::TEXTURE_GRADIENT_FACTORS] = HwUcSetTextureGradientFactors;
g_hw_uc_func[Pm4::TEXTURE_GRADIENT_CONTROL] = HwUcSetTextureGradientFactors;
g_hw_uc_func[Pm4::IA_MULTI_VGT_PARAM] = HwUcSetIaMultiVgtParam;
g_hw_uc_func[Pm4::GE_MULTI_PRIM_IB_RESET_EN] = HwUcSetMultiPrimIbReset;
g_hw_uc_func[Pm4::TA_CS_BC_BASE_ADDR] = HwUcSetBorderColorTableAddr;
@@ -44,11 +44,9 @@ uint32_t HwCtxSetBorderColorTableAddr(CommandProcessor&, uint32_t, uint32_t, con
uint32_t HwCtxSetStencilClear(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetDepthClear(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetScreenScissor(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetDepthRenderTarget(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
uint32_t);
uint32_t HwCtxSetStencilInfo(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetDepthHtileSurface(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
uint32_t);
uint32_t HwCtxSetDepthShadingRateEncoding(CommandProcessor&, uint32_t, uint32_t,
const uint32_t*, uint32_t);
uint32_t HwCtxSetHardwareScreenOffset(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
uint32_t);
uint32_t HwCtxSetWindowOffset(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
@@ -89,7 +87,6 @@ uint32_t HwCtxSetDrawPayloadControl(CommandProcessor&, uint32_t, uint32_t, const
uint32_t HwCtxSetPrimitiveIdReset(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetObjprimIdControl(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetShaderStages(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetRenderTarget(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetColorInfo(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetBlendControl(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwCtxSetViewportScissor(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
@@ -100,10 +97,8 @@ uint32_t HwShSetPsUserSgpr(CommandProcessor&, uint32_t, uint32_t, const uint32_t
uint32_t HwShSetGsUserSgpr(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwShSetHsUserSgpr(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwShSetCsUserSgpr(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwShSetPsUserAccumSgpr(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwShSetGsUserAccumSgpr(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwShSetHsUserAccumSgpr(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwShSetCsUserAccumSgpr(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwShIgnoreUserAccumulator(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
uint32_t);
uint32_t HwShSetCsRegisters(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwShIgnoreRegisters(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
uint32_t HwUcSetPrimitiveType(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
File diff suppressed because it is too large. Load diff
+12
View File
@@ -407,7 +407,19 @@ enum class BufferFormat : uint32_t {
k5_5_5_1UNorm = 134,
k1_5_5_5UNorm = 135,
k4_4_4_4UNorm = 136,
kFmask8_S2_F1 = 156,
kFmask8_S4_F1 = 157,
kFmask8_S8_F1 = 158,
kFmask8_S2_F2 = 159,
kFmask8_S4_F2 = 160,
kFmask8_S4_F4 = 161,
kFmask16_S16_F1 = 162,
kFmask16_S8_F2 = 163,
kFmask32_S16_F2 = 164,
kFmask32_S8_F4 = 165,
kFmask32_S8_F8 = 166,
kFmask64_S16_F4 = 167,
kFmask64_S16_F8 = 168,
kBc1UNorm = 169,
kBc1Srgb = 170,
kBc2UNorm = 171,
+13 -1
View File
@@ -68,7 +68,19 @@ constexpr FormatInfo kFormatInfo[] = {
{BufferFormat::k5_5_5_1UNorm, 2, 0, 2, true, false},
{BufferFormat::k1_5_5_5UNorm, 0, 0, 2, false, false},
{BufferFormat::k4_4_4_4UNorm, 2, 0, 2, true, false},
{BufferFormat::kFmask8_S2_F1, 1, 0, 1, true, false},
{BufferFormat::kFmask8_S4_F1, 1, 0, 1, true, false},
{BufferFormat::kFmask8_S8_F1, 1, 0, 1, true, false},
{BufferFormat::kFmask8_S2_F2, 1, 0, 1, true, false},
{BufferFormat::kFmask8_S4_F2, 1, 0, 1, true, false},
{BufferFormat::kFmask8_S4_F4, 1, 0, 1, true, false},
{BufferFormat::kFmask16_S16_F1, 2, 0, 2, true, false},
{BufferFormat::kFmask16_S8_F2, 2, 0, 2, true, false},
{BufferFormat::kFmask32_S16_F2, 4, 0, 4, true, false},
{BufferFormat::kFmask32_S8_F4, 4, 0, 4, true, false},
{BufferFormat::kFmask32_S8_F8, 4, 0, 4, true, false},
{BufferFormat::kFmask64_S16_F4, 8, 0, 8, true, false},
{BufferFormat::kFmask64_S16_F8, 8, 0, 8, true, false},
{BufferFormat::kBc1UNorm, 0, 8, 0, true, false},
{BufferFormat::kBc1Srgb, 0, 8, 0, true, false},
{BufferFormat::kBc2UNorm, 0, 16, 0, true, false},
@@ -203,7 +215,7 @@ uint32_t RenderTargetBytesPerElement(BufferFormat format) {
}
bool IsFmaskTextureFormat(BufferFormat format) {
return format == BufferFormat::kFmask8_S4_F4;
return format >= BufferFormat::kFmask8_S2_F1 && format <= BufferFormat::kFmask64_S16_F8;
}
bool IsSampledTextureFormat(BufferFormat format) {
+40 -145
View File
@@ -11,15 +11,6 @@ struct ColorBase {
uint64_t addr = 0;
};
struct ColorPitch {
uint32_t pitch_div8_minus1 = 0;
uint32_t fmask_pitch_div8_minus1 = 0;
};
struct ColorSlice {
uint32_t slice_div64_minus1 = 0;
};
struct ColorView {
uint32_t base_array_slice_index = 0;
uint32_t last_array_slice_index = 0;
@@ -36,20 +27,15 @@ struct ColorInfo {
bool blend_clamp = false;
bool blend_bypass = false;
bool round_mode = false;
uint32_t cmask_is_linear = 0;
uint32_t cmask_addr_type = 0;
bool alt_tile_mode = false;
Prospero::ChannelLayout format = Prospero::ChannelLayout::kInvalid;
Prospero::ChannelType channel_type = Prospero::ChannelType::kUNorm;
Prospero::ChannelOrder channel_order = Prospero::ChannelOrder::kStandard;
};
struct ColorAttrib {
bool force_dest_alpha_to_one = false;
Prospero::TileMode tile_mode = Prospero::TileMode::kLinear;
Prospero::TileMode fmask_tile_mode = Prospero::TileMode::kLinear;
uint32_t num_samples = 0;
uint32_t num_fragments = 0;
bool force_dest_alpha_to_one = false;
uint32_t num_samples = 0;
uint32_t num_fragments = 0;
};
struct ColorAttrib2 {
@@ -59,41 +45,33 @@ struct ColorAttrib2 {
};
struct ColorAttrib3 {
uint32_t depth = 0;
Prospero::TileMode tile_mode = Prospero::TileMode::kLinear;
uint32_t dimension = 0;
bool cmask_pipe_aligned = false;
bool dcc_pipe_aligned = false;
uint32_t depth = 0;
Prospero::TileMode tile_mode = Prospero::TileMode::kRenderTarget;
uint32_t dimension = 0;
bool metadata_pipe_aligned = false;
bool write_vrs_rate_hint_to_cmask = false;
};
struct ColorDccControl {
uint32_t max_uncompressed_block_size = 0;
uint32_t max_compressed_block_size = 0;
uint32_t min_compressed_block_size = 0;
uint32_t color_transform = 0;
bool dcc_clear_key_enable = false;
bool overwrite_combiner_disable = false;
bool independent_64b_blocks = false;
bool independent_128b_blocks = false;
bool data_write_on_dcc_clear_to_reg = false;
enum class IndependentBlockSize : uint8_t { Disabled, Bytes64, Bytes128 };
uint32_t max_uncompressed_block_size = 2;
uint32_t max_compressed_block_size = 2;
uint32_t color_transform = 0;
bool dcc_clear_key_enable = false;
bool overwrite_combiner_disable = false;
IndependentBlockSize independent_block_size = IndependentBlockSize::Disabled;
bool data_write_on_dcc_clear_to_reg = false;
};
struct ColorCmask {
uint64_t addr = 0;
};
struct ColorCmaskSlice {
uint32_t slice_minus1 = 0;
};
struct ColorFmask {
uint64_t addr = 0;
};
struct ColorFmaskSlice {
uint32_t slice_minus1 = 0;
};
struct ColorClearWord0 {
uint32_t word0 = 0;
};
@@ -106,15 +84,8 @@ struct ColorDccAddr {
uint64_t addr = 0;
};
struct ColorSize {
uint32_t width = 0;
uint32_t height = 0;
};
struct RenderTarget {
ColorBase base;
ColorPitch pitch;
ColorSlice slice;
ColorView view;
ColorInfo info;
ColorAttrib attrib;
@@ -122,13 +93,10 @@ struct RenderTarget {
ColorAttrib3 attrib3;
ColorDccControl dcc;
ColorCmask cmask;
ColorCmaskSlice cmask_slice;
ColorFmask fmask;
ColorFmaskSlice fmask_slice;
ColorClearWord0 clear_word0;
ColorClearWord1 clear_word1;
ColorDccAddr dcc_addr;
ColorSize size;
};
struct DepthZInfo {
@@ -136,7 +104,7 @@ struct DepthZInfo {
uint32_t num_samples = 0;
Prospero::TextureCompatiblePlaneCompression texture_compatibility =
Prospero::TextureCompatiblePlaneCompression::kDisable;
Prospero::ZCompareBase z_compare_base = Prospero::ZCompareBase::kZMin;
Prospero::ZCompareBase z_compare_base = Prospero::ZCompareBase::kZMax;
bool htile_acceleration = false;
bool expclear_enabled = false;
bool partially_resident = false;
@@ -171,7 +139,7 @@ struct DepthStencilInfo {
Prospero::TextureCompatibleStencil texture_compatibility =
Prospero::TextureCompatibleStencil::kDisable;
bool expclear_enabled = false;
bool htile_stencil_disabled = false;
bool htile_stencil_disabled = true;
bool partially_resident = false;
[[nodiscard]] static DepthStencilInfo Decode(uint32_t value) {
@@ -194,16 +162,6 @@ struct DepthStencilInfo {
}
};
struct DepthRenderTargetDepthInfo {
uint32_t addr5_swizzle_mask = 0;
uint32_t array_mode = 0;
uint32_t pipe_config = 0;
uint32_t bank_width = 0;
uint32_t bank_height = 0;
uint32_t macro_tile_aspect = 0;
uint32_t num_banks = 0;
};
struct DepthDepthView {
uint32_t slice_start = 0;
uint32_t slice_max = 0;
@@ -218,36 +176,18 @@ struct DepthDepthSizeXY {
bool valid = false;
};
struct DepthRenderTargetHTileSurface {
uint32_t linear = 0;
uint32_t full_cache = 0;
uint32_t htile_uses_preload_win = 0;
uint32_t preload = 0;
uint32_t prefetch_width = 0;
uint32_t prefetch_height = 0;
uint32_t dst_outside_zero_to_one = 0;
};
struct DepthRenderTarget {
DepthZInfo z_info;
DepthStencilInfo stencil_info;
DepthDepthView depth_view;
DepthDepthSizeXY size;
DepthRenderTargetDepthInfo depth_info;
DepthRenderTargetHTileSurface htile_surface;
DepthZInfo z_info;
DepthStencilInfo stencil_info;
DepthDepthView depth_view;
DepthDepthSizeXY size;
uint64_t z_read_base_addr = 0;
uint64_t stencil_read_base_addr = 0;
uint64_t z_write_base_addr = 0;
uint64_t stencil_write_base_addr = 0;
uint32_t pitch_div8_minus1 = 0;
uint32_t height_div8_minus1 = 0;
bool pitch_height_valid = false;
uint32_t slice_div64_minus1 = 0;
uint64_t htile_data_base_addr = 0;
uint32_t width = 0;
uint32_t height = 0;
bool width_height_valid = false;
uint8_t shading_rate_encoding = 0;
};
struct RenderControl {
@@ -256,6 +196,8 @@ struct RenderControl {
bool resummarize_enable = false;
bool stencil_compress_disable = false;
bool depth_compress_disable = false;
bool copy_depth_to_color = false;
bool copy_stencil_to_color = false;
bool copy_centroid = false;
uint8_t copy_sample = 0;
};
@@ -299,16 +241,14 @@ struct ClipControl {
};
struct DepthControl {
bool stencil_enable = false;
bool z_enable = false;
bool z_write_enable = false;
bool depth_bounds_enable = false;
uint8_t zfunc = 0;
bool backface_enable = false;
uint8_t stencilfunc = 0;
uint8_t stencilfunc_bf = 0;
bool color_writes_on_depth_fail_enable = false;
bool color_writes_on_depth_pass_disable = false;
bool stencil_enable = false;
bool z_enable = false;
bool z_write_enable = false;
bool depth_bounds_enable = false;
uint8_t zfunc = 0;
bool backface_enable = false;
uint8_t stencilfunc = 0;
uint8_t stencilfunc_bf = 0;
};
struct StencilControl {
@@ -468,27 +408,6 @@ struct ScreenViewport {
bool clip_rect_window_offset_enable[4] = {};
};
struct VsShaderResource1 {
uint8_t vgprs = 0;
uint8_t sgprs = 0;
uint8_t priority = 0;
uint8_t float_mode = 0;
bool dx10_clamp = false;
bool ieee_mode = false;
uint8_t vgpr_component_count = 0;
bool cu_group_enable = false;
bool require_forward_progress = false;
bool fp16_overflow = false;
};
struct VsShaderResource2 {
bool scratch_en = false;
uint8_t user_sgpr = 0;
bool offchip_lds = false;
bool streamout_enabled = false;
uint8_t shared_vgprs = 0;
};
struct HsShaderResource1 {
uint8_t vgprs = 0;
uint8_t priority = 0;
@@ -511,7 +430,6 @@ struct HsShaderResource2 {
struct PsShaderResource1 {
uint8_t vgprs = 0;
uint8_t sgprs = 0;
uint8_t priority = 0;
uint8_t float_mode = 0;
bool dx10_clamp = false;
@@ -535,7 +453,6 @@ struct PsStageRegisters {
uint64_t data_addr = 0;
PsShaderResource1 rsrc1;
PsShaderResource2 rsrc2;
uint64_t chksum = 0;
};
struct CsStageRegisters {
@@ -545,12 +462,13 @@ struct CsStageRegisters {
uint32_t num_thread_y = 0;
uint32_t num_thread_z = 0;
uint8_t vgprs = 0;
uint8_t sgprs = 0;
uint8_t priority = 0;
uint8_t float_mode = 0;
bool dx10_clamp = false;
bool debug_mode = false;
bool ieee_mode = false;
bool require_forward_progress = false;
bool fp16_overflow = false;
bool bulky = false;
bool threadgroup_configuration = false;
uint8_t wave_size = 64;
bool scratch_en = false;
@@ -561,6 +479,7 @@ struct CsStageRegisters {
bool tg_size_en = false;
uint8_t tidig_comp_cnt = 0;
uint16_t lds_size = 0;
uint8_t shared_vgprs = 0;
};
struct EsStageRegisters {
@@ -568,21 +487,17 @@ struct EsStageRegisters {
};
struct LsStageRegisters {
uint64_t data_addr = 0;
VsShaderResource1 rsrc1;
VsShaderResource2 rsrc2;
uint64_t data_addr = 0;
};
struct HsStageRegisters {
uint64_t data_addr = 0;
HsShaderResource1 rsrc1;
HsShaderResource2 rsrc2;
uint64_t chksum = 0;
};
struct GsShaderResource1 {
uint8_t vgprs = 0;
uint8_t sgprs = 0;
uint8_t priority = 0;
uint8_t float_mode = 0;
bool dx10_clamp = false;
@@ -608,7 +523,6 @@ struct GsStageRegisters {
uint64_t data_addr = 0;
GsShaderResource1 rsrc1;
GsShaderResource2 rsrc2;
uint64_t chksum = 0;
};
struct ShaderRegisters {
@@ -664,8 +578,7 @@ struct ShaderRegisters {
enum class UserSgprType { Unknown, Region, Vsharp };
struct UserSgprInfo {
// Changed from 16 to 64
static constexpr int SGPRS_MAX = 64;
static constexpr int SGPRS_MAX = 32;
uint32_t value[SGPRS_MAX] = {0};
UserSgprType type[SGPRS_MAX] = {};
@@ -712,12 +625,6 @@ public:
void Reset() { *this = Context(); }
void SetColorBase(uint32_t slot, const ColorBase& base) { m_render_targets[slot].base = base; }
void SetColorPitch(uint32_t slot, const ColorPitch& pitch) {
m_render_targets[slot].pitch = pitch;
}
void SetColorSlice(uint32_t slot, const ColorSlice& slice) {
m_render_targets[slot].slice = slice;
}
void SetColorView(uint32_t slot, const ColorView& view) { m_render_targets[slot].view = view; }
void SetColorInfo(uint32_t slot, const ColorInfo& info) { m_render_targets[slot].info = info; }
void SetColorAttrib(uint32_t slot, const ColorAttrib& attrib) {
@@ -735,15 +642,9 @@ public:
void SetColorCmask(uint32_t slot, const ColorCmask& cmask) {
m_render_targets[slot].cmask = cmask;
}
void SetColorCmaskSlice(uint32_t slot, const ColorCmaskSlice& cmask_slice) {
m_render_targets[slot].cmask_slice = cmask_slice;
}
void SetColorFmask(uint32_t slot, const ColorFmask& fmask) {
m_render_targets[slot].fmask = fmask;
}
void SetColorFmaskSlice(uint32_t slot, const ColorFmaskSlice& fmask_slice) {
m_render_targets[slot].fmask_slice = fmask_slice;
}
void SetColorClearWord0(uint32_t slot, const ColorClearWord0& clear_word0) {
m_render_targets[slot].clear_word0 = clear_word0;
}
@@ -753,7 +654,6 @@ public:
void SetColorDccAddr(uint32_t slot, const ColorDccAddr& dcc_addr) {
m_render_targets[slot].dcc_addr = dcc_addr;
}
void SetColorSize(uint32_t slot, const ColorSize& size) { m_render_targets[slot].size = size; }
[[nodiscard]] const RenderTarget& GetRenderTarget(uint32_t slot) const {
return m_render_targets[slot];
}
@@ -1072,21 +972,16 @@ public:
void SetEsShaderBase(uint64_t addr) { m_vs.es_regs.data_addr = addr; }
void SetLsShaderBase(uint64_t addr) { m_vs.ls_regs.data_addr = addr; }
void SetLsShaderResource1(const VsShaderResource1& rsrc1) { m_vs.ls_regs.rsrc1 = rsrc1; }
void SetLsShaderResource2(const VsShaderResource2& rsrc2) { m_vs.ls_regs.rsrc2 = rsrc2; }
void SetHsShaderBase(uint64_t addr) { m_vs.hs_regs.data_addr = addr; }
void SetHsShaderResource1(const HsShaderResource1& rsrc1) { m_vs.hs_regs.rsrc1 = rsrc1; }
void SetHsShaderResource2(const HsShaderResource2& rsrc2) { m_vs.hs_regs.rsrc2 = rsrc2; }
void SetHsShaderChksum(uint32_t value) { m_vs.hs_regs.chksum = value; }
void SetGsShaderBase(uint64_t addr) { m_vs.gs_regs.data_addr = addr; }
void SetGsShaderResource1(const GsShaderResource1& rsrc1) { m_vs.gs_regs.rsrc1 = rsrc1; }
void SetGsShaderResource2(const GsShaderResource2& rsrc2) { m_vs.gs_regs.rsrc2 = rsrc2; }
void SetGsShaderChksum(uint32_t value) { m_vs.gs_regs.chksum = value; }
void SetPsShaderBase(uint64_t addr) { m_ps.ps_regs.data_addr = addr; }
void SetPsShaderResource1(const PsShaderResource1& rsrc1) { m_ps.ps_regs.rsrc1 = rsrc1; }
void SetPsShaderResource2(const PsShaderResource2& rsrc2) { m_ps.ps_regs.rsrc2 = rsrc2; }
void SetPsShaderChksum(uint32_t value) { m_ps.ps_regs.chksum = value; }
void SetCsShader(const CsStageRegisters& cs_regs) { m_cs.cs_regs = cs_regs; }
void SetCsWaveSize(uint8_t wave_size) { m_cs.cs_regs.wave_size = wave_size; }
+35 -125
View File
@@ -98,6 +98,10 @@ constexpr uint32_t DB_RENDER_CONTROL_DEPTH_CLEAR_ENABLE_SHIFT = 0;
constexpr uint32_t DB_RENDER_CONTROL_DEPTH_CLEAR_ENABLE_MASK = 0x1;
constexpr uint32_t DB_RENDER_CONTROL_STENCIL_CLEAR_ENABLE_SHIFT = 1;
constexpr uint32_t DB_RENDER_CONTROL_STENCIL_CLEAR_ENABLE_MASK = 0x1;
constexpr uint32_t DB_RENDER_CONTROL_COPY_DEPTH_TO_COLOR_SHIFT = 2;
constexpr uint32_t DB_RENDER_CONTROL_COPY_DEPTH_TO_COLOR_MASK = 0x1;
constexpr uint32_t DB_RENDER_CONTROL_COPY_STENCIL_TO_COLOR_SHIFT = 3;
constexpr uint32_t DB_RENDER_CONTROL_COPY_STENCIL_TO_COLOR_MASK = 0x1;
constexpr uint32_t DB_RENDER_CONTROL_RESUMMARIZE_ENABLE_SHIFT = 4;
constexpr uint32_t DB_RENDER_CONTROL_RESUMMARIZE_ENABLE_MASK = 0x1;
constexpr uint32_t DB_RENDER_CONTROL_STENCIL_COMPRESS_DISABLE_SHIFT = 5;
@@ -163,22 +167,6 @@ constexpr uint32_t PA_SC_SCREEN_SCISSOR_BR_BR_Y_MASK = 0xFFFF;
constexpr uint32_t DB_DFSM_CONTROL = 0xE;
constexpr uint32_t DB_DEPTH_INFO = 0xF;
constexpr uint32_t DB_DEPTH_INFO_ADDR5_SWIZZLE_MASK_SHIFT = 0;
constexpr uint32_t DB_DEPTH_INFO_ADDR5_SWIZZLE_MASK_MASK = 0xF;
constexpr uint32_t DB_DEPTH_INFO_ARRAY_MODE_SHIFT = 4;
constexpr uint32_t DB_DEPTH_INFO_ARRAY_MODE_MASK = 0xF;
constexpr uint32_t DB_DEPTH_INFO_PIPE_CONFIG_SHIFT = 8;
constexpr uint32_t DB_DEPTH_INFO_PIPE_CONFIG_MASK = 0x1F;
constexpr uint32_t DB_DEPTH_INFO_BANK_WIDTH_SHIFT = 13;
constexpr uint32_t DB_DEPTH_INFO_BANK_WIDTH_MASK = 0x3;
constexpr uint32_t DB_DEPTH_INFO_BANK_HEIGHT_SHIFT = 15;
constexpr uint32_t DB_DEPTH_INFO_BANK_HEIGHT_MASK = 0x3;
constexpr uint32_t DB_DEPTH_INFO_MACRO_TILE_ASPECT_SHIFT = 17;
constexpr uint32_t DB_DEPTH_INFO_MACRO_TILE_ASPECT_MASK = 0x3;
constexpr uint32_t DB_DEPTH_INFO_NUM_BANKS_SHIFT = 19;
constexpr uint32_t DB_DEPTH_INFO_NUM_BANKS_MASK = 0x3;
constexpr uint32_t DB_Z_INFO = 0x10;
constexpr uint32_t DB_Z_INFO_FORMAT_SHIFT = 0;
constexpr uint32_t DB_Z_INFO_FORMAT_MASK = 0x3;
@@ -222,16 +210,6 @@ constexpr uint32_t DB_STENCIL_READ_BASE = 0x13;
constexpr uint32_t DB_Z_WRITE_BASE = 0x14;
constexpr uint32_t DB_STENCIL_WRITE_BASE = 0x15;
constexpr uint32_t DB_DEPTH_SIZE = 0x16;
constexpr uint32_t DB_DEPTH_SIZE_PITCH_TILE_MAX_SHIFT = 0;
constexpr uint32_t DB_DEPTH_SIZE_PITCH_TILE_MAX_MASK = 0x7FF;
constexpr uint32_t DB_DEPTH_SIZE_HEIGHT_TILE_MAX_SHIFT = 11;
constexpr uint32_t DB_DEPTH_SIZE_HEIGHT_TILE_MAX_MASK = 0x7FF;
constexpr uint32_t DB_DEPTH_SLICE = 0x17;
constexpr uint32_t DB_DEPTH_SLICE_SLICE_TILE_MAX_SHIFT = 0;
constexpr uint32_t DB_DEPTH_SLICE_SLICE_TILE_MAX_MASK = 0x3FFFFF;
constexpr uint32_t DB_Z_READ_BASE_HI = 0x1A;
constexpr uint32_t DB_STENCIL_READ_BASE_HI = 0x1B;
constexpr uint32_t DB_Z_WRITE_BASE_HI = 0x1C;
@@ -424,11 +402,6 @@ constexpr uint32_t DB_DEPTH_CONTROL_STENCILFUNC_SHIFT = 8
constexpr uint32_t DB_DEPTH_CONTROL_STENCILFUNC_MASK = 0x7;
constexpr uint32_t DB_DEPTH_CONTROL_STENCILFUNC_BF_SHIFT = 20;
constexpr uint32_t DB_DEPTH_CONTROL_STENCILFUNC_BF_MASK = 0x7;
constexpr uint32_t DB_DEPTH_CONTROL_ENABLE_COLOR_WRITES_ON_DEPTH_FAIL_SHIFT = 30;
constexpr uint32_t DB_DEPTH_CONTROL_ENABLE_COLOR_WRITES_ON_DEPTH_FAIL_MASK = 0x1;
constexpr uint32_t DB_DEPTH_CONTROL_DISABLE_COLOR_WRITES_ON_DEPTH_PASS_SHIFT = 31;
constexpr uint32_t DB_DEPTH_CONTROL_DISABLE_COLOR_WRITES_ON_DEPTH_PASS_MASK = 0x1;
constexpr uint32_t DB_EQAA = 0x201;
constexpr uint32_t DB_EQAA_MAX_ANCHOR_SAMPLES_SHIFT = 0;
constexpr uint32_t DB_EQAA_MAX_ANCHOR_SAMPLES_MASK = 0x7;
@@ -560,21 +533,9 @@ constexpr uint32_t VGT_DRAW_PAYLOAD_CNTL = 0x2A6;
constexpr uint32_t VGT_ESGS_RING_ITEMSIZE = 0x2AB;
constexpr uint32_t VGT_REUSE_OFF = 0x2AD;
constexpr uint32_t DB_HTILE_SURFACE = 0x2AF;
constexpr uint32_t DB_HTILE_SURFACE_LINEAR_SHIFT = 0;
constexpr uint32_t DB_HTILE_SURFACE_LINEAR_MASK = 0x1;
constexpr uint32_t DB_HTILE_SURFACE_FULL_CACHE_SHIFT = 1;
constexpr uint32_t DB_HTILE_SURFACE_FULL_CACHE_MASK = 0x1;
constexpr uint32_t DB_HTILE_SURFACE_HTILE_USES_PRELOAD_WIN_SHIFT = 2;
constexpr uint32_t DB_HTILE_SURFACE_HTILE_USES_PRELOAD_WIN_MASK = 0x1;
constexpr uint32_t DB_HTILE_SURFACE_PRELOAD_SHIFT = 3;
constexpr uint32_t DB_HTILE_SURFACE_PRELOAD_MASK = 0x1;
constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_WIDTH_SHIFT = 4;
constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_WIDTH_MASK = 0x3F;
constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_HEIGHT_SHIFT = 10;
constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_HEIGHT_MASK = 0x3F;
constexpr uint32_t DB_HTILE_SURFACE_DST_OUTSIDE_ZERO_TO_ONE_SHIFT = 16;
constexpr uint32_t DB_HTILE_SURFACE_DST_OUTSIDE_ZERO_TO_ONE_MASK = 0x1;
constexpr uint32_t DB_SHADING_RATE_ENCODING = 0x2AF;
constexpr uint32_t DB_SHADING_RATE_ENCODING_SHADING_RATE_ENCODING_SHIFT = 19;
constexpr uint32_t DB_SHADING_RATE_ENCODING_SHADING_RATE_ENCODING_MASK = 0x3;
constexpr uint32_t DB_SRESULTS_COMPARE_STATE0 = 0x2B0;
constexpr uint32_t DB_SRESULTS_COMPARE_STATE1 = 0x2B1;
@@ -621,7 +582,6 @@ constexpr uint32_t PA_SC_SHADER_CONTROL = 0x310;
constexpr uint32_t PA_SC_BINNER_CNTL_0 = 0x311;
constexpr uint32_t PA_SC_BINNER_CNTL_1 = 0x312;
constexpr uint32_t PA_SC_CONSERVATIVE_RASTERIZATION_CNTL = 0x313;
constexpr uint32_t PA_SC_NGG_MODE_CNTL = 0x314;
constexpr uint32_t CB_COLOR0_BASE = 0x318;
constexpr uint32_t CB_COLOR0_VIEW = 0x31B;
@@ -649,24 +609,13 @@ constexpr uint32_t CB_COLOR0_INFO_BLEND_BYPASS_SHIFT = 16;
constexpr uint32_t CB_COLOR0_INFO_BLEND_BYPASS_MASK = 0x1;
constexpr uint32_t CB_COLOR0_INFO_ROUND_MODE_SHIFT = 18;
constexpr uint32_t CB_COLOR0_INFO_ROUND_MODE_MASK = 0x1;
constexpr uint32_t CB_COLOR0_INFO_CMASK_IS_LINEAR_SHIFT = 19;
constexpr uint32_t CB_COLOR0_INFO_CMASK_IS_LINEAR_MASK = 0x1;
constexpr uint32_t CB_COLOR0_INFO_FMASK_COMPRESSION_DISABLE_SHIFT = 26;
constexpr uint32_t CB_COLOR0_INFO_FMASK_COMPRESSION_DISABLE_MASK = 0x1;
constexpr uint32_t CB_COLOR0_INFO_FMASK_COMPRESS_1FRAG_ONLY_SHIFT = 27;
constexpr uint32_t CB_COLOR0_INFO_FMASK_COMPRESS_1FRAG_ONLY_MASK = 0x1;
constexpr uint32_t CB_COLOR0_INFO_DCC_ENABLE_SHIFT = 28;
constexpr uint32_t CB_COLOR0_INFO_DCC_ENABLE_MASK = 0x1;
constexpr uint32_t CB_COLOR0_INFO_CMASK_ADDR_TYPE_SHIFT = 29;
constexpr uint32_t CB_COLOR0_INFO_CMASK_ADDR_TYPE_MASK = 0x3;
constexpr uint32_t CB_COLOR0_INFO_ALT_TILE_MODE_SHIFT = 31;
constexpr uint32_t CB_COLOR0_INFO_ALT_TILE_MODE_MASK = 0x1;
constexpr uint32_t CB_COLOR0_ATTRIB = 0x31D;
constexpr uint32_t CB_COLOR0_ATTRIB_TILE_MODE_INDEX_SHIFT = 0;
constexpr uint32_t CB_COLOR0_ATTRIB_TILE_MODE_INDEX_MASK = 0x1F;
constexpr uint32_t CB_COLOR0_ATTRIB_FMASK_TILE_MODE_INDEX_SHIFT = 5;
constexpr uint32_t CB_COLOR0_ATTRIB_FMASK_TILE_MODE_INDEX_MASK = 0x1F;
constexpr uint32_t CB_COLOR0_ATTRIB_NUM_SAMPLES_SHIFT = 12;
constexpr uint32_t CB_COLOR0_ATTRIB_NUM_SAMPLES_MASK = 0x7;
constexpr uint32_t CB_COLOR0_ATTRIB_NUM_FRAGMENTS_SHIFT = 15;
@@ -681,8 +630,6 @@ constexpr uint32_t CB_COLOR0_DCC_CONTROL_KEY_CLEAR_ENABLE_SHIFT
constexpr uint32_t CB_COLOR0_DCC_CONTROL_KEY_CLEAR_ENABLE_MASK = 0x1;
constexpr uint32_t CB_COLOR0_DCC_CONTROL_MAX_UNCOMPRESSED_BLOCK_SIZE_SHIFT = 2;
constexpr uint32_t CB_COLOR0_DCC_CONTROL_MAX_UNCOMPRESSED_BLOCK_SIZE_MASK = 0x3;
constexpr uint32_t CB_COLOR0_DCC_CONTROL_MIN_COMPRESSED_BLOCK_SIZE_SHIFT = 4;
constexpr uint32_t CB_COLOR0_DCC_CONTROL_MIN_COMPRESSED_BLOCK_SIZE_MASK = 0x1;
constexpr uint32_t CB_COLOR0_DCC_CONTROL_MAX_COMPRESSED_BLOCK_SIZE_SHIFT = 5;
constexpr uint32_t CB_COLOR0_DCC_CONTROL_MAX_COMPRESSED_BLOCK_SIZE_MASK = 0x3;
constexpr uint32_t CB_COLOR0_DCC_CONTROL_COLOR_TRANSFORM_SHIFT = 7;
@@ -739,31 +686,25 @@ constexpr uint32_t CB_COLOR0_ATTRIB3_CMASK_PIPE_ALIGNED_SHIFT = 26;
constexpr uint32_t CB_COLOR0_ATTRIB3_CMASK_PIPE_ALIGNED_MASK = 0x1;
constexpr uint32_t CB_COLOR0_ATTRIB3_DCC_PIPE_ALIGNED_SHIFT = 30;
constexpr uint32_t CB_COLOR0_ATTRIB3_DCC_PIPE_ALIGNED_MASK = 0x1;
constexpr uint32_t CB_COLOR0_ATTRIB3_WRITE_VRS_RATE_HINT_TO_CMASK_SHIFT = 31;
constexpr uint32_t CB_COLOR0_ATTRIB3_WRITE_VRS_RATE_HINT_TO_CMASK_MASK = 0x1;
constexpr uint32_t CB_COLOR7_ATTRIB3 = 0x3BF;
/* Fake codes. Don't exist on real HW */
constexpr uint32_t CX_NOP = 0x800003FF;
constexpr uint32_t CX_NOP = 0xDB;
constexpr uint32_t CX_NUM = 0x3FF + 1;
/* Shader registers */
constexpr uint32_t SPI_SHADER_TBA_LO_PS = 0x0;
constexpr uint32_t SPI_SHADER_PGM_RSRC4_PS = 0x1;
constexpr uint32_t SPI_SHADER_TMA_LO_PS = 0x2;
constexpr uint32_t SPI_SHADER_TMA_HI_PS = 0x3;
constexpr uint32_t SPI_SHADER_PGM_CHKSUM_PS = 0x6;
constexpr uint32_t SPI_SHADER_PGM_RSRC3_PS = 0x7;
constexpr uint32_t SPI_SHADER_PGM_LO_PS = 0x8;
constexpr uint32_t SPI_SHADER_PGM_HI_PS = 0x9;
constexpr uint32_t SPI_SHADER_PACE_ID_PS = 0x6;
constexpr uint32_t SPI_GRAPHICS_SHADER_CONTROL_PS = 0x7;
constexpr uint32_t SPI_SHADER_PGM_LO_PS = 0x8;
constexpr uint32_t SPI_SHADER_PGM_HI_PS = 0x9;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS = 0xA;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT = 0;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_VGPRS_MASK = 0x3F;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_SGPRS_SHIFT = 6;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_SGPRS_MASK = 0xF;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_PRIORITY_SHIFT = 10;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_PRIORITY_MASK = 0x3;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_FLOAT_MODE_SHIFT = 12;
@@ -800,14 +741,11 @@ constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_SHARED_VGPR_CNT_MASK = 0xF;
constexpr uint32_t SPI_SHADER_USER_DATA_PS_0 = 0xC;
constexpr uint32_t SPI_SHADER_USER_DATA_PS_15 = 0x1B;
constexpr uint32_t SPI_SHADER_USER_DATA_PS_31 = 0x2B;
constexpr uint32_t SPI_SHADER_REQ_CTRL_PS = 0x30;
constexpr uint32_t SPI_SHADER_USER_ACCUM_PS_0 = 0x32;
constexpr uint32_t SPI_SHADER_USER_ACCUM_PS_3 = 0x35;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_VS_VGPRS_SHIFT = 0;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_VS_VGPRS_MASK = 0x3F;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_VS_SGPRS_SHIFT = 6;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_VS_SGPRS_MASK = 0xF;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_VS_PRIORITY_SHIFT = 10;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_VS_PRIORITY_MASK = 0x3;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_VS_FLOAT_MODE_SHIFT = 12;
@@ -838,19 +776,20 @@ constexpr uint32_t SPI_SHADER_PGM_RSRC2_VS_USER_SGPR_MSB_MASK = 0x1;
constexpr uint32_t SPI_SHADER_PGM_RSRC2_VS_SHARED_VGPR_CNT_SHIFT = 28;
constexpr uint32_t SPI_SHADER_PGM_RSRC2_VS_SHARED_VGPR_CNT_MASK = 0xF;
constexpr uint32_t SPI_SHADER_PGM_CHKSUM_GS = 0x80;
constexpr uint32_t SPI_SHADER_PACE_ID_GS = 0x80;
// AGC compiler records use this numeric tag as opaque metadata. It is not a shader checksum
// register and intentionally has no checksum-state consumer in HardwareContext.
constexpr uint32_t SPI_SHADER_PGM_CHKSUM_GS = SPI_SHADER_PACE_ID_GS;
constexpr uint32_t SPI_SHADER_PGM_RSRC4_GS = 0x81;
constexpr uint32_t SPI_SHADER_USER_DATA_ADDR_LO_GS = 0x82;
constexpr uint32_t SPI_SHADER_USER_DATA_ADDR_HI_GS = 0x83;
constexpr uint32_t SPI_SHADER_PGM_RSRC3_GS = 0x87;
constexpr uint32_t SPI_GRAPHICS_SHADER_CONTROL_GS = 0x87;
constexpr uint32_t SPI_SHADER_PGM_LO_GS = 0x88;
constexpr uint32_t SPI_SHADER_PGM_HI_GS = 0x89;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS = 0x8A;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS_VGPRS_SHIFT = 0;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS_VGPRS_MASK = 0x3F;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS_SGPRS_SHIFT = 6;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS_SGPRS_MASK = 0xF;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS_PRIORITY_SHIFT = 10;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS_PRIORITY_MASK = 0x3;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS_FLOAT_MODE_SHIFT = 12;
@@ -891,22 +830,15 @@ constexpr uint32_t SPI_SHADER_PGM_RSRC2_GS_SHARED_VGPR_CNT_MASK = 0xF;
constexpr uint32_t SPI_SHADER_USER_DATA_GS_0 = 0x8C;
constexpr uint32_t SPI_SHADER_USER_DATA_GS_15 = 0x9B;
constexpr uint32_t SPI_SHADER_USER_DATA_GS_31 = 0xAB;
constexpr uint32_t SPI_SHADER_REQ_CTRL_ESGS = 0xB0;
constexpr uint32_t SPI_SHADER_USER_ACCUM_ESGS_0 = 0xB2;
constexpr uint32_t SPI_SHADER_USER_ACCUM_ESGS_3 = 0xB5;
constexpr uint32_t SPI_SHADER_PGM_RSRC2_ES_GS = 0xBC;
constexpr uint32_t SPI_SHADER_PGM_LO_ES = 0xC8;
constexpr uint32_t SPI_SHADER_PGM_HI_ES = 0xC9;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_ES = 0xCA;
constexpr uint32_t SPI_SHADER_PGM_RSRC2_ES = 0xCB;
constexpr uint32_t SPI_SHADER_USER_DATA_ES_0 = 0xCC;
constexpr uint32_t SPI_SHADER_USER_DATA_ES_15 = 0xDB;
constexpr uint32_t SPI_SHADER_USER_DATA_ES_31 = 0xEB;
// Retained only as an opaque AGC compiler-record tag; 0x100 is not a PS5 SH register.
constexpr uint32_t SPI_SHADER_PGM_CHKSUM_HS = 0x100;
constexpr uint32_t SPI_SHADER_PGM_RSRC4_HS = 0x101;
constexpr uint32_t SPI_SHADER_USER_DATA_ADDR_LO_HS = 0x102;
constexpr uint32_t SPI_SHADER_USER_DATA_ADDR_HI_HS = 0x103;
constexpr uint32_t SPI_SHADER_PGM_RSRC3_HS = 0x107;
constexpr uint32_t SPI_GRAPHICS_SHADER_CONTROL_HS = 0x107;
constexpr uint32_t SPI_SHADER_PGM_LO_HS = 0x108;
constexpr uint32_t SPI_SHADER_PGM_HI_HS = 0x109;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_HS = 0x10A;
@@ -944,13 +876,10 @@ constexpr uint32_t SPI_SHADER_PGM_RSRC2_HS_SHARED_VGPR_CNT_MASK = 0xF;
constexpr uint32_t SPI_SHADER_USER_DATA_HS_0 = 0x10C;
constexpr uint32_t SPI_SHADER_USER_DATA_HS_15 = 0x11B;
constexpr uint32_t SPI_SHADER_USER_DATA_HS_31 = 0x12B;
constexpr uint32_t SPI_SHADER_REQ_CTRL_LSHS = 0x130;
constexpr uint32_t SPI_SHADER_USER_ACCUM_LSHS_0 = 0x132;
constexpr uint32_t SPI_SHADER_USER_ACCUM_LSHS_3 = 0x135;
constexpr uint32_t SPI_SHADER_PGM_LO_LS = 0x148;
constexpr uint32_t SPI_SHADER_PGM_HI_LS = 0x149;
constexpr uint32_t SPI_SHADER_PGM_RSRC1_LS = 0x14A;
constexpr uint32_t SPI_SHADER_PGM_RSRC2_LS = 0x14B;
constexpr uint32_t COMPUTE_START_X = 0x204;
constexpr uint32_t COMPUTE_START_Y = 0x205;
constexpr uint32_t COMPUTE_START_Z = 0x206;
@@ -959,28 +888,26 @@ constexpr uint32_t COMPUTE_NUM_THREAD_Y = 0x208;
constexpr uint32_t COMPUTE_NUM_THREAD_Z = 0x209;
constexpr uint32_t COMPUTE_PGM_LO = 0x20C;
constexpr uint32_t COMPUTE_PGM_HI = 0x20D;
constexpr uint32_t COMPUTE_TBA_LO = 0x20E;
constexpr uint32_t COMPUTE_TBA_HI = 0x20F;
constexpr uint32_t COMPUTE_TMA_LO = 0x210;
constexpr uint32_t COMPUTE_TMA_HI = 0x211;
constexpr uint32_t COMPUTE_PGM_RSRC1 = 0x212;
constexpr uint32_t COMPUTE_PGM_RSRC1_VGPRS_SHIFT = 0;
constexpr uint32_t COMPUTE_PGM_RSRC1_VGPRS_MASK = 0x3F;
constexpr uint32_t COMPUTE_PGM_RSRC1_SGPRS_SHIFT = 6;
constexpr uint32_t COMPUTE_PGM_RSRC1_SGPRS_MASK = 0xF;
constexpr uint32_t COMPUTE_PGM_RSRC1_PRIORITY_SHIFT = 10;
constexpr uint32_t COMPUTE_PGM_RSRC1_PRIORITY_MASK = 0x3;
constexpr uint32_t COMPUTE_PGM_RSRC1_FLOAT_MODE_SHIFT = 12;
constexpr uint32_t COMPUTE_PGM_RSRC1_FLOAT_MODE_MASK = 0xFF;
constexpr uint32_t COMPUTE_PGM_RSRC1_DX10_CLAMP_SHIFT = 21;
constexpr uint32_t COMPUTE_PGM_RSRC1_DX10_CLAMP_MASK = 0x1;
constexpr uint32_t COMPUTE_PGM_RSRC1_DEBUG_MODE_SHIFT = 22;
constexpr uint32_t COMPUTE_PGM_RSRC1_DEBUG_MODE_MASK = 0x1;
constexpr uint32_t COMPUTE_PGM_RSRC1_IEEE_MODE_SHIFT = 23;
constexpr uint32_t COMPUTE_PGM_RSRC1_IEEE_MODE_MASK = 0x1;
constexpr uint32_t COMPUTE_PGM_RSRC1_BULKY_SHIFT = 24;
constexpr uint32_t COMPUTE_PGM_RSRC1_BULKY_MASK = 0x1;
constexpr uint32_t COMPUTE_PGM_RSRC1_FP16_OVFL_SHIFT = 26;
constexpr uint32_t COMPUTE_PGM_RSRC1_FP16_OVFL_MASK = 0x1;
constexpr uint32_t COMPUTE_PGM_RSRC1_WGP_MODE_SHIFT = 29;
constexpr uint32_t COMPUTE_PGM_RSRC1_WGP_MODE_MASK = 0x1;
constexpr uint32_t COMPUTE_PGM_RSRC1_FWD_PROGRESS_SHIFT = 31;
constexpr uint32_t COMPUTE_PGM_RSRC1_FWD_PROGRESS_MASK = 0x1;
constexpr uint32_t COMPUTE_DISPATCH_INITIATOR_CS_W32_EN_SHIFT = 15;
constexpr uint32_t COMPUTE_DISPATCH_INITIATOR_CS_W32_EN_MASK = 0x1;
@@ -1011,21 +938,16 @@ constexpr uint32_t COMPUTE_PGM_RSRC2_LDS_SIZE_SHIFT = 15;
constexpr uint32_t COMPUTE_PGM_RSRC2_LDS_SIZE_MASK = 0x1FF;
constexpr uint32_t COMPUTE_RESOURCE_LIMITS = 0x215;
constexpr uint32_t COMPUTE_DESTINATION_EN_SE0 = 0x216;
constexpr uint32_t COMPUTE_DESTINATION_EN_SE1 = 0x217;
constexpr uint32_t COMPUTE_TMPRING_SIZE = 0x218;
constexpr uint32_t COMPUTE_DESTINATION_EN_SE2 = 0x219;
constexpr uint32_t COMPUTE_DESTINATION_EN_SE3 = 0x21A;
constexpr uint32_t COMPUTE_USER_ACCUM_0 = 0x224;
constexpr uint32_t COMPUTE_PGM_RSRC3 = 0x228;
constexpr uint32_t COMPUTE_SHADER_CHKSUM = 0x22A;
constexpr uint32_t COMPUTE_PGM_RSRC3_SHARED_VGPRS_SHIFT = 0;
constexpr uint32_t COMPUTE_PGM_RSRC3_SHARED_VGPRS_MASK = 0xF;
constexpr uint32_t COMPUTE_PACE_ID = 0x22A;
constexpr uint32_t COMPUTE_USER_DATA_0 = 0x240;
constexpr uint32_t COMPUTE_USER_DATA_15 = 0x24F;
constexpr uint32_t COMPUTE_DISPATCH_TUNNEL = 0x27D;
/* Fake codes. Don't exist on real HW */
constexpr uint32_t SH_NOP = 0x800002FF;
constexpr uint32_t SH_NOP = 0x280;
constexpr uint32_t SH_NUM = 0x2FF + 1;
@@ -1042,6 +964,7 @@ constexpr uint32_t GE_INDX_OFFSET = 0x24A;
constexpr uint32_t GE_MULTI_PRIM_IB_RESET_EN = 0x24B;
constexpr uint32_t VGT_HS_OFFCHIP_PARAM = 0x24F;
constexpr uint32_t VGT_TF_MEMORY_BASE = 0x250;
constexpr uint32_t IA_MULTI_VGT_PARAM = 0x258;
constexpr uint32_t GE_CNTL = 0x25B;
constexpr uint32_t GE_CNTL_PRIM_GRP_SIZE_SHIFT = 0;
@@ -1063,28 +986,15 @@ constexpr uint32_t GE_USER_VGPR_EN_EN_USER_VGPR2_MASK = 0x1;
constexpr uint32_t GE_USER_VGPR_EN_EN_USER_VGPR3_SHIFT = 2;
constexpr uint32_t GE_USER_VGPR_EN_EN_USER_VGPR3_MASK = 0x1;
constexpr uint32_t IA_MULTI_VGT_PARAM = 0x258;
constexpr uint32_t TA_CS_BC_BASE_ADDR = 0x380;
constexpr uint32_t TA_CS_BC_BASE_ADDR_HI = 0x381;
constexpr uint32_t TEXTURE_GRADIENT_FACTORS = 0x382;
constexpr uint32_t TEXTURE_GRADIENT_FACTORS = 0x383;
constexpr uint32_t TEXTURE_GRADIENT_CONTROL = 0x384;
constexpr uint32_t GDS_OA_CNTL = 0x41D;
constexpr uint32_t GDS_OA_COUNTER = 0x41E;
constexpr uint32_t GDS_OA_ADDRESS = 0x41F;
/* Fake codes. Don't exist on real HW */
constexpr uint32_t FSR_EXTEND_SUBPIXEL_ROUNDING = 0x80003FF4;
constexpr uint32_t FSR_ALPHA_VALUE0 = 0x80003FF5;
constexpr uint32_t FSR_ALPHA_VALUE1 = 0x80003FF6;
constexpr uint32_t FSR_CONTROL_POINT0 = 0x80003FF7;
constexpr uint32_t FSR_CONTROL_POINT1 = 0x80003FF8;
constexpr uint32_t FSR_CONTROL_POINT2 = 0x80003FF9;
constexpr uint32_t FSR_CONTROL_POINT3 = 0x80003FFA;
constexpr uint32_t FSR_WINDOW0 = 0x80003FFB;
constexpr uint32_t FSR_WINDOW1 = 0x80003FFC;
constexpr uint32_t TEXTURE_GRADIENT_CONTROL = 0x80003FFD;
constexpr uint32_t MEMORY_MAPPING_MASK = 0x80003FFE;
constexpr uint32_t UC_NOP = 0x80003FFF;
constexpr uint32_t UC_NOP = 0xA2;
constexpr uint32_t UC_NUM = 0x3FFF + 1;
+3 -7
View File
@@ -18,8 +18,8 @@ MemoryTracker::~MemoryTracker() = default;
#if KYTY_BUILD == KYTY_BUILD_DEBUG
void MemoryTracker::ValidateGpuDirtyPages(const RangeSet& dirty, uint64_t vaddr, uint64_t size,
const char* operation) const noexcept {
if (vaddr == 0 || size == 0 || size > UINT64_MAX - vaddr ||
(vaddr & (TRACKER_PAGE_SIZE - 1)) != 0 || (size & (TRACKER_PAGE_SIZE - 1)) != 0) {
if (!GuestRange {vaddr, size}.Valid() || (vaddr & (TRACKER_PAGE_SIZE - 1)) != 0 ||
(size & (TRACKER_PAGE_SIZE - 1)) != 0) {
EXIT("MemoryTracker: invalid dirty-page validation range\n");
}
for (auto page = vaddr; page < vaddr + size; page += TRACKER_PAGE_SIZE) {
@@ -37,9 +37,6 @@ void MemoryTracker::ValidateGpuDirtyPages(const RangeSet& dirty, uint64_t vaddr,
void MemoryTracker::ValidateGpuDirtyOwnership(const RangeSet& dirty, uint64_t vaddr, uint64_t size,
const char* operation) {
ValidateRange(vaddr, size);
if (vaddr + size > UINT64_MAX - (TRACKER_PAGE_SIZE - 1)) {
EXIT("MemoryTracker: dirty ownership range alignment overflow\n");
}
const auto begin = vaddr & ~(TRACKER_PAGE_SIZE - 1);
const auto end = (vaddr + size + TRACKER_PAGE_SIZE - 1) & ~(TRACKER_PAGE_SIZE - 1);
for (auto page = begin; page < end; page += TRACKER_PAGE_SIZE) {
@@ -56,8 +53,7 @@ void MemoryTracker::ValidateGpuDirtyOwnership(const RangeSet& dirty, uint64_t va
#endif
void MemoryTracker::ValidateRange(uint64_t vaddr, uint64_t size) {
if (vaddr == 0 || size == 0 || vaddr >= TRACKER_ADDRESS_SIZE ||
size > TRACKER_ADDRESS_SIZE - vaddr) {
if (!GuestRange {vaddr, size}.Valid()) {
EXIT("invalid memory tracker range\n");
}
}
+1 -1
View File
@@ -110,7 +110,7 @@ private:
};
void ValidateRange(uint64_t vaddr, uint64_t size) {
if (vaddr == 0 || size == 0 || vaddr >= ADDRESS_SIZE || size > ADDRESS_SIZE - vaddr) {
if (!GuestRange {vaddr, size}.Valid()) {
Fatal("invalid range vaddr=0x%016" PRIx64 ", size=0x%016" PRIx64, vaddr, size);
}
}
+16
View File
@@ -4,6 +4,8 @@
#include "common/bitArray.h"
#include "common/common.h"
#include <compare>
namespace Libs::Graphics {
constexpr uint64_t TRACKER_PAGE_SIZE = 4ull * 1024ull;
@@ -11,6 +13,20 @@ constexpr uint64_t TRACKER_REGION_SIZE = 4ull * 1024ull * 1024ull;
constexpr uint64_t TRACKER_ADDRESS_SIZE = 1ull << 40u;
constexpr size_t TRACKER_REGION_PAGES = TRACKER_REGION_SIZE / TRACKER_PAGE_SIZE;
struct GuestRange {
uint64_t address = 0;
uint64_t size = 0;
[[nodiscard]] constexpr bool Empty() const noexcept { return address == 0 && size == 0; }
[[nodiscard]] constexpr bool Valid() const noexcept {
return address != 0 && size != 0 && address < TRACKER_ADDRESS_SIZE &&
size <= TRACKER_ADDRESS_SIZE - address;
}
[[nodiscard]] constexpr bool ValidOrEmpty() const noexcept { return Empty() || Valid(); }
[[nodiscard]] constexpr uint64_t End() const noexcept { return address + size; }
auto operator<=>(const GuestRange&) const = default;
};
enum class DirtySource { Cpu, Gpu };
using RegionBits = Common::BitArray<TRACKER_REGION_PAGES>;
static_assert(sizeof(RegionBits) == TRACKER_REGION_PAGES / 8);
+5 -9
View File
@@ -241,8 +241,7 @@ BufferCache::~BufferCache() {
}
void BufferCache::InvalidateMemory(uint64_t vaddr, uint64_t size) {
if (vaddr == 0 || size == 0 || vaddr >= TRACKER_ADDRESS_SIZE ||
size > TRACKER_ADDRESS_SIZE - vaddr) {
if (!GuestRange {vaddr, size}.Valid()) {
EXIT("BufferCache: invalid memory-invalidation range\n");
}
m_memory_tracker.InvalidateRegion(vaddr, size,
@@ -314,7 +313,7 @@ BufferId BufferCache::FindBuffer(uint64_t vaddr, uint64_t size) {
if (vaddr == 0) {
return NULL_BUFFER_ID;
}
if (size == 0 || vaddr >= TRACKER_ADDRESS_SIZE || size > TRACKER_ADDRESS_SIZE - vaddr) {
if (!GuestRange {vaddr, size}.Valid()) {
EXIT("BufferCache: invalid buffer discovery request\n");
}
const auto* owner = m_page_table.Find(vaddr >> PageTable::kPageBits);
@@ -443,8 +442,7 @@ std::pair<Buffer*, uint64_t> BufferCache::ObtainBuffer(uint64_t vaddr, uint64_t
bool is_written, bool is_texel_buffer,
BufferId id) {
auto& command = m_scheduler.Current();
if (command.IsInvalid() || vaddr == 0 || size == 0 ||
vaddr >= TRACKER_ADDRESS_SIZE || size > TRACKER_ADDRESS_SIZE - vaddr) {
if (command.IsInvalid() || !GuestRange {vaddr, size}.Valid()) {
EXIT("BufferCache: buffer request requires a recording command buffer\n");
}
@@ -474,8 +472,7 @@ std::pair<Buffer*, uint64_t> BufferCache::ObtainBuffer(uint64_t vaddr, uint64_t
}
std::pair<Buffer*, uint64_t> BufferCache::ObtainBufferForImage(uint64_t vaddr, uint64_t size) {
if (vaddr == 0 || size == 0 || vaddr >= TRACKER_ADDRESS_SIZE ||
size > TRACKER_ADDRESS_SIZE - vaddr) {
if (!GuestRange {vaddr, size}.Valid()) {
EXIT("BufferCache: invalid image source\n");
}
auto find_owner = [&]() -> Buffer* {
@@ -661,8 +658,7 @@ void BufferCache::CopyBuffer(uint64_t dst_vaddr, uint64_t src_vaddr, uint64_t si
}
bool BufferCache::IsRegionRegistered(uint64_t vaddr, uint64_t size) {
if (vaddr == 0 || size == 0 || vaddr >= TRACKER_ADDRESS_SIZE ||
size > TRACKER_ADDRESS_SIZE - vaddr) {
if (!GuestRange {vaddr, size}.Valid()) {
EXIT("BufferCache: invalid registered-region query\n");
}
// Cached buffers are ordered and non-overlapping. The last buffer beginning before the query
@@ -35,8 +35,7 @@ bool GpuResourceManager::InvalidateMemory(uint64_t vaddr, uint64_t size) {
}
bool GpuResourceManager::IsMapped(uint64_t vaddr, uint64_t size) const noexcept {
if (vaddr == 0 || size == 0 || vaddr >= TRACKER_ADDRESS_SIZE ||
size > TRACKER_ADDRESS_SIZE - vaddr) {
if (!GuestRange {vaddr, size}.Valid()) {
return false;
}
std::shared_lock lock(m_mapped_ranges_mutex);
@@ -204,13 +204,11 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
if (texture_tile &&
(!TileGetTextureBlockLayout(transfer_format, rt.attrib3.tile_mode, volume,
texture_tile_layout) ||
rt.pitch.pitch_div8_minus1 != 0 ||
(rt.base.addr & (texture_tile_layout.block.block_size - 1u)) != 0 ||
rt.info.fmask_compression_enable || rt.info.fmask_data_compression_disable ||
rt.info.fmask_one_frag_mode || rt.info.cmask_fast_clear_enable ||
rt.info.dcc_compression_enable || rt.info.cmask_is_linear != 0 ||
rt.info.cmask_addr_type != 0 || rt.info.alt_tile_mode || rt.cmask.addr != 0 ||
rt.fmask.addr != 0 || rt.dcc_addr.addr != 0 || rt.dcc.data_write_on_dcc_clear_to_reg)) {
rt.info.dcc_compression_enable || rt.cmask.addr != 0 || rt.fmask.addr != 0 ||
rt.dcc_addr.addr != 0 || rt.dcc.data_write_on_dcc_clear_to_reg)) {
EXIT("unsupported texture-tiled render target: addr=0x%016" PRIx64 " tile=%u"
" dimension=%u depth=%u levels=%u layer=%u/%u samples=%u fragments=%u bpe=%u"
" cmask=0x%016" PRIx64 " fmask=0x%016" PRIx64 " dcc=0x%016" PRIx64 "\n",
@@ -226,9 +224,7 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
" layer=%u/%u\n",
rt.attrib3.dimension, rt.attrib3.depth, view.base_layer, view.image_layers);
}
if (rt.pitch.pitch_div8_minus1 != 0) {
pitch = (rt.pitch.pitch_div8_minus1 + 1u) << 3u;
} else if (tile) {
if (tile) {
if (volume) {
pitch = TileGetTexturePitch(transfer_format, width, rt.attrib3.tile_mode);
} else if (texture_tile) {
@@ -294,12 +290,6 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
mip_sizes[0] = {static_cast<uint32_t>(size), 0, 0, 0, 0, 0};
mip_padded[0] = {pitch, height};
}
if (rt.slice.slice_div64_minus1 != 0 &&
(static_cast<uint64_t>(rt.slice.slice_div64_minus1) + 1u) * 64u != size) {
EXIT("render-target slice span mismatch: encoded=0x%016" PRIx64 " derived=0x%016" PRIx64
"\n",
(static_cast<uint64_t>(rt.slice.slice_div64_minus1) + 1u) * 64u, size);
}
if (size == 0 || (!volume && size > UINT64_MAX / view.image_layers)) {
EXIT("render-target memory footprint is invalid\n");
}
@@ -309,7 +299,7 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
if (backing_size == 0) {
EXIT("render-target backing is empty\n");
}
if (backing_size > TRACKER_ADDRESS_SIZE - rt.base.addr) {
if (!GuestRange {rt.base.addr, backing_size}.Valid()) {
EXIT("render-target backing range is invalid\n");
}
+32 -155
View File
@@ -97,17 +97,11 @@ 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> dst;
dst.reserve(53);
dst.reserve(40);
dst.push_back(fmt::format("{}\n", func));
dst.push_back(fmt::format("\t base.addr = 0x{:016x}\n", rt.base.addr));
dst.push_back(
fmt::format("\t pitch.pitch_div8_minus1 = 0x{:08x}\n", rt.pitch.pitch_div8_minus1));
dst.push_back(fmt::format("\t pitch.fmask_pitch_div8_minus1 = 0x{:08x}\n",
rt.pitch.fmask_pitch_div8_minus1));
dst.push_back(fmt::format("\t slice.slice_div64_minus1 = 0x{:08x}\n",
rt.slice.slice_div64_minus1));
dst.push_back(fmt::format("\t view.base_array_slice_index = 0x{:08x}\n",
rt.view.base_array_slice_index));
dst.push_back(fmt::format("\t view.last_array_slice_index = 0x{:08x}\n",
@@ -128,12 +122,6 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
rt.info.cmask_fast_clear_enable ? "true" : "false"));
dst.push_back(fmt::format("\t info.dcc_compression_enable = {}\n",
rt.info.dcc_compression_enable ? "true" : "false"));
dst.push_back(
fmt::format("\t info.cmask_is_linear = 0x{:08x}\n", rt.info.cmask_is_linear));
dst.push_back(
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",
rt.info.alt_tile_mode ? "true" : "false"));
dst.push_back(fmt::format("\t info.format = 0x{:08x}\n",
static_cast<uint32_t>(rt.info.format)));
dst.push_back(fmt::format("\t info.channel_type = 0x{:08x}\n",
@@ -148,10 +136,6 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
rt.info.round_mode ? "true" : "false"));
dst.push_back(fmt::format("\t attrib.force_dest_alpha_to_one = {}\n",
rt.attrib.force_dest_alpha_to_one ? "true" : "false"));
dst.push_back(fmt::format("\t attrib.tile_mode = 0x{:08x}\n",
static_cast<uint32_t>(rt.attrib.tile_mode)));
dst.push_back(fmt::format("\t attrib.fmask_tile_mode = 0x{:08x}\n",
static_cast<uint32_t>(rt.attrib.fmask_tile_mode)));
dst.push_back(
fmt::format("\t attrib.num_samples = 0x{:08x}\n", rt.attrib.num_samples));
dst.push_back(
@@ -166,42 +150,32 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
static_cast<uint32_t>(rt.attrib3.tile_mode)));
dst.push_back(
fmt::format("\t attrib3.dimension = 0x{:08x}\n", rt.attrib3.dimension));
dst.push_back(fmt::format("\t attrib3.cmask_pipe_aligned = {}\n",
rt.attrib3.cmask_pipe_aligned ? "true" : "false"));
dst.push_back(fmt::format("\t attrib3.dcc_pipe_aligned = {}\n",
rt.attrib3.dcc_pipe_aligned ? "true" : "false"));
dst.push_back(fmt::format("\t attrib3.metadata_pipe_aligned = {}\n",
rt.attrib3.metadata_pipe_aligned ? "true" : "false"));
dst.push_back(fmt::format("\t attrib3.write_vrs_rate_hint_to_cmask = {}\n",
rt.attrib3.write_vrs_rate_hint_to_cmask ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.max_uncompressed_block_size = 0x{:08x}\n",
rt.dcc.max_uncompressed_block_size));
dst.push_back(fmt::format("\t dcc.max_compressed_block_size = 0x{:08x}\n",
rt.dcc.max_compressed_block_size));
dst.push_back(fmt::format("\t dcc.min_compressed_block_size = 0x{:08x}\n",
rt.dcc.min_compressed_block_size));
dst.push_back(
fmt::format("\t dcc.color_transform = 0x{:08x}\n", rt.dcc.color_transform));
dst.push_back(fmt::format("\t dcc.overwrite_combiner_disable = {}\n",
rt.dcc.overwrite_combiner_disable ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.independent_64b_blocks = {}\n",
rt.dcc.independent_64b_blocks ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.independent_128b_blocks = {}\n",
rt.dcc.independent_128b_blocks ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.independent_block_size = 0x{:02x}\n",
static_cast<uint8_t>(rt.dcc.independent_block_size)));
dst.push_back(fmt::format("\t data_write_on_dcc_clear_to_reg = {}\n",
rt.dcc.data_write_on_dcc_clear_to_reg ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.dcc_clear_key_enable = {}\n",
rt.dcc.dcc_clear_key_enable ? "true" : "false"));
dst.push_back(fmt::format("\t cmask.addr = 0x{:016x}\n", rt.cmask.addr));
dst.push_back(fmt::format("\t cmask_slice.slice_minus1 = 0x{:08x}\n",
rt.cmask_slice.slice_minus1));
dst.push_back(fmt::format("\t fmask.addr = 0x{:016x}\n", rt.fmask.addr));
dst.push_back(fmt::format("\t fmask_slice.slice_minus1 = 0x{:08x}\n",
rt.fmask_slice.slice_minus1));
dst.push_back(
fmt::format("\t clear_word0.word0 = 0x{:08x}\n", rt.clear_word0.word0));
dst.push_back(
fmt::format("\t clear_word1.word1 = 0x{:08x}\n", rt.clear_word1.word1));
dst.push_back(
fmt::format("\t dcc_addr.addr = 0x{:016x}\n", rt.dcc_addr.addr));
dst.push_back(fmt::format("\t size.width = 0x{:08x}\n", rt.size.width));
dst.push_back(fmt::format("\t size.height = 0x{:08x}\n", rt.size.height));
return dst;
}
@@ -231,13 +205,8 @@ static bool RenderIsColorDimension(uint32_t dimension) {
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
static void RtCheck(const HW::RenderTarget& rt) {
if (rt.base.addr != 0) {
// bool render_to_texture = (rt.attrib.tile_mode == 0x0d);
// EXIT_NOT_IMPLEMENTED(rt.base_addr == 0);
EXIT_NOT_IMPLEMENTED(rt.pitch.pitch_div8_minus1 != 0);
EXIT_NOT_IMPLEMENTED(rt.pitch.fmask_pitch_div8_minus1 != 0);
EXIT_NOT_IMPLEMENTED(rt.slice.slice_div64_minus1 != 0);
EXIT_NOT_IMPLEMENTED(rt.view.base_array_slice_index > rt.view.last_array_slice_index);
if (rt.view.base_array_slice_index != 0x00000000 ||
rt.view.last_array_slice_index != 0x00000000) {
@@ -257,11 +226,6 @@ static void RtCheck(const HW::RenderTarget& rt) {
logged = true;
}
}
const bool native_2x_one_frag =
rt.info.fmask_compression_enable && !rt.info.fmask_data_compression_disable &&
rt.info.cmask_fast_clear_enable && rt.fmask.addr != 0 && rt.cmask.addr != 0 &&
rt.attrib.num_samples == 1 && rt.attrib.num_fragments == 1;
EXIT_NOT_IMPLEMENTED(rt.info.fmask_one_frag_mode && !native_2x_one_frag);
if (rt.info.fmask_compression_enable) {
EXIT_NOT_IMPLEMENTED(rt.attrib.num_samples == 0 && rt.attrib.num_fragments == 0);
static bool logged = false;
@@ -286,22 +250,6 @@ static void RtCheck(const HW::RenderTarget& rt) {
logged = true;
}
}
if (rt.info.cmask_is_linear != 0x00000000 || rt.info.cmask_addr_type != 0x00000000) {
static bool logged = false;
if (!logged) {
LOGF("RenderTarget: temporary: ignoring PS5 CMASK metadata fields "
"is_linear=%u addr_type=%u\n",
rt.info.cmask_is_linear, rt.info.cmask_addr_type);
logged = true;
}
}
if (rt.info.alt_tile_mode) {
static bool logged = false;
if (!logged) {
LOGF("RenderTarget: temporary: ignoring alternate tile mode flag\n");
logged = true;
}
}
if (rt.info.blend_bypass) {
static bool logged = false;
if (!logged) {
@@ -328,8 +276,6 @@ static void RtCheck(const HW::RenderTarget& rt) {
logged = true;
}
}
// EXIT_NOT_IMPLEMENTED(rt.tile_mode != 0x0000000a);
// EXIT_NOT_IMPLEMENTED(rt.fmask_tile_mode != 0x0000000a);
if (rt.attrib.num_samples != 0x00000000 || rt.attrib.num_fragments != 0x00000000) {
static bool logged = false;
if (!logged) {
@@ -364,34 +310,22 @@ static void RtCheck(const HW::RenderTarget& rt) {
if (!RenderIsColorDimension(rt.attrib3.dimension)) {
EXIT("unknown PS5 render-target dimension: 0x%08" PRIx32 "\n", rt.attrib3.dimension);
}
if (!rt.attrib3.cmask_pipe_aligned) {
if (!rt.attrib3.metadata_pipe_aligned) {
static bool logged = false;
if (!logged) {
LOGF("RenderTarget: temporary: accepting unaligned PS5 CMASK pipe flag\n");
logged = true;
}
}
if (!rt.attrib3.dcc_pipe_aligned) {
static bool logged = false;
if (!logged) {
LOGF("RenderTarget: temporary: accepting unaligned PS5 DCC pipe flag\n");
LOGF("RenderTarget: temporary: accepting unaligned PS5 metadata pipe flag\n");
logged = true;
}
}
EXIT_NOT_IMPLEMENTED(rt.attrib3.write_vrs_rate_hint_to_cmask);
// EXIT_NOT_IMPLEMENTED(rt.dcc_max_uncompressed_block_size != 0x00000002);
// EXIT_NOT_IMPLEMENTED(rt.dcc.max_compressed_block_size != 0x00000000);
EXIT_NOT_IMPLEMENTED(rt.dcc.min_compressed_block_size != 0x00000000);
// EXIT_NOT_IMPLEMENTED(rt.dcc.color_transform != 0x00000000);
EXIT_NOT_IMPLEMENTED(rt.dcc.overwrite_combiner_disable != false);
// EXIT_NOT_IMPLEMENTED(rt.dcc.force_independent_blocks != false);
// EXIT_NOT_IMPLEMENTED(rt.dcc.independent_128b_blocks != false);
// EXIT_NOT_IMPLEMENTED(rt.dcc.data_write_on_dcc_clear_to_reg != false);
EXIT_NOT_IMPLEMENTED(rt.dcc.dcc_clear_key_enable != false);
if (rt.cmask.addr != 0x0000000000000000 || rt.cmask_slice.slice_minus1 != 0x00000000 ||
rt.fmask.addr != 0x0000000000000000 ||
(rt.fmask_slice.slice_minus1 != 0x00000000 &&
rt.fmask_slice.slice_minus1 != rt.slice.slice_div64_minus1) ||
if (rt.cmask.addr != 0x0000000000000000 || rt.fmask.addr != 0x0000000000000000 ||
rt.dcc_addr.addr != 0x0000000000000000) {
static bool logged = false;
if (!logged) {
@@ -401,9 +335,6 @@ static void RtCheck(const HW::RenderTarget& rt) {
logged = true;
}
}
EXIT_NOT_IMPLEMENTED(rt.size.width != 0);
EXIT_NOT_IMPLEMENTED(rt.size.height != 0);
}
}
@@ -423,37 +354,20 @@ static void ZPrint(const char* func, const HW::DepthRenderTarget& z) {
"\t stencil_info.htile_stencil_disabled = %s\n"
"\t stencil_info.expclear_enabled = %s\n"
"\t stencil_info.partially_resident = %s\n"
"\t depth_info.addr5_swizzle_mask = 0x%08" PRIx32 "\n"
"\t depth_info.array_mode = 0x%08" PRIx32 "\n"
"\t depth_info.pipe_config = 0x%08" PRIx32 "\n"
"\t depth_info.bank_width = 0x%08" PRIx32 "\n"
"\t depth_info.bank_height = 0x%08" PRIx32 "\n"
"\t depth_info.macro_tile_aspect = 0x%08" PRIx32 "\n"
"\t depth_info.num_banks = 0x%08" PRIx32 "\n"
"\t depth_view.slice_start = 0x%08" PRIx32 "\n"
"\t depth_view.slice_max = 0x%08" PRIx32 "\n"
"\t depth_view.current_mip_level = 0x%02" PRIx8 "\n"
"\t depth_view.depth_write_disable = %s\n"
"\t depth_view.stencil_write_disable = %s\n"
"\t htile_surface.linear = 0x%08" PRIx32 "\n"
"\t htile_surface.full_cache = 0x%08" PRIx32 "\n"
"\t htile_surface.htile_uses_preload_win = 0x%08" PRIx32 "\n"
"\t htile_surface.preload = 0x%08" PRIx32 "\n"
"\t htile_surface.prefetch_width = 0x%08" PRIx32 "\n"
"\t htile_surface.prefetch_height = 0x%08" PRIx32 "\n"
"\t htile_surface.dst_outside_zero_to_one = 0x%08" PRIx32 "\n"
"\t z_read_base_addr = 0x%016" PRIx64 "\n"
"\t stencil_read_base_addr = 0x%016" PRIx64 "\n"
"\t z_write_base_addr = 0x%016" PRIx64 "\n"
"\t stencil_write_base_addr = 0x%016" PRIx64 "\n"
"\t pitch_div8_minus1 = 0x%08" PRIx32 "\n"
"\t height_div8_minus1 = 0x%08" PRIx32 "\n"
"\t slice_div64_minus1 = 0x%08" PRIx32 "\n"
"\t htile_data_base_addr = 0x%016" PRIx64 "\n"
"\t width = 0x%08" PRIx32 "\n"
"\t height = 0x%08" PRIx32 "\n"
"\t shading_rate_encoding = 0x%02" PRIx8 "\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"
"\t size.valid = %s\n",
static_cast<uint32_t>(z.z_info.format), z.z_info.num_samples,
static_cast<uint32_t>(z.z_info.texture_compatibility),
z.z_info.htile_acceleration ? "true" : "false",
@@ -464,30 +378,27 @@ static void ZPrint(const char* func, const HW::DepthRenderTarget& z) {
static_cast<uint32_t>(z.stencil_info.texture_compatibility),
z.stencil_info.htile_stencil_disabled ? "true" : "false",
z.stencil_info.expclear_enabled ? "true" : "false",
z.stencil_info.partially_resident ? "true" : "false", z.depth_info.addr5_swizzle_mask,
z.depth_info.array_mode, z.depth_info.pipe_config, z.depth_info.bank_width,
z.depth_info.bank_height, z.depth_info.macro_tile_aspect, z.depth_info.num_banks,
z.depth_view.slice_start, z.depth_view.slice_max, z.depth_view.current_mip_level,
z.stencil_info.partially_resident ? "true" : "false", z.depth_view.slice_start,
z.depth_view.slice_max, z.depth_view.current_mip_level,
z.depth_view.depth_write_disable ? "true" : "false",
z.depth_view.stencil_write_disable ? "true" : "false", z.htile_surface.linear,
z.htile_surface.full_cache, z.htile_surface.htile_uses_preload_win,
z.htile_surface.preload, z.htile_surface.prefetch_width, z.htile_surface.prefetch_height,
z.htile_surface.dst_outside_zero_to_one, z.z_read_base_addr, z.stencil_read_base_addr,
z.z_write_base_addr, z.stencil_write_base_addr, z.pitch_div8_minus1, z.height_div8_minus1,
z.slice_div64_minus1, z.htile_data_base_addr, z.width, z.height, z.size.x_max,
z.size.y_max);
z.depth_view.stencil_write_disable ? "true" : "false", z.z_read_base_addr,
z.stencil_read_base_addr, z.z_write_base_addr, z.stencil_write_base_addr,
z.htile_data_base_addr, z.shading_rate_encoding, z.size.x_max, z.size.y_max,
z.size.valid ? "true" : "false");
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
const HW::RenderControl& rc) {
const bool depth_active =
dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable || rc.depth_clear_enable;
const bool stencil_active = dc.stencil_enable || rc.stencil_clear_enable;
const bool depth_active = dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable ||
rc.depth_clear_enable || rc.copy_depth_to_color;
const bool stencil_active =
dc.stencil_enable || rc.stencil_clear_enable || rc.copy_stencil_to_color;
if (!depth_active && !stencil_active) {
return;
}
EXIT_NOT_IMPLEMENTED(rc.copy_depth_to_color || rc.copy_stencil_to_color);
EXIT_NOT_IMPLEMENTED(!z.z_info.HasValidTextureCompatibility());
EXIT_NOT_IMPLEMENTED(!z.stencil_info.HasValidTextureCompatibility());
if (z.z_info.format == Prospero::DepthFormat::kInvalid) {
@@ -524,21 +435,7 @@ static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
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.array_mode != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.depth_info.pipe_config != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.depth_info.bank_width != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.depth_info.bank_height != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.depth_info.macro_tile_aspect != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.depth_info.num_banks != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.htile_surface.linear != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.htile_surface.full_cache != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.htile_surface.htile_uses_preload_win != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.htile_surface.preload != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.htile_surface.prefetch_width != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.htile_surface.prefetch_height != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.htile_surface.dst_outside_zero_to_one != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.shading_rate_encoding != 0);
if (z.depth_view.current_mip_level != 0x00000000) {
static std::atomic<uint32_t> log_count {0};
@@ -560,23 +457,8 @@ static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
EXIT_NOT_IMPLEMENTED(!z.depth_view.stencil_write_disable &&
z.stencil_read_base_addr != z.stencil_write_base_addr);
EXIT_NOT_IMPLEMENTED(!z.depth_view.depth_write_disable && z.z_write_base_addr == 0);
// EXIT_NOT_IMPLEMENTED(z.pitch_div8_minus1 != 0x000000ff);
// EXIT_NOT_IMPLEMENTED(z.height_div8_minus1 != 0x0000008f);
// EXIT_NOT_IMPLEMENTED(z.slice_div64_minus1 != 0x00008fff);
// EXIT_NOT_IMPLEMENTED(z.htile_data_base_addr == 0);
// EXIT_NOT_IMPLEMENTED(z.width != 0x00000780);
// EXIT_NOT_IMPLEMENTED(z.height != 0x00000438);
EXIT_NOT_IMPLEMENTED(z.width != 0);
EXIT_NOT_IMPLEMENTED(z.height != 0);
if (z.size.x_max == 0 || z.size.y_max == 0) {
static std::atomic<uint32_t> log_count {0};
if (log_count.fetch_add(1) < 16) {
LOGF("DepthTarget: temporary: inferring PS5 default depth extent x_max=0x%04" PRIx16
", y_max=0x%04" PRIx16 "\n",
z.size.x_max, z.size.y_max);
}
}
EXIT_NOT_IMPLEMENTED(!z.size.valid);
}
}
@@ -759,8 +641,6 @@ static void DPrint(const char* func, const HW::DepthControl& c, const HW::Stenci
"\t backface_enable = %s\n"
"\t stencilfunc = %" PRIu8 "\n"
"\t stencilfunc_bf = %" PRIu8 "\n"
"\t color_writes_on_depth_fail_enable = %s\n"
"\t color_writes_on_depth_pass_disable = %s\n"
"\t stencil_fail = %" PRIu8 "\n"
"\t stencil_zpass = %" PRIu8 "\n"
"\t stencil_zfail = %" PRIu8 "\n"
@@ -777,12 +657,11 @@ static void DPrint(const char* func, const HW::DepthControl& c, const HW::Stenci
"\t stencil_opval_bf = %" PRIu8 "\n",
c.stencil_enable ? "true" : "false", c.z_enable ? "true" : "false",
c.z_write_enable ? "true" : "false", c.depth_bounds_enable ? "true" : "false", c.zfunc,
c.backface_enable ? "true" : "false", c.stencilfunc, c.stencilfunc_bf,
c.color_writes_on_depth_fail_enable ? "true" : "false",
c.color_writes_on_depth_pass_disable ? "true" : "false", s.stencil_fail, s.stencil_zpass,
s.stencil_zfail, s.stencil_fail_bf, s.stencil_zpass_bf, s.stencil_zfail_bf,
sm.stencil_testval, sm.stencil_mask, sm.stencil_writemask, sm.stencil_opval,
sm.stencil_testval_bf, sm.stencil_mask_bf, sm.stencil_writemask_bf, sm.stencil_opval_bf);
c.backface_enable ? "true" : "false", c.stencilfunc, c.stencilfunc_bf, s.stencil_fail,
s.stencil_zpass, s.stencil_zfail, s.stencil_fail_bf, s.stencil_zpass_bf,
s.stencil_zfail_bf, sm.stencil_testval, sm.stencil_mask, sm.stencil_writemask,
sm.stencil_opval, sm.stencil_testval_bf, sm.stencil_mask_bf, sm.stencil_writemask_bf,
sm.stencil_opval_bf);
}
static void DCheck(const HW::DepthControl& c, const HW::StencilControl& s,
@@ -794,8 +673,6 @@ static void DCheck(const HW::DepthControl& c, const HW::StencilControl& s,
// Back-face stencil state is handled separately when enabled.
// EXIT_NOT_IMPLEMENTED(c.stencilfunc != 0);
// EXIT_NOT_IMPLEMENTED(c.stencilfunc_bf != 0);
EXIT_NOT_IMPLEMENTED(c.color_writes_on_depth_fail_enable != false);
EXIT_NOT_IMPLEMENTED(c.color_writes_on_depth_pass_disable != false);
// EXIT_NOT_IMPLEMENTED(s.stencil_fail != 0);
// EXIT_NOT_IMPLEMENTED(s.stencil_zpass != 0);
// EXIT_NOT_IMPLEMENTED(s.stencil_zfail != 0);
@@ -108,9 +108,10 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
const auto& sc = hw.GetStencilControl();
const auto& sm = hw.GetStencilMask();
const bool has_stencil = z.stencil_info.format != Prospero::StencilFormat::kInvalid;
const bool depth_active =
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 depth_active = dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable ||
rc.depth_clear_enable || rc.copy_depth_to_color;
const bool stencil_active =
has_stencil && (dc.stencil_enable || rc.stencil_clear_enable || rc.copy_stencil_to_color);
if (!depth_active && !stencil_active) {
return;
}
@@ -127,22 +128,14 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
!z.stencil_info.expclear_enabled && !z.stencil_info.partially_resident &&
z.depth_view.slice_start == 0 && z.depth_view.slice_max == 0 &&
z.depth_view.current_mip_level == 0 && !z.depth_view.depth_write_disable &&
!z.depth_view.stencil_write_disable && z.depth_info.addr5_swizzle_mask == 0 &&
z.depth_info.array_mode == 0 && z.depth_info.pipe_config == 0 &&
z.depth_info.bank_width == 0 && z.depth_info.bank_height == 0 &&
z.depth_info.macro_tile_aspect == 0 && z.depth_info.num_banks == 0 &&
z.htile_surface.linear == 0 && z.htile_surface.full_cache == 0 &&
z.htile_surface.htile_uses_preload_win == 0 && z.htile_surface.preload == 0 &&
z.htile_surface.prefetch_width == 0 && z.htile_surface.prefetch_height == 0 &&
z.htile_surface.dst_outside_zero_to_one == 0 && z.z_read_base_addr == 0 &&
z.z_write_base_addr == 0 && z.stencil_read_base_addr == 0 &&
z.stencil_write_base_addr == 0 && z.htile_data_base_addr == 0 &&
!z.depth_view.stencil_write_disable && z.z_read_base_addr == 0 && z.z_write_base_addr == 0 &&
z.stencil_read_base_addr == 0 && z.stencil_write_base_addr == 0 &&
z.htile_data_base_addr == 0 &&
// DB_DEPTH_SIZE_XY is independent state and may remain programmed after the attachment
// formats and addresses are unbound. A zero encoding is the valid 1x1 value, so its
// presence alone must not manufacture a depth attachment.
!z.z_info.htile_acceleration && !z.width_height_valid && !z.pitch_height_valid &&
z.size.x_max == 0 && z.size.y_max == 0 && z.pitch_div8_minus1 == 0 &&
z.height_div8_minus1 == 0 && z.slice_div64_minus1 == 0 && z.width == 0 && z.height == 0;
!z.z_info.htile_acceleration && z.shading_rate_encoding == 0 && z.size.x_max == 0 &&
z.size.y_max == 0;
if (attachment_unbound) {
static std::atomic_bool logged = false;
if (!logged.exchange(true, std::memory_order_relaxed)) {
@@ -165,17 +158,12 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
DepthFatal("invalid depth view: base=%u last=%u", z.depth_view.slice_start,
z.depth_view.slice_max);
}
if (rc.copy_centroid || rc.copy_sample != 0 || z.z_info.expclear_enabled ||
if (rc.copy_depth_to_color || rc.copy_stencil_to_color || rc.copy_centroid ||
rc.copy_sample != 0 || z.z_info.expclear_enabled ||
z.stencil_info.expclear_enabled || z.z_info.partially_resident ||
z.stencil_info.partially_resident || z.z_info.max_mip_level != 0 ||
z.depth_view.current_mip_level != 0 || z.depth_info.addr5_swizzle_mask != 0 ||
z.depth_info.array_mode != 0 || z.depth_info.pipe_config != 0 ||
z.depth_info.bank_width != 0 || z.depth_info.bank_height != 0 ||
z.depth_info.macro_tile_aspect != 0 || z.depth_info.num_banks != 0 ||
z.htile_surface.linear != 0 || z.htile_surface.full_cache != 0 ||
z.htile_surface.htile_uses_preload_win != 0 || z.htile_surface.preload != 0 ||
z.htile_surface.prefetch_width != 0 || z.htile_surface.prefetch_height != 0 ||
z.htile_surface.dst_outside_zero_to_one != 0 || z.z_read_base_addr == 0 ||
z.depth_view.current_mip_level != 0 || z.shading_rate_encoding != 0 ||
z.z_read_base_addr == 0 ||
(!z.depth_view.depth_write_disable && z.z_write_base_addr != z.z_read_base_addr) ||
(z.z_read_base_addr & 0xffffu) != 0 ||
dc.zfunc > static_cast<uint8_t>(vk::CompareOp::eAlways)) {
@@ -189,10 +177,7 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
(z.stencil_read_base_addr & 0xffffu) != 0) {
DepthFatal("unsupported stencil attachment state");
}
} else if (z.stencil_read_base_addr != 0 || z.stencil_write_base_addr != 0 ||
!htile_stencil_compat ||
z.stencil_info.texture_compatibility !=
Prospero::TextureCompatibleStencil::kDisable) {
} else if (z.stencil_read_base_addr != 0 || z.stencil_write_base_addr != 0) {
DepthFatal("stencil state without an active stencil attachment");
}
if (has_htile) {
@@ -203,18 +188,13 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
DepthFatal("HTile clear tracking supports at most 32 slices");
}
}
const bool size_xy_valid = z.size.valid;
const bool wh_valid = z.width_height_valid && z.width != 0 && z.height != 0;
if (!size_xy_valid && !wh_valid) {
if (!z.size.valid) {
DepthFatal("missing depth extent");
}
const uint32_t width = size_xy_valid ? static_cast<uint32_t>(z.size.x_max) + 1u : z.width;
const uint32_t height = size_xy_valid ? static_cast<uint32_t>(z.size.y_max) + 1u : z.height;
if (width > 16384 || height > 16384 ||
(size_xy_valid && wh_valid && (width != z.width || height != z.height)) ||
(!z.pitch_height_valid &&
(z.pitch_div8_minus1 != 0 || z.height_div8_minus1 != 0 || z.slice_div64_minus1 != 0))) {
DepthFatal("inconsistent depth extent or encoded layout");
const uint32_t width = static_cast<uint32_t>(z.size.x_max) + 1u;
const uint32_t height = static_cast<uint32_t>(z.size.y_max) + 1u;
if (width > 16384 || height > 16384) {
DepthFatal("invalid depth extent");
}
const auto* policy = FindDepthFormatPolicy(z.z_info.format);
if (policy == nullptr) {
@@ -229,11 +209,6 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
const auto guest_format = policy->guest_format;
const uint32_t bytes = policy->bytes_per_element;
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 ||
(static_cast<uint64_t>(z.height_div8_minus1) + 1u) * 8u !=
((static_cast<uint64_t>(height) + 7u) & ~7ull))) {
DepthFatal("encoded depth pitch or height mismatch");
}
TileSizeAlign depth_size {};
TileSizeAlign stencil_size {};
TileSizeAlign htile_size {};
@@ -244,14 +219,6 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
(has_htile != (htile_size.align == 32768 && htile_size.size != 0))) {
DepthFatal("unsupported depth/stencil/HTile footprint");
}
if (z.pitch_height_valid &&
(static_cast<uint64_t>(z.slice_div64_minus1) + 1u) * 64u != depth_size.size) {
DepthFatal("depth footprint mismatch: extent=%ux%u pitch=%u expected=0x%016" PRIx64
" align=0x%016" PRIx64 " encoded_valid=%u encoded=0x%016" PRIx64,
width, height, pitch, depth_size.size, depth_size.align,
z.pitch_height_valid ? 1u : 0u,
(static_cast<uint64_t>(z.slice_div64_minus1) + 1u) * 64u);
}
if (depth_size.size > UINT64_MAX / view.image_layers ||
stencil_size.size > UINT64_MAX / view.image_layers ||
htile_size.size > UINT64_MAX / view.image_layers) {
@@ -260,9 +227,9 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
const auto depth_backing_size = depth_size.size * view.image_layers;
const auto stencil_backing_size = stencil_size.size * view.image_layers;
const auto htile_backing_size = htile_size.size * view.image_layers;
if (depth_backing_size > TRACKER_ADDRESS_SIZE - z.z_read_base_addr ||
(has_stencil && stencil_backing_size > TRACKER_ADDRESS_SIZE - z.stencil_read_base_addr) ||
(has_htile && htile_backing_size > TRACKER_ADDRESS_SIZE - z.htile_data_base_addr)) {
if (!GuestRange {z.z_read_base_addr, depth_backing_size}.Valid() ||
(has_stencil && !GuestRange {z.stencil_read_base_addr, stencil_backing_size}.Valid()) ||
(has_htile && !GuestRange {z.htile_data_base_addr, htile_backing_size}.Valid())) {
DepthFatal("layered depth backing range is invalid");
}
r.htile = has_htile;
@@ -11,9 +11,11 @@
namespace Libs::Graphics {
// Without a stencil plane, Hi-Stencil fields are inactive. An active plane is compatible when
// Hi-Stencil is disabled or HTile backing is present.
inline constexpr bool depth_htile_stencil_acceleration_compatible(bool has_stencil, bool has_htile,
bool htile_stencil_disabled) {
return htile_stencil_disabled || (has_stencil && has_htile);
return !has_stencil || htile_stencil_disabled || has_htile;
}
struct RenderDepthInfo {
+8 -12
View File
@@ -73,10 +73,8 @@ namespace {
return usage;
}
void ValidateRange(GuestRange range, const char* name) {
if ((range.address == 0) != (range.size == 0) ||
(range.address != 0 && (range.address >= TRACKER_ADDRESS_SIZE ||
range.size > TRACKER_ADDRESS_SIZE - range.address))) {
void ValidateOptionalRange(GuestRange range, const char* name) {
if (!range.ValidOrEmpty()) {
EXIT("invalid %s image range: address=0x%016llx size=0x%016llx\n", name,
static_cast<unsigned long long>(range.address),
static_cast<unsigned long long>(range.size));
@@ -567,13 +565,13 @@ void Image::CopyMip(Image& source, uint32_t mip, uint32_t layer) {
namespace ImageOps {
void Validate(const ImageInfo& info) {
ValidateRange(info.data, "data");
ValidateRange(info.stencil, "stencil");
ValidateOptionalRange(info.data, "data");
ValidateOptionalRange(info.stencil, "stencil");
if (info.pixel_format == vk::Format::eUndefined) {
const bool metadata_empty =
info.metadata.range.address == 0 && info.metadata.range.size == 0 &&
info.metadata.kind == ImageMetadataKind::None && info.metadata.control == 0 &&
info.metadata.range.Empty() && info.metadata.kind == ImageMetadataKind::None &&
info.metadata.control == 0 &&
info.metadata.compression == VideoOutCompression::Uncompressed &&
!info.metadata.stencil_compressed;
if (info.data.Empty() || info.HasStencil() || !metadata_empty || info.extent.width == 0 ||
@@ -620,16 +618,14 @@ void Validate(const ImageInfo& info) {
}
switch (info.metadata.kind) {
case ImageMetadataKind::None:
if (info.metadata.range.address != 0 || info.metadata.range.size != 0 ||
info.metadata.control != 0 ||
if (!info.metadata.range.Empty() || info.metadata.control != 0 ||
info.metadata.compression != VideoOutCompression::Uncompressed ||
info.metadata.stencil_compressed) {
EXIT("metadata-free image has metadata state\n");
}
break;
case ImageMetadataKind::Htile:
ValidateRange(info.metadata.range, "HTILE");
if (info.metadata.range.Empty() ||
if (!info.metadata.range.Valid() ||
info.metadata.compression != VideoOutCompression::Uncompressed) {
EXIT("invalid HTILE metadata\n");
}
@@ -15,18 +15,6 @@
namespace Libs::Graphics {
struct GuestRange {
uint64_t address = 0;
uint64_t size = 0;
[[nodiscard]] constexpr bool Empty() const noexcept { return address == 0 || size == 0; }
[[nodiscard]] constexpr bool Valid() const noexcept {
return !Empty() && address < TRACKER_ADDRESS_SIZE && size <= TRACKER_ADDRESS_SIZE - address;
}
[[nodiscard]] constexpr uint64_t End() const noexcept { return address + size; }
auto operator<=>(const GuestRange&) const = default;
};
enum class VideoOutCompression : uint8_t { Uncompressed, Dcc256_256_0, Dcc256_64_64, Unsupported };
enum class ImageMetadataKind : uint8_t { None, Htile, Dcc };
@@ -443,6 +431,10 @@ IsSupportedDisplayRenderTargetTileMode(Prospero::TileMode tile_mode) noexcept {
return encoded <= 0.04045f ? encoded / 12.92f : std::pow((encoded + 0.055f) / 1.055f, 2.4f);
};
switch (format) {
// A single-plane float target carries its clear as raw float bits, the same encoding the
// depth decoder below uses. Without this the clear is discarded and the target keeps stale
// contents.
case vk::Format::eR32Sfloat: next.float32[0] = std::bit_cast<float>(packed); break;
case vk::Format::eR32Uint: next.uint32[0] = packed; break;
case vk::Format::eR32Sint: next.int32[0] = static_cast<int32_t>(packed); break;
case vk::Format::eR8G8B8A8Srgb:
@@ -411,7 +411,7 @@ static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuf
static bool DrawHasValidVertexShader(const HW::Shader& sh_ctx) {
const auto& vs = sh_ctx.GetVs();
return vs.gs_regs.chksum != 0 && ShaderAddressValid(vs.es_regs.data_addr);
return ShaderAddressValid(vs.es_regs.data_addr);
}
static bool PixelShaderHasDepthOrCoverageSideEffects(const HW::ShaderRegisters& sh_regs) {
@@ -443,7 +443,6 @@ static bool ShouldSkipGeShader(const CommandBuffer& buffer) {
};
const bool ps5_ngg_vertex_path = stages == 0x02002000 && vertex_info.es_regs.data_addr != 0 &&
vertex_info.gs_regs.chksum != 0 &&
sh_regs.m_vgtGsMaxVertOut == 0x00000000 &&
is_known_gs_out_prim_type(sh_regs.m_vgtGsOutPrimType);
@@ -1450,7 +1449,7 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_
if (graphics_debug_dump_enabled()) {
LOGF("DrawIndexAuto: skipping rect-list draw with no VS param exports and PS inputs: "
"ps_inputs=%u ps=0x%016" PRIx64 " es=0x%016" PRIx64 " gs=0x%016" PRIx64 "\n",
state.ps_input_info.input_num, sh_ctx.GetPs().ps_regs.chksum,
state.ps_input_info.input_num, sh_ctx.GetPs().ps_regs.data_addr,
sh_ctx.GetVs().es_regs.data_addr, sh_ctx.GetVs().gs_regs.data_addr);
}
ResetBindings();
+22 -10
View File
@@ -29,6 +29,7 @@ struct ControlInfo {
uint32_t button = 0;
Controller::Axis axis = Controller::Axis::AxisMax;
bool positive = false;
float touch_x = 0.0f;
};
static constexpr std::array CONTROL_INFO = {
@@ -47,7 +48,10 @@ static constexpr std::array CONTROL_INFO = {
ControlInfo {"Circle", Controller::PAD_BUTTON_CIRCLE},
ControlInfo {"Cross", Controller::PAD_BUTTON_CROSS},
ControlInfo {"Square", Controller::PAD_BUTTON_SQUARE},
ControlInfo {"TouchPad", Controller::PAD_BUTTON_TOUCH_PAD},
ControlInfo {"TouchPad", Controller::PAD_BUTTON_TOUCH_PAD, Controller::Axis::AxisMax, false,
0.25f},
ControlInfo {"TouchPadRight", Controller::PAD_BUTTON_TOUCH_PAD, Controller::Axis::AxisMax,
false, 0.75f},
ControlInfo {"LeftStickLeft", 0, Controller::Axis::LeftX, false},
ControlInfo {"LeftStickRight", 0, Controller::Axis::LeftX, true},
ControlInfo {"LeftStickUp", 0, Controller::Axis::LeftY, false},
@@ -83,11 +87,6 @@ std::size_t ControlFromName(std::string_view name) {
return static_cast<std::size_t>(std::distance(CONTROL_INFO.begin(), info));
}
const ControlInfo& Info(std::size_t control) {
EXIT_IF(control >= CONTROL_INFO.size());
return CONTROL_INFO[control];
}
SDL_Keycode NormalizeKey(SDL_Keycode key) {
switch (key) {
case SDLK_RSHIFT: return SDLK_LSHIFT;
@@ -205,6 +204,10 @@ void SetButton(uint32_t button, bool down) {
}
}
void SetTouchPad(float x, bool down) {
Controller::ControllerTouchPad(Controller::HOST_INPUT_CONTROLLER_ID, 0, down, x, 0.5f);
}
uint32_t DefaultKeyboardButton(int key_code) {
switch (NormalizeKey(static_cast<SDL_Keycode>(key_code))) {
case SDLK_UP: return Controller::PAD_BUTTON_UP;
@@ -221,8 +224,6 @@ uint32_t DefaultKeyboardButton(int key_code) {
case SDLK_LCTRL: return Controller::PAD_BUTTON_R3;
case SDLK_RETURN:
case SDLK_RETURN2: return Controller::PAD_BUTTON_OPTIONS;
case SDLK_BACKSPACE:
case SDLK_TAB: return Controller::PAD_BUTTON_TOUCH_PAD;
default: return 0;
}
}
@@ -235,7 +236,12 @@ struct StickKeys {
};
void SetStickAxis(Controller::Axis axis, bool negative, bool positive) {
const int value = negative == positive ? 128 : negative ? 0 : 255;
int value = 128;
if (negative && !positive) {
value = 0;
} else if (positive && !negative) {
value = 255;
}
Controller::ControllerAxis(Controller::HOST_INPUT_CONTROLLER_ID, axis, value);
}
@@ -244,7 +250,11 @@ void SetControl(std::size_t control, bool down) {
return;
}
const auto& info = Info(control);
const auto& info = CONTROL_INFO[control];
if (info.button == Controller::PAD_BUTTON_TOUCH_PAD) {
SetTouchPad(info.touch_x, down);
return;
}
if (info.button != 0) {
SetButton(info.button, down);
return;
@@ -271,6 +281,8 @@ void DefaultKeyboardInput(int key_code, bool down) {
static StickKeys right;
switch (NormalizeKey(static_cast<SDL_Keycode>(key_code))) {
case SDLK_BACKSPACE: SetTouchPad(0.25f, down); return;
case SDLK_TAB: SetTouchPad(0.75f, down); return;
case SDLK_a:
left.left = down;
SetStickAxis(Controller::Axis::LeftX, left.left, left.right);
+11 -1
View File
@@ -76,7 +76,6 @@ static uint32_t ControllerButtonToPadButton(int button) {
case SDL_CONTROLLER_BUTTON_B: return Controller::PAD_BUTTON_CIRCLE;
case SDL_CONTROLLER_BUTTON_X: return Controller::PAD_BUTTON_SQUARE;
case SDL_CONTROLLER_BUTTON_Y: return Controller::PAD_BUTTON_TRIANGLE;
case SDL_CONTROLLER_BUTTON_BACK: return Controller::PAD_BUTTON_TOUCH_PAD;
case SDL_CONTROLLER_BUTTON_START: return Controller::PAD_BUTTON_OPTIONS;
case SDL_CONTROLLER_BUTTON_LEFTSTICK: return Controller::PAD_BUTTON_L3;
case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return Controller::PAD_BUTTON_R3;
@@ -86,6 +85,7 @@ static uint32_t ControllerButtonToPadButton(int button) {
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return Controller::PAD_BUTTON_DOWN;
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return Controller::PAD_BUTTON_LEFT;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return Controller::PAD_BUTTON_RIGHT;
case SDL_CONTROLLER_BUTTON_TOUCHPAD: return Controller::PAD_BUTTON_TOUCH_PAD;
default: return 0;
}
}
@@ -705,6 +705,16 @@ void WindowContext::ProcessEvent(double time_s) {
break;
}
case SDL_CONTROLLERTOUCHPADDOWN:
case SDL_CONTROLLERTOUCHPADMOTION:
case SDL_CONTROLLERTOUCHPADUP:
if (event->ctouchpad.touchpad == 0) {
Controller::ControllerTouchPad(event->ctouchpad.which, event->ctouchpad.finger,
event->ctouchpad.type != SDL_CONTROLLERTOUCHPADUP,
event->ctouchpad.x, event->ctouchpad.y);
}
break;
case SDL_CONTROLLERDEVICEADDED:
case SDL_CONTROLLERDEVICEREMOVED:
case SDL_CONTROLLERDEVICEREMAPPED: {
@@ -30,14 +30,6 @@ namespace Libs::Graphics::ShaderRecompiler {
namespace {
bool ReadZeroMemory(void*, uint64_t, uint32_t* value) {
if (value == nullptr) {
return false;
}
*value = 0;
return true;
}
const char* GetDumpLabel(const CompileOptions& options) {
return options.dump_label != nullptr ? options.dump_label : "ShaderRecompiler";
}
@@ -554,28 +546,20 @@ CompileResult Recompile(std::span<const uint32_t> code, const CompileOptions& op
switch (options.stage) {
case ShaderType::Vertex:
vertex = options.input_info.vertex;
if (vertex == nullptr) {
EXIT("vertex shader recompilation has no input metadata\n");
}
break;
case ShaderType::Pixel:
pixel = options.input_info.pixel;
if (pixel == nullptr) {
EXIT("pixel shader recompilation has no input metadata\n");
}
break;
case ShaderType::Compute:
compute = options.input_info.compute;
if (compute == nullptr) {
EXIT("compute shader recompilation has no input metadata\n");
}
break;
default: break;
}
EmbeddedFetchData embedded_fetch;
if (options.stage == ShaderType::Vertex && vertex->fetch_embedded) {
embedded_fetch = DetectEmbeddedVertexFetch(decoded, vertex, options.user_data_base,
options.user_data_count, options.wave_size);
static_cast<uint32_t>(options.user_data.size()),
options.wave_size);
if (!embedded_fetch.loads.empty()) {
LOGF("%s embedded vertex fetch plan: detected=%" PRIu64 "\n", GetDumpLabel(options),
static_cast<uint64_t>(embedded_fetch.loads.size()));
@@ -586,7 +570,7 @@ CompileResult Recompile(std::span<const uint32_t> code, const CompileOptions& op
.wave_size = options.wave_size,
.shader_hash = options.shader_hash,
.user_data_base = options.user_data_base,
.user_data_count = options.user_data_count,
.user_data_count = static_cast<uint32_t>(options.user_data.size()),
.scratch_dwords = options.scratch_dwords,
.dispatcher_fallback = dispatcher_fallback,
.cfg_failure_kind = cfg.failure_kind,
@@ -634,32 +618,17 @@ CompileResult Recompile(std::span<const uint32_t> code, const CompileOptions& op
ir.info.vertex_offset_sgpr = embedded_fetch.vertex_offset_sgpr;
}
const IR::SrtRuntime runtime {
.user_data = options.user_data,
.shader_base = reinterpret_cast<uint64_t>(code.data()),
.read_memory = options.read_memory,
.userdata = options.read_memory_data,
.read_specialization_memory = options.read_specialization_memory,
};
IR::ResourceSnapshot resources;
if (options.resource_snapshot != nullptr) {
resources = *options.resource_snapshot;
} else {
IR::SrtRuntime runtime;
std::array<uint32_t, 64> zero_user_data {};
if (options.user_data == nullptr) {
for (uint32_t i = 2; i < zero_user_data.size(); i += 4) {
zero_user_data[i] = UINT32_MAX;
}
}
const auto* user_data =
options.user_data != nullptr ? options.user_data : zero_user_data.data();
runtime.user_data = std::span<const uint32_t>(user_data, options.user_data_count);
runtime.shader_base = options.shader_base != 0 ? options.shader_base
: reinterpret_cast<uint64_t>(code.data());
runtime.read_memory = options.read_memory;
runtime.read_specialization_memory = options.read_specialization_memory;
if (runtime.read_memory == nullptr && options.user_data == nullptr) {
runtime.read_memory = ReadZeroMemory;
}
runtime.userdata = options.read_memory_data;
if (!IR::MaterializeResources(ir, runtime, resources)) {
EXIT("shader resource materialization failed: stage=%s hash=0x%016" PRIx64 "\n",
StageName(options.stage), options.shader_hash);
}
if (!IR::MaterializeResources(ir, runtime, resources)) {
EXIT("shader resource materialization failed: stage=%s hash=0x%016" PRIx64 "\n",
StageName(options.stage), options.shader_hash);
}
IR::SpecializeResources(ir, resources);
@@ -15,19 +15,16 @@ struct CompileOptions {
ShaderType stage = ShaderType::Compute;
uint32_t wave_size = 64;
uint32_t user_data_base = 0;
uint32_t user_data_count = 64;
uint32_t scratch_dwords = 0;
uint64_t shader_hash = 0;
uint64_t shader_base = 0;
uint32_t push_constant_offset = 0;
bool dump_ir = true;
bool early_dump = false;
const char* dump_label = nullptr;
const uint32_t* user_data = nullptr;
std::span<const uint32_t> user_data;
IR::SrtMemoryReader read_memory = nullptr;
IR::SrtMemoryReader read_specialization_memory = nullptr;
void* read_memory_data = nullptr;
const IR::ResourceSnapshot* resource_snapshot = nullptr;
ShaderStageInputInfo input_info;
};
@@ -45,6 +45,7 @@ constexpr OpcodeMap SOP1_OPCODE_LIST[] = {
{0x10u, Opcode::S_BCNT1_I32_B64},
{0x13u, Opcode::S_FF1_I32_B32},
{0x14u, Opcode::S_FF1_I32_B64},
{0x15u, Opcode::S_FLBIT_I32_B32},
{0x16u, Opcode::S_FLBIT_I32_B64},
{0x1bu, Opcode::S_BITSET0_B32},
{0x1du, Opcode::S_BITSET1_B32},
@@ -476,6 +476,7 @@ std::string InstructionToString(const Instruction& inst) {
case Opcode::S_ABS_I32:
case Opcode::S_BREV_B32:
case Opcode::S_BCNT1_I32_B32:
case Opcode::S_FLBIT_I32_B32:
case Opcode::S_FF1_I32_B32:
case Opcode::S_FF1_I32_B64:
case Opcode::S_NOT_B64:
@@ -45,6 +45,7 @@ enum class Opcode {
S_BCNT1_I32_B64,
S_FF1_I32_B32,
S_FF1_I32_B64,
S_FLBIT_I32_B32,
S_FLBIT_I32_B64,
S_BITREPLICATE_B64_B32,
S_QUADMASK_B64,
@@ -395,6 +396,7 @@ enum class Opcode {
V_CMP_GE_U32,
V_CMP_T_U32,
V_CMP_EQ_I64,
V_CMP_LT_U64,
V_CMP_EQ_U64,
V_CMP_GT_U64,
V_CMP_NE_U64,
@@ -240,8 +240,9 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = {
{0xb5u, Opcode::V_CMPX_NE_I64, false}, {0xd1u, Opcode::V_CMPX_LT_U32},
{0xd2u, Opcode::V_CMPX_EQ_U32}, {0xd3u, Opcode::V_CMPX_LE_U32},
{0xd4u, Opcode::V_CMPX_GT_U32}, {0xd5u, Opcode::V_CMPX_NE_U32},
{0xd6u, Opcode::V_CMPX_GE_U32}, {0xe2u, Opcode::V_CMP_EQ_U64, false},
{0xe4u, Opcode::V_CMP_GT_U64, false}, {0xe5u, Opcode::V_CMP_NE_U64, false},
{0xd6u, Opcode::V_CMPX_GE_U32}, {0xe1u, Opcode::V_CMP_LT_U64, false},
{0xe2u, Opcode::V_CMP_EQ_U64, false}, {0xe4u, Opcode::V_CMP_GT_U64, false},
{0xe5u, Opcode::V_CMP_NE_U64, false},
{0xf5u, Opcode::V_CMPX_NE_U64, false}, {0xc9u, Opcode::V_CMP_LT_F16},
{0xcau, Opcode::V_CMP_EQ_F16}, {0xcbu, Opcode::V_CMP_LE_F16},
{0xccu, Opcode::V_CMP_GT_F16}, {0xcdu, Opcode::V_CMP_LG_F16},
@@ -938,7 +939,7 @@ constexpr Vop2SdwaRule VOP2_SDWA_RULES[] = {
{SdwaSelAll(), SdwaSelAll(), SdwaSelAll(), true, true},
{SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), false, false},
{SdwaSelAll(), SdwaSelAll(), SdwaSelAll(), true, false},
{SdwaSelFull(), SdwaSelAll(), SdwaSelWords() | SdwaSelFull(), false, false},
{SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), false, false},
{SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), false, false},
{SdwaSelWords() | SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), true, false},
};
@@ -181,6 +181,7 @@ bool Translator::EmitScalar(const Decoder::Instruction& inst) {
case O::S_XNOR_B32:
return ComposedIntegerBinary(inst, IR::ValueOpcode::BitwiseXor32, false, true, true);
case O::S_FF1_I32_B64: return S_FF1_I32_B64(inst);
case O::S_FLBIT_I32_B32: return V_FFBH_32(inst, false);
case O::S_FLBIT_I32_B64: return S_FLBIT_I32_B64(inst);
case O::S_BITSET0_B32: return S_BITSET_B32(inst, false);
@@ -99,6 +99,9 @@ bool Translator::EmitVector(const Decoder::Instruction& inst) {
case O::V_CMP_EQ_U64:
EmitIntegerCompare(inst, IR::ValueOpcode::IEqual64, IR::Type::U64, false, false);
return true;
case O::V_CMP_LT_U64:
EmitIntegerCompare(inst, IR::ValueOpcode::ULessThan64, IR::Type::U64, false, false);
return true;
case O::V_CMP_GT_U64:
EmitIntegerCompare(inst, IR::ValueOpcode::UGreaterThan64, IR::Type::U64, false, false);
return true;
@@ -61,7 +61,8 @@ bool NullImageDescriptor(const DescriptorValue& descriptor) {
bool ValidImageDescriptor(const DescriptorValue& descriptor, bool r128 = false) {
const auto type = static_cast<Prospero::ImageType>((descriptor.dwords[3] >> 28u) & 0xfu);
const auto format = static_cast<Prospero::BufferFormat>((descriptor.dwords[1] >> 20u) & 0x1ffu);
if (type < Prospero::ImageType::kColor1D || format == Prospero::BufferFormat::kInvalid) {
if (type < Prospero::ImageType::kColor1D || format == Prospero::BufferFormat::kInvalid ||
format > Prospero::BufferFormat::kBc7Srgb) {
return false;
}
if (r128 && type != Prospero::ImageType::kColor1D && type != Prospero::ImageType::kColor2D &&
@@ -139,7 +139,8 @@ public:
}
std::erase_if(m_program.dynamic_reads, [&](Value value) {
const auto* inst = value.Resolve().TryInstruction();
return std::ranges::any_of(m_indirect_images, [&](const IndirectImagePlan& plan) {
return std::any_of(m_indirect_images.begin(), m_indirect_images.end(),
[&](const IndirectImagePlan& plan) {
return std::ranges::find(plan.reads, inst) != plan.reads.end();
});
});
@@ -432,14 +433,16 @@ private:
const IndirectImagePlan* FindIndirectImage(const Inst& handle) const {
const auto found =
std::ranges::find_if(m_indirect_images, [&](const IndirectImagePlan& plan) {
std::find_if(m_indirect_images.begin(), m_indirect_images.end(),
[&](const IndirectImagePlan& plan) {
return plan.handle == &handle;
});
return found == m_indirect_images.end() ? nullptr : &*found;
}
bool IsIndirectPlanningMemory(uint32_t index) const {
return std::ranges::any_of(m_indirect_images, [&](const IndirectImagePlan& plan) {
return std::any_of(m_indirect_images.begin(), m_indirect_images.end(),
[&](const IndirectImagePlan& plan) {
return std::ranges::find(plan.memory, index) != plan.memory.end();
});
}
+16 -16
View File
@@ -173,6 +173,11 @@ static const ShaderBinaryInfo* GetBinaryInfo(const uint32_t* code) {
return nullptr;
}
static uint64_t GetDeclaredShaderHash(uint64_t shader_addr) {
const auto* header = GetBinaryInfo(reinterpret_cast<const uint32_t*>(shader_addr));
return header != nullptr ? (static_cast<uint64_t>(header->hash1) << 32u) | header->hash0 : 0;
}
static ShaderParams GetShaderParams(uint64_t shader_addr, const char* label, uint64_t declared_hash,
std::span<const uint32_t> user_data,
const ShaderMappedData& data) {
@@ -210,7 +215,6 @@ static void vs_check(const HW::VertexShaderInfo& vs, const HW::ShaderRegisters&
};
const bool ps5_ngg_passthrough_triangle_path =
vs.es_regs.data_addr != 0 && vs.gs_regs.data_addr == vs.es_regs.data_addr &&
vs.gs_regs.chksum != 0 &&
sh.m_geNggSubgrpCntl == 0x00000001 && sh.m_vgtGsMaxVertOut == 0x00000003 &&
sh.m_vgtGsOutPrimType == 0x00000002 && sh.m_geMaxOutputPerSubgroup <= 0x000000c0;
@@ -275,7 +279,6 @@ static void ps_check(const HW::PsStageRegisters& ps, const HW::ShaderRegisters&
// EXIT_NOT_IMPLEMENTED(ps.m_spiShaderPgmRsrc1Ps != 0x002c0000);
// EXIT_NOT_IMPLEMENTED(ps.m_spiShaderPgmRsrc2Ps != 0x00000000);
// EXIT_NOT_IMPLEMENTED(ps.vgprs != 0x00 && ps.vgprs != 0x01);
// EXIT_NOT_IMPLEMENTED(ps.sgprs != 0x00 && ps.sgprs != 0x01);
EXIT_NOT_IMPLEMENTED(ps.rsrc1.priority != 0);
EXIT_NOT_IMPLEMENTED(ps.rsrc1.float_mode != 192);
EXIT_NOT_IMPLEMENTED(ps.rsrc1.dx10_clamp != true);
@@ -365,8 +368,10 @@ static void cs_check(const HW::CsStageRegisters& cs, const HW::ShaderRegisters&
// EXIT_NOT_IMPLEMENTED(cs.num_thread_y != 0x00000001);
// EXIT_NOT_IMPLEMENTED(cs.num_thread_z != 0x00000001);
// EXIT_NOT_IMPLEMENTED(cs.vgprs != 0x00 && cs.vgprs != 0x01);
// EXIT_NOT_IMPLEMENTED(cs.sgprs != 0x01 && cs.sgprs != 0x02);
EXIT_NOT_IMPLEMENTED(cs.bulky != 0x00);
EXIT_NOT_IMPLEMENTED(cs.priority != 0x00);
EXIT_NOT_IMPLEMENTED(cs.debug_mode != false);
EXIT_NOT_IMPLEMENTED(cs.require_forward_progress != false);
EXIT_NOT_IMPLEMENTED(cs.shared_vgprs != 0x00);
EXIT_NOT_IMPLEMENTED(cs.scratch_en != 0x00);
// EXIT_NOT_IMPLEMENTED(cs.user_sgpr != 0x0c);
if (cs.tgid_x_en == 0x00) {
@@ -689,7 +694,7 @@ static bool ShaderGetStaticInputInfoVS(const HW::VertexShaderInfo& regs,
info.export_count = static_cast<int>(sh.GetExportCount());
info.pa_cl_vs_out_cntl = sh.m_paClVsOutCntl;
EXIT_NOT_IMPLEMENTED(regs.es_regs.data_addr == 0 || regs.gs_regs.chksum == 0);
EXIT_NOT_IMPLEMENTED(regs.es_regs.data_addr == 0);
uint64_t shader_addr = regs.es_regs.data_addr;
const HW::UserSgprInfo& user_sgpr = regs.gs_user_sgpr;
@@ -698,8 +703,8 @@ static bool ShaderGetStaticInputInfoVS(const HW::VertexShaderInfo& regs,
if (data.user_data == nullptr) {
LOGF("ShaderGetInputInfoVS(): no AGC user data for shader=0x%016" PRIx64 " es=0x%016" PRIx64
" gs=0x%016" PRIx64 " chksum=0x%016" PRIx64 " user_sgpr_num=%u\n",
shader_addr, regs.es_regs.data_addr, regs.gs_regs.data_addr, regs.gs_regs.chksum,
" gs=0x%016" PRIx64 " user_sgpr_num=%u\n",
shader_addr, regs.es_regs.data_addr, regs.gs_regs.data_addr,
static_cast<uint32_t>(user_sgpr_num));
}
ShaderVertexMetadata metadata;
@@ -979,7 +984,7 @@ ShaderParams PrepareProgram(const HW::VertexShaderInfo& regs, const HW::ShaderRe
EXIT("failed to prepare vertex shader program\n");
}
return GetShaderParams(
regs.es_regs.data_addr, "ShaderRecompiler VS", regs.gs_regs.chksum,
regs.es_regs.data_addr, "ShaderRecompiler VS", GetDeclaredShaderHash(regs.es_regs.data_addr),
std::span<const uint32_t>(regs.gs_user_sgpr.value, regs.gs_regs.rsrc2.user_sgpr), data);
}
@@ -991,7 +996,7 @@ ShaderParams PrepareProgram(
const auto data = ShaderGetMappedData(regs.ps_regs.data_addr, "ShaderGetInputInfoPS():");
ShaderGetStaticInputInfoPS(regs, sh, vs_info, target_export_mapping, data, ps_info);
return GetShaderParams(
regs.ps_regs.data_addr, "ShaderRecompiler PS", regs.ps_regs.chksum,
regs.ps_regs.data_addr, "ShaderRecompiler PS", GetDeclaredShaderHash(regs.ps_regs.data_addr),
std::span<const uint32_t>(regs.ps_user_sgpr.value, regs.ps_regs.rsrc2.user_sgpr), data);
}
@@ -999,11 +1004,8 @@ ShaderParams PrepareProgram(const HW::ComputeShaderInfo& regs, const HW::ShaderR
ShaderComputeInputInfo& info) {
const auto data = ShaderGetMappedData(regs.cs_regs.data_addr, "ShaderGetInputInfoCS():");
ShaderGetStaticInputInfoCS(regs, sh, data, info);
const auto* header = GetBinaryInfo(reinterpret_cast<const uint32_t*>(regs.cs_regs.data_addr));
const auto declared_hash =
header != nullptr ? (static_cast<uint64_t>(header->hash1) << 32u) | header->hash0 : 0;
return GetShaderParams(
regs.cs_regs.data_addr, "ShaderRecompiler CS", declared_hash,
regs.cs_regs.data_addr, "ShaderRecompiler CS", GetDeclaredShaderHash(regs.cs_regs.data_addr),
std::span<const uint32_t>(regs.cs_user_sgpr.value, regs.cs_regs.user_sgpr), data);
}
@@ -1234,9 +1236,7 @@ static ShaderRecompiler::CompileOptions MakeCompileOptions(const ShaderParams& p
ShaderRecompiler::CompileOptions options;
options.stage = stage;
options.shader_hash = params.hash;
options.shader_base = params.Base();
options.user_data_count = static_cast<uint32_t>(params.user_data.size());
options.user_data = params.user_data.data();
options.user_data = params.user_data;
options.read_specialization_memory = ReadShaderGuestMemory;
options.dump_ir = ShaderRecompilerTextDumpEnabled();
options.early_dump = options.dump_ir;
+2 -1
View File
@@ -51,7 +51,8 @@ constexpr PadControl PAD_CONTROLS[] = {
{"L3", "L3", "Left Shift"},
{"R3", "R3", "Left Ctrl"},
{"Options", "Options", "Return"},
{"TouchPad", "Touch pad", "Backspace"},
{"TouchPad", "Touch pad left (SELECT)", "Backspace"},
{"TouchPadRight", "Touch pad right (START)", "Tab"},
};
QString KeypadName(int key) {
+7 -22
View File
@@ -145,7 +145,6 @@ struct RegisterDefaultsStorage {
static constexpr uint32_t GRAPHICS_REGISTER_DEFAULTS_MAX_VERSION = 13;
static constexpr uint32_t GRAPHICS_REGISTER_DEFAULTS_FALLBACK_VERSION = 13;
static constexpr uint32_t GRAPHICS_INIT_NO_FEATURE_STATE = 0;
static std::mutex g_register_defaults_mutex;
@@ -336,20 +335,12 @@ int KYTY_SYSV_ABI AgcInit(uint32_t* state, uint32_t ver) {
"\t ver = %u\n",
reinterpret_cast<uint64_t>(state), ver);
if (state == nullptr) {
LOGF_COLOR(Log::Color::Red, "\t state is null\n");
return OK;
}
if (ver > GRAPHICS_REGISTER_DEFAULTS_MAX_VERSION) {
LOGF_COLOR(Log::Color::Red, "\t unsupported version %u\n", ver);
}
printf("version = %u\n", ver);
state[0] = ver;
state[1] = GRAPHICS_INIT_NO_FEATURE_STATE;
return OK;
}
@@ -903,8 +894,12 @@ static bool is_native_reg_indirect_packet(const uint32_t* cmd, RegIndirectPacket
return ((cmd[0] >> 8u) & 0xffu) == reg_indirect_native_op(type);
}
static constexpr bool is_trinity_mode() {
return false;
}
static uint32_t reg_indirect_pm4_r(RegIndirectPacket type) {
return (type == RegIndirectPacket::Uc && AgcGetIsTrinityMode() != 0 ? 1u : 0u);
return (type == RegIndirectPacket::Uc && is_trinity_mode() ? 1u : 0u);
}
static void reg_indirect_write_packet(uint32_t* cmd, uint64_t vaddr, uint32_t num_regs,
@@ -1574,15 +1569,6 @@ int KYTY_SYSV_ABI AgcWriteDataPatchSetAddressOrOffset(uint32_t* cmd, uint64_t ad
return GRAPHICS5_ERROR_INVALID_PACKET;
}
int KYTY_SYSV_ABI AgcUnknownJumpPatchSetTarget(uint32_t* cmd, const volatile uint32_t* target,
uint32_t size_in_dwords) {
PRINT_NAME();
LOGF("Calling unknown stub");
return AgcJumpPatchSetTarget(cmd, target, size_in_dwords);
}
int KYTY_SYSV_ABI AgcJumpPatchSetTarget(uint32_t* cmd, const volatile uint32_t* target,
uint32_t size_in_dwords) {
PRINT_NAME();
@@ -1690,9 +1676,8 @@ uint64_t KYTY_SYSV_ABI AgcDcbContextStateOpGetSize(uint32_t operation) {
return static_cast<uint64_t>(context_state_op_size_dw(operation)) * sizeof(uint32_t);
}
uint64_t KYTY_SYSV_ABI AgcGetIsTrinityMode() {
// PS5 Pro?
return 0;
void KYTY_SYSV_ABI AgcGetIsTrinityMode(uint8_t* result) {
*result = is_trinity_mode();
}
static constexpr int GRAPHICS5_DRIVER_ERROR_INVALID_VALUE = static_cast<int>(0x8a6c0033u);
+1 -3
View File
@@ -71,14 +71,12 @@ int KYTY_SYSV_ABI AgcCreateInterpolantMapping2(ShaderRegister* regs, const Shade
int KYTY_SYSV_ABI AgcGetDataPacketPayloadAddress(uint32_t** addr, uint32_t* cmd, int type);
int KYTY_SYSV_ABI AgcGetDataPacketPayloadRange(MemoryRange* range, uint32_t* cmd, int type);
int KYTY_SYSV_ABI AgcWriteDataPatchSetAddressOrOffset(uint32_t* cmd, uint64_t address_or_offset);
int KYTY_SYSV_ABI AgcUnknownJumpPatchSetTarget(uint32_t* cmd, const volatile uint32_t* target,
uint32_t size_in_dwords);
int KYTY_SYSV_ABI AgcJumpPatchSetTarget(uint32_t* cmd, const volatile uint32_t* target,
uint32_t size_in_dwords);
int KYTY_SYSV_ABI AgcSuspendPoint();
uint32_t* KYTY_SYSV_ABI AgcDcbContextStateOp(CommandBuffer* buf, uint32_t operation);
uint64_t KYTY_SYSV_ABI AgcDcbContextStateOpGetSize(uint32_t operation);
uint64_t KYTY_SYSV_ABI AgcGetIsTrinityMode();
void KYTY_SYSV_ABI AgcGetIsTrinityMode(uint8_t* result);
uint32_t KYTY_SYSV_ABI AgcDriverGetDefaultOwner();
uint32_t KYTY_SYSV_ABI AgcDriverGetResourceRegistrationMaxNameLength();
+105 -101
View File
@@ -45,15 +45,22 @@ struct PadVibrationParam {
};
struct ControllerState {
struct Touch {
uint8_t id = 0;
bool down = false;
uint16_t x = 0;
uint16_t y = 0;
};
uint64_t time = 0;
uint32_t buttons = 0;
int axes[static_cast<int>(Axis::AxisMax)] = {128, 128, 128, 128, 0, 0};
Touch touch[2];
};
class GameController {
public:
GameController() = default;
virtual ~GameController() = default;
GameController() = default;
KYTY_CLASS_NO_COPY(GameController);
@@ -62,6 +69,7 @@ public:
void Button(int id, uint32_t button, bool down);
void Axis(int id, Axis axis, int value);
void RightStick(int id, int x, int y);
void TouchPad(int id, int finger, bool down, float x, float y);
void ResetInputState();
void GetConnectionInfo(bool* flag, int* count);
void SetVibration(uint8_t large_motor, uint8_t small_motor);
@@ -71,51 +79,49 @@ public:
private:
static constexpr uint32_t STATES_MAX = 64;
struct StatePrivate {
bool obtained = false;
};
void CheckActive();
[[nodiscard]] ControllerState GetLastState() const;
void AddState(const ControllerState& state);
void CheckActive();
void AddState();
Common::Mutex m_mutex;
std::vector<int> m_connected_ids;
int m_active_id = -1;
bool m_connected = false;
int m_connected_count = 0;
ControllerState m_state;
ControllerState m_states[STATES_MAX];
StatePrivate m_private[STATES_MAX];
ControllerState m_last_state;
uint32_t m_states_num = 0;
uint32_t m_first_state = 0;
bool m_obtained[STATES_MAX] {};
uint32_t m_states_num = 0;
uint32_t m_first_state = 0;
uint8_t m_next_touch_id = 1;
};
static GameController* g_controller = nullptr;
static uint8_t pad_connected_count_to_u8(int connected_count) {
return static_cast<uint8_t>(connected_count > 255 ? 255 : connected_count);
}
static void pad_fill_data(PadData* data, const ControllerState& state, bool connected,
int connected_count) {
EXIT_IF(data == nullptr);
std::memset(data, 0, sizeof(*data));
data->buttons = state.buttons;
data->left_stick_x = state.axes[static_cast<int>(Axis::LeftX)];
data->left_stick_y = state.axes[static_cast<int>(Axis::LeftY)];
data->right_stick_x = state.axes[static_cast<int>(Axis::RightX)];
data->right_stick_y = state.axes[static_cast<int>(Axis::RightY)];
data->analog_buttons_l2 = state.axes[static_cast<int>(Axis::TriggerLeft)];
data->analog_buttons_r2 = state.axes[static_cast<int>(Axis::TriggerRight)];
data->orientation_w = 1.0f;
data->touch_data_touch0_id = 1;
data->touch_data_touch1_id = 2;
data->buttons = state.buttons;
data->left_stick_x = state.axes[static_cast<int>(Axis::LeftX)];
data->left_stick_y = state.axes[static_cast<int>(Axis::LeftY)];
data->right_stick_x = state.axes[static_cast<int>(Axis::RightX)];
data->right_stick_y = state.axes[static_cast<int>(Axis::RightY)];
data->analog_buttons_l2 = state.axes[static_cast<int>(Axis::TriggerLeft)];
data->analog_buttons_r2 = state.axes[static_cast<int>(Axis::TriggerRight)];
data->orientation_w = 1.0f;
for (const auto& touch: state.touch) {
if (touch.down) {
auto& output = data->touch_data.touch[data->touch_data.touch_num++];
output.x = touch.x;
output.y = touch.y;
output.id = touch.id;
}
}
data->connected = connected;
data->timestamp = state.time;
data->connected_count = pad_connected_count_to_u8(connected_count);
data->connected_count = static_cast<uint8_t>(std::min(connected_count, 255));
data->device_unique_data_len = 0;
}
@@ -155,7 +161,6 @@ void GameController::Disconnect(int id) {
}
void GameController::CheckActive() {
bool reset = false;
int new_active_id = -1;
bool new_connected = false;
@@ -170,46 +175,29 @@ void GameController::CheckActive() {
new_connected = true;
}
const bool was_connected = m_connected;
if (m_connected != new_connected || m_active_id != new_active_id) {
m_active_id = new_active_id;
m_connected = new_connected;
if (!was_connected && new_connected) {
m_connected_count++;
}
reset = true;
if (m_connected == new_connected && m_active_id == new_active_id) {
return;
}
if (reset) {
m_states_num = 0;
m_last_state = ControllerState();
if (!m_connected && new_connected) {
m_connected_count++;
}
m_active_id = new_active_id;
m_connected = new_connected;
m_state = {};
m_states_num = 0;
m_first_state = 0;
m_next_touch_id = 1;
}
ControllerState GameController::GetLastState() const {
if (m_states_num == 0) {
return m_last_state;
}
auto last = (m_first_state + m_states_num - 1) % STATES_MAX;
return m_states[last];
}
void GameController::AddState(const ControllerState& state) {
void GameController::AddState() {
if (m_states_num >= STATES_MAX) {
m_states_num = STATES_MAX - 1;
m_first_state = (m_first_state + 1) % STATES_MAX;
}
auto index = (m_first_state + m_states_num) % STATES_MAX;
m_states[index] = state;
m_last_state = state;
m_private[index].obtained = false;
const auto index = (m_first_state + m_states_num) % STATES_MAX;
m_states[index] = m_state;
m_obtained[index] = false;
m_states_num++;
}
@@ -218,17 +206,11 @@ void GameController::Button(int id, uint32_t button, bool down) {
// The keyboard shares the player-1 pad with the active gamepad.
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
auto state = GetLastState();
m_state.time = LibKernel::KernelGetProcessTime();
state.time = LibKernel::KernelGetProcessTime();
m_state.buttons = down ? m_state.buttons | button : m_state.buttons & ~button;
if (down) {
state.buttons |= button;
} else {
state.buttons &= ~button;
}
AddState(state);
AddState();
}
}
@@ -236,33 +218,25 @@ void GameController::Axis(int id, Controller::Axis axis, int value) {
Common::LockGuard lock(m_mutex);
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
auto state = GetLastState();
state.time = LibKernel::KernelGetProcessTime();
m_state.time = LibKernel::KernelGetProcessTime();
int axis_id = static_cast<int>(axis);
EXIT_IF(axis_id < 0 || axis_id >= static_cast<int>(Controller::Axis::AxisMax));
state.axes[axis_id] = value;
m_state.axes[axis_id] = value;
uint32_t trigger = 0;
if (axis == Controller::Axis::TriggerLeft) {
if (value > 0) {
state.buttons |= PAD_BUTTON_L2;
} else {
state.buttons &= ~PAD_BUTTON_L2;
}
trigger = PAD_BUTTON_L2;
} else if (axis == Controller::Axis::TriggerRight) {
trigger = PAD_BUTTON_R2;
}
if (trigger != 0) {
m_state.buttons = value > 0 ? m_state.buttons | trigger : m_state.buttons & ~trigger;
}
if (axis == Controller::Axis::TriggerRight) {
if (value > 0) {
state.buttons |= PAD_BUTTON_R2;
} else {
state.buttons &= ~PAD_BUTTON_R2;
}
}
AddState(state);
AddState();
}
}
@@ -270,21 +244,45 @@ void GameController::RightStick(int id, int x, int y) {
Common::LockGuard lock(m_mutex);
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
auto state = GetLastState();
state.time = LibKernel::KernelGetProcessTime();
state.axes[static_cast<int>(Axis::RightX)] = x;
state.axes[static_cast<int>(Axis::RightY)] = y;
AddState(state);
m_state.time = LibKernel::KernelGetProcessTime();
m_state.axes[static_cast<int>(Axis::RightX)] = x;
m_state.axes[static_cast<int>(Axis::RightY)] = y;
AddState();
}
}
void GameController::TouchPad(int id, int finger, bool down, float x, float y) {
if (finger < 0 || finger >= 2) {
return;
}
Common::LockGuard lock(m_mutex);
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
auto& touch = m_state.touch[finger];
m_state.time = LibKernel::KernelGetProcessTime();
if (down && !touch.down) {
touch.id = m_next_touch_id;
m_next_touch_id = m_next_touch_id == 127 ? 1 : m_next_touch_id + 1;
}
touch.down = down;
touch.x = static_cast<uint16_t>(std::clamp(x, 0.0f, 1.0f) * 1920.0f);
touch.y = static_cast<uint16_t>(std::clamp(y, 0.0f, 1.0f) * 943.0f);
if (id == HOST_INPUT_CONTROLLER_ID) {
m_state.buttons = down ? m_state.buttons | PAD_BUTTON_TOUCH_PAD
: m_state.buttons & ~PAD_BUTTON_TOUCH_PAD;
}
AddState();
}
}
void GameController::ResetInputState() {
Common::LockGuard lock(m_mutex);
ControllerState state {};
state.time = LibKernel::KernelGetProcessTime();
m_states_num = 0;
m_first_state = 0;
AddState(state);
m_state = {};
m_state.time = LibKernel::KernelGetProcessTime();
m_states_num = 0;
m_first_state = 0;
m_next_touch_id = 1;
AddState();
}
void GameController::SetVibration(uint8_t large_motor, uint8_t small_motor) {
@@ -325,7 +323,7 @@ void GameController::ReadState(ControllerState* state, bool* flag, int* count) {
*flag = m_connected;
*count = m_connected_count;
*state = GetLastState();
*state = m_state;
}
int GameController::ReadStates(ControllerState* states, int states_num, bool* flag, int* count) {
@@ -348,8 +346,8 @@ int GameController::ReadStates(ControllerState* states, int states_num, bool* fl
break;
}
auto index = (m_first_state + i) % STATES_MAX;
if (!m_private[index].obtained) {
m_private[index].obtained = true;
if (!m_obtained[index]) {
m_obtained[index] = true;
states[ret_num++] = m_states[index];
}
@@ -390,6 +388,12 @@ void ControllerRightStick(int id, int x, int y) {
g_controller->RightStick(id, x, y);
}
void ControllerTouchPad(int id, int finger, bool down, float x, float y) {
EXIT_IF(g_controller == nullptr);
g_controller->TouchPad(id, finger, down, x, y);
}
void ControllerResetInputState() {
EXIT_IF(g_controller == nullptr);
g_controller->ResetInputState();
@@ -508,7 +512,7 @@ int KYTY_SYSV_ABI PadGetControllerInformation(int handle, PadControllerInformati
info->stick_dead_zone_left = controller_get_axis(-32768, 32767, 8000) - 128;
info->stick_dead_zone_right = controller_get_axis(-32768, 32767, 8000) - 128;
info->connection_type = 0;
info->connected_count = pad_connected_count_to_u8(connected_count);
info->connected_count = static_cast<uint8_t>(std::min(connected_count, 255));
info->connected = connected;
info->device_class = 0;
+8 -1
View File
@@ -51,7 +51,13 @@ struct PadLightBarParam;
inline int controller_get_axis(int min, int max, int value) {
int v = (255 * (value - min)) / (max - min);
return (v < 0 ? 0 : (v > 255 ? 255 : v));
if (v < 0) {
return 0;
}
if (v > 255) {
return 255;
}
return v;
}
void ControllerConnect(int id);
@@ -59,6 +65,7 @@ void ControllerDisconnect(int id);
void ControllerButton(int id, uint32_t button, bool down);
void ControllerAxis(int id, Axis axis, int value);
void ControllerRightStick(int id, int x, int y);
void ControllerTouchPad(int id, int finger, bool down, float x, float y);
void ControllerResetInputState();
int KYTY_SYSV_ABI PadInit();
-1
View File
@@ -37,7 +37,6 @@ LIB_DEFINE(InitAgcDriver_1) {
LIB_FUNC("V++UgBtQhn0", Gen5::AgcGetDataPacketPayloadAddress);
LIB_FUNC("s+VGAMDQ0AQ", Gen5::AgcGetDataPacketPayloadRange);
LIB_FUNC("fPSCdQxgpSw", Gen5::AgcWriteDataPatchSetAddressOrOffset);
LIB_FUNC("bxca0BK4FNg", Gen5::AgcUnknownJumpPatchSetTarget);
LIB_FUNC("2BS4EtAaF28", Gen5::AgcJumpPatchSetTarget);
LIB_FUNC("h9z6+0hEydk", Gen5::AgcSuspendPoint);
LIB_FUNC("qj7QZpgr9Uw", Gen5::AgcDcbContextStateOp);
+1
View File
@@ -2665,6 +2665,7 @@ LIB_DEFINE(InitAmpr_1_Ampr) {
LIB_FUNC("dXPaz65HNmk", Ampr::CommandBufferPushMarker);
LIB_FUNC("mv0O8Zg0woU", Ampr::CommandBufferPopMarker);
LIB_FUNC("DLfoNxTFNVk", Ampr::CommandBufferWaitOnAddress);
LIB_FUNC("V7GQTEeUfhw", Ampr::CommandBufferWaitOnAddress);
LIB_FUNC("cQb8Zr8Q0Y0", Ampr::CommandBufferWaitOnCounter);
LIB_FUNC("j0+3uJMxYJY", Ampr::CommandBufferWriteAddress);
LIB_FUNC("sJXyWHjP-F8", Ampr::CommandBufferWriteAddressOnCompletion);
+43 -39
View File
@@ -5,46 +5,50 @@
namespace Libs::Controller {
struct PadTouch {
uint16_t x;
uint16_t y;
uint8_t id;
uint8_t reserve[3];
};
struct PadTouchData {
uint8_t touch_num;
uint8_t reserve[3];
uint32_t reserve1;
PadTouch touch[2];
};
struct PadData {
uint32_t buttons;
uint8_t left_stick_x;
uint8_t left_stick_y;
uint8_t right_stick_x;
uint8_t right_stick_y;
uint8_t analog_buttons_l2;
uint8_t analog_buttons_r2;
uint8_t padding[2];
float orientation_x;
float orientation_y;
float orientation_z;
float orientation_w;
float acceleration_x;
float acceleration_y;
float acceleration_z;
float angular_velocity_x;
float angular_velocity_y;
float angular_velocity_z;
uint8_t touch_data_touch_num;
uint8_t touch_data_reserve[3];
uint32_t touch_data_reserve1;
uint16_t touch_data_touch0_x;
uint16_t touch_data_touch0_y;
uint8_t touch_data_touch0_id;
uint8_t touch_data_touch0_reserve[3];
uint16_t touch_data_touch1_x;
uint16_t touch_data_touch1_y;
uint8_t touch_data_touch1_id;
uint8_t touch_data_touch1_reserve[3];
bool connected;
uint64_t timestamp;
uint32_t extension_unit_data_extension_unit_id;
uint8_t extension_unit_data_reserve[1];
uint8_t extension_unit_data_data_length;
uint8_t extension_unit_data_data[10];
uint8_t connected_count;
uint8_t reserve[2];
uint8_t device_unique_data_len;
uint8_t device_unique_data[12];
uint32_t buttons;
uint8_t left_stick_x;
uint8_t left_stick_y;
uint8_t right_stick_x;
uint8_t right_stick_y;
uint8_t analog_buttons_l2;
uint8_t analog_buttons_r2;
uint8_t padding[2];
float orientation_x;
float orientation_y;
float orientation_z;
float orientation_w;
float acceleration_x;
float acceleration_y;
float acceleration_z;
float angular_velocity_x;
float angular_velocity_y;
float angular_velocity_z;
PadTouchData touch_data;
bool connected;
uint64_t timestamp;
uint32_t extension_unit_data_extension_unit_id;
uint8_t extension_unit_data_reserve[1];
uint8_t extension_unit_data_data_length;
uint8_t extension_unit_data_data[10];
uint8_t connected_count;
uint8_t reserve[2];
uint8_t device_unique_data_len;
uint8_t device_unique_data[12];
};
static_assert(sizeof(PadData) == 120);
+24
View File
@@ -29,9 +29,11 @@
namespace {
using Libs::Graphics::GuestRange;
using Libs::Graphics::MemoryTracker;
using Libs::Graphics::PageManager;
using Libs::Graphics::RangeSet;
using Libs::Graphics::TRACKER_ADDRESS_SIZE;
void Check(bool value, const char *text) {
if (!value) {
@@ -208,6 +210,27 @@ void TestRangeSet() {
"range set subtraction did not preserve both exact tails");
}
void TestGuestRange() {
constexpr GuestRange empty{};
constexpr GuestRange first_byte{1, 1};
constexpr GuestRange last_byte{TRACKER_ADDRESS_SIZE - 1, 1};
static_assert(empty.Empty() && !empty.Valid() && empty.ValidOrEmpty());
static_assert(!first_byte.Empty() && first_byte.Valid() &&
first_byte.ValidOrEmpty() && first_byte.End() == 2);
static_assert(last_byte.Valid() && last_byte.End() == TRACKER_ADDRESS_SIZE);
Check(!GuestRange{0, 1}.Empty() && !GuestRange{0, 1}.ValidOrEmpty(),
"zero-address nonempty guest range is rejected");
Check(!GuestRange{1, 0}.Empty() && !GuestRange{1, 0}.ValidOrEmpty(),
"nonzero-address empty guest range is rejected");
Check(!GuestRange{TRACKER_ADDRESS_SIZE, 1}.Valid(),
"first address beyond the guest range is rejected");
Check(!GuestRange{TRACKER_ADDRESS_SIZE - 1, 2}.Valid(),
"guest range crossing the address-space end is rejected");
Check(!GuestRange{UINT64_MAX, 2}.Valid(), "wrapping guest range is rejected");
}
void TestQueriesDoNotRequireMappedOwnership() {
constexpr uint64_t address = 0x0000000203000000ull;
TrackerHarness harness;
@@ -829,6 +852,7 @@ int main(int argc, char **argv) {
if (argc == 3 && std::strcmp(argv[1], "--death") == 0) {
RunDeathCase(argv[2]);
}
TestGuestRange();
TestRangeSet();
TestQueriesDoNotRequireMappedOwnership();
TestConcurrentRegionPublication();
+261 -28
View File
@@ -1209,7 +1209,7 @@ CompiledShader CompileCase(const TestCase &test) {
options.stage = ShaderType::Compute;
options.dump_ir = true;
options.input_info.compute = &test.compute_info;
options.user_data = user_data.data();
options.user_data = user_data;
options.read_memory = ReadTestMemory;
options.read_memory_data = const_cast<std::vector<u32> *>(&test.initial);
options.scratch_dwords = test.compute_info.scratch_size_dwords;
@@ -1349,7 +1349,7 @@ CompiledShader CompileFragmentCase(const GraphicsCase &test) {
options.stage = ShaderType::Pixel;
options.dump_ir = false;
options.input_info.pixel = &pixel_info;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(test.fragment_code, options);
Require(test.name, "SPIR-V emit", !result.spirv.empty(),
@@ -7060,8 +7060,7 @@ public:
registers.SetColorAttrib3(0,
{.tile_mode = Prospero::TileMode::kRenderTarget,
.dimension = 0,
.cmask_pipe_aligned = true,
.dcc_pipe_aligned = true});
.metadata_pipe_aligned = true});
registers.SetRenderTargetMask(0x0f);
scheduler.Begin(registers, user_config, shaders);
@@ -7094,7 +7093,7 @@ public:
rendering.width == width && rendering.height == height &&
rendering.num_layers == 1 &&
rendering.num_color_attachments == 1,
"SDK dimension=0 did not create a 512x1 Vulkan attachment");
"dimension=0 did not create a 512x1 Vulkan attachment");
RenderExecutorTestAccess::ResetBindings(executor);
resources.UnmapMemory(base, allocation_size);
@@ -7153,8 +7152,7 @@ public:
{.depth = 31,
.tile_mode = Prospero::TileMode::kRenderTarget,
.dimension = 2,
.cmask_pipe_aligned = true,
.dcc_pipe_aligned = true});
.metadata_pipe_aligned = true});
constexpr uint64_t dcc_address = base + allocation_size - 0x1000;
registers.SetColorDccAddr(0, {.addr = dcc_address});
registers.SetColorClearWord0(0, {.word0 = 0});
@@ -7198,7 +7196,7 @@ public:
static_cast<bool>(image.backing.flags &
vk::ImageCreateFlagBits::e2DArrayCompatible) &&
image.usage.render_target && image.IsGpuModified(),
"dimension=2/depth=31 did not create the SDK-defined 32x32x32 "
"dimension=2/depth=31 did not create the expected 32x32x32 "
"backing and 2D "
"attachment slice");
@@ -7367,8 +7365,7 @@ public:
registers.SetColorAttrib2(0, {.height = 255, .width = 255});
registers.SetColorAttrib3(0, {.tile_mode = tile_case.tile,
.dimension = 1,
.cmask_pipe_aligned = true,
.dcc_pipe_aligned = true});
.metadata_pipe_aligned = true});
registers.SetRenderTargetMask(0x0f);
scheduler.Begin(registers, user_config, shaders);
@@ -7477,8 +7474,7 @@ public:
registers.SetColorAttrib2(0, {.height = 63, .width = 63});
registers.SetColorAttrib3(0, {.tile_mode = Prospero::TileMode::kDepth,
.dimension = 1,
.cmask_pipe_aligned = true,
.dcc_pipe_aligned = true});
.metadata_pipe_aligned = true});
registers.SetRenderTargetMask(0x0f);
scheduler.Begin(registers, user_config, shaders);
@@ -8362,12 +8358,17 @@ public:
RenderExecutorTestAccess::ResetBindings(executor);
constexpr uint64_t depth_only_address = base + 0x140000;
constexpr uint64_t depth_only_htile_address = base + 0x150000;
constexpr uint32_t captured_depth_only_z_info = 0x22900983u;
constexpr uint32_t captured_depth_only_stencil_info = 0x00100980u;
HW::DepthRenderTarget depth_only_target{};
depth_only_target.z_info.format = Prospero::DepthFormat::kZ32F;
depth_only_target.z_info.z_compare_base = Prospero::ZCompareBase::kZMax;
depth_only_target.stencil_info.htile_stencil_disabled = true;
depth_only_target.z_info =
HW::DepthZInfo::Decode(captured_depth_only_z_info);
depth_only_target.stencil_info =
HW::DepthStencilInfo::Decode(captured_depth_only_stencil_info);
depth_only_target.z_read_base_addr = depth_only_address;
depth_only_target.z_write_base_addr = depth_only_address;
depth_only_target.htile_data_base_addr = depth_only_htile_address;
depth_only_target.size = {63, 63, true};
registers.SetDepthRenderTarget(depth_only_target);
HW::DepthControl depth_only_control{};
@@ -8386,6 +8387,7 @@ public:
Require(
name, "depth-only target with stale stencil state",
depth_only.image_id && depth_only.format == vk::Format::eD32Sfloat &&
depth_only.htile &&
depth_only.depth_test_enable && depth_only.depth_write_enable &&
depth_only.depth_clear_enable &&
!depth_only.stencil_test_enable &&
@@ -8393,14 +8395,16 @@ public:
depth_only.stencil_buffer_vaddr == 0 &&
depth_only.stencil_buffer_size == 0 &&
depth_only.desc.info.stencil.Empty() &&
depth_only.htile_buffer_vaddr == depth_only_htile_address &&
depth_only.desc.info.metadata.range.address ==
depth_only_htile_address &&
depth_only.depth_buffer_size != 0 &&
depth_only_address + depth_only.depth_buffer_size <=
base + allocation_size &&
depth_only.vaddr_num == 1 &&
depth_only.AttachmentWriteAspects() ==
vk::ImageAspectFlagBits::eDepth,
"raw stencil test or clear state leaked into a depth-only "
"attachment");
"inactive stencil state changed a depth-only HTile attachment");
RenderExecutorTestAccess::ResetBindings(executor);
const auto sampled_width = depth_only.desc.info.extent.width - 1u;
@@ -12956,6 +12960,36 @@ TestCase ScalarFlbitI32B64Gpu() {
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
}
TestCase ScalarFlbitI32B32Gpu() {
using O = ShaderOpcode;
std::vector<u32> code;
AppendSMovLiteral(&code, 0, 0x00000000u);
code.push_back(EncodeSop1(0x15, 20, 0));
AppendSMovLiteral(&code, 0, 0x0000ccccu);
code.push_back(EncodeSop1(0x15, 21, 0));
AppendSMovLiteral(&code, 0, 0x80000000u);
code.push_back(EncodeSop1(0x15, 22, 0));
AppendSMovLiteral(&code, 0, 0x7fffffffu);
code.push_back(EncodeSop1(0x15, 23, 0));
AppendStoreSgpr(&code, 20, 0);
AppendStoreSgpr(&code, 21, 1);
AppendStoreSgpr(&code, 22, 2);
AppendStoreSgpr(&code, 23, 3);
AppendEnd(&code);
return {"ScalarFlbitI32B32Gpu",
code,
{},
{0xffffffffu, 16, 0, 1},
{O::S_MOV_B32, O::S_FLBIT_I32_B32, O::V_MOV_B32,
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
}
TestCase ScalarSaveExecOps() {
using O = ShaderOpcode;
@@ -13677,6 +13711,32 @@ TestCase Vop2SdwaAshrrevCapturedWord0SignExtends() {
return test;
}
TestCase Vop2SdwaLshrrevCapturedByte1Source() {
using O = ShaderOpcode;
std::vector<u32> code;
AppendSMovLiteral(&code, 106, 4);
AppendBufferLoadDword(&code, 8, 30);
code.push_back(0x2c1210f9u);
code.push_back(0x0186066au); // v_lshrrev_b32 v9, vcc_lo, v8.byte1
AppendStoreVgpr(&code, 9, 1);
AppendEnd(&code);
TestCase test;
test.name = "Vop2SdwaLshrrevCapturedByte1Source";
test.code = std::move(code);
test.initial = {0x12348678u, 0};
test.expected = {0x12348678u, 8};
test.opcodes = {O::S_MOV_B32, O::BUFFER_LOAD_DWORD, O::V_LSHRREV_B32,
O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
test.decoded_counts = {
{"V_LSHRREV_B32 v9, vcc_lo, v8.sdwa(sel=1,sext=0)", 1}};
test.ir_counts = {{" = BitFieldUExtract ", 1},
{" = ShiftRightLogical32 ", 1}};
test.required_spirv = {"OpBitFieldUExtract", "OpShiftRightLogical"};
return test;
}
TestCase Vop2SdwaSubNcPreservesByteAndWordDestinations() {
using O = ShaderOpcode;
@@ -16061,6 +16121,36 @@ TestCase VectorVop3CompareGtU64OnGpu() {
return test;
}
TestCase VectorVopcCompareLtU64OnGpu() {
using O = ShaderOpcode;
std::vector<u32> code;
AppendVMovU32(&code, 0, 5);
AppendVMovU32(&code, 1, 0);
AppendVMovU32(&code, 2, 1);
AppendSMovLiteral(&code, 4, 4);
AppendSMovLiteral(&code, 5, 0);
code.push_back(EncodeVopc(0xe1, 4, 0));
code.push_back(EncodeVop2(0x01, 3, InlineU32(0), 2));
AppendStoreVgpr(&code, 3, 0);
AppendSMovLiteral(&code, 4, 6);
code.push_back(EncodeVopc(0xe1, 4, 0));
code.push_back(EncodeVop2(0x01, 4, InlineU32(0), 2));
AppendStoreVgpr(&code, 4, 1);
AppendEnd(&code);
TestCase test{"VectorVopcCompareLtU64OnGpu",
code,
{},
{1, 0},
{O::V_MOV_B32, O::S_MOV_B32, O::V_CMP_LT_U64,
O::V_CNDMASK_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
test.decoded_counts = {{"V_CMP_LT_U64 vcc_lo, s4, v0", 2}};
return test;
}
TestCase VectorVop3CompareEqI64OnGpu() {
using O = ShaderOpcode;
@@ -21118,6 +21208,7 @@ std::vector<TestCase> MakeCases() {
AddCase(ScalarMovB32SpecialAliases);
AddCase(ScalarQuadmaskB64);
AddCase(ScalarFlbitI32B64Gpu);
AddCase(ScalarFlbitI32B32Gpu);
AddCase(ScalarSaveExecOps);
AddCase(ScalarOrn2SaveexecUsesSourceOrNotExec);
AddCase(ScalarGetpcWritesNextInstructionPc);
@@ -21141,6 +21232,7 @@ std::vector<TestCase> MakeCases() {
AddCase(Vop2SdwaSubNcExactByte2Destination);
AddCase(Vop2SdwaAddNcCapturedHighWordDestination);
AddCase(Vop2SdwaAshrrevCapturedWord0SignExtends);
AddCase(Vop2SdwaLshrrevCapturedByte1Source);
AddCase(Vop2SdwaSubNcPreservesByteAndWordDestinations);
AddCase(Vop3CvtPkI16I32Captured);
AddCase(Vop3Med3I16Captured);
@@ -21207,6 +21299,7 @@ std::vector<TestCase> MakeCases() {
AddCase(VectorVop3CompareEqI64OnGpu);
AddCase(VectorVop3CompareEqU64OnGpu);
AddCase(VectorVop3CompareGtU64OnGpu);
AddCase(VectorVopcCompareLtU64OnGpu);
AddCase(VectorVop3CompareNeU64OnGpu);
AddCase(VectorVopcCmpxNeU64CapturedExecMask);
AddCase(VectorVop3CmpxNeI64CapturedExecMask);
@@ -21425,8 +21518,7 @@ void CheckPs5GameExampleImageClearRuntimeShape() {
options.stage = ShaderType::Compute;
options.wave_size = 64;
options.user_data_base = 0;
options.user_data_count = static_cast<u32>(user_data.size());
options.user_data = user_data.data();
options.user_data = user_data;
options.input_info.compute = &compute;
options.dump_ir = false;
auto result = ShaderRecompiler::Recompile(code, options);
@@ -21522,8 +21614,7 @@ void CheckEmbeddedFetchVertexOffset() {
ShaderRecompiler::CompileOptions options;
options.stage = ShaderType::Vertex;
options.user_data_base = 8;
options.user_data_count = static_cast<u32>(user_data.size());
options.user_data = user_data.data();
options.user_data = user_data;
options.input_info.vertex = &vertex;
auto result = ShaderRecompiler::Recompile(code, options);
@@ -23771,18 +23862,18 @@ void CheckNativeMsaaState() {
}
void CheckDepthHtileStencilCompatibility() {
Require("DepthHtileStencilCompatibility", "inactive stencil plane",
depth_htile_stencil_acceleration_compatible(false, true, false),
"inactive Hi-Stencil state was treated as an attachment");
Require("DepthHtileStencilCompatibility", "disabled acceleration",
depth_htile_stencil_acceleration_compatible(false, false, true),
depth_htile_stencil_acceleration_compatible(true, false, true),
"disabled Hi-Stencil state was rejected");
Require("DepthHtileStencilCompatibility", "PS5 stencil plus HTile",
depth_htile_stencil_acceleration_compatible(true, true, false),
"valid PS5 Hi-Stencil attachment was rejected");
Require("DepthHtileStencilCompatibility", "missing stencil plane",
!depth_htile_stencil_acceleration_compatible(false, true, false),
"Hi-Stencil without a stencil plane was silently admitted");
Require("DepthHtileStencilCompatibility", "missing HTile metadata",
!depth_htile_stencil_acceleration_compatible(true, false, false),
"Hi-Stencil without HTile metadata was silently admitted");
"active Hi-Stencil without HTile metadata was admitted");
std::printf("[host] %-32s ok\n", "DepthHtileStencilCompatibility");
}
@@ -24223,8 +24314,7 @@ void CheckEmbeddedFetchLaneSpill() {
ShaderRecompiler::CompileOptions options;
options.stage = ShaderType::Vertex;
options.user_data_base = 8;
options.user_data_count = static_cast<u32>(user_data.size());
options.user_data = user_data.data();
options.user_data = user_data;
options.input_info.vertex = &vertex;
auto result = ShaderRecompiler::Recompile(code, options);
@@ -24370,6 +24460,147 @@ void CheckPm4StencilInfoValueLane(RenderContext &renderer) {
std::printf("[host] %-32s ok\n", "Pm4StencilInfoValueLane");
}
void CheckPm4NativeTargetGeometryRegisters(RenderContext &renderer) {
GraphicsInitJmpTables();
CommandProcessor packet(renderer, 0);
CommandProcessor indirect(renderer, 0);
const auto write_context = [](CommandProcessor &processor, uint32_t offset,
uint32_t value) {
std::array<uint32_t, 3> command{
KYTY_PM4(3, Pm4::IT_SET_CONTEXT_REG, Pm4::R_ZERO), offset, value};
Pm4Execution execution;
return processor.Process(execution, command) == Pm4ProcessResult::Complete;
};
constexpr uint32_t color_slot = 7;
constexpr uint32_t width_minus_one = 1919;
constexpr uint32_t height_minus_one = 1079;
constexpr uint32_t depth_minus_one = 5;
constexpr uint32_t max_mip = 3;
constexpr uint32_t dimension_3d = 2;
constexpr uint32_t attrib2_value =
height_minus_one | (width_minus_one << 14u) | (max_mip << 28u);
constexpr uint32_t attrib3_value =
depth_minus_one |
(static_cast<uint32_t>(Prospero::TileMode::kStandard64KB) << 14u) |
(dimension_3d << 24u) | (1u << 26u) | (1u << 30u);
const bool color_packets_complete =
write_context(packet, Pm4::CB_COLOR7_ATTRIB2, attrib2_value) &&
write_context(packet, Pm4::CB_COLOR7_ATTRIB3, attrib3_value);
g_hw_ctx_indirect_func[Pm4::CB_COLOR7_ATTRIB2](
indirect, Pm4::CB_COLOR7_ATTRIB2, attrib2_value);
g_hw_ctx_indirect_func[Pm4::CB_COLOR7_ATTRIB3](
indirect, Pm4::CB_COLOR7_ATTRIB3, attrib3_value);
const auto color_matches = [](const HW::RenderTarget &target) {
return target.attrib2.width == width_minus_one &&
target.attrib2.height == height_minus_one &&
target.attrib2.num_mip_levels == max_mip &&
target.attrib3.depth == depth_minus_one &&
target.attrib3.tile_mode == Prospero::TileMode::kStandard64KB &&
target.attrib3.dimension == dimension_3d &&
target.attrib3.metadata_pipe_aligned;
};
Require("Pm4NativeTargetGeometry", "sparse color geometry",
color_packets_complete &&
color_matches(packet.GetCtx().GetRenderTarget(color_slot)) &&
color_matches(indirect.GetCtx().GetRenderTarget(color_slot)) &&
!color_matches(packet.GetCtx().GetRenderTarget(0)) &&
!color_matches(indirect.GetCtx().GetRenderTarget(0)),
"ATTRIB2/ATTRIB3 did not provide native color extent and layout");
constexpr uint32_t depth_size_value =
width_minus_one | (height_minus_one << 16u);
const bool depth_packet_complete =
write_context(packet, Pm4::DB_DEPTH_SIZE_XY, depth_size_value);
g_hw_ctx_indirect_func[Pm4::DB_DEPTH_SIZE_XY](indirect, Pm4::DB_DEPTH_SIZE_XY,
depth_size_value);
const auto depth_matches = [](const HW::DepthRenderTarget &target) {
return target.size.valid && target.size.x_max == width_minus_one &&
target.size.y_max == height_minus_one;
};
Require("Pm4NativeTargetGeometry", "native depth geometry",
depth_packet_complete &&
depth_matches(packet.GetCtx().GetDepthRenderTarget()) &&
depth_matches(indirect.GetCtx().GetDepthRenderTarget()),
"DB_DEPTH_SIZE_XY did not provide the native depth extent");
bool legacy_slots_are_unhandled = true;
for (uint32_t slot = 0; slot < 8; slot++) {
const auto stride = slot * 15u;
const std::array legacy_color_slots{
Pm4::CB_COLOR0_BASE + stride + 1u,
Pm4::CB_COLOR0_BASE + stride + 2u,
Pm4::CB_COLOR0_CMASK + stride + 1u,
Pm4::CB_COLOR0_FMASK + stride + 1u,
};
for (const auto offset : legacy_color_slots) {
legacy_slots_are_unhandled &= g_hw_ctx_func[offset] == nullptr &&
g_hw_ctx_indirect_func[offset] == nullptr;
}
}
// These offsets are the removed GCN DB_DEPTH_INFO, DB_DEPTH_SIZE, and
// DB_DEPTH_SLICE holes. Keep them numeric so deleting their legacy PM4 names
// does not weaken this dispatch-table regression check.
constexpr std::array<uint32_t, 3> legacy_depth_slots{0x000fu, 0x0016u,
0x0017u};
for (const auto offset : legacy_depth_slots) {
legacy_slots_are_unhandled &= g_hw_ctx_func[offset] == nullptr &&
g_hw_ctx_indirect_func[offset] == nullptr;
}
// Removed GCN PA_SC_NGG_MODE_CNTL.
legacy_slots_are_unhandled &= g_hw_ctx_func[0x0314u] == nullptr &&
g_hw_ctx_indirect_func[0x0314u] == nullptr;
// Removed GCN shader resource/checksum/queue registers. Numeric offsets keep
// this check independent of the deleted legacy names.
constexpr std::array<uint32_t, 22> legacy_shader_slots{
0x000u, 0x001u, 0x002u, 0x003u, 0x030u, 0x081u, 0x0b0u, 0x0bcu,
0x100u, 0x101u, 0x130u, 0x14au, 0x14bu, 0x20eu, 0x20fu, 0x210u,
0x211u, 0x216u, 0x217u, 0x219u, 0x21au, 0x27du,
};
for (const auto offset : legacy_shader_slots) {
legacy_slots_are_unhandled &= g_hw_sh_func[offset] == nullptr &&
g_hw_sh_indirect_func[offset] == nullptr;
}
for (uint32_t offset = 0x0cau; offset <= 0x0ebu; offset++) {
legacy_slots_are_unhandled &= g_hw_sh_func[offset] == nullptr &&
g_hw_sh_indirect_func[offset] == nullptr;
}
constexpr std::array<uint32_t, 1> legacy_uconfig_slots{0x0260u};
for (const auto offset : legacy_uconfig_slots) {
legacy_slots_are_unhandled &= g_hw_uc_func[offset] == nullptr &&
g_hw_uc_indirect_func[offset] == nullptr;
}
std::array<uint32_t, 3> index_size_packet{
KYTY_PM4(3, Pm4::IT_SET_UCONFIG_REG_INDEX, Pm4::R_ZERO),
0x20000000u | Pm4::VGT_INDEX_TYPE,
0x441u,
};
Pm4Execution index_size_execution;
const bool native_index_size_packet_complete =
packet.Process(index_size_execution, index_size_packet) ==
Pm4ProcessResult::Complete &&
g_hw_uc_func[Pm4::VGT_INDEX_TYPE] != nullptr &&
g_hw_uc_indirect_func[Pm4::VGT_INDEX_TYPE] != nullptr &&
g_hw_uc_func[Pm4::IA_MULTI_VGT_PARAM] != nullptr &&
g_hw_uc_indirect_func[Pm4::IA_MULTI_VGT_PARAM] != nullptr;
const bool native_pace_slots_are_handled =
g_hw_sh_indirect_func[Pm4::SPI_SHADER_PACE_ID_PS] != nullptr &&
g_hw_sh_indirect_func[Pm4::SPI_SHADER_PACE_ID_GS] != nullptr &&
g_hw_sh_indirect_func[Pm4::COMPUTE_PACE_ID] != nullptr;
Require("Pm4NativeTargetGeometry", "legacy register holes",
legacy_slots_are_unhandled && native_pace_slots_are_handled &&
native_index_size_packet_complete,
"a removed GCN register has a handler or a native packet is not handled");
std::printf("[host] %-32s ok\n", "Pm4NativeTargetGeometry");
}
void CheckPm4DirectShaderRegisterFallback(RenderContext &renderer) {
GraphicsInitJmpTables();
CommandProcessor processor(renderer, 0);
@@ -25129,6 +25360,7 @@ int main(int argc, char **argv) {
}
if (argc == 2 && std::strcmp(argv[1], "--context-state-only") == 0) {
VulkanHarness vulkan;
CheckPm4NativeTargetGeometryRegisters(vulkan.RuntimeRenderer());
CheckPm4BlendColorRegisterRanges(vulkan.RuntimeRenderer());
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
CheckPm4ContextStateOperations(vulkan.RuntimeRenderer());
@@ -25308,6 +25540,7 @@ int main(int argc, char **argv) {
CheckPm4AcquireMemNoOp(vulkan.RuntimeRenderer());
CheckPm4SyntheticOcclusionCounterDump(vulkan.RuntimeRenderer());
CheckPm4StencilInfoValueLane(vulkan.RuntimeRenderer());
CheckPm4NativeTargetGeometryRegisters(vulkan.RuntimeRenderer());
CheckPm4DirectShaderRegisterFallback(vulkan.RuntimeRenderer());
CheckPm4GuardBandRegisterRanges(vulkan.RuntimeRenderer());
CheckPm4BlendColorRegisterRanges(vulkan.RuntimeRenderer());
+69 -57
View File
@@ -28,6 +28,7 @@
#include "graphics/shader/shaderCompiler.h"
#include "libs/agc.h"
#include "spirv-tools/libspirv.hpp"
#include "xxhash.h"
#include <algorithm>
#include <array>
@@ -84,9 +85,11 @@ ShaderRecompiler::CompileOptions MakeCompileOptions(ShaderType stage) {
static const ShaderVertexInputInfo vertex{};
static const ShaderPixelInputInfo pixel{};
static const ShaderComputeInputInfo compute{};
static const std::array<uint32_t, 64> user_data{};
ShaderRecompiler::CompileOptions options;
options.stage = stage;
options.user_data = user_data;
switch (stage) {
case ShaderType::Vertex:
options.input_info.vertex = &vertex;
@@ -115,9 +118,7 @@ void CompilePixelRuntime(const ShaderParams &params,
ShaderPixelInputInfo &input_info) {
auto options = MakeCompileOptions(ShaderType::Pixel);
options.shader_hash = params.hash;
options.shader_base = params.Base();
options.user_data = params.user_data.data();
options.user_data_count = static_cast<uint32_t>(params.user_data.size());
options.user_data = params.user_data;
options.scratch_dwords = input_info.scratch_size_dwords;
options.push_constant_offset = input_info.push_constant_offset;
options.read_specialization_memory = ReadHostTestMemory;
@@ -3696,7 +3697,6 @@ void TestNewShaderRecompilerScalarB64LaneTranslation() {
const uint32_t user_data[] = {0x01234567u, 0x89abcdefu};
auto options = MakeCompileOptions(ShaderType::Vertex);
options.user_data = user_data;
options.user_data_count = static_cast<uint32_t>(std::size(user_data));
options.dump_ir = true;
auto result = ShaderRecompiler::Recompile(shader, options);
@@ -3969,6 +3969,37 @@ void TestNewShaderDecoderArchitecture() {
cmp_eq_u64.src1.kind == OperandKind::VccLo,
"decoder rejected the captured VOP3 V_CMP_EQ_U64 instruction");
const uint32_t completed_pr_opcodes[] = {
EncodeSop1(0x15, 0, 1), // s_flbit_i32_b32 s0, s1
EncodeVopc(0xe1, 128, 0), // v_cmp_lt_u64 vcc, 0, v[0:1]
EncodeSopp(0x01, 0),
};
Instruction flbit_i32_b32;
ShaderRecompiler::Decoder::DecodeInstruction(completed_pr_opcodes, 0u,
flbit_i32_b32);
Instruction cmp_lt_u64;
ShaderRecompiler::Decoder::DecodeInstruction(completed_pr_opcodes, 1u,
cmp_lt_u64);
Check(flbit_i32_b32.family == Family::SOP1 &&
flbit_i32_b32.opcode == Opcode::S_FLBIT_I32_B32 &&
flbit_i32_b32.dst.kind == OperandKind::Sgpr &&
flbit_i32_b32.dst.reg == 0u &&
flbit_i32_b32.src0.kind == OperandKind::Sgpr &&
flbit_i32_b32.src0.reg == 1u &&
cmp_lt_u64.family == Family::VOPC &&
cmp_lt_u64.opcode == Opcode::V_CMP_LT_U64 &&
cmp_lt_u64.dst.kind == OperandKind::VccLo,
"decoder rejected completed PR #427 scalar/vector opcodes");
const auto completed_options = MakeCompileOptions(ShaderType::Compute);
const auto completed_result =
ShaderRecompiler::Recompile(completed_pr_opcodes, completed_options);
Check(Common::ContainsStr(completed_result.decoded_dump,
"S_FLBIT_I32_B32 s0, s1") &&
Common::ContainsStr(completed_result.decoded_dump,
"V_CMP_LT_U64 vcc_lo, 0, v0"),
"completed PR #427 opcodes were absent from the decoded shader");
const uint32_t ffbh_i32_code[] = {0x7e1c770eu};
Instruction ffbh_i32;
ShaderRecompiler::Decoder::DecodeInstruction(ffbh_i32_code, 0u, ffbh_i32);
@@ -4369,7 +4400,7 @@ void TestNewShaderRecompilerMemoryFamilyTranslation() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
options.read_memory = ReadZeroTestMemory;
auto result = ShaderRecompiler::Recompile(shader, options);
@@ -4463,8 +4494,7 @@ void TestNewShaderRecompilerScalarMemoryBindingDomains() {
raw_user_data[8] = 0x1003u;
auto raw_options = MakeCompileOptions(ShaderType::Pixel);
raw_options.user_data = raw_user_data.data();
raw_options.user_data_count = static_cast<uint32_t>(raw_user_data.size());
raw_options.user_data = raw_user_data;
auto raw = ShaderRecompiler::Recompile(raw_shader, raw_options);
const auto *address_binding = ShaderRecompiler::IR::FindBinding(
@@ -4508,9 +4538,7 @@ void TestNewShaderRecompilerScalarMemoryBindingDomains() {
buffer_user_data[10] = 4u;
auto buffer_options = MakeCompileOptions(ShaderType::Pixel);
buffer_options.user_data = buffer_user_data.data();
buffer_options.user_data_count =
static_cast<uint32_t>(buffer_user_data.size());
buffer_options.user_data = buffer_user_data;
auto buffer = ShaderRecompiler::Recompile(buffer_shader, buffer_options);
const auto *buffer_binding = ShaderRecompiler::IR::FindBinding(
@@ -4548,7 +4576,7 @@ void TestNewShaderRecompilerImageQueryTranslation() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_get_lod"),
@@ -4592,7 +4620,7 @@ void TestNewShaderRecompilerCubeSampleCoordinates() {
auto user_data = ImageTestUserData(Prospero::ImageType::kCube);
auto options = MakeCompileOptions(ShaderType::Compute);
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(result.program.info.images.size() == 1 &&
@@ -4638,7 +4666,7 @@ void TestNewShaderRecompilerImageSampleVariants() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_sample_l"),
@@ -4726,7 +4754,7 @@ void TestNewShaderRecompilerImageSampleA16SamplerCoords() {
auto user_data = ImageTestUserData(Prospero::ImageType::kColor3D);
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump,
@@ -4768,7 +4796,7 @@ void TestNewShaderRecompilerImageSampleOpcodeAliases() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_sample_a"),
@@ -4804,7 +4832,7 @@ void TestNewShaderRecompilerImageSampleA16ExceptionComponents() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
CheckSpirvBinaryValidates(result.spirv);
@@ -4850,7 +4878,7 @@ void TestNewShaderRecompilerImageLoadA16UintCoords() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_load"),
@@ -4894,7 +4922,7 @@ void TestNewShaderRecompilerPixelImageSampleLodSelection() {
auto options = MakeCompileOptions(ShaderType::Pixel);
options.input_info.pixel = &ps_info;
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
CheckSpirvBinaryValidates(result.spirv);
@@ -5005,7 +5033,7 @@ void TestNewShaderRecompilerImageViewDimensions() {
auto options = MakeCompileOptions(ShaderType::Pixel);
options.input_info.pixel = &ps_info;
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_dim=2d_array"),
@@ -5082,7 +5110,7 @@ void TestNewShaderRecompilerStorageImage1DDescriptorVariants() {
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.ir_dump, "image_dim=1d"),
@@ -5113,7 +5141,7 @@ void TestNewShaderRecompilerNullImageUsesCanonical2DView() {
std::array<uint32_t, 64> user_data{};
auto options = MakeCompileOptions(ShaderType::Compute);
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
CheckSpirvBinaryValidates(result.spirv);
@@ -5144,7 +5172,7 @@ void TestNewShaderRecompilerImageGatherVariants() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_gather4_lz"),
@@ -5230,7 +5258,7 @@ void TestNewShaderRecompilerImageLoadVariants() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_load"),
@@ -5276,7 +5304,7 @@ void TestNewShaderRecompilerImageLoad2DMsaa() {
auto options = MakeCompileOptions(ShaderType::Pixel);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_dim=2d_msaa") &&
@@ -5317,7 +5345,7 @@ void TestNewShaderRecompilerImageStoreTranslation() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_store"),
@@ -5368,7 +5396,7 @@ void TestNewShaderRecompilerStorageImage3DDescriptorVariant() {
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.input_info.compute = &input_info;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_dim=3d"),
@@ -5422,7 +5450,7 @@ void TestNewShaderRecompilerStorageImage2DDescriptorOverridesMimg3D() {
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.input_info.compute = &input_info;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_dim=3d"),
@@ -5464,7 +5492,7 @@ void TestNewShaderRecompilerImageAtomicTranslation() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(Common::ContainsStr(result.decoded_dump, "image_atomic_add"),
@@ -6127,7 +6155,7 @@ void TestNewShaderRecompilerFormattedStoreUsesRuntimeArrayLengthOnly() {
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
Check(result.resources.buffers.size() == 1 &&
@@ -8891,9 +8919,6 @@ void TestNewShaderRecompilerAuxPositionExports() {
"compilation");
#endif
HW::VertexShaderInfo regs{};
regs.es_regs.data_addr = 1;
regs.gs_regs.chksum = 1;
ShaderVertexInputInfo key0{};
ShaderVertexInputInfo key1{};
key1.pa_cl_vs_out_cntl = 1;
@@ -8946,7 +8971,7 @@ void TestDemandDrivenSpirvDeclarations() {
auto user_data = ImageTestUserData();
SetImageTestFormat(&user_data, 0, format);
auto options = MakeCompileOptions(ShaderType::Compute);
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
CheckSpirvBinaryValidates(result.spirv);
return result.spirv;
@@ -8959,7 +8984,7 @@ void TestDemandDrivenSpirvDeclarations() {
auto query_pixel_info = RegressionPixelInputInfo();
auto query_options = MakeCompileOptions(ShaderType::Pixel);
query_options.input_info.pixel = &query_pixel_info;
query_options.user_data = query_user_data.data();
query_options.user_data = query_user_data;
auto query_result = ShaderRecompiler::Recompile(query, query_options);
CheckSpirvBinaryValidates(query_result.spirv);
const auto &query_spirv = query_result.spirv;
@@ -10234,7 +10259,6 @@ void TestRenderTargetReverseExportMapping() {
"pixel shader cache identity omitted the render-target export mapping");
regs.ps_regs.data_addr = reinterpret_cast<uint64_t>(shader);
regs.ps_regs.chksum = 0xf16ab6f000000001ull;
ShaderMappedData mapped{};
mapped.code_size_bytes = sizeof(shader);
ShaderMapUserData(regs.ps_regs.data_addr, mapped);
@@ -10320,7 +10344,7 @@ void TestNewShaderRecompilerNativeBindingPlan() {
SetImageTestFormat(&user_data, 6, Prospero::BufferFormat::k32UInt);
auto options = MakeCompileOptions(ShaderType::Compute);
options.dump_ir = true;
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(shader, options);
const auto *buffers = ShaderRecompiler::IR::FindBinding(
@@ -10703,7 +10727,7 @@ void TestTypedDescriptorRealCarryAndScalarLoads() {
auto user_data = ImageTestUserData();
auto options = MakeCompileOptions(ShaderType::Pixel);
options.user_data = user_data.data();
options.user_data = user_data;
auto result = ShaderRecompiler::Recompile(inline_sampler_shader, options);
}
@@ -11122,7 +11146,6 @@ void TestNewShaderRecompilerPixelPipelineEntry() {
HW::PixelShaderInfo regs{};
regs.ps_regs.data_addr = reinterpret_cast<uint64_t>(shader);
regs.ps_regs.chksum = 0x1234567800000001ull;
ShaderMappedData mapped{};
mapped.code_size_bytes = sizeof(shader);
ShaderMapUserData(regs.ps_regs.data_addr, mapped);
@@ -11132,7 +11155,8 @@ void TestNewShaderRecompilerPixelPipelineEntry() {
ShaderVertexInputInfo vertex_info{};
ShaderPixelInputInfo input_info{};
const auto params = PrepareProgram(regs, sh, vertex_info, mappings, input_info);
Check(params.hash == regs.ps_regs.chksum && params.code.data() == shader,
Check(params.hash == XXH3_64bits(params.code.data(), params.code.size_bytes()) &&
params.code.data() == shader,
"pixel shader program parameters lost source identity");
const uint32_t vcc_load_shader[] = {
@@ -11150,7 +11174,6 @@ void TestNewShaderRecompilerPixelPipelineEntry() {
HW::PixelShaderInfo vcc_regs{};
vcc_regs.ps_regs.data_addr = reinterpret_cast<uint64_t>(vcc_load_shader);
vcc_regs.ps_regs.chksum = 0x6306606500000001ull;
vcc_regs.ps_regs.rsrc2.user_sgpr = 29;
vcc_regs.ps_user_sgpr.value[27] = static_cast<uint32_t>(table_address);
vcc_regs.ps_user_sgpr.value[28] = static_cast<uint32_t>(table_address >> 32u);
@@ -11189,9 +11212,7 @@ void TestComputeLdsAllocationIdentity() {
"COMPUTE_PGM_RSRC2 LDS allocation units were not decoded");
auto options = MakeCompileOptions(ShaderType::Compute);
options.shader_hash = params.hash;
options.shader_base = params.Base();
options.user_data = params.user_data.data();
options.user_data_count = static_cast<uint32_t>(params.user_data.size());
options.user_data = params.user_data;
options.input_info.compute = &input_info;
options.wave_size = input_info.wave_size;
options.scratch_dwords = input_info.scratch_size_dwords;
@@ -11257,10 +11278,7 @@ void TestComputeLdsAllocationIdentity() {
"AGC per-thread scratch size was not propagated");
auto scratch_options = MakeCompileOptions(ShaderType::Compute);
scratch_options.shader_hash = scratch_params.hash;
scratch_options.shader_base = scratch_params.Base();
scratch_options.user_data = scratch_params.user_data.data();
scratch_options.user_data_count =
static_cast<uint32_t>(scratch_params.user_data.size());
scratch_options.user_data = scratch_params.user_data;
scratch_options.input_info.compute = &scratch_info;
scratch_options.wave_size = scratch_info.wave_size;
scratch_options.scratch_dwords = scratch_info.scratch_size_dwords;
@@ -11432,11 +11450,9 @@ void TestPixelProgramCacheBindingIdentity() {
Check(MakeStageStaticKey(no_depth_export) != MakeStageStaticKey(shifted_push),
"pixel shader identity omitted graphics push-bank placement");
auto check_program_identity = [&](const uint32_t *shader,
uint64_t checksum) {
auto check_program_identity = [&](const uint32_t *shader) {
HW::PixelShaderInfo regs{};
regs.ps_regs.data_addr = reinterpret_cast<uint64_t>(shader);
regs.ps_regs.chksum = checksum;
ShaderMappedData mapped{};
mapped.code_size_bytes = sizeof(uint32_t);
ShaderMapUserData(regs.ps_regs.data_addr, mapped);
@@ -11462,8 +11478,8 @@ void TestPixelProgramCacheBindingIdentity() {
return std::pair {first_params.hash, first_key};
};
const auto request_01 = check_program_identity(shader_01, 0);
const auto request_10 = check_program_identity(shader_10, 0);
const auto request_01 = check_program_identity(shader_01);
const auto request_10 = check_program_identity(shader_10);
Check(request_01 == request_10,
"relocated identical pixel programs did not share their source identity");
@@ -11474,7 +11490,6 @@ void TestPixelProgramCacheBindingIdentity() {
};
HW::PixelShaderInfo push_regs{};
push_regs.ps_regs.data_addr = reinterpret_cast<uint64_t>(push_shader);
push_regs.ps_regs.chksum = 0x91a27e6300000003ull;
push_regs.ps_regs.rsrc2.user_sgpr = 4;
ShaderMappedData push_mapped{};
push_mapped.code_size_bytes = sizeof(push_shader);
@@ -11537,8 +11552,7 @@ void TestGraphicsPushConstantPlacement() {
auto options = MakeCompileOptions(ShaderType::Pixel);
options.input_info.pixel = &pixel_info;
options.user_data = user_data.data();
options.user_data_count = static_cast<uint32_t>(user_data.size());
options.user_data = user_data;
options.push_constant_offset = 36;
auto placed = ShaderRecompiler::Recompile(shader, options);
@@ -11601,7 +11615,6 @@ void TestNewShaderRecompilerFlatUserPointerUsesDma() {
auto options = MakeCompileOptions(ShaderType::Pixel);
options.user_data = user_data;
options.user_data_count = static_cast<uint32_t>(std::size(user_data));
auto result = ShaderRecompiler::Recompile(shader, options);
Check(result.program.info.uses_dma,
@@ -11623,7 +11636,6 @@ void TestNewShaderRecompilerFlatAddressDomainsUseDma() {
auto options = MakeCompileOptions(ShaderType::Compute);
options.user_data = user_data;
options.user_data_count = static_cast<uint32_t>(std::size(user_data));
options.scratch_dwords = 1;
auto result = ShaderRecompiler::Recompile(segmented_shader, options);
Check(result.program.info.uses_dma,