vulkan: implement draw(DrawCommand)

Now love.graphics.point and love.graphics.line works
This commit is contained in:
niki
2022-07-13 13:56:00 +02:00
parent 14b8abeef5
commit 0834408b90
5 changed files with 61 additions and 18 deletions
+36 -14
View File
@@ -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<uint32_t>(cmd.vertexCount), static_cast<uint32_t>(cmd.instanceCount), static_cast<uint32_t>(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<uint32_t>(cmd.indexCount), 1, 0, 0, 0);
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), static_cast<uint32_t>(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<VkBuffer> bufferVector;
std::vector<VkDeviceSize> 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<uint32_t>(bufferVector.size()), bufferVector.data(), offsets.data());
}
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();
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;
}