diff --git a/core/rend/vulkan/buffer.h b/core/rend/vulkan/buffer.h index 3ddc76a47..1becd317a 100644 --- a/core/rend/vulkan/buffer.h +++ b/core/rend/vulkan/buffer.h @@ -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; diff --git a/core/rend/vulkan/pipeline.cpp b/core/rend/vulkan/pipeline.cpp index 24acc762c..a4ff07c0b 100644 --- a/core/rend/vulkan/pipeline.cpp +++ b/core/rend/vulkan/pipeline.cpp @@ -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); diff --git a/core/rend/vulkan/pipeline.h b/core/rend/vulkan/pipeline.h index 002a8e42c..08f620053 100644 --- a/core/rend/vulkan/pipeline.h +++ b/core/rend/vulkan/pipeline.h @@ -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 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 pipelines; + std::vector modVolPipelines; ShaderManager shaderManager; DescriptorSets descriptorSets; }; diff --git a/core/rend/vulkan/vulkan_renderer.cpp b/core/rend/vulkan/vulkan_renderer.cpp index e0f325fd1..b1ebf12e3 100644 --- a/core/rend/vulkan/vulkan_renderer.cpp +++ b/core/rend/vulkan/vulkan_renderer.cpp @@ -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(GetContext()->GetViewPort().width), static_cast(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& 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 pushConstants = { 0, 0, 0, 0, trilinearAlpha }; + SetTileClip(param.ppid->tileclip, &pushConstants[0]); + cmdBuffer.pushConstants(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(new BufferData(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice().get(), - std::max(512 * 1024u, vertexSize), vk::BufferUsageFlagBits::eVertexBuffer))); + mainBuffers.push_back(std::unique_ptr(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(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(new BufferData(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice().get(), newSize, + vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndexBuffer)); } - if (indexBuffers.empty()) + + std::vector chunks; + std::vector 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& idx : sortedIndexes) { - for (int i = 0; i < GetContext()->GetSwapChainSize(); i++) - indexBuffers.push_back(std::unique_ptr(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(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(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> sortedPolys; + std::vector> sortedIndexes; + u32 sortedIndexCount; + std::unique_ptr fogTexture; // Uniforms @@ -518,8 +577,7 @@ private: vk::DeviceSize modVolUniformsMemSize; // Buffers - std::vector> vertexBuffers; - std::vector> indexBuffers; + std::vector> mainBuffers; ShaderManager shaderManager; PipelineManager pipelineManager;