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)
|
if (mode == ModVolMode::Final)
|
||||||
{
|
{
|
||||||
pipelineVertexInputStateCreateInfo = GetMainVertexInputStateCreateInfo();
|
pipelineVertexInputStateCreateInfo = GetMainVertexInputStateCreateInfo(false);
|
||||||
pipelineInputAssemblyStateCreateInfo = vk::PipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(),
|
pipelineInputAssemblyStateCreateInfo = vk::PipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(),
|
||||||
vk::PrimitiveTopology::eTriangleStrip);
|
vk::PrimitiveTopology::eTriangleStrip);
|
||||||
}
|
}
|
||||||
else
|
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(
|
pipelineVertexInputStateCreateInfo = vk::PipelineVertexInputStateCreateInfo(
|
||||||
vk::PipelineVertexInputStateCreateFlags(),
|
vk::PipelineVertexInputStateCreateFlags(),
|
||||||
|
@ -99,7 +99,7 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
||||||
(
|
(
|
||||||
vk::PipelineRasterizationStateCreateFlags(), // flags
|
vk::PipelineRasterizationStateCreateFlags(), // flags
|
||||||
false, // depthClampEnable
|
false, // depthClampEnable
|
||||||
mode != ModVolMode::Final, // rasterizerDiscardEnable
|
false, // rasterizerDiscardEnable
|
||||||
vk::PolygonMode::eFill, // polygonMode
|
vk::PolygonMode::eFill, // polygonMode
|
||||||
vk::CullModeFlagBits::eNone, // cullMode
|
vk::CullModeFlagBits::eNone, // cullMode
|
||||||
vk::FrontFace::eCounterClockwise, // frontFace
|
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);
|
stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eReplace, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 2, 2, 2);
|
||||||
break;
|
break;
|
||||||
case ModVolMode::Inclusion:
|
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;
|
break;
|
||||||
case ModVolMode::Exclusion:
|
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;
|
break;
|
||||||
case ModVolMode::Final:
|
case ModVolMode::Final:
|
||||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eZero, vk::StencilOp::eZero, vk::StencilOp::eZero, vk::CompareOp::eEqual, 0x81, 3, 0x81);
|
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
|
false, // depthBoundTestEnable
|
||||||
true, // stencilTestEnable
|
true, // stencilTestEnable
|
||||||
stencilOpState, // front
|
stencilOpState, // front
|
||||||
vk::StencilOpState() // back
|
stencilOpState // back
|
||||||
);
|
);
|
||||||
|
|
||||||
// Color flags and blending
|
// 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(
|
vk::PipelineColorBlendAttachmentState pipelineColorBlendAttachmentState(
|
||||||
mode == ModVolMode::Final, // blendEnable
|
mode == ModVolMode::Final, // blendEnable
|
||||||
vk::BlendFactor::eSrcAlpha, // srcColorBlendFactor
|
vk::BlendFactor::eSrcAlpha, // srcColorBlendFactor
|
||||||
|
@ -169,7 +171,7 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
||||||
vk::DynamicState dynamicStates[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
vk::DynamicState dynamicStates[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
||||||
vk::PipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo(vk::PipelineDynamicStateCreateFlags(), 2, dynamicStates);
|
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::ShaderModule fragment_module = shaderManager.GetModVolShader();
|
||||||
|
|
||||||
vk::PipelineShaderStageCreateInfo stages[] = {
|
vk::PipelineShaderStageCreateInfo stages[] = {
|
||||||
|
@ -195,7 +197,7 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (modVolPipelines.empty())
|
if (modVolPipelines.empty())
|
||||||
modVolPipelines.reserve((size_t)ModVolMode::Final + 1);
|
modVolPipelines.resize((size_t)ModVolMode::Final + 1);
|
||||||
modVolPipelines[(size_t)mode] =
|
modVolPipelines[(size_t)mode] =
|
||||||
GetContext()->GetDevice()->createGraphicsPipelineUnique(GetContext()->GetPipelineCache(),
|
GetContext()->GetDevice()->createGraphicsPipelineUnique(GetContext()->GetPipelineCache(),
|
||||||
graphicsPipelineCreateInfo);
|
graphicsPipelineCreateInfo);
|
||||||
|
@ -250,7 +252,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
|
||||||
depthWriteEnable = !pp.isp.ZWriteDis;
|
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::StencilOpState stencilOpStateNop(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eAlways);
|
||||||
vk::PipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo
|
vk::PipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo
|
||||||
(
|
(
|
||||||
|
@ -260,8 +262,8 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
|
||||||
depthOp, // depthCompareOp
|
depthOp, // depthCompareOp
|
||||||
false, // depthBoundTestEnable
|
false, // depthBoundTestEnable
|
||||||
listType == ListType_Opaque || listType == ListType_Punch_Through, // stencilTestEnable
|
listType == ListType_Opaque || listType == ListType_Punch_Through, // stencilTestEnable
|
||||||
pp.pcw.Shadow != 0 ? stencilOpStateSet : stencilOpStateNop, // front
|
pp.pcw.Shadow != 0 ? stencilOpStateSet : stencilOpStateNop, // front
|
||||||
stencilOpStateNop // back
|
pp.pcw.Shadow != 0 ? stencilOpStateSet : stencilOpStateNop // back
|
||||||
);
|
);
|
||||||
|
|
||||||
// Color flags and blending
|
// Color flags and blending
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
|
|
||||||
void UpdateUniforms(const vk::Buffer& vertexUniformBuffer, const vk::Buffer& fragmentUniformBuffer, vk::ImageView fogImageView)
|
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);
|
std::vector<vk::DescriptorSetLayout> layouts(GetContext()->GetSwapChainSize(), *perFrameLayout);
|
||||||
perFrameDescSets = GetContext()->GetDevice()->allocateDescriptorSetsUnique(
|
perFrameDescSets = GetContext()->GetDevice()->allocateDescriptorSetsUnique(
|
||||||
|
@ -170,6 +170,13 @@ public:
|
||||||
return *pipelines[pipehash];
|
return *pipelines[pipehash];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vk::Pipeline GetModifierVolumePipeline(ModVolMode mode)
|
||||||
|
{
|
||||||
|
if (modVolPipelines.empty() || !modVolPipelines[(size_t)mode])
|
||||||
|
CreateModVolPipeline(mode);
|
||||||
|
return *modVolPipelines[(size_t)mode];
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VulkanContext *GetContext() const { return VulkanContext::Instance(); }
|
VulkanContext *GetContext() const { return VulkanContext::Instance(); }
|
||||||
void CreateModVolPipeline(ModVolMode mode);
|
void CreateModVolPipeline(ModVolMode mode);
|
||||||
|
@ -189,7 +196,7 @@ private:
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::PipelineVertexInputStateCreateInfo GetMainVertexInputStateCreateInfo() const
|
vk::PipelineVertexInputStateCreateInfo GetMainVertexInputStateCreateInfo(bool full = true) const
|
||||||
{
|
{
|
||||||
// Vertex input state
|
// Vertex input state
|
||||||
static const vk::VertexInputBindingDescription vertexBindingDescriptions[] =
|
static const vk::VertexInputBindingDescription vertexBindingDescriptions[] =
|
||||||
|
@ -203,12 +210,16 @@ private:
|
||||||
vk::VertexInputAttributeDescription(2, 0, vk::Format::eR8G8B8A8Uint, offsetof(Vertex, spc)), // offset color
|
vk::VertexInputAttributeDescription(2, 0, vk::Format::eR8G8B8A8Uint, offsetof(Vertex, spc)), // offset color
|
||||||
vk::VertexInputAttributeDescription(3, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, u)), // tex coord
|
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(
|
return vk::PipelineVertexInputStateCreateInfo(
|
||||||
vk::PipelineVertexInputStateCreateFlags(),
|
vk::PipelineVertexInputStateCreateFlags(),
|
||||||
ARRAY_SIZE(vertexBindingDescriptions),
|
ARRAY_SIZE(vertexBindingDescriptions),
|
||||||
vertexBindingDescriptions,
|
vertexBindingDescriptions,
|
||||||
ARRAY_SIZE(vertexInputAttributeDescriptions),
|
full ? ARRAY_SIZE(vertexInputAttributeDescriptions) : ARRAY_SIZE(vertexInputLightAttributeDescriptions),
|
||||||
vertexInputAttributeDescriptions);
|
full ? vertexInputAttributeDescriptions : vertexInputLightAttributeDescriptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatePipeline(u32 listType, bool sortTriangles, const PolyParam& pp);
|
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
|
#version 400
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_ARB_shading_language_420pack : 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;
|
float sp_ShaderColor;
|
||||||
} uniformBuffer;
|
} pushConstants;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float w = gl_FragCoord.w * 100000.0;
|
float w = gl_FragCoord.w * 100000.0;
|
||||||
gl_FragDepth = log2(1.0 + w) / 34.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);
|
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()
|
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;
|
float extra_depth_scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModVolShaderUniforms
|
|
||||||
{
|
|
||||||
float sp_ShaderColor;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderManager
|
class ShaderManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -88,6 +83,12 @@ public:
|
||||||
}
|
}
|
||||||
vk::ShaderModule GetVertexShader(const VertexShaderParams& params) { return getShader(vertexShaders, params); }
|
vk::ShaderModule GetVertexShader(const VertexShaderParams& params) { return getShader(vertexShaders, params); }
|
||||||
vk::ShaderModule GetFragmentShader(const FragmentShaderParams& params) { return getShader(fragmentShaders, params); }
|
vk::ShaderModule GetFragmentShader(const FragmentShaderParams& params) { return getShader(fragmentShaders, params); }
|
||||||
|
vk::ShaderModule GetModVolVertexShader()
|
||||||
|
{
|
||||||
|
if (!modVolVertexShader)
|
||||||
|
modVolVertexShader = compileVertexModVolShader();
|
||||||
|
return *modVolVertexShader;
|
||||||
|
}
|
||||||
vk::ShaderModule GetModVolShader()
|
vk::ShaderModule GetModVolShader()
|
||||||
{
|
{
|
||||||
if (!modVolShader)
|
if (!modVolShader)
|
||||||
|
@ -107,9 +108,11 @@ private:
|
||||||
}
|
}
|
||||||
vk::UniqueShaderModule compileShader(const VertexShaderParams& params);
|
vk::UniqueShaderModule compileShader(const VertexShaderParams& params);
|
||||||
vk::UniqueShaderModule compileShader(const FragmentShaderParams& params);
|
vk::UniqueShaderModule compileShader(const FragmentShaderParams& params);
|
||||||
|
vk::UniqueShaderModule compileVertexModVolShader();
|
||||||
vk::UniqueShaderModule compileModVolShader();
|
vk::UniqueShaderModule compileModVolShader();
|
||||||
|
|
||||||
std::map<u32, vk::UniqueShaderModule> vertexShaders;
|
std::map<u32, vk::UniqueShaderModule> vertexShaders;
|
||||||
std::map<u32, vk::UniqueShaderModule> fragmentShaders;
|
std::map<u32, vk::UniqueShaderModule> fragmentShaders;
|
||||||
|
vk::UniqueShaderModule modVolVertexShader;
|
||||||
vk::UniqueShaderModule modVolShader;
|
vk::UniqueShaderModule modVolShader;
|
||||||
};
|
};
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
static VulkanContext *Instance() { return contextInstance; }
|
static VulkanContext *Instance() { return contextInstance; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitDepthBuffer();
|
vk::Format InitDepthBuffer();
|
||||||
void InitImgui();
|
void InitImgui();
|
||||||
|
|
||||||
bool HasSurfaceDimensionChanged()
|
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;
|
const vk::Format depthFormats[] = { vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint };
|
||||||
vk::FormatProperties formatProperties = physicalDevice.getFormatProperties(depthFormat);
|
|
||||||
|
|
||||||
vk::ImageTiling tiling;
|
vk::ImageTiling tiling;
|
||||||
if (formatProperties.linearTilingFeatures & vk::FormatFeatureFlagBits::eDepthStencilAttachment)
|
vk::Format depthFormat = vk::Format::eUndefined;
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(depthFormats); i++)
|
||||||
{
|
{
|
||||||
tiling = vk::ImageTiling::eLinear;
|
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 (formatProperties.optimalTilingFeatures & vk::FormatFeatureFlagBits::eDepthStencilAttachment)
|
if (depthFormat == vk::Format::eUndefined)
|
||||||
{
|
{
|
||||||
tiling = vk::ImageTiling::eOptimal;
|
die("No supported depth/stencil format found");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
die("DepthStencilAttachment is not supported for D16Unorm depth format.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::ImageCreateInfo imageCreateInfo(vk::ImageCreateFlags(), vk::ImageType::e2D, depthFormat, vk::Extent3D(width, height, 1), 1, 1, vk::SampleCountFlagBits::e1, tiling, vk::ImageUsageFlagBits::eDepthStencilAttachment);
|
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::ComponentMapping componentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA);
|
||||||
vk::ImageSubresourceRange subResourceRange(vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1);
|
vk::ImageSubresourceRange subResourceRange(vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1);
|
||||||
depthView = device->createImageViewUnique(vk::ImageViewCreateInfo(vk::ImageViewCreateFlags(), *depthImage, vk::ImageViewType::e2D, depthFormat, componentMapping, subResourceRange));
|
depthView = device->createImageViewUnique(vk::ImageViewCreateInfo(vk::ImageViewCreateFlags(), *depthImage, vk::ImageViewType::e2D, depthFormat, componentMapping, subResourceRange));
|
||||||
|
|
||||||
|
return depthFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::InitImgui()
|
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()));
|
commandBuffers.push_back(std::move(device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(*commandPools.back(), vk::CommandBufferLevel::ePrimary, 1)).front()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vk::Format depthFormat = InitDepthBuffer();
|
||||||
|
|
||||||
// Render pass
|
// Render pass
|
||||||
vk::Format depthFormat = vk::Format::eD16Unorm;
|
|
||||||
vk::AttachmentDescription attachmentDescriptions[2];
|
vk::AttachmentDescription attachmentDescriptions[2];
|
||||||
// FIXME we should use vk::AttachmentLoadOp::eLoad for loadOp to preserve previous framebuffer but it fails on the first render
|
// 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,
|
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));
|
renderPass = device->createRenderPassUnique(vk::RenderPassCreateInfo(vk::RenderPassCreateFlags(), 2, attachmentDescriptions, 1, &subpass));
|
||||||
|
|
||||||
InitDepthBuffer();
|
|
||||||
|
|
||||||
// Framebuffers, fences, semaphores
|
// Framebuffers, fences, semaphores
|
||||||
vk::ImageView attachments[2];
|
vk::ImageView attachments[2];
|
||||||
attachments[1] = *depthView;
|
attachments[1] = *depthView;
|
||||||
|
|
|
@ -199,12 +199,9 @@ public:
|
||||||
|
|
||||||
fragUniforms.cp_AlphaTestValue = (PT_ALPHA_REF & 0xFF) / 255.0f;
|
fragUniforms.cp_AlphaTestValue = (PT_ALPHA_REF & 0xFF) / 255.0f;
|
||||||
|
|
||||||
ModVolShaderUniforms modVolUniforms;
|
|
||||||
modVolUniforms.sp_ShaderColor = 1 - FPU_SHAD_SCALE.scale_factor / 256.f;
|
|
||||||
|
|
||||||
SortTriangles();
|
SortTriangles();
|
||||||
|
|
||||||
UploadUniforms(vtxUniforms, fragUniforms, modVolUniforms);
|
UploadUniforms(vtxUniforms, fragUniforms);
|
||||||
|
|
||||||
GetContext()->BeginRenderPass();
|
GetContext()->BeginRenderPass();
|
||||||
vk::CommandBuffer cmdBuffer = GetContext()->GetCurrentCommandBuffer();
|
vk::CommandBuffer cmdBuffer = GetContext()->GetCurrentCommandBuffer();
|
||||||
|
@ -220,7 +217,7 @@ public:
|
||||||
// Bind vertex and index buffers
|
// Bind vertex and index buffers
|
||||||
const vk::DeviceSize offsets[] = { 0 };
|
const vk::DeviceSize offsets[] = { 0 };
|
||||||
cmdBuffer.bindVertexBuffers(0, 1, &mainBuffers[GetCurrentImage()]->buffer.get(), offsets);
|
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),
|
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));
|
static_cast<float>(GetContext()->GetViewPort().width), 1.0f, 0.0f));
|
||||||
|
@ -238,6 +235,7 @@ public:
|
||||||
current_pass.mvo_count - previous_pass.mvo_count);
|
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_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);
|
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 (current_pass.autosort)
|
||||||
{
|
{
|
||||||
if (!settings.rend.PerStripSorting)
|
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()
|
void InitUniforms()
|
||||||
{
|
{
|
||||||
vertexUniformBuffer = GetContext()->GetDevice()->createBufferUnique(vk::BufferCreateInfo(vk::BufferCreateFlags(),
|
vertexUniformBuffer = GetContext()->GetDevice()->createBufferUnique(vk::BufferCreateInfo(vk::BufferCreateFlags(),
|
||||||
|
@ -477,18 +527,9 @@ private:
|
||||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
fragmentUniformMemory = GetContext()->GetDevice()->allocateMemoryUnique(vk::MemoryAllocateInfo(fragmentUniformsMemSize, typeIndex));
|
fragmentUniformMemory = GetContext()->GetDevice()->allocateMemoryUnique(vk::MemoryAllocateInfo(fragmentUniformsMemSize, typeIndex));
|
||||||
GetContext()->GetDevice()->bindBufferMemory(fragmentUniformBuffer.get(), fragmentUniformMemory.get(), 0);
|
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));
|
uint8_t* pData = static_cast<uint8_t*>(GetContext()->GetDevice()->mapMemory(vertexUniformMemory.get(), 0, vertexUniformMemSize));
|
||||||
memcpy(pData, &vertexUniforms, sizeof(vertexUniforms));
|
memcpy(pData, &vertexUniforms, sizeof(vertexUniforms));
|
||||||
|
@ -497,15 +538,11 @@ private:
|
||||||
pData = static_cast<uint8_t*>(GetContext()->GetDevice()->mapMemory(fragmentUniformMemory.get(), 0, fragmentUniformsMemSize));
|
pData = static_cast<uint8_t*>(GetContext()->GetDevice()->mapMemory(fragmentUniformMemory.get(), 0, fragmentUniformsMemSize));
|
||||||
memcpy(pData, &fragmentUniforms, sizeof(fragmentUniforms));
|
memcpy(pData, &fragmentUniforms, sizeof(fragmentUniforms));
|
||||||
GetContext()->GetDevice()->unmapMemory(fragmentUniformMemory.get());
|
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()
|
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())
|
if (mainBuffers.empty())
|
||||||
{
|
{
|
||||||
for (int i = 0; i < GetContext()->GetSwapChainSize(); i++)
|
for (int i = 0; i < GetContext()->GetSwapChainSize(); i++)
|
||||||
|
@ -527,6 +564,8 @@ private:
|
||||||
|
|
||||||
chunks.push_back(pvrrc.verts.head());
|
chunks.push_back(pvrrc.verts.head());
|
||||||
chunkSizes.push_back(pvrrc.verts.bytes());
|
chunkSizes.push_back(pvrrc.verts.bytes());
|
||||||
|
chunks.push_back(pvrrc.modtrig.head());
|
||||||
|
chunkSizes.push_back(pvrrc.modtrig.bytes());
|
||||||
chunks.push_back(pvrrc.idx.head());
|
chunks.push_back(pvrrc.idx.head());
|
||||||
chunkSizes.push_back(pvrrc.idx.bytes());
|
chunkSizes.push_back(pvrrc.idx.bytes());
|
||||||
for (const std::vector<u32>& idx : sortedIndexes)
|
for (const std::vector<u32>& idx : sortedIndexes)
|
||||||
|
@ -568,13 +607,10 @@ private:
|
||||||
// Uniforms
|
// Uniforms
|
||||||
vk::UniqueBuffer vertexUniformBuffer;
|
vk::UniqueBuffer vertexUniformBuffer;
|
||||||
vk::UniqueBuffer fragmentUniformBuffer;
|
vk::UniqueBuffer fragmentUniformBuffer;
|
||||||
vk::UniqueBuffer modVolUniformBuffer;
|
|
||||||
vk::UniqueDeviceMemory vertexUniformMemory;
|
vk::UniqueDeviceMemory vertexUniformMemory;
|
||||||
vk::UniqueDeviceMemory fragmentUniformMemory;
|
vk::UniqueDeviceMemory fragmentUniformMemory;
|
||||||
vk::UniqueDeviceMemory modVolUniformMemory;
|
|
||||||
vk::DeviceSize vertexUniformMemSize;
|
vk::DeviceSize vertexUniformMemSize;
|
||||||
vk::DeviceSize fragmentUniformsMemSize;
|
vk::DeviceSize fragmentUniformsMemSize;
|
||||||
vk::DeviceSize modVolUniformsMemSize;
|
|
||||||
|
|
||||||
// Buffers
|
// Buffers
|
||||||
std::vector<std::unique_ptr<BufferData>> mainBuffers;
|
std::vector<std::unique_ptr<BufferData>> mainBuffers;
|
||||||
|
|
Loading…
Reference in New Issue