diff --git a/src/rendering/vulkan/renderer/vk_renderpass.cpp b/src/rendering/vulkan/renderer/vk_renderpass.cpp index 1307a204e..c27be2e87 100644 --- a/src/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/rendering/vulkan/renderer/vk_renderpass.cpp @@ -200,10 +200,20 @@ void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key) VK_FORMAT_A2R10G10B10_SNORM_PACK32 }; + bool inputLocations[6] = { false, false, false, false, false, false }; + for (size_t i = 0; i < vfmt.Attrs.size(); i++) { const auto &attr = vfmt.Attrs[i]; builder.addVertexAttribute(attr.location, attr.binding, vkfmts[attr.format], attr.offset); + inputLocations[attr.location] = true; + } + + // To do: does vulkan absolutely needs a binding for each location or not? What happens if it isn't specified? Better be safe than sorry.. + for (int i = 0; i < 6; i++) + { + if (!inputLocations[i]) + builder.addVertexAttribute(i, 0, VK_FORMAT_R32G32B32_SFLOAT, 0); } builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT); @@ -219,6 +229,16 @@ void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key) builder.setViewport(0.0f, 0.0f, (float)SCREENWIDTH, (float)SCREENHEIGHT); builder.setScissor(0, 0, SCREENWIDTH, SCREENHEIGHT); + static const VkPrimitiveTopology vktopology[] = { + VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP + }; + + builder.setTopology(vktopology[key.DrawType]); + static const int blendstyles[] = { VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, diff --git a/src/rendering/vulkan/renderer/vk_renderpass.h b/src/rendering/vulkan/renderer/vk_renderpass.h index 33c4b685f..4d0b96e63 100644 --- a/src/rendering/vulkan/renderer/vk_renderpass.h +++ b/src/rendering/vulkan/renderer/vk_renderpass.h @@ -14,14 +14,13 @@ public: FRenderStyle RenderStyle; int SpecialEffect; int EffectState; - bool AlphaTest; + int AlphaTest; int VertexFormat; + int DrawType; bool operator<(const VkRenderPassKey &other) const { - uint64_t a = RenderStyle.AsDWORD | (static_cast(SpecialEffect) << 32) | (static_cast(EffectState) << 40) | (static_cast(AlphaTest) << 48) | (static_cast(VertexFormat) << 56); - uint64_t b = other.RenderStyle.AsDWORD | (static_cast(other.SpecialEffect) << 32) | (static_cast(other.EffectState) << 40) | (static_cast(other.AlphaTest) << 48) | (static_cast(other.VertexFormat) << 56); - return a < b; + return memcmp(this, &other, sizeof(VkRenderPassKey)); } }; diff --git a/src/rendering/vulkan/renderer/vk_renderstate.cpp b/src/rendering/vulkan/renderer/vk_renderstate.cpp index c9502ed98..0ae93d61c 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/src/rendering/vulkan/renderer/vk_renderstate.cpp @@ -140,6 +140,7 @@ void VkRenderState::Apply(int dt) // Find a render pass that matches our state VkRenderPassKey passKey; + passKey.DrawType = dt; passKey.VertexFormat = static_cast(mVertexBuffer)->VertexFormat; passKey.RenderStyle = mRenderStyle; if (mSpecialEffect > EFF_NONE) diff --git a/src/rendering/vulkan/system/vk_builders.h b/src/rendering/vulkan/system/vk_builders.h index 27c6602e6..a12e94d72 100644 --- a/src/rendering/vulkan/system/vk_builders.h +++ b/src/rendering/vulkan/system/vk_builders.h @@ -181,6 +181,7 @@ public: void setSubpass(int subpass); void setLayout(VulkanPipelineLayout *layout); void setRenderPass(VulkanRenderPass *renderPass); + void setTopology(VkPrimitiveTopology topology); void setViewport(float x, float y, float width, float height, float minDepth = 0.0f, float maxDepth = 1.0f); void setScissor(int x, int y, int width, int height); @@ -727,6 +728,11 @@ inline void GraphicsPipelineBuilder::setRenderPass(VulkanRenderPass *renderPass) pipelineInfo.renderPass = renderPass->renderPass; } +inline void GraphicsPipelineBuilder::setTopology(VkPrimitiveTopology topology) +{ + inputAssembly.topology = topology; +} + inline void GraphicsPipelineBuilder::setViewport(float x, float y, float width, float height, float minDepth, float maxDepth) { viewport.x = 0.0f;