mirror of
https://github.com/love2d/love.git
synced 2026-08-19 12:14:20 +02:00
vulkan: implement draw(DrawCommand)
Now love.graphics.point and love.graphics.line works
This commit is contained in:
@@ -112,8 +112,6 @@ namespace love {
|
|||||||
renderPassInfo.clearValueCount = 1;
|
renderPassInfo.clearValueCount = 1;
|
||||||
renderPassInfo.pClearValues = &clearColor;
|
renderPassInfo.pClearValues = &clearColor;
|
||||||
|
|
||||||
const auto& commandBuffer = commandBuffers.at(imageIndex);
|
|
||||||
|
|
||||||
vkCmdBeginRenderPass(commandBuffers.at(imageIndex), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(commandBuffers.at(imageIndex), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
currentGraphicsPipeline = VK_NULL_HANDLE;
|
currentGraphicsPipeline = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
@@ -250,6 +248,8 @@ namespace love {
|
|||||||
|
|
||||||
updatedBatchedDrawBuffers();
|
updatedBatchedDrawBuffers();
|
||||||
|
|
||||||
|
Shader::current = Shader::standardShaders[graphics::Shader::StandardShader::STANDARD_DEFAULT];
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,13 +322,21 @@ namespace love {
|
|||||||
return info;
|
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<uint32_t>(cmd.vertexCount), static_cast<uint32_t>(cmd.instanceCount), static_cast<uint32_t>(cmd.vertexStart), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::draw(const DrawIndexedCommand& cmd) {
|
void Graphics::draw(const DrawIndexedCommand& cmd) {
|
||||||
std::cout << "drawIndexed ";
|
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));
|
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast<VkDeviceSize>(cmd.indexBufferOffset), getVulkanIndexBufferType(cmd.indexType));
|
||||||
vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.indexCount), 1, 0, 0, 0);
|
vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.indexCount), static_cast<uint32_t>(cmd.instanceCount), 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setColor(Colorf c) {
|
void Graphics::setColor(Colorf c) {
|
||||||
@@ -366,13 +374,19 @@ namespace love {
|
|||||||
return true;
|
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) {
|
void Graphics::drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) {
|
||||||
std::cout << "drawQuads ";
|
std::cout << "drawQuads ";
|
||||||
|
|
||||||
const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
|
const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
|
||||||
const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4;
|
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));
|
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16));
|
||||||
|
|
||||||
@@ -1176,15 +1190,18 @@ namespace love {
|
|||||||
configuration.vertexInputAttributeDescriptions = attributeDescriptions;
|
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<VkBuffer> bufferVector;
|
std::vector<VkBuffer> bufferVector;
|
||||||
|
|
||||||
std::vector<VkDeviceSize> offsets;
|
std::vector<VkDeviceSize> offsets;
|
||||||
|
|
||||||
bool useConstantColorBuffer;
|
bool useConstantColorBuffer;
|
||||||
GraphicsPipelineConfiguration configuration;
|
|
||||||
createVulkanVertexFormat(attributes, useConstantColorBuffer, 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)) {
|
if (buffers.useBits & (1u << i)) {
|
||||||
bufferVector.push_back((VkBuffer)buffers.info[i].buffer->getHandle());
|
bufferVector.push_back((VkBuffer)buffers.info[i].buffer->getHandle());
|
||||||
offsets.push_back((VkDeviceSize)buffers.info[i].offset);
|
offsets.push_back((VkDeviceSize)buffers.info[i].offset);
|
||||||
@@ -1206,16 +1223,15 @@ namespace love {
|
|||||||
ensureGraphicsPipelineConfiguration(configuration);
|
ensureGraphicsPipelineConfiguration(configuration);
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, getDescriptorSet(currentFrame), 0, nullptr);
|
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<uint32_t>(bufferVector.size()), bufferVector.data(), offsets.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration configuration) {
|
VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration configuration) {
|
||||||
auto shader = reinterpret_cast<love::graphics::vulkan::Shader*>(love::graphics::vulkan::Shader::standardShaders[Shader::STANDARD_DEFAULT]);
|
auto shader = configuration.shader;
|
||||||
auto shaderStages = shader->getShaderStages();
|
auto shaderStages = shader->getShaderStages();
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
|
VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
|
||||||
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
|
|
||||||
vertexInputInfo.vertexBindingDescriptionCount = configuration.vertexInputBindingDescriptions.size();
|
vertexInputInfo.vertexBindingDescriptionCount = configuration.vertexInputBindingDescriptions.size();
|
||||||
vertexInputInfo.pVertexBindingDescriptions = configuration.vertexInputBindingDescriptions.data();
|
vertexInputInfo.pVertexBindingDescriptions = configuration.vertexInputBindingDescriptions.data();
|
||||||
vertexInputInfo.vertexAttributeDescriptionCount = configuration.vertexInputAttributeDescriptions.size();
|
vertexInputInfo.vertexAttributeDescriptionCount = configuration.vertexInputAttributeDescriptions.size();
|
||||||
@@ -1223,7 +1239,7 @@ namespace love {
|
|||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
|
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
|
||||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
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;
|
inputAssembly.primitiveRestartEnable = VK_FALSE;
|
||||||
|
|
||||||
VkViewport viewport{};
|
VkViewport viewport{};
|
||||||
@@ -1250,7 +1266,7 @@ namespace love {
|
|||||||
rasterizer.depthClampEnable = VK_FALSE;
|
rasterizer.depthClampEnable = VK_FALSE;
|
||||||
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
rasterizer.lineWidth = 1.0f;
|
rasterizer.lineWidth = 2.0f;
|
||||||
rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT;
|
rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT;
|
||||||
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||||
rasterizer.depthBiasEnable = VK_FALSE;
|
rasterizer.depthBiasEnable = VK_FALSE;
|
||||||
@@ -1433,6 +1449,12 @@ namespace love {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other) {
|
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()) {
|
if (first.vertexInputAttributeDescriptions.size() != other.vertexInputAttributeDescriptions.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ namespace love {
|
|||||||
struct GraphicsPipelineConfiguration {
|
struct GraphicsPipelineConfiguration {
|
||||||
std::vector<VkVertexInputBindingDescription> vertexInputBindingDescriptions;
|
std::vector<VkVertexInputBindingDescription> vertexInputBindingDescriptions;
|
||||||
std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions;
|
std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions;
|
||||||
|
Shader* shader = nullptr;
|
||||||
|
PrimitiveType primitiveType = PRIMITIVE_MAX_ENUM;
|
||||||
|
|
||||||
friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other);
|
friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other);
|
||||||
};
|
};
|
||||||
@@ -103,10 +105,10 @@ namespace love {
|
|||||||
void setWireframe(bool enable) override { std::cout << "setWireframe "; }
|
void setWireframe(bool enable) override { std::cout << "setWireframe "; }
|
||||||
PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override;
|
PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override;
|
||||||
bool isPixelFormatSupported(PixelFormat format, uint32 usage, bool sRGB = false) 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; }
|
bool usesGLSLES() const override { std::cout << "usesGLSES "; return false; }
|
||||||
RendererInfo getRendererInfo() const override;
|
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 draw(const DrawIndexedCommand& cmd) override;
|
||||||
void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) 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);
|
VkDescriptorSet* getDescriptorSet(int currentFrame);
|
||||||
graphics::StreamBuffer* getUniformBuffer();
|
graphics::StreamBuffer* getUniformBuffer();
|
||||||
void createVulkanVertexFormat(VertexAttributes vertexAttributes, bool& useConstantVertexColor, GraphicsPipelineConfiguration& configuration);
|
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;
|
VkInstance instance = VK_NULL_HANDLE;
|
||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
namespace love {
|
namespace love {
|
||||||
@@ -20,7 +21,9 @@ namespace love {
|
|||||||
return shaderStages;
|
return shaderStages;
|
||||||
}
|
}
|
||||||
|
|
||||||
void attach() override {}
|
void attach() override {
|
||||||
|
Shader::current = this;
|
||||||
|
}
|
||||||
|
|
||||||
ptrdiff_t getHandle() const { return 0; }
|
ptrdiff_t getHandle() const { return 0; }
|
||||||
|
|
||||||
|
|||||||
@@ -286,6 +286,21 @@ namespace love {
|
|||||||
|
|
||||||
return ss.str();
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ namespace love {
|
|||||||
static TextureFormat getTextureFormat(PixelFormat);
|
static TextureFormat getTextureFormat(PixelFormat);
|
||||||
static std::string getVendorName(uint32_t vendorId);
|
static std::string getVendorName(uint32_t vendorId);
|
||||||
static std::string getVulkanApiVersion(uint32_t apiVersion);
|
static std::string getVulkanApiVersion(uint32_t apiVersion);
|
||||||
|
static VkPrimitiveTopology getPrimitiveTypeTopology(graphics::PrimitiveType);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user