[GPU] Cleanup RB_COLOR_MASK and RB_DEPTHCONTROL normalization
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user