vulkan: modifier volumes

This commit is contained in:
Flyinghead 2019-10-07 12:30:56 +02:00
parent 8d520fa5e4
commit b790a336e9
7 changed files with 165 additions and 69 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
};

View File

@ -74,7 +74,7 @@ public:
static VulkanContext *Instance() { return contextInstance; }
private:
void InitDepthBuffer();
vk::Format InitDepthBuffer();
void InitImgui();
bool HasSurfaceDimensionChanged()

View File

@ -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;

View File

@ -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;