[GPU] Cleanup RB_COLOR_MASK and RB_DEPTHCONTROL normalization

This commit is contained in:
Triang3l
2022-02-13 20:50:31 +03:00
parent 8ca67b8aa7
commit 8d07c79897
8 changed files with 114 additions and 96 deletions

View File

@@ -2,7 +2,7 @@
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Copyright 2022 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
@@ -550,6 +550,49 @@ void GetScissor(const RegisterFile& regs, Scissor& scissor_out,
scissor_out.extent[1] = uint32_t(br_y - tl_y);
}
uint32_t GetNormalizedColorMask(const RegisterFile& regs,
uint32_t pixel_shader_writes_color_targets) {
if (regs.Get<reg::RB_MODECONTROL>().edram_mode !=
xenos::ModeControl::kColorDepth) {
return 0;
}
uint32_t normalized_color_mask = 0;
uint32_t rb_color_mask = regs[XE_GPU_REG_RB_COLOR_MASK].u32;
for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) {
// Exclude the render targets not statically written to by the pixel shader.
// If the shader doesn't write to a render target, it shouldn't be written
// to, and no ownership transfers should happen to it on the host even -
// otherwise, in 4D5307E6, one render target is being destroyed by a shader
// not writing anything, and in 58410955, the result of clearing the top
// tile is being ignored because there are 4 render targets bound with the
// same EDRAM base (clearly not correct usage), but the shader only clears
// 1, and then ownership of EDRAM portions by host render targets is
// conflicting.
if (!(pixel_shader_writes_color_targets & (uint32_t(1) << i))) {
continue;
}
// Check if any existing component is written to.
uint32_t format_component_mask =
(uint32_t(1) << xenos::GetColorRenderTargetFormatComponentCount(
regs.Get<reg::RB_COLOR_INFO>(
reg::RB_COLOR_INFO::rt_register_indices[i])
.color_format)) -
1;
uint32_t rt_write_mask = (rb_color_mask >> (4 * i)) & format_component_mask;
if (!rt_write_mask) {
continue;
}
// Mark the non-existent components as written so in the host driver, no
// slow path (involving reading and merging components) is taken if the
// driver doesn't perform this check internally, and some components are not
// included in the mask even though they actually don't exist in the format.
rt_write_mask |= 0b1111 & ~format_component_mask;
// Add to the normalized mask.
normalized_color_mask |= rt_write_mask << (4 * i);
}
return normalized_color_mask;
}
xenos::CopySampleSelect SanitizeCopySampleSelect(
xenos::CopySampleSelect copy_sample_select, xenos::MsaaSamples msaa_samples,
bool is_depth) {