vulkan: fix validation warnings

Sometimes no buffer for tex coords are given, however the shader
still expects some. We can fix this by using a default buffer, which
contains the constant tex coords (0, 0), which is then bound instead.
This commit is contained in:
niki
2023-07-18 14:56:42 +02:00
parent ba15a2ab05
commit 3b9476b5dd
2 changed files with 42 additions and 10 deletions
+41 -9
View File
@@ -559,8 +559,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
beginFrame();
uint8 whiteColor[] = { 255, 255, 255, 255 };
if (batchedDrawState.vb[0] == nullptr)
{
// Initial sizes that should be good enough for most cases. It will
@@ -570,9 +568,19 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
batchedDrawState.indexBuffer = new StreamBuffer(this, BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
}
// sometimes the VertexTexCoord is not set, so we manually adjust it to (0, 0)
if (defaultConstantTexCoord == nullptr)
{
float zeroTexCoord[2] = { 0.0f, 0.0f };
Buffer::DataDeclaration format("ConstantTexCoord", DATAFORMAT_FLOAT_VEC2);
Buffer::Settings settings(BUFFERUSAGEFLAG_VERTEX, BUFFERDATAUSAGE_STATIC);
defaultConstantTexCoord = newBuffer(settings, { format }, zeroTexCoord, sizeof(zeroTexCoord), 1);
}
// sometimes the VertexColor is not set, so we manually adjust it to white color
if (defaultConstantColor == nullptr)
{
uint8 whiteColor[] = { 255, 255, 255, 255 };
Buffer::DataDeclaration format("ConstantColor", DATAFORMAT_UNORM8_VEC4);
Buffer::Settings settings(BUFFERUSAGEFLAG_VERTEX, BUFFERDATAUSAGE_STATIC);
defaultConstantColor = newBuffer(settings, { format }, whiteColor, sizeof(whiteColor), 1);
@@ -2217,11 +2225,6 @@ VkRenderPass Graphics::getRenderPass(RenderPassConfiguration &configuration)
return renderPass;
}
bool Graphics::usesConstantVertexColor(const VertexAttributes &vertexAttributes)
{
return !!(vertexAttributes.enableBits & (1u << ATTRIB_COLOR));
}
void Graphics::createVulkanVertexFormat(
VertexAttributes vertexAttributes,
std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
@@ -2233,6 +2236,7 @@ void Graphics::createVulkanVertexFormat(
auto allBits = enableBits;
bool usesColor = false;
bool usesTexCoord = false;
uint8_t highestBufferBinding = 0;
@@ -2242,6 +2246,8 @@ void Graphics::createVulkanVertexFormat(
uint32 bit = 1u << i;
if (enableBits & bit)
{
if (i == ATTRIB_TEXCOORD)
usesTexCoord = true;
if (i == ATTRIB_COLOR)
usesColor = true;
@@ -2276,11 +2282,31 @@ void Graphics::createVulkanVertexFormat(
allBits >>= 1;
}
if (!usesTexCoord)
{
// FIXME: is there a case where gaps happen between buffer bindings?
// then this doesn't work. We might need to enable null buffers again.
const auto constantTexCoordBufferBinding = ++highestBufferBinding;
VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = constantTexCoordBufferBinding;
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
bindingDescription.stride = 0; // no stride, will always read the same coord multiple times.
bindingDescriptions.push_back(bindingDescription);
VkVertexInputAttributeDescription attributeDescription{};
attributeDescription.binding = constantTexCoordBufferBinding;
attributeDescription.location = ATTRIB_TEXCOORD;
attributeDescription.offset = 0;
attributeDescription.format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions.push_back(attributeDescription);
}
if (!usesColor)
{
// FIXME: is there a case where gaps happen between buffer bindings?
// then this doesn't work. We might need to enable null buffers again.
const auto constantColorBufferBinding = highestBufferBinding + 1;
const auto constantColorBufferBinding = ++highestBufferBinding;
VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = constantColorBufferBinding;
@@ -2340,7 +2366,13 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
}
}
if (!usesConstantVertexColor(attributes))
if (!(attributes.enableBits & (1u << ATTRIB_TEXCOORD)))
{
bufferVector.push_back((VkBuffer)defaultConstantTexCoord->getHandle());
offsets.push_back((VkDeviceSize)0);
}
if (!(attributes.enableBits & (1u << ATTRIB_COLOR)))
{
bufferVector.push_back((VkBuffer)defaultConstantColor->getHandle());
offsets.push_back((VkDeviceSize)0);
+1 -1
View File
@@ -366,7 +366,6 @@ private:
void startRecordingGraphicsCommands();
void endRecordingGraphicsCommands();
void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration);
bool usesConstantVertexColor(const VertexAttributes &attribs);
void createVulkanVertexFormat(
VertexAttributes vertexAttributes,
std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
@@ -435,6 +434,7 @@ private:
VmaAllocator vmaAllocator = VK_NULL_HANDLE;
StrongRef<love::graphics::Texture> defaultTexture;
StrongRef<love::graphics::Buffer> defaultConstantColor;
StrongRef<love::graphics::Buffer> defaultConstantTexCoord;
// functions that need to be called to cleanup objects that were needed for rendering a frame.
// We need a vector for each frame in flight.
std::vector<std::vector<std::function<void()>>> cleanUpFunctions;