[DXBC] ROV: Force late Z write with kill instructions
This commit is contained in:
parent
9349cf4ff4
commit
bc0c2040e2
|
@ -189,12 +189,12 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
kSysFlag_ROVStencilTest_Shift,
|
kSysFlag_ROVStencilTest_Shift,
|
||||||
// If the depth/stencil test has failed, but resulted in a stencil value
|
// If the depth/stencil test has failed, but resulted in a stencil value
|
||||||
// that is different than the one currently in the depth buffer, write it
|
// that is different than the one currently in the depth buffer, write it
|
||||||
// anyway and don't run the shader (to check if the sample may be discarded
|
// anyway and don't run the rest of the shader (to check if the sample may
|
||||||
// some way). This, however, also results in depth/stencil testing done
|
// be discarded some way) - use when alpha test and alpha to coverage are
|
||||||
// entirely early even when it passes to prevent writing in divergent places
|
// disabled. Ignored by the shader if not applicable to it (like if it has
|
||||||
// in the shader. When the shader can kill, this must be set only for
|
// kill instructions or writes the depth output).
|
||||||
// RB_DEPTHCONTROL EARLY_Z_ENABLE, not for alpha test/alpha to coverage
|
// TODO(Triang3l): Replace with an alpha-to-mask flag, check if
|
||||||
// disabled.
|
// (flags & (alpha test | alpha to mask)) == (always | disabled).
|
||||||
kSysFlag_ROVDepthStencilEarlyWrite_Shift,
|
kSysFlag_ROVDepthStencilEarlyWrite_Shift,
|
||||||
|
|
||||||
kSysFlag_Count,
|
kSysFlag_Count,
|
||||||
|
|
|
@ -1024,51 +1024,60 @@ void DxbcShaderTranslator::ROV_DepthStencilTest() {
|
||||||
// temp.z = viewport maximum depth if not writing to oDepth
|
// temp.z = viewport maximum depth if not writing to oDepth
|
||||||
// temp.w = whether depth/stencil has been modified
|
// temp.w = whether depth/stencil has been modified
|
||||||
DxbcOpINE(temp_w_dest, sample_depth_stencil_src, temp_w_src);
|
DxbcOpINE(temp_w_dest, sample_depth_stencil_src, temp_w_src);
|
||||||
// Check if need to write.
|
if (depth_stencil_early && !CanWriteZEarly()) {
|
||||||
// temp.x? = resulting sample depth/stencil
|
// Set the sample bit in bits 4:7 of system_temp_rov_params_.x - always
|
||||||
// temp.y = polygon offset if not writing to oDepth
|
// need to write late in this shader, as it may do something like
|
||||||
// temp.z = viewport maximum depth if not writing to oDepth
|
// explicitly killing pixels.
|
||||||
// temp.w = free
|
DxbcOpBFI(DxbcDest::R(system_temp_rov_params_, 0b0001), DxbcSrc::LU(1),
|
||||||
DxbcOpIf(true, temp_w_src);
|
DxbcSrc::LU(4 + i), temp_w_src,
|
||||||
{
|
DxbcSrc::R(system_temp_rov_params_, DxbcSrc::kXXXX));
|
||||||
if (depth_stencil_early) {
|
} else {
|
||||||
// Get if early depth/stencil write is enabled to temp.w.
|
// Check if need to write.
|
||||||
// temp.w = whether early depth/stencil write is enabled
|
// temp.x? = resulting sample depth/stencil
|
||||||
system_constants_used_ |= 1ull << kSysConst_Flags_Index;
|
// temp.y = polygon offset if not writing to oDepth
|
||||||
DxbcOpAnd(temp_w_dest,
|
// temp.z = viewport maximum depth if not writing to oDepth
|
||||||
DxbcSrc::CB(cbuffer_index_system_constants_,
|
// temp.w = free
|
||||||
uint32_t(CbufferRegister::kSystemConstants),
|
DxbcOpIf(true, temp_w_src);
|
||||||
kSysConst_Flags_Vec)
|
{
|
||||||
.Select(kSysConst_Flags_Comp),
|
if (depth_stencil_early) {
|
||||||
DxbcSrc::LU(kSysFlag_ROVDepthStencilEarlyWrite));
|
// Get if early depth/stencil write is enabled to temp.w.
|
||||||
// Check if need to write early.
|
// temp.w = whether early depth/stencil write is enabled
|
||||||
// temp.w = free
|
system_constants_used_ |= 1ull << kSysConst_Flags_Index;
|
||||||
DxbcOpIf(true, temp_w_src);
|
DxbcOpAnd(temp_w_dest,
|
||||||
}
|
DxbcSrc::CB(cbuffer_index_system_constants_,
|
||||||
// Write the new depth/stencil.
|
uint32_t(CbufferRegister::kSystemConstants),
|
||||||
if (uav_index_edram_ == kBindingIndexUnallocated) {
|
kSysConst_Flags_Vec)
|
||||||
uav_index_edram_ = uav_count_++;
|
.Select(kSysConst_Flags_Comp),
|
||||||
}
|
DxbcSrc::LU(kSysFlag_ROVDepthStencilEarlyWrite));
|
||||||
DxbcOpStoreUAVTyped(
|
// Check if need to write early.
|
||||||
DxbcDest::U(uav_index_edram_, uint32_t(UAVRegister::kEdram)),
|
// temp.w = free
|
||||||
DxbcSrc::R(system_temp_rov_params_, DxbcSrc::kYYYY), 1,
|
DxbcOpIf(true, temp_w_src);
|
||||||
sample_depth_stencil_src);
|
}
|
||||||
if (depth_stencil_early) {
|
// Write the new depth/stencil.
|
||||||
// Need to still run the shader to know whether to write the
|
if (uav_index_edram_ == kBindingIndexUnallocated) {
|
||||||
// depth/stencil value.
|
uav_index_edram_ = uav_count_++;
|
||||||
DxbcOpElse();
|
}
|
||||||
// Set sample bit out of bits 4:7 of system_temp_rov_params_.x if need
|
DxbcOpStoreUAVTyped(
|
||||||
// to write later (after checking if the sample is not discarded by a
|
DxbcDest::U(uav_index_edram_, uint32_t(UAVRegister::kEdram)),
|
||||||
// kill instruction, alphatest or alpha-to-coverage).
|
DxbcSrc::R(system_temp_rov_params_, DxbcSrc::kYYYY), 1,
|
||||||
DxbcOpOr(DxbcDest::R(system_temp_rov_params_, 0b0001),
|
sample_depth_stencil_src);
|
||||||
DxbcSrc::R(system_temp_rov_params_, DxbcSrc::kXXXX),
|
if (depth_stencil_early) {
|
||||||
DxbcSrc::LU(1 << (4 + i)));
|
// Need to still run the shader to know whether to write the
|
||||||
// Close the early depth/stencil check.
|
// depth/stencil value.
|
||||||
DxbcOpEndIf();
|
DxbcOpElse();
|
||||||
|
// Set the sample bit in bits 4:7 of system_temp_rov_params_.x if need
|
||||||
|
// to write later (after checking if the sample is not discarded by a
|
||||||
|
// kill instruction, alphatest or alpha-to-coverage).
|
||||||
|
DxbcOpOr(DxbcDest::R(system_temp_rov_params_, 0b0001),
|
||||||
|
DxbcSrc::R(system_temp_rov_params_, DxbcSrc::kXXXX),
|
||||||
|
DxbcSrc::LU(1 << (4 + i)));
|
||||||
|
// Close the early depth/stencil check.
|
||||||
|
DxbcOpEndIf();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Close the write check.
|
||||||
|
DxbcOpEndIf();
|
||||||
}
|
}
|
||||||
// Close the write check.
|
|
||||||
DxbcOpEndIf();
|
|
||||||
|
|
||||||
// Release sample_temp.
|
// Release sample_temp.
|
||||||
PopSystemTemp();
|
PopSystemTemp();
|
||||||
|
|
Loading…
Reference in New Issue