diff --git a/core/rend/vulkan/drawer.cpp b/core/rend/vulkan/drawer.cpp index 612e09ac1..b655eb8a3 100644 --- a/core/rend/vulkan/drawer.cpp +++ b/core/rend/vulkan/drawer.cpp @@ -232,16 +232,16 @@ void Drawer::DrawModVols(const vk::CommandBuffer& cmdBuffer, int first, int coun mod_base = param.first; if (!param.isp.VolumeLast && mv_mode > 0) - pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Or); // OR'ing (open volume or quad) + pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Or, param.isp.CullMode); // OR'ing (open volume or quad) else - pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Xor); // XOR'ing (closed volume) + pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Xor, param.isp.CullMode); // XOR'ing (closed volume) cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); cmdBuffer.draw(param.count * 3, 1, param.first * 3, 0); if (mv_mode == 1 || mv_mode == 2) { // Sum the area - pipeline = pipelineManager->GetModifierVolumePipeline(mv_mode == 1 ? ModVolMode::Inclusion : ModVolMode::Exclusion); + pipeline = pipelineManager->GetModifierVolumePipeline(mv_mode == 1 ? ModVolMode::Inclusion : ModVolMode::Exclusion, param.isp.CullMode); cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); cmdBuffer.draw((param.first + param.count - mod_base) * 3, 1, mod_base * 3, 0); mod_base = -1; @@ -253,7 +253,7 @@ void Drawer::DrawModVols(const vk::CommandBuffer& cmdBuffer, int first, int coun std::array pushConstants = { 1 - FPU_SHAD_SCALE.scale_factor / 256.f, 0, 0, 0, 0 }; cmdBuffer.pushConstants(pipelineManager->GetPipelineLayout(), vk::ShaderStageFlagBits::eFragment, 0, pushConstants); - pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Final); + pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Final, 0); cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); cmdBuffer.drawIndexed(4, 1, 0, 0, 0); } diff --git a/core/rend/vulkan/oit/oit_drawer.cpp b/core/rend/vulkan/oit/oit_drawer.cpp index 241bc31cd..fb6f06aaa 100644 --- a/core/rend/vulkan/oit/oit_drawer.cpp +++ b/core/rend/vulkan/oit/oit_drawer.cpp @@ -121,17 +121,17 @@ void OITDrawer::DrawModifierVolumes(const vk::CommandBuffer& cmdBuffer, int firs { // OR'ing (open volume or quad) if (Translucent) - pipeline = pipelineManager->GetTrModifierVolumePipeline(ModVolMode::Or); + pipeline = pipelineManager->GetTrModifierVolumePipeline(ModVolMode::Or, param.isp.CullMode); else - pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Or); + pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Or, param.isp.CullMode); } else { // XOR'ing (closed volume) if (Translucent) - pipeline = pipelineManager->GetTrModifierVolumePipeline(ModVolMode::Xor); + pipeline = pipelineManager->GetTrModifierVolumePipeline(ModVolMode::Xor, param.isp.CullMode); else - pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Xor); + pipeline = pipelineManager->GetModifierVolumePipeline(ModVolMode::Xor, param.isp.CullMode); } cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); cmdBuffer.draw(param.count * 3, 1, param.first * 3, 0); @@ -144,10 +144,10 @@ void OITDrawer::DrawModifierVolumes(const vk::CommandBuffer& cmdBuffer, int firs vk::MemoryBarrier barrier(vk::AccessFlagBits::eShaderWrite, vk::AccessFlagBits::eShaderRead); cmdBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader, vk::PipelineStageFlagBits::eFragmentShader, vk::DependencyFlagBits::eByRegion, barrier, nullptr, nullptr); - pipeline = pipelineManager->GetTrModifierVolumePipeline(mv_mode == 1 ? ModVolMode::Inclusion : ModVolMode::Exclusion); + pipeline = pipelineManager->GetTrModifierVolumePipeline(mv_mode == 1 ? ModVolMode::Inclusion : ModVolMode::Exclusion, param.isp.CullMode); } else - pipeline = pipelineManager->GetModifierVolumePipeline(mv_mode == 1 ? ModVolMode::Inclusion : ModVolMode::Exclusion); + pipeline = pipelineManager->GetModifierVolumePipeline(mv_mode == 1 ? ModVolMode::Inclusion : ModVolMode::Exclusion, param.isp.CullMode); cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); cmdBuffer.draw((param.first + param.count - mod_base) * 3, 1, mod_base * 3, 0); @@ -212,9 +212,16 @@ void OITDrawer::UploadMainBuffer(const OITDescriptorSets::VertexShaderUniforms& chunks.push_back(nullptr); chunkSizes.push_back(padding); - chunks.push_back(pvrrc.global_param_tr.head()); - chunkSizes.push_back(pvrrc.global_param_tr.bytes()); - u32 totalSize = offsets.polyParamsOffset + pvrrc.global_param_tr.bytes(); + std::vector trPolyParams(pvrrc.global_param_tr.used() * 2); + for (int i = 0; i < pvrrc.global_param_tr.used(); i++) + { + const PolyParam& pp = pvrrc.global_param_tr.head()[i]; + trPolyParams[i * 2] = (pp.tsp.full & 0xffff00c0) | ((pp.isp.full >> 16) & 0xe400) | ((pp.pcw.full >> 7) & 1); + trPolyParams[i * 2 + 1] = pp.tsp1.full; + } + chunks.push_back(trPolyParams.data()); + chunkSizes.push_back(trPolyParams.size() * 4); + u32 totalSize = offsets.polyParamsOffset + trPolyParams.size() * 4; BufferData *buffer = GetMainBuffer(totalSize); buffer->upload(chunks.size(), &chunkSizes[0], &chunks[0]); @@ -269,11 +276,12 @@ bool OITDrawer::Draw(const Texture *fogTexture) { const RenderPass& current_pass = pvrrc.render_passes.head()[render_pass]; - DEBUG_LOG(RENDERER, "Render pass %d OP %d PT %d TR %d MV %d autosort %d", render_pass + 1, + DEBUG_LOG(RENDERER, "Render pass %d OP %d PT %d TR %d MV %d TrMV %d autosort %d", render_pass + 1, current_pass.op_count - previous_pass.op_count, current_pass.pt_count - previous_pass.pt_count, current_pass.tr_count - previous_pass.tr_count, - current_pass.mvo_count - previous_pass.mvo_count, current_pass.autosort); + current_pass.mvo_count - previous_pass.mvo_count, + current_pass.mvo_tr_count - previous_pass.mvo_tr_count, current_pass.autosort); // Reset the pixel counter oitBuffers->ResetPixelCounter(cmdBuffer); diff --git a/core/rend/vulkan/oit/oit_drawer.h b/core/rend/vulkan/oit/oit_drawer.h index 3040a7048..3f058a9d4 100644 --- a/core/rend/vulkan/oit/oit_drawer.h +++ b/core/rend/vulkan/oit/oit_drawer.h @@ -119,6 +119,7 @@ public: screenPipelineManager->GetPerPolyDSLayout(), screenPipelineManager->GetColorInputDSLayout()); } + currentScreenScaling = 0; MakeFramebuffers(); } void Term() diff --git a/core/rend/vulkan/oit/oit_pipeline.cpp b/core/rend/vulkan/oit/oit_pipeline.cpp index 9575e67c4..385ac1cd5 100644 --- a/core/rend/vulkan/oit/oit_pipeline.cpp +++ b/core/rend/vulkan/oit/oit_pipeline.cpp @@ -53,7 +53,7 @@ void OITPipelineManager::CreatePipeline(u32 listType, bool autosort, const PolyP // Depth and stencil vk::CompareOp depthOp; - if (pass == 1) + if (pass == 1 && !pp.isp.ZWriteDis) depthOp = vk::CompareOp::eEqual; else if (listType == ListType_Punch_Through || autosort) depthOp = vk::CompareOp::eGreaterOrEqual; @@ -69,12 +69,17 @@ void OITPipelineManager::CreatePipeline(u32 listType, bool autosort, const PolyP else depthWriteEnable = !pp.isp.ZWriteDis; - bool shadowed = pass == 0 && (listType == ListType_Opaque || listType == ListType_Punch_Through) && pp.pcw.Shadow != 0; + bool shadowed = pass == 0 && (listType == ListType_Opaque || listType == ListType_Punch_Through); vk::StencilOpState stencilOpState; if (shadowed) - stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 0x80, 0x80); + { + if (pp.pcw.Shadow != 0) + stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 0x80, 0x80); + else + stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 0x80, 0); + } else - stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eAlways); + stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eNever); vk::PipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo ( vk::PipelineDepthStencilStateCreateFlags(), // flags @@ -346,7 +351,7 @@ void OITPipelineManager::CreateClearPipeline() clearPipeline = GetContext()->GetDevice().createGraphicsPipelineUnique(GetContext()->GetPipelineCache(), graphicsPipelineCreateInfo); } -void OITPipelineManager::CreateModVolPipeline(ModVolMode mode) +void OITPipelineManager::CreateModVolPipeline(ModVolMode mode, int cullMode) { verify(mode != ModVolMode::Final); @@ -379,7 +384,9 @@ void OITPipelineManager::CreateModVolPipeline(ModVolMode mode) false, // depthClampEnable false, // rasterizerDiscardEnable vk::PolygonMode::eFill, // polygonMode - vk::CullModeFlagBits::eNone, // cullMode + cullMode == 3 ? vk::CullModeFlagBits::eBack + : cullMode == 2 ? vk::CullModeFlagBits::eFront + : vk::CullModeFlagBits::eNone, // cullMode vk::FrontFace::eCounterClockwise, // frontFace false, // depthBiasEnable 0.0f, // depthBiasConstantFactor @@ -462,14 +469,12 @@ void OITPipelineManager::CreateModVolPipeline(ModVolMode mode) 0 // subpass ); - if (modVolPipelines.empty()) - modVolPipelines.resize((size_t)ModVolMode::Final); - modVolPipelines[(size_t)mode] = + modVolPipelines[hash(mode, cullMode)] = GetContext()->GetDevice().createGraphicsPipelineUnique(GetContext()->GetPipelineCache(), graphicsPipelineCreateInfo); } -void OITPipelineManager::CreateTrModVolPipeline(ModVolMode mode) +void OITPipelineManager::CreateTrModVolPipeline(ModVolMode mode, int cullMode) { verify(mode != ModVolMode::Final); @@ -502,7 +507,9 @@ void OITPipelineManager::CreateTrModVolPipeline(ModVolMode mode) false, // depthClampEnable false, // rasterizerDiscardEnable vk::PolygonMode::eFill, // polygonMode - vk::CullModeFlagBits::eNone, // cullMode + cullMode == 3 ? vk::CullModeFlagBits::eBack + : cullMode == 2 ? vk::CullModeFlagBits::eFront + : vk::CullModeFlagBits::eNone, // cullMode vk::FrontFace::eCounterClockwise, // frontFace false, // depthBiasEnable 0.0f, // depthBiasConstantFactor @@ -557,9 +564,7 @@ void OITPipelineManager::CreateTrModVolPipeline(ModVolMode mode) 2 // subpass ); - if (trModVolPipelines.empty()) - trModVolPipelines.resize((size_t)ModVolMode::Final); - trModVolPipelines[(size_t)mode] = + trModVolPipelines[hash(mode, cullMode)] = GetContext()->GetDevice().createGraphicsPipelineUnique(GetContext()->GetPipelineCache(), graphicsPipelineCreateInfo); } diff --git a/core/rend/vulkan/oit/oit_pipeline.h b/core/rend/vulkan/oit/oit_pipeline.h index 878ca7e76..195f7a24d 100644 --- a/core/rend/vulkan/oit/oit_pipeline.h +++ b/core/rend/vulkan/oit/oit_pipeline.h @@ -262,17 +262,25 @@ public: return *pipelines[pipehash]; } - vk::Pipeline GetModifierVolumePipeline(ModVolMode mode) + vk::Pipeline GetModifierVolumePipeline(ModVolMode mode, int cullMode) { - if (modVolPipelines.empty() || !modVolPipelines[(size_t)mode]) - CreateModVolPipeline(mode); - return *modVolPipelines[(size_t)mode]; + u32 pipehash = hash(mode, cullMode); + const auto &pipeline = modVolPipelines.find(pipehash); + if (pipeline != modVolPipelines.end()) + return pipeline->second.get(); + CreateModVolPipeline(mode, cullMode); + + return *modVolPipelines[pipehash]; } - vk::Pipeline GetTrModifierVolumePipeline(ModVolMode mode) + vk::Pipeline GetTrModifierVolumePipeline(ModVolMode mode, int cullMode) { - if (trModVolPipelines.empty() || !trModVolPipelines[(size_t)mode]) - CreateTrModVolPipeline(mode); - return *trModVolPipelines[(size_t)mode]; + u32 pipehash = hash(mode, cullMode); + const auto &pipeline = trModVolPipelines.find(pipehash); + if (pipeline != trModVolPipelines.end()) + return pipeline->second.get(); + CreateTrModVolPipeline(mode, cullMode); + + return *trModVolPipelines[pipehash]; } vk::Pipeline GetFinalPipeline(bool autosort) { @@ -295,8 +303,8 @@ public: vk::RenderPass GetRenderPass(bool initial, bool last) { return renderPasses->GetRenderPass(initial, last); } private: - void CreateModVolPipeline(ModVolMode mode); - void CreateTrModVolPipeline(ModVolMode mode); + void CreateModVolPipeline(ModVolMode mode, int cullMode); + void CreateTrModVolPipeline(ModVolMode mode, int cullMode); u32 hash(u32 listType, bool autosort, const PolyParam *pp, int pass) const { @@ -319,6 +327,10 @@ private: return hash; } + u32 hash(ModVolMode mode, int cullMode) const + { + return ((int)mode << 2) | cullMode; + } vk::PipelineVertexInputStateCreateInfo GetMainVertexInputStateCreateInfo(bool full = true) const { @@ -354,8 +366,8 @@ private: void CreateClearPipeline(); std::map pipelines; - std::vector modVolPipelines; - std::vector trModVolPipelines; + std::map modVolPipelines; + std::map trModVolPipelines; vk::UniquePipeline finalAutosortPipeline; vk::UniquePipeline finalNosortPipeline; vk::UniquePipeline clearPipeline; diff --git a/core/rend/vulkan/oit/oit_shaders.cpp b/core/rend/vulkan/oit/oit_shaders.cpp index b600d7b3d..14a96fab1 100644 --- a/core/rend/vulkan/oit/oit_shaders.cpp +++ b/core/rend/vulkan/oit/oit_shaders.cpp @@ -88,7 +88,7 @@ layout (std140, set = 0, binding = 1) uniform FragmentShaderUniforms layout(set = 3, binding = 2, r32ui) uniform coherent restrict uimage2D abufferPointerImg; struct Pixel { - vec4 color; + uint color; float depth; uint seq_num; uint next; @@ -126,26 +126,14 @@ void setFragDepth(void) gl_FragDepth = log2(1.0 + w) / 34.0; } struct PolyParam { - int first; - int count; - int texid_low; - int texid_high; - int tsp; - int tcw; - int pcw; - int isp; - float zvZ; - int tileclip; + int tsp_isp_pcw; int tsp1; - int tcw1; - int texid1_low; - int texid1_high; }; layout (set = 0, binding = 3, std430) readonly buffer TrPolyParamBuffer { PolyParam tr_poly_params[]; } TrPolyParam; -#define GET_TSP_FOR_AREA int tsp = area1 ? pp.tsp1 : pp.tsp; +#define GET_TSP_FOR_AREA int tsp = area1 ? pp.tsp1 : pp.tsp_isp_pcw; int getSrcBlendFunc(const PolyParam pp, bool area1) { @@ -197,17 +185,17 @@ int getShadingInstruction(const PolyParam pp, bool area1) int getDepthFunc(const PolyParam pp) { - return (pp.isp >> 29) & 7; + return (pp.tsp_isp_pcw >> 13) & 7; } bool getDepthMask(const PolyParam pp) { - return ((pp.isp >> 26) & 1) != 1; + return ((pp.tsp_isp_pcw >> 10) & 1) != 1; } bool getShadowEnable(const PolyParam pp) { - return ((pp.pcw >> 7) & 1) != 0; + return (pp.tsp_isp_pcw & 1) != 0; } uint getPolyNumber(const Pixel pixel) @@ -225,7 +213,17 @@ bool isShadowed(const Pixel pixel) bool isTwoVolumes(const PolyParam pp) { - return pp.tsp1 != -1 || pp.tcw1 != -1; + return pp.tsp1 != -1; +} + +uint packColors(vec4 v) +{ + return (uint(round(v.r * 255.0)) << 24) | (uint(round(v.g * 255.0)) << 16) | (uint(round(v.b * 255.0)) << 8) | uint(round(v.a * 255.0)); +} + +vec4 unpackColors(uint u) +{ + return vec4(float((u >> 24) & 255) / 255.0, float((u >> 16) & 255) / 255.0, float((u >> 8) & 255) / 255.0, float(u & 255) / 255.0); } )"; @@ -304,7 +302,7 @@ layout (location = 3) INTERPOLATION in lowp vec4 vtx_base1; // new for OIT. On layout (location = 4) INTERPOLATION in lowp vec4 vtx_offs1; layout (location = 5) in mediump vec2 vtx_uv1; -#if pp_FogCtrl != 2 +#if pp_FogCtrl != 2 || pp_TwoVolumes == 1 layout (set = 0, binding = 2) uniform sampler2D fog_table; float fog_mode2(float w) @@ -331,7 +329,7 @@ vec4 colorClamp(vec4 col) void main() { setFragDepth(); - + #if PASS == 3 // Manual depth testing highp float frontDepth = subpassLoad(DepthTex).r; @@ -548,7 +546,7 @@ void main() uint idx = getNextPixelIndex(); Pixel pixel; - pixel.color = color; + pixel.color = packColors(clamp(color, vec4(0.0), vec4(1.0))); pixel.depth = gl_FragDepth; pixel.seq_num = uint(pushConstants.pp_Number); pixel.next = imageAtomicExchange(abufferPointerImg, coords, idx); @@ -680,7 +678,7 @@ vec4 resolveAlphaBlend(ivec2 coords) { srcColor = secondaryBuffer; else { - srcColor = pixel.color; + srcColor = unpackColors(pixel.color); if (shadowed) srcColor.rgb *= uniformBuffer.shade_scale_factor; } diff --git a/core/rend/vulkan/pipeline.cpp b/core/rend/vulkan/pipeline.cpp index 32a1f7ecd..0a06ba5dc 100644 --- a/core/rend/vulkan/pipeline.cpp +++ b/core/rend/vulkan/pipeline.cpp @@ -23,7 +23,7 @@ #include "rend/osd.h" #include "quad.h" -void PipelineManager::CreateModVolPipeline(ModVolMode mode) +void PipelineManager::CreateModVolPipeline(ModVolMode mode, int cullMode) { // Vertex input state vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo; @@ -66,7 +66,9 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode) false, // depthClampEnable false, // rasterizerDiscardEnable vk::PolygonMode::eFill, // polygonMode - vk::CullModeFlagBits::eNone, // cullMode + cullMode == 3 ? vk::CullModeFlagBits::eBack + : cullMode == 2 ? vk::CullModeFlagBits::eFront + : vk::CullModeFlagBits::eNone, // cullMode vk::FrontFace::eCounterClockwise, // frontFace false, // depthBiasEnable 0.0f, // depthBiasConstantFactor @@ -161,9 +163,7 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode) renderPass // renderPass ); - if (modVolPipelines.empty()) - modVolPipelines.resize((size_t)ModVolMode::Final + 1); - modVolPipelines[(size_t)mode] = + modVolPipelines[hash(mode, cullMode)] = GetContext()->GetDevice().createGraphicsPipelineUnique(GetContext()->GetPipelineCache(), graphicsPipelineCreateInfo); } @@ -217,12 +217,17 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol depthWriteEnable = !pp.isp.ZWriteDis; } - bool shadowed = (listType == ListType_Opaque || listType == ListType_Punch_Through) && pp.pcw.Shadow != 0; + bool shadowed = listType == ListType_Opaque || listType == ListType_Punch_Through; vk::StencilOpState stencilOpState; if (shadowed) - stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 0x80, 0x80); + { + if (pp.pcw.Shadow != 0) + stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 0x80, 0x80); + else + stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 0x80, 0); + } else - stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eAlways); + stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eNever); vk::PipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo ( vk::PipelineDepthStencilStateCreateFlags(), // flags diff --git a/core/rend/vulkan/pipeline.h b/core/rend/vulkan/pipeline.h index a71ab7966..c203d7541 100644 --- a/core/rend/vulkan/pipeline.h +++ b/core/rend/vulkan/pipeline.h @@ -172,11 +172,15 @@ public: return *pipelines[pipehash]; } - vk::Pipeline GetModifierVolumePipeline(ModVolMode mode) + vk::Pipeline GetModifierVolumePipeline(ModVolMode mode, int cullMode) { - if (modVolPipelines.empty() || !modVolPipelines[(size_t)mode]) - CreateModVolPipeline(mode); - return *modVolPipelines[(size_t)mode]; + u32 pipehash = hash(mode, cullMode); + const auto &pipeline = modVolPipelines.find(pipehash); + if (pipeline != modVolPipelines.end()) + return pipeline->second.get(); + CreateModVolPipeline(mode, cullMode); + + return *modVolPipelines[pipehash]; } vk::PipelineLayout GetPipelineLayout() const { return *pipelineLayout; } vk::DescriptorSetLayout GetPerFrameDSLayout() const { return *perFrameLayout; } @@ -184,7 +188,7 @@ public: vk::RenderPass GetRenderPass() const { return renderPass; } private: - void CreateModVolPipeline(ModVolMode mode); + void CreateModVolPipeline(ModVolMode mode, int cullMode); u32 hash(u32 listType, bool sortTriangles, const PolyParam *pp) const { @@ -199,6 +203,10 @@ private: return hash; } + u32 hash(ModVolMode mode, int cullMode) const + { + return ((int)mode << 2) | cullMode; + } vk::PipelineVertexInputStateCreateInfo GetMainVertexInputStateCreateInfo(bool full = true) const { @@ -229,7 +237,7 @@ private: void CreatePipeline(u32 listType, bool sortTriangles, const PolyParam& pp); std::map pipelines; - std::vector modVolPipelines; + std::map modVolPipelines; vk::UniquePipelineLayout pipelineLayout; vk::UniqueDescriptorSetLayout perFrameLayout;