vulkan: per-triangle sorting
This commit is contained in:
parent
b82a97853f
commit
8d520fa5e4
|
@ -26,16 +26,33 @@ struct BufferData
|
|||
BufferData(vk::PhysicalDevice const& physicalDevice, vk::Device const& device, vk::DeviceSize size, vk::BufferUsageFlags usage,
|
||||
vk::MemoryPropertyFlags propertyFlags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||
|
||||
void upload(vk::Device const& device, u32 size, void *data) const
|
||||
void upload(vk::Device const& device, u32 size, const void *data, u32 offset = 0) const
|
||||
{
|
||||
verify((m_propertyFlags & vk::MemoryPropertyFlagBits::eHostCoherent) && (m_propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible));
|
||||
verify(size <= m_size);
|
||||
verify(offset + size <= m_size);
|
||||
|
||||
void* dataPtr = device.mapMemory(*this->deviceMemory, 0, size);
|
||||
void* dataPtr = device.mapMemory(*this->deviceMemory, offset, size);
|
||||
memcpy(dataPtr, data, size);
|
||||
device.unmapMemory(*this->deviceMemory);
|
||||
}
|
||||
|
||||
void upload(vk::Device const& device, size_t count, u32 *sizes, const void **data, u32 offset = 0) const
|
||||
{
|
||||
verify((m_propertyFlags & vk::MemoryPropertyFlagBits::eHostCoherent) && (m_propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible));
|
||||
|
||||
u32 totalSize = 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
totalSize += sizes[i];
|
||||
verify(offset + totalSize <= m_size);
|
||||
void* dataPtr = device.mapMemory(*this->deviceMemory, offset, totalSize);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
memcpy(dataPtr, data[i], sizes[i]);
|
||||
dataPtr = (u8 *)dataPtr + sizes[i];
|
||||
}
|
||||
device.unmapMemory(*this->deviceMemory);
|
||||
}
|
||||
|
||||
vk::UniqueDeviceMemory deviceMemory;
|
||||
vk::UniqueBuffer buffer;
|
||||
vk::DeviceSize m_size;
|
||||
|
|
|
@ -58,29 +58,156 @@ static vk::BlendFactor getBlendFactor(u32 instr, bool src)
|
|||
}
|
||||
}
|
||||
|
||||
void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const PolyParam& pp)
|
||||
void PipelineManager::CreateModVolPipeline(ModVolMode mode)
|
||||
{
|
||||
// Vertex input state
|
||||
const vk::VertexInputBindingDescription vertexBindingDescriptions[] =
|
||||
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo;
|
||||
// Input assembly state
|
||||
vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo;
|
||||
|
||||
if (mode == ModVolMode::Final)
|
||||
{
|
||||
{ 0, sizeof(Vertex) },
|
||||
};
|
||||
const vk::VertexInputAttributeDescription vertexInputAttributeDescriptions[] =
|
||||
pipelineVertexInputStateCreateInfo = GetMainVertexInputStateCreateInfo();
|
||||
pipelineInputAssemblyStateCreateInfo = vk::PipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(),
|
||||
vk::PrimitiveTopology::eTriangleStrip);
|
||||
}
|
||||
else
|
||||
{
|
||||
vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, x)), // pos
|
||||
vk::VertexInputAttributeDescription(1, 0, vk::Format::eR8G8B8A8Uint, offsetof(Vertex, col)), // base 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
|
||||
const vk::VertexInputBindingDescription vertexBindingDescriptions[] =
|
||||
{
|
||||
{ 0, sizeof(ModTriangle) },
|
||||
};
|
||||
const vk::VertexInputAttributeDescription vertexInputAttributeDescriptions[] =
|
||||
{
|
||||
vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, x)), // pos
|
||||
};
|
||||
pipelineVertexInputStateCreateInfo = vk::PipelineVertexInputStateCreateInfo(
|
||||
vk::PipelineVertexInputStateCreateFlags(),
|
||||
ARRAY_SIZE(vertexBindingDescriptions),
|
||||
vertexBindingDescriptions,
|
||||
ARRAY_SIZE(vertexInputAttributeDescriptions),
|
||||
vertexInputAttributeDescriptions);
|
||||
pipelineInputAssemblyStateCreateInfo = vk::PipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(),
|
||||
vk::PrimitiveTopology::eTriangleList);
|
||||
}
|
||||
|
||||
// Viewport and scissor states
|
||||
vk::PipelineViewportStateCreateInfo pipelineViewportStateCreateInfo(vk::PipelineViewportStateCreateFlags(), 1, nullptr, 1, nullptr);
|
||||
|
||||
// Rasterization and multisample states
|
||||
vk::PipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo
|
||||
(
|
||||
vk::PipelineRasterizationStateCreateFlags(), // flags
|
||||
false, // depthClampEnable
|
||||
mode != ModVolMode::Final, // rasterizerDiscardEnable
|
||||
vk::PolygonMode::eFill, // polygonMode
|
||||
vk::CullModeFlagBits::eNone, // cullMode
|
||||
vk::FrontFace::eCounterClockwise, // frontFace
|
||||
false, // depthBiasEnable
|
||||
0.0f, // depthBiasConstantFactor
|
||||
0.0f, // depthBiasClamp
|
||||
0.0f, // depthBiasSlopeFactor
|
||||
1.0f // lineWidth
|
||||
);
|
||||
vk::PipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo;
|
||||
|
||||
// Depth and stencil
|
||||
vk::StencilOpState stencilOpState;
|
||||
switch (mode)
|
||||
{
|
||||
case ModVolMode::Xor:
|
||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eInvert, vk::StencilOp::eKeep, vk::CompareOp::eAlways, 0, 2, 2);
|
||||
break;
|
||||
case ModVolMode::Or:
|
||||
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);
|
||||
break;
|
||||
case ModVolMode::Exclusion:
|
||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eZero, vk::StencilOp::eKeep, vk::StencilOp::eZero, vk::CompareOp::eEqual, 1, 3, 3);
|
||||
break;
|
||||
case ModVolMode::Final:
|
||||
stencilOpState = vk::StencilOpState(vk::StencilOp::eZero, vk::StencilOp::eZero, vk::StencilOp::eZero, vk::CompareOp::eEqual, 0x81, 3, 0x81);
|
||||
break;
|
||||
}
|
||||
vk::PipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo
|
||||
(
|
||||
vk::PipelineDepthStencilStateCreateFlags(), // flags
|
||||
mode == ModVolMode::Xor || mode == ModVolMode::Or, // depthTestEnable
|
||||
false, // depthWriteEnable
|
||||
vk::CompareOp::eGreater, // depthCompareOp
|
||||
false, // depthBoundTestEnable
|
||||
true, // stencilTestEnable
|
||||
stencilOpState, // front
|
||||
vk::StencilOpState() // back
|
||||
);
|
||||
|
||||
// Color flags and blending
|
||||
vk::ColorComponentFlags colorComponentFlags(vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA);
|
||||
vk::PipelineColorBlendAttachmentState pipelineColorBlendAttachmentState(
|
||||
mode == ModVolMode::Final, // blendEnable
|
||||
vk::BlendFactor::eSrcAlpha, // srcColorBlendFactor
|
||||
vk::BlendFactor::eOneMinusSrcAlpha, // dstColorBlendFactor
|
||||
vk::BlendOp::eAdd, // colorBlendOp
|
||||
vk::BlendFactor::eSrcAlpha, // srcAlphaBlendFactor
|
||||
vk::BlendFactor::eOneMinusSrcAlpha, // dstAlphaBlendFactor
|
||||
vk::BlendOp::eAdd, // alphaBlendOp
|
||||
colorComponentFlags // colorWriteMask
|
||||
);
|
||||
|
||||
vk::PipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo
|
||||
(
|
||||
vk::PipelineColorBlendStateCreateFlags(), // flags
|
||||
false, // logicOpEnable
|
||||
vk::LogicOp::eNoOp, // logicOp
|
||||
1, // attachmentCount
|
||||
&pipelineColorBlendAttachmentState, // pAttachments
|
||||
{ { (1.0f, 1.0f, 1.0f, 1.0f) } } // blendConstants
|
||||
);
|
||||
|
||||
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 fragment_module = shaderManager.GetModVolShader();
|
||||
|
||||
vk::PipelineShaderStageCreateInfo stages[] = {
|
||||
{ vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vertex_module, "main" },
|
||||
{ vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragment_module, "main" },
|
||||
};
|
||||
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo(
|
||||
vk::PipelineVertexInputStateCreateFlags(),
|
||||
ARRAY_SIZE(vertexBindingDescriptions),
|
||||
vertexBindingDescriptions,
|
||||
ARRAY_SIZE(vertexInputAttributeDescriptions),
|
||||
vertexInputAttributeDescriptions);
|
||||
vk::GraphicsPipelineCreateInfo graphicsPipelineCreateInfo
|
||||
(
|
||||
vk::PipelineCreateFlags(), // flags
|
||||
2, // stageCount
|
||||
stages, // pStages
|
||||
&pipelineVertexInputStateCreateInfo, // pVertexInputState
|
||||
&pipelineInputAssemblyStateCreateInfo, // pInputAssemblyState
|
||||
nullptr, // pTessellationState
|
||||
&pipelineViewportStateCreateInfo, // pViewportState
|
||||
&pipelineRasterizationStateCreateInfo, // pRasterizationState
|
||||
&pipelineMultisampleStateCreateInfo, // pMultisampleState
|
||||
&pipelineDepthStencilStateCreateInfo, // pDepthStencilState
|
||||
&pipelineColorBlendStateCreateInfo, // pColorBlendState
|
||||
&pipelineDynamicStateCreateInfo, // pDynamicState
|
||||
descriptorSets.GetPipelineLayout(), // layout
|
||||
GetContext()->GetRenderPass() // renderPass
|
||||
);
|
||||
|
||||
if (modVolPipelines.empty())
|
||||
modVolPipelines.reserve((size_t)ModVolMode::Final + 1);
|
||||
modVolPipelines[(size_t)mode] =
|
||||
GetContext()->GetDevice()->createGraphicsPipelineUnique(GetContext()->GetPipelineCache(),
|
||||
graphicsPipelineCreateInfo);
|
||||
}
|
||||
|
||||
void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const PolyParam& pp)
|
||||
{
|
||||
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = GetMainVertexInputStateCreateInfo();
|
||||
|
||||
// Input assembly state
|
||||
vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(), vk::PrimitiveTopology::eTriangleStrip);
|
||||
vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(),
|
||||
sortTriangles && !settings.rend.PerStripSorting ? vk::PrimitiveTopology::eTriangleList : vk::PrimitiveTopology::eTriangleStrip);
|
||||
|
||||
// Viewport and scissor states
|
||||
vk::PipelineViewportStateCreateInfo pipelineViewportStateCreateInfo(vk::PipelineViewportStateCreateFlags(), 1, nullptr, 1, nullptr);
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "texture.h"
|
||||
#include "hw/pvr/ta_ctx.h"
|
||||
|
||||
enum class ModVolMode { Xor, Or, Inclusion, Exclusion, Final };
|
||||
|
||||
class DescriptorSets
|
||||
{
|
||||
public:
|
||||
|
@ -109,18 +111,7 @@ public:
|
|||
inFlight[index] = std::move(descSets.back());
|
||||
descSets.pop_back();
|
||||
}
|
||||
/* TODO Should be part of per-frame descriptor set
|
||||
void SetFogTexture(Texture & texture)
|
||||
{
|
||||
vk::DescriptorImageInfo imageInfo = texture.GetDescriptorImageInfo();
|
||||
|
||||
int currentImage = GetContext()->GetCurrentImageIndex();
|
||||
std::vector<vk::WriteDescriptorSet> writeDescriptorSets;
|
||||
writeDescriptorSets.push_back(vk::WriteDescriptorSet(*perPolyDescSets[currentImage], 1, 0, 1, vk::DescriptorType::eCombinedImageSampler, &imageInfo, nullptr, nullptr));
|
||||
|
||||
GetContext()->GetDevice()->updateDescriptorSets(writeDescriptorSets, nullptr);
|
||||
}
|
||||
*/
|
||||
void BindPerFrameDescriptorSets(vk::CommandBuffer cmdBuffer)
|
||||
{
|
||||
int currentImage = GetContext()->GetCurrentImageIndex();
|
||||
|
@ -181,8 +172,9 @@ public:
|
|||
|
||||
private:
|
||||
VulkanContext *GetContext() const { return VulkanContext::Instance(); }
|
||||
void CreateModVolPipeline(ModVolMode mode);
|
||||
|
||||
u32 hash(u32 listType, bool sortTriangles, const PolyParam *pp)
|
||||
u32 hash(u32 listType, bool sortTriangles, const PolyParam *pp) const
|
||||
{
|
||||
u32 hash = pp->pcw.Gouraud | (pp->pcw.Offset << 1) | (pp->pcw.Texture << 2) | (pp->pcw.Shadow << 3)
|
||||
| ((pp->tileclip >> 28) << 4);
|
||||
|
@ -196,9 +188,33 @@ private:
|
|||
|
||||
return hash;
|
||||
}
|
||||
|
||||
vk::PipelineVertexInputStateCreateInfo GetMainVertexInputStateCreateInfo() const
|
||||
{
|
||||
// Vertex input state
|
||||
static const vk::VertexInputBindingDescription vertexBindingDescriptions[] =
|
||||
{
|
||||
{ 0, sizeof(Vertex) },
|
||||
};
|
||||
static const vk::VertexInputAttributeDescription vertexInputAttributeDescriptions[] =
|
||||
{
|
||||
vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, x)), // pos
|
||||
vk::VertexInputAttributeDescription(1, 0, vk::Format::eR8G8B8A8Uint, offsetof(Vertex, col)), // base 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
|
||||
};
|
||||
return vk::PipelineVertexInputStateCreateInfo(
|
||||
vk::PipelineVertexInputStateCreateFlags(),
|
||||
ARRAY_SIZE(vertexBindingDescriptions),
|
||||
vertexBindingDescriptions,
|
||||
ARRAY_SIZE(vertexInputAttributeDescriptions),
|
||||
vertexInputAttributeDescriptions);
|
||||
}
|
||||
|
||||
void CreatePipeline(u32 listType, bool sortTriangles, const PolyParam& pp);
|
||||
|
||||
std::map<u32, vk::UniquePipeline> pipelines;
|
||||
std::vector<vk::UniquePipeline> modVolPipelines;
|
||||
ShaderManager shaderManager;
|
||||
DescriptorSets descriptorSets;
|
||||
};
|
||||
|
|
|
@ -202,17 +202,14 @@ public:
|
|||
ModVolShaderUniforms modVolUniforms;
|
||||
modVolUniforms.sp_ShaderColor = 1 - FPU_SHAD_SCALE.scale_factor / 256.f;
|
||||
|
||||
SortTriangles();
|
||||
|
||||
UploadUniforms(vtxUniforms, fragUniforms, modVolUniforms);
|
||||
|
||||
GetContext()->BeginRenderPass();
|
||||
vk::CommandBuffer cmdBuffer = GetContext()->GetCurrentCommandBuffer();
|
||||
|
||||
// Upload vertex and index buffers
|
||||
CheckVertexIndexBuffers(pvrrc.verts.bytes(), pvrrc.idx.bytes());
|
||||
if (pvrrc.verts.bytes() > 0)
|
||||
vertexBuffers[GetCurrentImage()]->upload(GetContext()->GetDevice().get(), pvrrc.verts.bytes(), pvrrc.verts.head());
|
||||
if (pvrrc.idx.bytes() > 0)
|
||||
indexBuffers[GetCurrentImage()]->upload(GetContext()->GetDevice().get(), pvrrc.idx.bytes(), pvrrc.idx.head());
|
||||
UploadMainBuffer();
|
||||
|
||||
// Update per-frame descriptor set and bind it
|
||||
pipelineManager.GetDescriptorSets().UpdateUniforms(*vertexUniformBuffer, *fragmentUniformBuffer, fogTexture->GetImageView());
|
||||
|
@ -222,8 +219,8 @@ public:
|
|||
|
||||
// Bind vertex and index buffers
|
||||
const vk::DeviceSize offsets[] = { 0 };
|
||||
cmdBuffer.bindVertexBuffers(0, 1, &vertexBuffers[GetCurrentImage()]->buffer.get(), offsets);
|
||||
cmdBuffer.bindIndexBuffer(*indexBuffers[GetCurrentImage()]->buffer, 0, vk::IndexType::eUint32);
|
||||
cmdBuffer.bindVertexBuffers(0, 1, &mainBuffers[GetCurrentImage()]->buffer.get(), offsets);
|
||||
cmdBuffer.bindIndexBuffer(*mainBuffers[GetCurrentImage()]->buffer, pvrrc.verts.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));
|
||||
|
@ -243,13 +240,11 @@ public:
|
|||
DrawList(cmdBuffer, ListType_Punch_Through, false, pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count);
|
||||
if (current_pass.autosort)
|
||||
{
|
||||
// TODO
|
||||
// if (!settings.rend.PerStripSorting)
|
||||
// {
|
||||
// //SortTriangles(previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
|
||||
// //DrawSorted(render_pass < pvrrc.render_passes.used() - 1);
|
||||
// }
|
||||
// else
|
||||
if (!settings.rend.PerStripSorting)
|
||||
{
|
||||
DrawSorted(cmdBuffer, sortedPolys[render_pass]);
|
||||
}
|
||||
else
|
||||
{
|
||||
SortPParams(previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
|
||||
DrawList(cmdBuffer, ListType_Translucent, true, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
|
||||
|
@ -406,6 +401,63 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void SortTriangles()
|
||||
{
|
||||
sortedPolys.resize(pvrrc.render_passes.used());
|
||||
sortedIndexes.resize(pvrrc.render_passes.used());
|
||||
sortedIndexCount = 0;
|
||||
RenderPass previousPass = {};
|
||||
|
||||
for (int render_pass = 0; render_pass < pvrrc.render_passes.used(); render_pass++)
|
||||
{
|
||||
const RenderPass& current_pass = pvrrc.render_passes.head()[render_pass];
|
||||
sortedIndexes[render_pass].clear();
|
||||
if (current_pass.autosort)
|
||||
{
|
||||
GenSorted(previousPass.tr_count, current_pass.tr_count - previousPass.tr_count, sortedPolys[render_pass], sortedIndexes[render_pass]);
|
||||
for (auto& poly : sortedPolys[render_pass])
|
||||
poly.first += sortedIndexCount;
|
||||
sortedIndexCount += sortedIndexes[render_pass].size();
|
||||
}
|
||||
else
|
||||
sortedPolys[render_pass].clear();
|
||||
previousPass = current_pass;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME Code dup with DrawList()
|
||||
void DrawSorted(const vk::CommandBuffer& cmdBuffer, const std::vector<SortTrigDrawParam>& polys)
|
||||
{
|
||||
for (const SortTrigDrawParam& param : polys)
|
||||
{
|
||||
float trilinearAlpha;
|
||||
if (param.ppid->pcw.Texture && param.ppid->tsp.FilterMode > 1)
|
||||
{
|
||||
trilinearAlpha = 0.25 * (param.ppid->tsp.MipMapD & 0x3);
|
||||
if (param.ppid->tsp.FilterMode == 2)
|
||||
// Trilinear pass A
|
||||
trilinearAlpha = 1.0 - trilinearAlpha;
|
||||
}
|
||||
else
|
||||
trilinearAlpha = 1.f;
|
||||
|
||||
std::array<float, 5> pushConstants = { 0, 0, 0, 0, trilinearAlpha };
|
||||
SetTileClip(param.ppid->tileclip, &pushConstants[0]);
|
||||
cmdBuffer.pushConstants<float>(pipelineManager.GetDescriptorSets().GetPipelineLayout(), vk::ShaderStageFlagBits::eFragment, 0, pushConstants);
|
||||
|
||||
if (param.ppid->pcw.Texture)
|
||||
pipelineManager.GetDescriptorSets().SetTexture(param.ppid->texid, param.ppid->tsp);
|
||||
|
||||
vk::Pipeline pipeline = pipelineManager.GetPipeline(ListType_Translucent, true, *param.ppid);
|
||||
cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
|
||||
if (param.ppid->pcw.Texture)
|
||||
pipelineManager.GetDescriptorSets().BindPerPolyDescriptorSets(cmdBuffer, param.ppid->texid, param.ppid->tsp);
|
||||
|
||||
cmdBuffer.drawIndexed(param.count, 1, pvrrc.idx.used() + param.first, 0, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void InitUniforms()
|
||||
{
|
||||
vertexUniformBuffer = GetContext()->GetDevice()->createBufferUnique(vk::BufferCreateInfo(vk::BufferCreateFlags(),
|
||||
|
@ -451,39 +503,41 @@ private:
|
|||
GetContext()->GetDevice()->unmapMemory(modVolUniformMemory.get());
|
||||
}
|
||||
|
||||
void CheckVertexIndexBuffers(u32 vertexSize, u32 indexSize)
|
||||
void UploadMainBuffer()
|
||||
{
|
||||
if (vertexBuffers.empty())
|
||||
u32 totalSize = pvrrc.verts.bytes() + pvrrc.idx.bytes() + sortedIndexCount * sizeof(u32);
|
||||
if (mainBuffers.empty())
|
||||
{
|
||||
for (int i = 0; i < GetContext()->GetSwapChainSize(); i++)
|
||||
vertexBuffers.push_back(std::unique_ptr<BufferData>(new BufferData(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice().get(),
|
||||
std::max(512 * 1024u, vertexSize), vk::BufferUsageFlagBits::eVertexBuffer)));
|
||||
mainBuffers.push_back(std::unique_ptr<BufferData>(new BufferData(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice().get(),
|
||||
std::max(512 * 1024u, totalSize), vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndexBuffer)));
|
||||
}
|
||||
else if (vertexBuffers[GetCurrentImage()]->m_size < vertexSize)
|
||||
else if (mainBuffers[GetCurrentImage()]->m_size < totalSize)
|
||||
{
|
||||
u32 newSize = vertexBuffers[GetCurrentImage()]->m_size;
|
||||
while (newSize < vertexSize)
|
||||
u32 newSize = mainBuffers[GetCurrentImage()]->m_size;
|
||||
while (newSize < totalSize)
|
||||
newSize *= 2;
|
||||
INFO_LOG(RENDERER, "Increasing vertex buffer size %d -> %d", (u32)vertexBuffers[GetCurrentImage()]->m_size, newSize);
|
||||
vertexBuffers[GetCurrentImage()] = std::unique_ptr<BufferData>(new BufferData(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice().get(), newSize,
|
||||
vk::BufferUsageFlagBits::eVertexBuffer));
|
||||
INFO_LOG(RENDERER, "Increasing main buffer size %d -> %d", (u32)mainBuffers[GetCurrentImage()]->m_size, newSize);
|
||||
mainBuffers[GetCurrentImage()] = std::unique_ptr<BufferData>(new BufferData(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice().get(), newSize,
|
||||
vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndexBuffer));
|
||||
}
|
||||
if (indexBuffers.empty())
|
||||
|
||||
std::vector<const void *> chunks;
|
||||
std::vector<u32> chunkSizes;
|
||||
|
||||
chunks.push_back(pvrrc.verts.head());
|
||||
chunkSizes.push_back(pvrrc.verts.bytes());
|
||||
chunks.push_back(pvrrc.idx.head());
|
||||
chunkSizes.push_back(pvrrc.idx.bytes());
|
||||
for (const std::vector<u32>& idx : sortedIndexes)
|
||||
{
|
||||
for (int i = 0; i < GetContext()->GetSwapChainSize(); i++)
|
||||
indexBuffers.push_back(std::unique_ptr<BufferData>(new BufferData(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice().get(),
|
||||
std::max(64 * 1024u, indexSize),
|
||||
vk::BufferUsageFlagBits::eIndexBuffer)));
|
||||
}
|
||||
else if (indexBuffers[GetCurrentImage()]->m_size < indexSize)
|
||||
{
|
||||
u32 newSize = indexBuffers[GetCurrentImage()]->m_size;
|
||||
while (newSize < indexSize)
|
||||
newSize *= 2;
|
||||
INFO_LOG(RENDERER, "Increasing index buffer size %d -> %d", (u32)indexBuffers[GetCurrentImage()]->m_size, newSize);
|
||||
indexBuffers[GetCurrentImage()] = std::unique_ptr<BufferData>(new BufferData(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice().get(), newSize,
|
||||
vk::BufferUsageFlagBits::eIndexBuffer));
|
||||
if (!idx.empty())
|
||||
{
|
||||
chunks.push_back(&idx[0]);
|
||||
chunkSizes.push_back(idx.size() * sizeof(u32));
|
||||
}
|
||||
}
|
||||
mainBuffers[GetCurrentImage()]->upload(GetContext()->GetDevice().get(), chunks.size(), &chunkSizes[0], &chunks[0]);
|
||||
}
|
||||
|
||||
void CheckFogTexture()
|
||||
|
@ -492,6 +546,7 @@ private:
|
|||
{
|
||||
fogTexture = std::unique_ptr<Texture>(new Texture(GetContext()->GetPhysicalDevice(), *GetContext()->GetDevice()));
|
||||
fogTexture->tex_type = TextureType::_8;
|
||||
fog_needs_update = true;
|
||||
}
|
||||
if (!fog_needs_update || !settings.rend.Fog)
|
||||
return;
|
||||
|
@ -504,6 +559,10 @@ private:
|
|||
// temp stuff
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
std::vector<std::vector<SortTrigDrawParam>> sortedPolys;
|
||||
std::vector<std::vector<u32>> sortedIndexes;
|
||||
u32 sortedIndexCount;
|
||||
|
||||
std::unique_ptr<Texture> fogTexture;
|
||||
|
||||
// Uniforms
|
||||
|
@ -518,8 +577,7 @@ private:
|
|||
vk::DeviceSize modVolUniformsMemSize;
|
||||
|
||||
// Buffers
|
||||
std::vector<std::unique_ptr<BufferData>> vertexBuffers;
|
||||
std::vector<std::unique_ptr<BufferData>> indexBuffers;
|
||||
std::vector<std::unique_ptr<BufferData>> mainBuffers;
|
||||
|
||||
ShaderManager shaderManager;
|
||||
PipelineManager pipelineManager;
|
||||
|
|
Loading…
Reference in New Issue