mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
UberShaderPixel: always run indirect stage logic
Hardware testing has confirmed that fb_addprev and wrapping both run even when the indirect stage is disabled.
This commit is contained in:
@ -148,29 +148,18 @@ void PixelShaderManager::SetConstants()
|
|||||||
|
|
||||||
for (u32 i = 0; i < (bpmem.genMode.numtevstages + 1); ++i)
|
for (u32 i = 0; i < (bpmem.genMode.numtevstages + 1); ++i)
|
||||||
{
|
{
|
||||||
|
// Note: a tevind of zero just happens to be a passthrough, so no need
|
||||||
|
// to set an extra bit. Furthermore, wrap and add to previous apply even if there is no
|
||||||
|
// indirect stage.
|
||||||
|
constants.pack1[i][2] = bpmem.tevind[i].hex;
|
||||||
|
|
||||||
u32 stage = bpmem.tevind[i].bt;
|
u32 stage = bpmem.tevind[i].bt;
|
||||||
if (stage < bpmem.genMode.numindstages)
|
|
||||||
{
|
// We use an extra bit (1 << 16) to provide a fast way of testing if this feature is in use.
|
||||||
// We set some extra bits so the ubershader can quickly check if these
|
// Note also that this is indexed by indirect stage, not by TEV stage.
|
||||||
// features are in use.
|
if (bpmem.tevind[i].IsActive() && stage < bpmem.genMode.numindstages)
|
||||||
if (bpmem.tevind[i].IsActive())
|
|
||||||
constants.pack1[stage][3] =
|
constants.pack1[stage][3] =
|
||||||
bpmem.tevindref.getTexCoord(stage) | bpmem.tevindref.getTexMap(stage) << 8 | 1 << 16;
|
bpmem.tevindref.getTexCoord(stage) | bpmem.tevindref.getTexMap(stage) << 8 | 1 << 16;
|
||||||
// Note: a tevind of zero just happens to be a passthrough, so no need
|
|
||||||
// to set an extra bit.
|
|
||||||
constants.pack1[i][2] = bpmem.tevind[i].hex; // TODO: This match shadergen, but videosw
|
|
||||||
// will always wrap.
|
|
||||||
|
|
||||||
// The ubershader uses tevind != 0 as a condition whether to calculate texcoords,
|
|
||||||
// even when texture is disabled, instead of the stage < bpmem.genMode.numindstages.
|
|
||||||
// We set an unused bit here to indicate that the stage is active, even if it
|
|
||||||
// is just a pass-through.
|
|
||||||
constants.pack1[i][2] |= 0x80000000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
constants.pack1[i][2] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
@ -287,6 +287,8 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
|
|||||||
// ======================
|
// ======================
|
||||||
const auto LookupIndirectTexture = [&out, stereo](std::string_view out_var_name,
|
const auto LookupIndirectTexture = [&out, stereo](std::string_view out_var_name,
|
||||||
std::string_view in_index_name) {
|
std::string_view in_index_name) {
|
||||||
|
// in_index_name is the indirect stage, not the tev stage
|
||||||
|
// bpmem_iref is packed differently from RAS1_IREF
|
||||||
out.Write("{{\n"
|
out.Write("{{\n"
|
||||||
" uint iref = bpmem_iref({});\n"
|
" uint iref = bpmem_iref({});\n"
|
||||||
" if ( iref != 0u)\n"
|
" if ( iref != 0u)\n"
|
||||||
@ -304,6 +306,10 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
|
|||||||
"[texmap].xy, {})).abg;\n",
|
"[texmap].xy, {})).abg;\n",
|
||||||
in_index_name, in_index_name, in_index_name, in_index_name, out_var_name,
|
in_index_name, in_index_name, in_index_name, in_index_name, out_var_name,
|
||||||
stereo ? "float(layer)" : "0.0");
|
stereo ? "float(layer)" : "0.0");
|
||||||
|
// There is always a bit set in bpmem_iref if the data is valid (matrix is not off, and the
|
||||||
|
// indirect texture stage is enabled). If the matrix is off, the result doesn't matter; if the
|
||||||
|
// indirect texture stage is disabled, the result is undefined (and produces a glitchy pattern
|
||||||
|
// on hardware, different from this).
|
||||||
out.Write(" }}\n"
|
out.Write(" }}\n"
|
||||||
" else\n"
|
" else\n"
|
||||||
" {{\n"
|
" {{\n"
|
||||||
|
Reference in New Issue
Block a user