diff --git a/core/libs/prx/libSceAgc/Shader/include/ShaderConstants.hpp b/core/libs/prx/libSceAgc/Shader/include/ShaderConstants.hpp index 78a080587..14c803b8f 100644 --- a/core/libs/prx/libSceAgc/Shader/include/ShaderConstants.hpp +++ b/core/libs/prx/libSceAgc/Shader/include/ShaderConstants.hpp @@ -78,7 +78,7 @@ enum class PrimitiveType : std::uint32_t { }; constexpr std::uint32_t VGT_SHADER_STAGES_GS_BIT = 0x20u; -constexpr std::uint32_t VGT_SHADER_STAGES_NGG_BIT = 0x04u; +constexpr std::uint32_t VGT_SHADER_STAGES_HS_BIT = 0x04u; enum class AgcDirectResourceType : std::uint32_t { GdsCounterRange = 0, diff --git a/core/libs/prx/libSceAgc/Shader/src/PrimState.cpp b/core/libs/prx/libSceAgc/Shader/src/PrimState.cpp index 17b198724..9963ae2db 100644 --- a/core/libs/prx/libSceAgc/Shader/src/PrimState.cpp +++ b/core/libs/prx/libSceAgc/Shader/src/PrimState.cpp @@ -46,14 +46,17 @@ int APS5_VABI sceAgcCreatePrimState(ShaderRegister* cx_regs, ShaderRegister* uc_ } std::array primitiveValues{gs->specials->ge_cntl, hs != nullptr ? hs->specials->ge_user_vgpr_en : gs->specials->ge_user_vgpr_en, ShaderRegister{ShaderRegs::VGT_PRIMITIVE_TYPE, prim_type}}; const std::array stages{hs, gs}; - AgcDriverResolveGraphicsStagesAbi_nid_postfix(std::span(stages).subspan(hs == nullptr ? 1u : 0u), contextValues, primitiveValues); + const bool patch = prim_type == static_cast(ShaderRegs::PrimitiveType::Patch); + if (patch == ((contextValues[0].value & ShaderRegs::VGT_SHADER_STAGES_HS_BIT) != 0)) { + AgcDriverResolveGraphicsStagesAbi_nid_postfix(std::span(stages).subspan(hs == nullptr ? 1u : 0u), contextValues, primitiveValues); + } if (cx_regs != nullptr) std::copy(contextValues.begin(), contextValues.end(), cx_regs); if (uc_regs != nullptr) std::copy(primitiveValues.begin(), primitiveValues.end(), uc_regs); return 0; } int APS5_VABI sceAgcUpdatePrimState(ShaderRegister* cx_regs, ShaderRegister* uc_regs, std::uint32_t prim_type) { - if (cx_regs != nullptr && (cx_regs[0].value & (ShaderRegs::VGT_SHADER_STAGES_GS_BIT | ShaderRegs::VGT_SHADER_STAGES_NGG_BIT)) == 0) { + if (cx_regs != nullptr && (cx_regs[0].value & (ShaderRegs::VGT_SHADER_STAGES_GS_BIT | ShaderRegs::VGT_SHADER_STAGES_HS_BIT)) == 0) { cx_regs[1].value &= ~0x7u; cx_regs[1].value |= GraphicsPrimTypeToGsOut(prim_type); } diff --git a/core/libs/prx/libSceAgc/tests/ShaderHelpers.cpp b/core/libs/prx/libSceAgc/tests/ShaderHelpers.cpp index 4ad8bcab8..061ea5e82 100644 --- a/core/libs/prx/libSceAgc/tests/ShaderHelpers.cpp +++ b/core/libs/prx/libSceAgc/tests/ShaderHelpers.cpp @@ -110,6 +110,19 @@ int main() { } } } + preparations = 0; + std::array patchContext{}; + std::array patchPrimitive{}; + Require(sceAgcCreatePrimState(patchContext.data(), patchPrimitive.data(), nullptr, &vertex, 9) == 0); + Require(preparations == 0 && patchContext[0].offset == VGT_SHADER_STAGES_EN && patchContext[0].value == 0 && patchPrimitive[2].offset == VGT_PRIMITIVE_TYPE && patchPrimitive[2].value == 9); + ShaderSpecialRegs hullSpecial = special; + hullSpecial.vgt_shader_stages_en.value = VGT_SHADER_STAGES_HS_BIT; + hull.specials = &hullSpecial; + Require(sceAgcCreatePrimState(patchContext.data(), patchPrimitive.data(), &hull, &vertex, 4) == 0); + Require(preparations == 0 && patchContext[0].value == VGT_SHADER_STAGES_HS_BIT && patchPrimitive[2].value == 4); + Require(sceAgcCreatePrimState(patchContext.data(), patchPrimitive.data(), &hull, &vertex, 9) == 0); + Require(preparations == 1 && stageCount == 2 && preparedContext[0].value == VGT_SHADER_STAGES_HS_BIT && preparedPrimitive[2].value == 9 && patchPrimitive[2].value == 9); + hull.specials = &special; std::array linkedContext{}; std::array linkedPrimitive{}; for (auto& value : linkedContext) value.value = 0xdeadbeef; diff --git a/core/libs/tests/GuestShaderLink.cpp b/core/libs/tests/GuestShaderLink.cpp index 20ba2f0cd..b78b1ea7b 100644 --- a/core/libs/tests/GuestShaderLink.cpp +++ b/core/libs/tests/GuestShaderLink.cpp @@ -50,7 +50,7 @@ int main() { } Require(hasRenderTarget && hasRasterizer); ShaderSpecialRegs special{}; - special.vgt_shader_stages_en = {VGT_SHADER_STAGES_EN, VGT_SHADER_STAGES_NGG_BIT}; + special.vgt_shader_stages_en = {VGT_SHADER_STAGES_EN, 0x2000u}; special.vgt_gs_out_prim_type = {VGT_GS_OUT_PRIM_TYPE, 0}; special.ge_cntl = {GE_CNTL, 0x123}; special.ge_user_vgpr_en = {GE_USER_VGPR_EN, 7}; @@ -64,7 +64,7 @@ int main() { context.back() = {0xdeadbeef, 0xcafebabe}; primitive.back() = context.back(); Require(sceAgcLinkShaders(context.data(), primitive.data(), nullptr, &vertex, &pixel, 4) == 0); - Require(context[0].offset == VGT_SHADER_STAGES_EN && context[0].value == VGT_SHADER_STAGES_NGG_BIT); + Require(context[0].offset == VGT_SHADER_STAGES_EN && context[0].value == 0x2000u); Require(context[1].offset == VGT_GS_OUT_PRIM_TYPE && context[1].value == 2); for (unsigned i = 0; i < 32; ++i) Require(context[i + 2].offset == SPI_PS_INPUT_CNTL_0 + i && context[i + 2].value == i);