diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index a2d69582c..d3dcfd073 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -112,8 +112,6 @@ namespace love { renderPassInfo.clearValueCount = 1; renderPassInfo.pClearValues = &clearColor; - const auto& commandBuffer = commandBuffers.at(imageIndex); - vkCmdBeginRenderPass(commandBuffers.at(imageIndex), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); currentGraphicsPipeline = VK_NULL_HANDLE; } @@ -250,6 +248,8 @@ namespace love { updatedBatchedDrawBuffers(); + Shader::current = Shader::standardShaders[graphics::Shader::StandardShader::STANDARD_DEFAULT]; + return true; } @@ -322,13 +322,21 @@ namespace love { return info; } + void Graphics::draw(const DrawCommand& cmd) { + std::cout << "draw "; + + prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType); + + vkCmdDraw(commandBuffers.at(imageIndex), static_cast(cmd.vertexCount), static_cast(cmd.instanceCount), static_cast(cmd.vertexStart), 0); + } + void Graphics::draw(const DrawIndexedCommand& cmd) { std::cout << "drawIndexed "; - prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture); + prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType); - vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), 0, getVulkanIndexBufferType(cmd.indexType)); - vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast(cmd.indexCount), 1, 0, 0, 0); + vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast(cmd.indexBufferOffset), getVulkanIndexBufferType(cmd.indexType)); + vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast(cmd.indexCount), static_cast(cmd.instanceCount), 0, 0, 0); } void Graphics::setColor(Colorf c) { @@ -366,13 +374,19 @@ namespace love { return true; } + Renderer Graphics::getRenderer() const { + std::cout << "getRenderer "; + + return RENDERER_VULKAN; + } + void Graphics::drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) { std::cout << "drawQuads "; const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX; const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4; - prepareDraw(attributes, buffers, texture); + prepareDraw(attributes, buffers, texture, PRIMITIVE_TRIANGLES); vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16)); @@ -1176,15 +1190,18 @@ namespace love { configuration.vertexInputAttributeDescriptions = attributeDescriptions; } - void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) { + void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType primitiveType) { + GraphicsPipelineConfiguration configuration; + configuration.shader = (Shader*)Shader::current; + configuration.primitiveType = primitiveType; std::vector bufferVector; + std::vector offsets; bool useConstantColorBuffer; - GraphicsPipelineConfiguration configuration; createVulkanVertexFormat(attributes, useConstantColorBuffer, configuration); - for (uint32_t i = 0; i < 2; i++) { + for (uint32_t i = 0; i < VertexAttributes::MAX; i++) { if (buffers.useBits & (1u << i)) { bufferVector.push_back((VkBuffer)buffers.info[i].buffer->getHandle()); offsets.push_back((VkDeviceSize)buffers.info[i].offset); @@ -1206,16 +1223,15 @@ namespace love { ensureGraphicsPipelineConfiguration(configuration); vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, getDescriptorSet(currentFrame), 0, nullptr); - vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, bufferVector.size(), bufferVector.data(), offsets.data()); + vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, static_cast(bufferVector.size()), bufferVector.data(), offsets.data()); } VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration configuration) { - auto shader = reinterpret_cast(love::graphics::vulkan::Shader::standardShaders[Shader::STANDARD_DEFAULT]); + auto shader = configuration.shader; auto shaderStages = shader->getShaderStages(); VkPipelineVertexInputStateCreateInfo vertexInputInfo{}; vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertexInputInfo.vertexBindingDescriptionCount = configuration.vertexInputBindingDescriptions.size(); vertexInputInfo.pVertexBindingDescriptions = configuration.vertexInputBindingDescriptions.data(); vertexInputInfo.vertexAttributeDescriptionCount = configuration.vertexInputAttributeDescriptions.size(); @@ -1223,7 +1239,7 @@ namespace love { VkPipelineInputAssemblyStateCreateInfo inputAssembly{}; inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + inputAssembly.topology = Vulkan::getPrimitiveTypeTopology(configuration.primitiveType); inputAssembly.primitiveRestartEnable = VK_FALSE; VkViewport viewport{}; @@ -1250,7 +1266,7 @@ namespace love { rasterizer.depthClampEnable = VK_FALSE; rasterizer.rasterizerDiscardEnable = VK_FALSE; rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - rasterizer.lineWidth = 1.0f; + rasterizer.lineWidth = 2.0f; rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT; rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; rasterizer.depthBiasEnable = VK_FALSE; @@ -1433,6 +1449,12 @@ namespace love { } bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other) { + if (first.primitiveType != other.primitiveType) { + return false; + } + if (first.shader != other.shader) { + return false; + } if (first.vertexInputAttributeDescriptions.size() != other.vertexInputAttributeDescriptions.size()) { return false; } diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 566365f7e..2964829cf 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -22,6 +22,8 @@ namespace love { struct GraphicsPipelineConfiguration { std::vector vertexInputBindingDescriptions; std::vector vertexInputAttributeDescriptions; + Shader* shader = nullptr; + PrimitiveType primitiveType = PRIMITIVE_MAX_ENUM; friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other); }; @@ -103,10 +105,10 @@ namespace love { void setWireframe(bool enable) override { std::cout << "setWireframe "; } PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override; bool isPixelFormatSupported(PixelFormat format, uint32 usage, bool sRGB = false) override; - Renderer getRenderer() const override { std::cout << "getRenderer "; return RENDERER_VULKAN; } + Renderer getRenderer() const override; bool usesGLSLES() const override { std::cout << "usesGLSES "; return false; } RendererInfo getRendererInfo() const override; - void draw(const DrawCommand& cmd) override { std::cout << "draw "; } + void draw(const DrawCommand& cmd) override; void draw(const DrawIndexedCommand& cmd) override; void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) override; @@ -172,7 +174,7 @@ namespace love { VkDescriptorSet* getDescriptorSet(int currentFrame); graphics::StreamBuffer* getUniformBuffer(); void createVulkanVertexFormat(VertexAttributes vertexAttributes, bool& useConstantVertexColor, GraphicsPipelineConfiguration& configuration); - void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture); + void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType); VkInstance instance = VK_NULL_HANDLE; VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; diff --git a/src/modules/graphics/vulkan/Shader.h b/src/modules/graphics/vulkan/Shader.h index 479866618..042fcf7c1 100644 --- a/src/modules/graphics/vulkan/Shader.h +++ b/src/modules/graphics/vulkan/Shader.h @@ -6,6 +6,7 @@ #include #include +#include namespace love { @@ -20,7 +21,9 @@ namespace love { return shaderStages; } - void attach() override {} + void attach() override { + Shader::current = this; + } ptrdiff_t getHandle() const { return 0; } diff --git a/src/modules/graphics/vulkan/Vulkan.cpp b/src/modules/graphics/vulkan/Vulkan.cpp index 9c4b2c1f4..3430ab9f1 100644 --- a/src/modules/graphics/vulkan/Vulkan.cpp +++ b/src/modules/graphics/vulkan/Vulkan.cpp @@ -286,6 +286,21 @@ namespace love { return ss.str(); } + + VkPrimitiveTopology Vulkan::getPrimitiveTypeTopology(graphics::PrimitiveType primitiveType) { + switch (primitiveType) { + case PRIMITIVE_POINTS: + return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + case PRIMITIVE_TRIANGLES: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + case PRIMITIVE_TRIANGLE_FAN: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; + case PRIMITIVE_TRIANGLE_STRIP: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + default: + throw love::Exception("unknown primitive type"); + } + } } } } diff --git a/src/modules/graphics/vulkan/Vulkan.h b/src/modules/graphics/vulkan/Vulkan.h index ea0d9fed3..f4a4c19e9 100644 --- a/src/modules/graphics/vulkan/Vulkan.h +++ b/src/modules/graphics/vulkan/Vulkan.h @@ -22,6 +22,7 @@ namespace love { static TextureFormat getTextureFormat(PixelFormat); static std::string getVendorName(uint32_t vendorId); static std::string getVulkanApiVersion(uint32_t apiVersion); + static VkPrimitiveTopology getPrimitiveTypeTopology(graphics::PrimitiveType); }; } }