[GPU] Cleanup definitions of some registers

VS/PS_NUM_REG is 6-bit on Adreno 200, and games aren't seen using the
bit 7 to indicate that no GPRs are used. It's not clear why Freedreno
configures it this way.

Some texture fetch fields were deprecated or moved during the development
of the Xenos, reflect that in the comments.

Add definitions of the registers configuring the conversion of vertex
positions to fixed-point. Although there isn't much that can be done with
it when emulating using PC GPU APIs, there are some places in Xenia that
wrongly (though sometimes deliberately, for results closer to the behavior
of the host GPU) assume that the conversion works like in Direct3D 10+,
however the Xenos supports only up to 4 subpixel bits rather than 8. The
effects of this difference are largely negligible, though.

Also add more detailed info about register references and differences from
other ATI/AMD GPUs for potential future contributors.
This commit is contained in:
Triang3l
2025-08-06 13:21:19 +03:00
parent 9ae3a72500
commit a06be03f1b
9 changed files with 177 additions and 102 deletions

View File

@@ -40,12 +40,12 @@ namespace draw_util {
bool IsRasterizationPotentiallyDone(const RegisterFile& regs,
bool primitive_polygonal) {
// TODO(Triang3l): Investigate ModeControl::kIgnore better, with respect to
// TODO(Triang3l): Investigate EdramMode::kNoOperation better, with respect to
// sample counting. Let's assume sample counting is a part of depth / stencil,
// thus disabled too.
xenos::ModeControl edram_mode = regs.Get<reg::RB_MODECONTROL>().edram_mode;
if (edram_mode != xenos::ModeControl::kColorDepth &&
edram_mode != xenos::ModeControl::kDepth) {
xenos::EdramMode edram_mode = regs.Get<reg::RB_MODECONTROL>().edram_mode;
if (edram_mode != xenos::EdramMode::kColorDepth &&
edram_mode != xenos::EdramMode::kDepthOnly) {
return false;
}
if (regs.Get<reg::SQ_PROGRAM_CNTL>().vs_export_mode ==
@@ -64,9 +64,9 @@ bool IsRasterizationPotentiallyDone(const RegisterFile& regs,
}
reg::RB_DEPTHCONTROL GetNormalizedDepthControl(const RegisterFile& regs) {
xenos::ModeControl edram_mode = regs.Get<reg::RB_MODECONTROL>().edram_mode;
if (edram_mode != xenos::ModeControl::kColorDepth &&
edram_mode != xenos::ModeControl::kDepth) {
xenos::EdramMode edram_mode = regs.Get<reg::RB_MODECONTROL>().edram_mode;
if (edram_mode != xenos::EdramMode::kColorDepth &&
edram_mode != xenos::EdramMode::kDepthOnly) {
// Both depth and stencil disabled (EDRAM depth and stencil ignored).
reg::RB_DEPTHCONTROL disabled;
disabled.value = 0;
@@ -124,10 +124,10 @@ bool IsPixelShaderNeededWithRasterization(const Shader& shader,
assert_true(shader.type() == xenos::ShaderType::kPixel);
assert_true(shader.is_ucode_analyzed());
// See xenos::ModeControl for explanation why the pixel shader is only used
// when it's kColorDepth here.
// See xenos::EdramMode for explanation why the pixel shader is only used when
// it's kColorDepth here.
if (regs.Get<reg::RB_MODECONTROL>().edram_mode !=
xenos::ModeControl::kColorDepth) {
xenos::EdramMode::kColorDepth) {
return false;
}
@@ -340,7 +340,8 @@ void GetHostViewportInfo(const RegisterFile& regs,
offset_add_xy[0] += float(pa_sc_window_offset.window_x_offset);
offset_add_xy[1] += float(pa_sc_window_offset.window_y_offset);
}
if (cvars::half_pixel_offset && !pa_su_vtx_cntl.pix_center) {
if (cvars::half_pixel_offset &&
pa_su_vtx_cntl.pix_center == xenos::PixelCenter::kD3DZero) {
offset_add_xy[0] += 0.5f;
offset_add_xy[1] += 0.5f;
}
@@ -607,7 +608,7 @@ void GetScissor(const RegisterFile& regs, Scissor& scissor_out,
uint32_t GetNormalizedColorMask(const RegisterFile& regs,
uint32_t pixel_shader_writes_color_targets) {
if (regs.Get<reg::RB_MODECONTROL>().edram_mode !=
xenos::ModeControl::kColorDepth) {
xenos::EdramMode::kColorDepth) {
return 0;
}
uint32_t normalized_color_mask = 0;
@@ -838,7 +839,9 @@ bool GetResolveInfo(const RegisterFile& regs, const Memory& memory,
memory.TranslatePhysical(fetch.address * sizeof(uint32_t)));
// Most vertices have a negative half-pixel offset applied, which we reverse.
float half_pixel_offset =
regs.Get<reg::PA_SU_VTX_CNTL>().pix_center ? 0.0f : 0.5f;
regs.Get<reg::PA_SU_VTX_CNTL>().pix_center == xenos::PixelCenter::kD3DZero
? 0.5f
: 0.0f;
int32_t vertices_fixed[6];
for (size_t i = 0; i < xe::countof(vertices_fixed); ++i) {
vertices_fixed[i] = ui::FloatToD3D11Fixed16p8(
@@ -1097,7 +1100,9 @@ bool GetResolveInfo(const RegisterFile& regs, const Memory& memory,
bool fill_half_pixel_offset =
(draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) &&
cvars::resolve_resolution_scale_fill_half_pixel_offset &&
cvars::half_pixel_offset && !regs.Get<reg::PA_SU_VTX_CNTL>().pix_center;
cvars::half_pixel_offset &&
regs.Get<reg::PA_SU_VTX_CNTL>().pix_center ==
xenos::PixelCenter::kD3DZero;
int32_t exp_bias = is_depth ? 0 : rb_copy_dest_info.copy_dest_exp_bias;
ResolveEdramInfo depth_edram_info;
depth_edram_info.packed = 0;