vulkan: implement cull and winding

This commit is contained in:
niki
2022-07-13 17:27:11 +02:00
parent c6d79ae87e
commit 38f15ae97d
4 changed files with 57 additions and 8 deletions
+27 -6
View File
@@ -205,6 +205,7 @@ namespace love {
Shader::current = Shader::standardShaders[graphics::Shader::StandardShader::STANDARD_DEFAULT]; Shader::current = Shader::standardShaders[graphics::Shader::StandardShader::STANDARD_DEFAULT];
currentPolygonMode = VK_POLYGON_MODE_FILL; currentPolygonMode = VK_POLYGON_MODE_FILL;
restoreState(states.back());
return true; return true;
} }
@@ -265,6 +266,18 @@ namespace love {
cleanup(); cleanup();
} }
void Graphics::setFrontFaceWinding(Winding winding) {
const auto& currentState = states.back();
if (currentState.winding == winding) {
return;
}
flushBatchedDraws();
states.back().winding = winding;
}
void Graphics::setColorMask(ColorChannelMask mask) { void Graphics::setColorMask(ColorChannelMask mask) {
flushBatchedDraws(); flushBatchedDraws();
@@ -308,7 +321,7 @@ namespace love {
void Graphics::draw(const DrawCommand& cmd) { void Graphics::draw(const DrawCommand& cmd) {
std::cout << "draw "; std::cout << "draw ";
prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType); prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
vkCmdDraw(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.vertexCount), static_cast<uint32_t>(cmd.instanceCount), static_cast<uint32_t>(cmd.vertexStart), 0); vkCmdDraw(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.vertexCount), static_cast<uint32_t>(cmd.instanceCount), static_cast<uint32_t>(cmd.vertexStart), 0);
} }
@@ -316,7 +329,7 @@ namespace love {
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, cmd.primitiveType); prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast<VkDeviceSize>(cmd.indexBufferOffset), 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), static_cast<uint32_t>(cmd.instanceCount), 0, 0, 0); vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.indexCount), static_cast<uint32_t>(cmd.instanceCount), 0, 0, 0);
@@ -384,7 +397,7 @@ namespace love {
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, PRIMITIVE_TRIANGLES); prepareDraw(attributes, buffers, texture, PRIMITIVE_TRIANGLES, CULL_BACK);
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16)); vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16));
@@ -1237,12 +1250,14 @@ namespace love {
configuration.vertexInputAttributeDescriptions = attributeDescriptions; configuration.vertexInputAttributeDescriptions = attributeDescriptions;
} }
void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType primitiveType) { void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType primitiveType, CullMode cullmode) {
GraphicsPipelineConfiguration configuration; GraphicsPipelineConfiguration configuration;
configuration.shader = (Shader*)Shader::current; configuration.shader = (Shader*)Shader::current;
configuration.primitiveType = primitiveType; configuration.primitiveType = primitiveType;
configuration.polygonMode = currentPolygonMode; configuration.polygonMode = currentPolygonMode;
configuration.blendState = states.back().blend; configuration.blendState = states.back().blend;
configuration.winding = states.back().winding;
configuration.cullmode = cullmode;
std::vector<VkBuffer> bufferVector; std::vector<VkBuffer> bufferVector;
std::vector<VkDeviceSize> offsets; std::vector<VkDeviceSize> offsets;
@@ -1316,8 +1331,8 @@ namespace love {
rasterizer.rasterizerDiscardEnable = VK_FALSE; rasterizer.rasterizerDiscardEnable = VK_FALSE;
rasterizer.polygonMode = configuration.polygonMode; rasterizer.polygonMode = configuration.polygonMode;
rasterizer.lineWidth = 1.0f; rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT; rasterizer.cullMode = Vulkan::getCullMode(configuration.cullmode);
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; rasterizer.frontFace = Vulkan::getFrontFace(configuration.winding);
rasterizer.depthBiasEnable = VK_FALSE; rasterizer.depthBiasEnable = VK_FALSE;
rasterizer.depthBiasConstantFactor = 0.0f; rasterizer.depthBiasConstantFactor = 0.0f;
rasterizer.depthBiasClamp = 0.0f; rasterizer.depthBiasClamp = 0.0f;
@@ -1498,6 +1513,12 @@ namespace love {
} }
bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other) { bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other) {
if (first.cullmode != other.cullmode) {
return false;
}
if (first.winding != other.winding) {
return false;
}
if (first.colorChannelMask != other.colorChannelMask) { if (first.colorChannelMask != other.colorChannelMask) {
return false; return false;
} }
+4 -2
View File
@@ -27,6 +27,8 @@ namespace love {
VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL; VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
BlendState blendState; BlendState blendState;
ColorChannelMask colorChannelMask; ColorChannelMask colorChannelMask;
Winding winding;
CullMode cullmode;
friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other); friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other);
}; };
@@ -99,7 +101,7 @@ namespace love {
void setScissor() override { std::cout << "setScissor2 "; } void setScissor() override { std::cout << "setScissor2 "; }
void setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override { std::cout << "setStencilMode "; } void setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override { std::cout << "setStencilMode "; }
void setDepthMode(CompareMode compare, bool write) override { std::cout << "setDepthMode "; } void setDepthMode(CompareMode compare, bool write) override { std::cout << "setDepthMode "; }
void setFrontFaceWinding(Winding winding) override { std::cout << "setFrontFaceWinding "; } void setFrontFaceWinding(Winding winding) override;
void setColorMask(ColorChannelMask mask) override; void setColorMask(ColorChannelMask mask) override;
void setBlendState(const BlendState& blend) override; void setBlendState(const BlendState& blend) override;
void setPointSize(float size) override; void setPointSize(float size) override;
@@ -175,7 +177,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, PrimitiveType); void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType, CullMode);
VkInstance instance = VK_NULL_HANDLE; VkInstance instance = VK_NULL_HANDLE;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
+24
View File
@@ -374,6 +374,30 @@ namespace love {
return flags; return flags;
} }
VkFrontFace Vulkan::getFrontFace(Winding winding) {
switch (winding) {
case WINDING_CW:
return VK_FRONT_FACE_CLOCKWISE;
case WINDING_CCW:
return VK_FRONT_FACE_COUNTER_CLOCKWISE;
default:
throw love::Exception("unknown winding");
}
}
VkCullModeFlags Vulkan::getCullMode(CullMode cullmode) {
switch (cullmode) {
case CULL_BACK:
return VK_CULL_MODE_BACK_BIT;
case CULL_FRONT:
return VK_CULL_MODE_FRONT_BIT;
case CULL_NONE:
return VK_CULL_MODE_NONE;
default:
throw love::Exception("unknown cull mode");
}
}
} }
} }
} }
+2
View File
@@ -27,6 +27,8 @@ namespace love {
static VkBlendOp getBlendOp(BlendOperation); static VkBlendOp getBlendOp(BlendOperation);
static VkBool32 getBool(bool); static VkBool32 getBool(bool);
static VkColorComponentFlags getColorMask(ColorChannelMask); static VkColorComponentFlags getColorMask(ColorChannelMask);
static VkFrontFace getFrontFace(Winding);
static VkCullModeFlags getCullMode(CullMode);
}; };
} }
} }