diff --git a/src/Cafe/HW/Latte/Core/LatteShader.cpp b/src/Cafe/HW/Latte/Core/LatteShader.cpp index e0164584..3091e079 100644 --- a/src/Cafe/HW/Latte/Core/LatteShader.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShader.cpp @@ -9,6 +9,7 @@ #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h" #include "Cafe/OS/libs/gx2/GX2.h" // todo - remove dependency #include "Cafe/GraphicPack/GraphicPack2.h" +#include "HW/Latte/Core/Latte.h" #include "HW/Latte/Renderer/Renderer.h" #include "util/helpers/StringParser.h" #include "config/ActiveSettings.h" @@ -543,20 +544,7 @@ void LatteSHRC_UpdateVSBaseHash(uint8* vertexShaderPtr, uint32 vertexShaderSize, if (!usesGeometryShader) { - // Rasterization - bool rasterizationEnabled = !LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL(); - - // HACK - if (!LatteGPUState.contextNew.PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA()) - rasterizationEnabled = true; - - const auto& polygonControlReg = LatteGPUState.contextNew.PA_SU_SC_MODE_CNTL; - uint32 cullFront = polygonControlReg.get_CULL_FRONT(); - uint32 cullBack = polygonControlReg.get_CULL_BACK(); - if (cullFront && cullBack) - rasterizationEnabled = false; - - if (rasterizationEnabled) + if (LatteGPUState.contextNew.IsRasterizationEnabled()) vsHash += 51ULL; // Vertex fetch diff --git a/src/Cafe/HW/Latte/ISA/LatteReg.h b/src/Cafe/HW/Latte/ISA/LatteReg.h index d1a2a028..121d4e89 100644 --- a/src/Cafe/HW/Latte/ISA/LatteReg.h +++ b/src/Cafe/HW/Latte/ISA/LatteReg.h @@ -52,20 +52,20 @@ namespace Latte { // same as E_TILEMODE but contains additional options with special meaning TM_LINEAR_GENERAL = 0, - TM_LINEAR_ALIGNED = 1, + TM_LINEAR_ALIGNED = 1, // micro-tiled - TM_1D_TILED_THIN1 = 2, - TM_1D_TILED_THICK = 3, + TM_1D_TILED_THIN1 = 2, + TM_1D_TILED_THICK = 3, // macro-tiled - TM_2D_TILED_THIN1 = 4, - TM_2D_TILED_THIN2 = 5, - TM_2D_TILED_THIN4 = 6, - TM_2D_TILED_THICK = 7, + TM_2D_TILED_THIN1 = 4, + TM_2D_TILED_THIN2 = 5, + TM_2D_TILED_THIN4 = 6, + TM_2D_TILED_THICK = 7, - TM_2B_TILED_THIN1 = 8, - TM_2B_TILED_THIN2 = 9, + TM_2B_TILED_THIN1 = 8, + TM_2B_TILED_THIN2 = 9, TM_2B_TILED_THIN4 = 10, TM_2B_TILED_THICK = 11, @@ -179,7 +179,7 @@ namespace Latte HWFMT_4_4_4_4 = 0xB, HWFMT_5_5_5_1 = 0xC, HWFMT_32 = 0xD, - HWFMT_32_FLOAT = 0xE, + HWFMT_32_FLOAT = 0xE, HWFMT_16_16 = 0xF, HWFMT_16_16_FLOAT = 0x10, HWFMT_8_24 = 0x11, @@ -284,7 +284,7 @@ namespace Latte R32_G32_B32_A32_UINT = (HWFMT_32_32_32_32 | FMT_BIT_INT), R32_G32_B32_A32_SINT = (HWFMT_32_32_32_32 | FMT_BIT_INT | FMT_BIT_SIGNED), R32_G32_B32_A32_FLOAT = (HWFMT_32_32_32_32_FLOAT | FMT_BIT_FLOAT), - + // depth D24_S8_UNORM = (HWFMT_8_24), D24_S8_FLOAT = (HWFMT_8_24 | FMT_BIT_FLOAT), @@ -353,7 +353,7 @@ namespace Latte enum GPU_LIMITS { NUM_VERTEX_BUFFERS = 16, - NUM_TEXTURES_PER_STAGE = 18, + NUM_TEXTURES_PER_STAGE = 18, NUM_SAMPLERS_PER_STAGE = 18, // is this 16 or 18? NUM_COLOR_ATTACHMENTS = 8, }; @@ -1579,7 +1579,7 @@ struct LatteContextRegister /* +0x3A4C0 */ _LatteRegisterSetTextureUnit SQ_TEX_START_GS[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE]; uint8 padding_3A6B8[0x3C000 - 0x3A6B8]; - + /* +0x3C000 */ _LatteRegisterSetSampler SQ_TEX_SAMPLER[18 * 3]; /* +0x3C288 */ @@ -1598,6 +1598,24 @@ struct LatteContextRegister { return (uint32*)hleSpecialState; } + + bool IsRasterizationEnabled() const + { + bool rasterizationEnabled = !PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL(); + + // GX2SetSpecialState(0, true) enables DX_RASTERIZATION_KILL, but still expects depth writes to happen? -> Research which stages are disabled by DX_RASTERIZATION_KILL exactly + // for now we use a workaround: + if (!PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA()) + rasterizationEnabled = true; + + // Culling both front and back faces effectively disables rasterization + uint32 cullFront = PA_SU_SC_MODE_CNTL.get_CULL_FRONT(); + uint32 cullBack = PA_SU_SC_MODE_CNTL.get_CULL_BACK(); + if (cullFront && cullBack) + rasterizationEnabled = false; + + return rasterizationEnabled; + } }; static_assert(sizeof(LatteContextRegister) == 0x10000 * 4 + 9 * 4); @@ -1664,4 +1682,4 @@ static_assert(offsetof(LatteContextRegister, SQ_PGM_RESOURCES_ES) == Latte::REGA static_assert(offsetof(LatteContextRegister, SQ_PGM_START_GS) == Latte::REGADDR::SQ_PGM_START_GS * 4); static_assert(offsetof(LatteContextRegister, SQ_PGM_RESOURCES_GS) == Latte::REGADDR::SQ_PGM_RESOURCES_GS * 4); static_assert(offsetof(LatteContextRegister, SPI_VS_OUT_CONFIG) == Latte::REGADDR::SPI_VS_OUT_CONFIG * 4); -static_assert(offsetof(LatteContextRegister, LATTE_SPI_VS_OUT_ID_N) == Latte::REGADDR::SPI_VS_OUT_ID_0 * 4); \ No newline at end of file +static_assert(offsetof(LatteContextRegister, LATTE_SPI_VS_OUT_ID_N) == Latte::REGADDR::SPI_VS_OUT_ID_0 * 4); diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp index c4b50db1..1c731127 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp @@ -3938,21 +3938,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, bool fetchVertexManually = (usesGeometryShader || (shaderContext->fetchShader && shaderContext->fetchShader->mtlFetchVertexManually)); // Rasterization - rasterizationEnabled = true; - if (shader->shaderType == LatteConst::ShaderType::Vertex && !usesGeometryShader) - { - rasterizationEnabled = !shaderContext->contextRegistersNew->PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL(); - - // HACK - if (!shaderContext->contextRegistersNew->PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA()) - rasterizationEnabled = true; - - const auto& polygonControlReg = shaderContext->contextRegistersNew->PA_SU_SC_MODE_CNTL; - uint32 cullFront = polygonControlReg.get_CULL_FRONT(); - uint32 cullBack = polygonControlReg.get_CULL_BACK(); - if (cullFront && cullBack) - rasterizationEnabled = false; - } + rasterizationEnabled = shaderContext->contextRegistersNew->IsRasterizationEnabled(); StringBuf* src = new StringBuf(1024*1024*12); // reserve 12MB for generated source (we resize-to-fit at the end) shaderContext->shaderSource = src; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp index afd63f8b..1892c257 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp @@ -295,19 +295,7 @@ void MetalPipelineCompiler::InitFromState(const LatteFetchShader* fetchShader, c m_usesGeometryShader = (geometryShader != nullptr || isPrimitiveRect); // Rasterization - m_rasterizationEnabled = !lcr.PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL(); - - // HACK - // TODO: include this in the hash? - if (!lcr.PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA()) - m_rasterizationEnabled = true; - - // Culling both front and back faces effectively disables rasterization - const auto& polygonControlReg = lcr.PA_SU_SC_MODE_CNTL; - uint32 cullFront = polygonControlReg.get_CULL_FRONT(); - uint32 cullBack = polygonControlReg.get_CULL_BACK(); - if (cullFront && cullBack) - m_rasterizationEnabled = false; + m_rasterizationEnabled = lcr.IsRasterizationEnabled(); // Shaders m_vertexShaderMtl = static_cast(vertexShader->shader); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index fb284b80..b9e84db5 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -1065,15 +1065,7 @@ void MetalRenderer::draw_beginSequence() LatteRenderTarget_updateViewport(); LatteRenderTarget_updateScissorBox(); - // check for conditions which would turn the drawcalls into no-ops - bool rasterizerEnable = !LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL(); - - // GX2SetSpecialState(0, true) enables DX_RASTERIZATION_KILL, but still expects depth writes to happen? -> Research which stages are disabled by DX_RASTERIZATION_KILL exactly - // for now we use a workaround: - if (!LatteGPUState.contextNew.PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA()) - rasterizerEnable = true; - - if (!rasterizerEnable && !streamoutEnable) + if (!LatteGPUState.contextNew.IsRasterizationEnabled() && !streamoutEnable) m_state.m_skipDrawSequence = true; }