vulkan: fix modvols. fix depth-write disabled poly. optimizations
stencil must be reset to zero if poly isn't shadowed -> fixes jet set radio "see-through" shadows take culling into account for modvols oit: reduce per-pixel and per-poly mem usage oit: framebuffers weren't resized when needed oit: poly with depth write disabled weren't drawn (Soul calibur missing water surface) Fix glsl error when two-volume mode needs fog attachment
This commit is contained in:
parent
21b2eb3e5d
commit
4730da31d5
|
@ -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<float, 5> pushConstants = { 1 - FPU_SHAD_SCALE.scale_factor / 256.f, 0, 0, 0, 0 };
|
||||
cmdBuffer.pushConstants<float>(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);
|
||||
}
|
||||
|
|
|
@ -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<u32> 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);
|
||||
|
|
|
@ -119,6 +119,7 @@ public:
|
|||
screenPipelineManager->GetPerPolyDSLayout(),
|
||||
screenPipelineManager->GetColorInputDSLayout());
|
||||
}
|
||||
currentScreenScaling = 0;
|
||||
MakeFramebuffers();
|
||||
}
|
||||
void Term()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<u32, vk::UniquePipeline> pipelines;
|
||||
std::vector<vk::UniquePipeline> modVolPipelines;
|
||||
std::vector<vk::UniquePipeline> trModVolPipelines;
|
||||
std::map<u32, vk::UniquePipeline> modVolPipelines;
|
||||
std::map<u32, vk::UniquePipeline> trModVolPipelines;
|
||||
vk::UniquePipeline finalAutosortPipeline;
|
||||
vk::UniquePipeline finalNosortPipeline;
|
||||
vk::UniquePipeline clearPipeline;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<u32, vk::UniquePipeline> pipelines;
|
||||
std::vector<vk::UniquePipeline> modVolPipelines;
|
||||
std::map<u32, vk::UniquePipeline> modVolPipelines;
|
||||
|
||||
vk::UniquePipelineLayout pipelineLayout;
|
||||
vk::UniqueDescriptorSetLayout perFrameLayout;
|
||||
|
|
Loading…
Reference in New Issue