vulkan: modifier volumes
This commit is contained in:
parent
8d520fa5e4
commit
b790a336e9
|
@ -67,19 +67,19 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
|||
|
||||
if (mode == ModVolMode::Final)
|
||||
{
|
||||
pipelineVertexInputStateCreateInfo = GetMainVertexInputStateCreateInfo();
|
||||
pipelineVertexInputStateCreateInfo = GetMainVertexInputStateCreateInfo(false);
|
||||
pipelineInputAssemblyStateCreateInfo = vk::PipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(),
|
||||
vk::PrimitiveTopology::eTriangleStrip);
|
||||
}
|
||||
else
|
||||
{
|
||||
const vk::VertexInputBindingDescription vertexBindingDescriptions[] =
|
||||
static const vk::VertexInputBindingDescription vertexBindingDescriptions[] =
|
||||
{
|
||||
{ 0, sizeof(ModTriangle) },
|
||||
{ 0, sizeof(float) * 3 },
|
||||
};
|
||||
const vk::VertexInputAttributeDescription vertexInputAttributeDescriptions[] =
|
||||
static const vk::VertexInputAttributeDescription vertexInputAttributeDescriptions[] =
|
||||
{
|
||||
vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, x)), // pos
|
||||
vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, 0), // pos
|
||||
};
|
||||
pipelineVertexInputStateCreateInfo = vk::PipelineVertexInputStateCreateInfo(
|
||||
vk::PipelineVertexInputStateCreateFlags(),
|
||||
|
@ -99,7 +99,7 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
|||
(
|
||||
vk::PipelineRasterizationStateCreateFlags(), // flags
|
||||
false, // depthClampEnable
|
||||
mode != ModVolMode::Final, // rasterizerDiscardEnable
|
||||
false, // rasterizerDiscardEnable
|
||||
vk::PolygonMode::eFill, // polygonMode
|
||||
vk::CullModeFlagBits::eNone, // cullMode
|
||||
vk::FrontFace::eCounterClockwise, // frontFace
|
||||
|
@ -122,10 +122,10 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
|||
stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 2, 2, 2);
|
||||
break;
|
||||
case ModVolMode::Inclusion:
|
||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eZero, vk::StencilOp::eReplace, vk::StencilOp::eZero, vk::CompareOp::eLessOrEqual, 1, 3, 3);
|
||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eZero, vk::StencilOp::eReplace, vk::StencilOp::eZero, vk::CompareOp::eLessOrEqual, 3, 3, 1);
|
||||
break;
|
||||
case ModVolMode::Exclusion:
|
||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eZero, vk::StencilOp::eKeep, vk::StencilOp::eZero, vk::CompareOp::eEqual, 1, 3, 3);
|
||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eZero, vk::StencilOp::eKeep, vk::StencilOp::eZero, vk::CompareOp::eEqual, 3, 3, 1);
|
||||
break;
|
||||
case ModVolMode::Final:
|
||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eZero, vk::StencilOp::eZero, vk::StencilOp::eZero, vk::CompareOp::eEqual, 0x81, 3, 0x81);
|
||||
|
@ -140,11 +140,13 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
|||
false, // depthBoundTestEnable
|
||||
true, // stencilTestEnable
|
||||
stencilOpState, // front
|
||||
vk::StencilOpState() // back
|
||||
stencilOpState // back
|
||||
);
|
||||
|
||||
// Color flags and blending
|
||||
vk::ColorComponentFlags colorComponentFlags(vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA);
|
||||
vk::ColorComponentFlags colorComponentFlags(
|
||||
mode != ModVolMode::Final ? (vk::ColorComponentFlagBits)0
|
||||
: vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA);
|
||||
vk::PipelineColorBlendAttachmentState pipelineColorBlendAttachmentState(
|
||||
mode == ModVolMode::Final, // blendEnable
|
||||
vk::BlendFactor::eSrcAlpha, // srcColorBlendFactor
|
||||
|
@ -169,7 +171,7 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
|||
vk::DynamicState dynamicStates[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
||||
vk::PipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo(vk::PipelineDynamicStateCreateFlags(), 2, dynamicStates);
|
||||
|
||||
vk::ShaderModule vertex_module = shaderManager.GetVertexShader(VertexShaderParams{ false, false }); // TODO rotate90
|
||||
vk::ShaderModule vertex_module = shaderManager.GetModVolVertexShader();
|
||||
vk::ShaderModule fragment_module = shaderManager.GetModVolShader();
|
||||
|
||||
vk::PipelineShaderStageCreateInfo stages[] = {
|
||||
|
@ -195,7 +197,7 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
|||
);
|
||||
|
||||
if (modVolPipelines.empty())
|
||||
modVolPipelines.reserve((size_t)ModVolMode::Final + 1);
|
||||
modVolPipelines.resize((size_t)ModVolMode::Final + 1);
|
||||
modVolPipelines[(size_t)mode] =
|
||||
GetContext()->GetDevice()->createGraphicsPipelineUnique(GetContext()->GetPipelineCache(),
|
||||
graphicsPipelineCreateInfo);
|
||||
|
@ -250,7 +252,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
|
|||
depthWriteEnable = !pp.isp.ZWriteDis;
|
||||
}
|
||||
|
||||
vk::StencilOpState stencilOpStateSet(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 0x80, 0x80);
|
||||
vk::StencilOpState stencilOpStateSet(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 0x80, 0x80);
|
||||
vk::StencilOpState stencilOpStateNop(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eAlways);
|
||||
vk::PipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo
|
||||
(
|
||||
|
@ -261,7 +263,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
|
|||
false, // depthBoundTestEnable
|
||||
listType == ListType_Opaque || listType == ListType_Punch_Through, // stencilTestEnable
|
||||
pp.pcw.Shadow != 0 ? stencilOpStateSet : stencilOpStateNop, // front
|
||||
stencilOpStateNop // back
|
||||
pp.pcw.Shadow != 0 ? stencilOpStateSet : stencilOpStateNop // back
|
||||
);
|
||||
|
||||
// Color flags and blending
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
void UpdateUniforms(const vk::Buffer& vertexUniformBuffer, const vk::Buffer& fragmentUniformBuffer, vk::ImageView fogImageView)
|
||||
{
|
||||
while (perFrameDescSets.empty())
|
||||
if (perFrameDescSets.empty())
|
||||
{
|
||||
std::vector<vk::DescriptorSetLayout> layouts(GetContext()->GetSwapChainSize(), *perFrameLayout);
|
||||
perFrameDescSets = GetContext()->GetDevice()->allocateDescriptorSetsUnique(
|
||||
|
@ -170,6 +170,13 @@ public:
|
|||
return *pipelines[pipehash];
|
||||
}
|
||||
|
||||
vk::Pipeline GetModifierVolumePipeline(ModVolMode mode)
|
||||
{
|
||||
if (modVolPipelines.empty() || !modVolPipelines[(size_t)mode])
|
||||
CreateModVolPipeline(mode);
|
||||
return *modVolPipelines[(size_t)mode];
|
||||
}
|
||||
|
||||
private:
|
||||
VulkanContext *GetContext() const { return VulkanContext::Instance(); }
|
||||
void CreateModVolPipeline(ModVolMode mode);
|
||||
|
@ -189,7 +196,7 @@ private:
|
|||
return hash;
|
||||
}
|
||||
|
||||
vk::PipelineVertexInputStateCreateInfo GetMainVertexInputStateCreateInfo() const
|
||||
vk::PipelineVertexInputStateCreateInfo GetMainVertexInputStateCreateInfo(bool full = true) const
|
||||
{
|
||||
// Vertex input state
|
||||
static const vk::VertexInputBindingDescription vertexBindingDescriptions[] =
|
||||
|
@ -203,12 +210,16 @@ private:
|
|||
vk::VertexInputAttributeDescription(2, 0, vk::Format::eR8G8B8A8Uint, offsetof(Vertex, spc)), // offset color
|
||||
vk::VertexInputAttributeDescription(3, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, u)), // tex coord
|
||||
};
|
||||
static const vk::VertexInputAttributeDescription vertexInputLightAttributeDescriptions[] =
|
||||
{
|
||||
vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, x)), // pos
|
||||
};
|
||||
return vk::PipelineVertexInputStateCreateInfo(
|
||||
vk::PipelineVertexInputStateCreateFlags(),
|
||||
ARRAY_SIZE(vertexBindingDescriptions),
|
||||
vertexBindingDescriptions,
|
||||
ARRAY_SIZE(vertexInputAttributeDescriptions),
|
||||
vertexInputAttributeDescriptions);
|
||||
full ? ARRAY_SIZE(vertexInputAttributeDescriptions) : ARRAY_SIZE(vertexInputLightAttributeDescriptions),
|
||||
full ? vertexInputAttributeDescriptions : vertexInputLightAttributeDescriptions);
|
||||
}
|
||||
|
||||
void CreatePipeline(u32 listType, bool sortTriangles, const PolyParam& pp);
|
||||
|
|
|
@ -251,23 +251,53 @@ void main()
|
|||
}
|
||||
)";
|
||||
|
||||
static const char ModVolShaderSource[] = R"(
|
||||
static const char ModVolVertexShaderSource[] = R"(
|
||||
#version 400
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
out vec4 FragColor;
|
||||
layout (std140, set = 0, binding = 0) uniform VertexShaderUniforms
|
||||
{
|
||||
vec4 scale;
|
||||
float extra_depth_scale;
|
||||
} uniformBuffer;
|
||||
|
||||
layout (std140, binding = 1) uniform buffer
|
||||
layout (location = 0) in vec4 in_pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 vpos = in_pos;
|
||||
if (vpos.z < 0.0 || vpos.z > 3.4e37)
|
||||
{
|
||||
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
|
||||
return;
|
||||
}
|
||||
|
||||
vpos.w = uniformBuffer.extra_depth_scale / vpos.z;
|
||||
vpos.z = vpos.w;
|
||||
vpos.xy = vpos.xy * uniformBuffer.scale.xy - uniformBuffer.scale.zw;
|
||||
vpos.xy *= vpos.w;
|
||||
gl_Position = vpos;
|
||||
}
|
||||
)";
|
||||
|
||||
static const char ModVolFragmentShaderSource[] = R"(
|
||||
#version 400
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (push_constant) uniform pushBlock
|
||||
{
|
||||
float sp_ShaderColor;
|
||||
} uniformBuffer;
|
||||
} pushConstants;
|
||||
|
||||
void main()
|
||||
{
|
||||
float w = gl_FragCoord.w * 100000.0;
|
||||
gl_FragDepth = log2(1.0 + w) / 34.0;
|
||||
FragColor = vec4(0.0, 0.0, 0.0, uniformBuffer.sp_ShaderColor);
|
||||
FragColor = vec4(0.0, 0.0, 0.0, pushConstants.sp_ShaderColor);
|
||||
}
|
||||
)";
|
||||
|
||||
|
@ -468,7 +498,12 @@ vk::UniqueShaderModule ShaderManager::compileShader(const FragmentShaderParams&
|
|||
return createShaderModule(VulkanContext::Instance()->GetDevice(), vk::ShaderStageFlagBits::eFragment, buf);
|
||||
}
|
||||
|
||||
vk::UniqueShaderModule ShaderManager::compileVertexModVolShader()
|
||||
{
|
||||
return createShaderModule(VulkanContext::Instance()->GetDevice(), vk::ShaderStageFlagBits::eVertex, ModVolVertexShaderSource);
|
||||
}
|
||||
|
||||
vk::UniqueShaderModule ShaderManager::compileModVolShader()
|
||||
{
|
||||
return createShaderModule(VulkanContext::Instance()->GetDevice(), vk::ShaderStageFlagBits::eFragment, ModVolShaderSource);
|
||||
return createShaderModule(VulkanContext::Instance()->GetDevice(), vk::ShaderStageFlagBits::eFragment, ModVolFragmentShaderSource);
|
||||
}
|
||||
|
|
|
@ -74,11 +74,6 @@ struct FragmentShaderUniforms
|
|||
float extra_depth_scale;
|
||||
};
|
||||
|
||||
struct ModVolShaderUniforms
|
||||
{
|
||||
float sp_ShaderColor;
|
||||
};
|
||||
|
||||
class ShaderManager
|
||||
{
|
||||
public:
|
||||
|
@ -88,6 +83,12 @@ public:
|
|||
}
|
||||
vk::ShaderModule GetVertexShader(const VertexShaderParams& params) { return getShader(vertexShaders, params); }
|
||||
vk::ShaderModule GetFragmentShader(const FragmentShaderParams& params) { return getShader(fragmentShaders, params); }
|
||||
vk::ShaderModule GetModVolVertexShader()
|
||||
{
|
||||
if (!modVolVertexShader)
|
||||
modVolVertexShader = compileVertexModVolShader();
|
||||
return *modVolVertexShader;
|
||||
}
|
||||
vk::ShaderModule GetModVolShader()
|
||||
{
|
||||
if (!modVolShader)
|
||||
|
@ -107,9 +108,11 @@ private:
|
|||
}
|
||||
vk::UniqueShaderModule compileShader(const VertexShaderParams& params);
|
||||
vk::UniqueShaderModule compileShader(const FragmentShaderParams& params);
|
||||
vk::UniqueShaderModule compileVertexModVolShader();
|
||||
vk::UniqueShaderModule compileModVolShader();
|
||||
|
||||
std::map<u32, vk::UniqueShaderModule> vertexShaders;
|
||||
std::map<u32, vk::UniqueShaderModule> fragmentShaders;
|
||||
vk::UniqueShaderModule modVolVertexShader;
|
||||
vk::UniqueShaderModule modVolShader;
|
||||
};
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
static VulkanContext *Instance() { return contextInstance; }
|
||||
|
||||
private:
|
||||
void InitDepthBuffer();
|
||||
vk::Format InitDepthBuffer();
|
||||
void InitImgui();
|
||||
|
||||
bool HasSurfaceDimensionChanged()
|
||||
|
|
|
@ -144,23 +144,31 @@ void VulkanContext::InitInstance(const char** extensions, uint32_t extensions_co
|
|||
}
|
||||
}
|
||||
|
||||
void VulkanContext::InitDepthBuffer()
|
||||
vk::Format VulkanContext::InitDepthBuffer()
|
||||
{
|
||||
const vk::Format depthFormat = vk::Format::eD16Unorm;
|
||||
vk::FormatProperties formatProperties = physicalDevice.getFormatProperties(depthFormat);
|
||||
|
||||
const vk::Format depthFormats[] = { vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint };
|
||||
vk::ImageTiling tiling;
|
||||
vk::Format depthFormat = vk::Format::eUndefined;
|
||||
for (int i = 0; i < ARRAY_SIZE(depthFormats); i++)
|
||||
{
|
||||
vk::FormatProperties formatProperties = physicalDevice.getFormatProperties(depthFormats[i]);
|
||||
|
||||
if (formatProperties.linearTilingFeatures & vk::FormatFeatureFlagBits::eDepthStencilAttachment)
|
||||
{
|
||||
tiling = vk::ImageTiling::eLinear;
|
||||
depthFormat = depthFormats[i];
|
||||
break;
|
||||
}
|
||||
else if (formatProperties.optimalTilingFeatures & vk::FormatFeatureFlagBits::eDepthStencilAttachment)
|
||||
{
|
||||
tiling = vk::ImageTiling::eOptimal;
|
||||
depthFormat = depthFormats[i];
|
||||
break;
|
||||
}
|
||||
else
|
||||
}
|
||||
if (depthFormat == vk::Format::eUndefined)
|
||||
{
|
||||
die("DepthStencilAttachment is not supported for D16Unorm depth format.");
|
||||
die("No supported depth/stencil format found");
|
||||
}
|
||||
|
||||
vk::ImageCreateInfo imageCreateInfo(vk::ImageCreateFlags(), vk::ImageType::e2D, depthFormat, vk::Extent3D(width, height, 1), 1, 1, vk::SampleCountFlagBits::e1, tiling, vk::ImageUsageFlagBits::eDepthStencilAttachment);
|
||||
|
@ -187,6 +195,8 @@ void VulkanContext::InitDepthBuffer()
|
|||
vk::ComponentMapping componentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA);
|
||||
vk::ImageSubresourceRange subResourceRange(vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1);
|
||||
depthView = device->createImageViewUnique(vk::ImageViewCreateInfo(vk::ImageViewCreateFlags(), *depthImage, vk::ImageViewType::e2D, depthFormat, componentMapping, subResourceRange));
|
||||
|
||||
return depthFormat;
|
||||
}
|
||||
|
||||
void VulkanContext::InitImgui()
|
||||
|
@ -415,8 +425,9 @@ void VulkanContext::CreateSwapChain()
|
|||
commandBuffers.push_back(std::move(device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(*commandPools.back(), vk::CommandBufferLevel::ePrimary, 1)).front()));
|
||||
}
|
||||
|
||||
vk::Format depthFormat = InitDepthBuffer();
|
||||
|
||||
// Render pass
|
||||
vk::Format depthFormat = vk::Format::eD16Unorm;
|
||||
vk::AttachmentDescription attachmentDescriptions[2];
|
||||
// FIXME we should use vk::AttachmentLoadOp::eLoad for loadOp to preserve previous framebuffer but it fails on the first render
|
||||
attachmentDescriptions[0] = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), colorFormat, vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear,
|
||||
|
@ -430,8 +441,6 @@ void VulkanContext::CreateSwapChain()
|
|||
|
||||
renderPass = device->createRenderPassUnique(vk::RenderPassCreateInfo(vk::RenderPassCreateFlags(), 2, attachmentDescriptions, 1, &subpass));
|
||||
|
||||
InitDepthBuffer();
|
||||
|
||||
// Framebuffers, fences, semaphores
|
||||
vk::ImageView attachments[2];
|
||||
attachments[1] = *depthView;
|
||||
|
|
|
@ -199,12 +199,9 @@ public:
|
|||
|
||||
fragUniforms.cp_AlphaTestValue = (PT_ALPHA_REF & 0xFF) / 255.0f;
|
||||
|
||||
ModVolShaderUniforms modVolUniforms;
|
||||
modVolUniforms.sp_ShaderColor = 1 - FPU_SHAD_SCALE.scale_factor / 256.f;
|
||||
|
||||
SortTriangles();
|
||||
|
||||
UploadUniforms(vtxUniforms, fragUniforms, modVolUniforms);
|
||||
UploadUniforms(vtxUniforms, fragUniforms);
|
||||
|
||||
GetContext()->BeginRenderPass();
|
||||
vk::CommandBuffer cmdBuffer = GetContext()->GetCurrentCommandBuffer();
|
||||
|
@ -220,7 +217,7 @@ public:
|
|||
// Bind vertex and index buffers
|
||||
const vk::DeviceSize offsets[] = { 0 };
|
||||
cmdBuffer.bindVertexBuffers(0, 1, &mainBuffers[GetCurrentImage()]->buffer.get(), offsets);
|
||||
cmdBuffer.bindIndexBuffer(*mainBuffers[GetCurrentImage()]->buffer, pvrrc.verts.bytes(), vk::IndexType::eUint32);
|
||||
cmdBuffer.bindIndexBuffer(*mainBuffers[GetCurrentImage()]->buffer, pvrrc.verts.bytes() + pvrrc.modtrig.bytes(), vk::IndexType::eUint32);
|
||||
|
||||
cmdBuffer.setViewport(0, vk::Viewport(0.0f, 0.0f, static_cast<float>(GetContext()->GetViewPort().width),
|
||||
static_cast<float>(GetContext()->GetViewPort().width), 1.0f, 0.0f));
|
||||
|
@ -238,6 +235,7 @@ public:
|
|||
current_pass.mvo_count - previous_pass.mvo_count);
|
||||
DrawList(cmdBuffer, ListType_Opaque, false, pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count);
|
||||
DrawList(cmdBuffer, ListType_Punch_Through, false, pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count);
|
||||
DrawModVols(cmdBuffer, previous_pass.mvo_count, current_pass.mvo_count - previous_pass.mvo_count);
|
||||
if (current_pass.autosort)
|
||||
{
|
||||
if (!settings.rend.PerStripSorting)
|
||||
|
@ -458,6 +456,58 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void DrawModVols(const vk::CommandBuffer& cmdBuffer, int first, int count)
|
||||
{
|
||||
if (count == 0 || pvrrc.modtrig.used() == 0)
|
||||
return;
|
||||
|
||||
vk::DeviceSize offsets[] = { (vk::DeviceSize)pvrrc.verts.bytes() };
|
||||
cmdBuffer.bindVertexBuffers(0, 1, &mainBuffers[GetCurrentImage()]->buffer.get(), offsets);
|
||||
|
||||
ModifierVolumeParam* params = &pvrrc.global_param_mvo.head()[first];
|
||||
|
||||
int mod_base = -1;
|
||||
vk::Pipeline pipeline;
|
||||
|
||||
for (u32 cmv = 0; cmv < count; cmv++)
|
||||
{
|
||||
ModifierVolumeParam& param = params[cmv];
|
||||
|
||||
if (param.count == 0)
|
||||
continue;
|
||||
|
||||
u32 mv_mode = param.isp.DepthMode;
|
||||
|
||||
if (mod_base == -1)
|
||||
mod_base = param.first;
|
||||
|
||||
if (!param.isp.VolumeLast && mv_mode > 0)
|
||||
pipeline = pipelineManager.GetModifierVolumePipeline(ModVolMode::Or); // OR'ing (open volume or quad)
|
||||
else
|
||||
pipeline = pipelineManager.GetModifierVolumePipeline(ModVolMode::Xor); // 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);
|
||||
cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
|
||||
cmdBuffer.draw((param.first + param.count - mod_base) * 3, 1, mod_base * 3, 0);
|
||||
mod_base = -1;
|
||||
}
|
||||
}
|
||||
offsets[0] = 0;
|
||||
cmdBuffer.bindVertexBuffers(0, 1, &mainBuffers[GetCurrentImage()]->buffer.get(), offsets);
|
||||
|
||||
std::array<float, 5> pushConstants = { 1 - FPU_SHAD_SCALE.scale_factor / 256.f, 0, 0, 0, 0 };
|
||||
cmdBuffer.pushConstants<float>(pipelineManager.GetDescriptorSets().GetPipelineLayout(), vk::ShaderStageFlagBits::eFragment, 0, pushConstants);
|
||||
|
||||
pipeline = pipelineManager.GetModifierVolumePipeline(ModVolMode::Final);
|
||||
cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
|
||||
cmdBuffer.drawIndexed(4, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
void InitUniforms()
|
||||
{
|
||||
vertexUniformBuffer = GetContext()->GetDevice()->createBufferUnique(vk::BufferCreateInfo(vk::BufferCreateFlags(),
|
||||
|
@ -477,18 +527,9 @@ private:
|
|||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||
fragmentUniformMemory = GetContext()->GetDevice()->allocateMemoryUnique(vk::MemoryAllocateInfo(fragmentUniformsMemSize, typeIndex));
|
||||
GetContext()->GetDevice()->bindBufferMemory(fragmentUniformBuffer.get(), fragmentUniformMemory.get(), 0);
|
||||
|
||||
modVolUniformBuffer = GetContext()->GetDevice()->createBufferUnique(vk::BufferCreateInfo(vk::BufferCreateFlags(),
|
||||
sizeof(ModVolShaderUniforms), vk::BufferUsageFlagBits::eUniformBuffer));
|
||||
memRequirements = GetContext()->GetDevice()->getBufferMemoryRequirements(modVolUniformBuffer.get());
|
||||
modVolUniformsMemSize = memRequirements.size;
|
||||
typeIndex = findMemoryType(GetContext()->GetPhysicalDevice().getMemoryProperties(), memRequirements.memoryTypeBits,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||
modVolUniformMemory = GetContext()->GetDevice()->allocateMemoryUnique(vk::MemoryAllocateInfo(modVolUniformsMemSize, typeIndex));
|
||||
GetContext()->GetDevice()->bindBufferMemory(modVolUniformBuffer.get(), modVolUniformMemory.get(), 0);
|
||||
}
|
||||
|
||||
void UploadUniforms(const VertexShaderUniforms& vertexUniforms, const FragmentShaderUniforms& fragmentUniforms, const ModVolShaderUniforms& modVolUniforms)
|
||||
void UploadUniforms(const VertexShaderUniforms& vertexUniforms, const FragmentShaderUniforms& fragmentUniforms)
|
||||
{
|
||||
uint8_t* pData = static_cast<uint8_t*>(GetContext()->GetDevice()->mapMemory(vertexUniformMemory.get(), 0, vertexUniformMemSize));
|
||||
memcpy(pData, &vertexUniforms, sizeof(vertexUniforms));
|
||||
|
@ -497,15 +538,11 @@ private:
|
|||
pData = static_cast<uint8_t*>(GetContext()->GetDevice()->mapMemory(fragmentUniformMemory.get(), 0, fragmentUniformsMemSize));
|
||||
memcpy(pData, &fragmentUniforms, sizeof(fragmentUniforms));
|
||||
GetContext()->GetDevice()->unmapMemory(fragmentUniformMemory.get());
|
||||
|
||||
pData = static_cast<uint8_t*>(GetContext()->GetDevice()->mapMemory(modVolUniformMemory.get(), 0, modVolUniformsMemSize));
|
||||
memcpy(pData, &modVolUniforms, sizeof(modVolUniforms));
|
||||
GetContext()->GetDevice()->unmapMemory(modVolUniformMemory.get());
|
||||
}
|
||||
|
||||
void UploadMainBuffer()
|
||||
{
|
||||
u32 totalSize = pvrrc.verts.bytes() + pvrrc.idx.bytes() + sortedIndexCount * sizeof(u32);
|
||||
u32 totalSize = pvrrc.verts.bytes() + pvrrc.idx.bytes() + pvrrc.modtrig.bytes() + sortedIndexCount * sizeof(u32);
|
||||
if (mainBuffers.empty())
|
||||
{
|
||||
for (int i = 0; i < GetContext()->GetSwapChainSize(); i++)
|
||||
|
@ -527,6 +564,8 @@ private:
|
|||
|
||||
chunks.push_back(pvrrc.verts.head());
|
||||
chunkSizes.push_back(pvrrc.verts.bytes());
|
||||
chunks.push_back(pvrrc.modtrig.head());
|
||||
chunkSizes.push_back(pvrrc.modtrig.bytes());
|
||||
chunks.push_back(pvrrc.idx.head());
|
||||
chunkSizes.push_back(pvrrc.idx.bytes());
|
||||
for (const std::vector<u32>& idx : sortedIndexes)
|
||||
|
@ -568,13 +607,10 @@ private:
|
|||
// Uniforms
|
||||
vk::UniqueBuffer vertexUniformBuffer;
|
||||
vk::UniqueBuffer fragmentUniformBuffer;
|
||||
vk::UniqueBuffer modVolUniformBuffer;
|
||||
vk::UniqueDeviceMemory vertexUniformMemory;
|
||||
vk::UniqueDeviceMemory fragmentUniformMemory;
|
||||
vk::UniqueDeviceMemory modVolUniformMemory;
|
||||
vk::DeviceSize vertexUniformMemSize;
|
||||
vk::DeviceSize fragmentUniformsMemSize;
|
||||
vk::DeviceSize modVolUniformsMemSize;
|
||||
|
||||
// Buffers
|
||||
std::vector<std::unique_ptr<BufferData>> mainBuffers;
|
||||
|
|
Loading…
Reference in New Issue