Skip to content

Commit

Permalink
igl | vulkan | Detect inconsistent vertex buffer bindings
Browse files Browse the repository at this point in the history
Summary: Bound vertex buffers should match `VertexInputState` in the rendering pipeline.

Reviewed By: EricGriffith, pixelperfect3

Differential Revision: D49175381

fbshipit-source-id: 64788a02c7e7561b11e7e431623fb35ac515c02d
  • Loading branch information
corporateshark authored and facebook-github-bot committed Sep 13, 2023
1 parent f043488 commit 4d22eb6
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/igl/vulkan/RenderCommandEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <igl/vulkan/RenderPipelineState.h>
#include <igl/vulkan/SamplerState.h>
#include <igl/vulkan/Texture.h>
#include <igl/vulkan/VertexInputState.h>
#include <igl/vulkan/VulkanBuffer.h>
#include <igl/vulkan/VulkanContext.h>
#include <igl/vulkan/VulkanDevice.h>
Expand Down Expand Up @@ -484,6 +485,9 @@ void RenderCommandEncoder::bindBuffer(int index,
if (isVertexBuffer) {
IGL_ASSERT(target == BindTarget::kVertex);
IGL_ASSERT(!isUniformOrStorageBuffer);
if (IGL_VERIFY(index < IGL_VERTEX_BINDINGS_MAX)) {
isVertexBufferBound_[index] = true;
}
const VkDeviceSize offset = bufferOffset;
vkCmdBindVertexBuffers(cmdBuffer_, index, 1, &vkBuf, &offset);
} else if (isUniformOrStorageBuffer) {
Expand Down Expand Up @@ -596,6 +600,8 @@ void RenderCommandEncoder::draw(PrimitiveType primitiveType,
return;
}

ensureVertexBuffers();

binder_.updateBindings();
dynamicState_.setTopology(primitiveTypeToVkPrimitiveTopology(primitiveType));
bindPipeline();
Expand All @@ -620,6 +626,8 @@ void RenderCommandEncoder::drawIndexed(PrimitiveType primitiveType,
return;
}

ensureVertexBuffers();

binder_.updateBindings();
dynamicState_.setTopology(primitiveTypeToVkPrimitiveTopology(primitiveType));
bindPipeline();
Expand Down Expand Up @@ -656,6 +664,8 @@ void RenderCommandEncoder::multiDrawIndirect(PrimitiveType primitiveType,
uint32_t stride) {
IGL_PROFILER_FUNCTION();

ensureVertexBuffers();

binder_.updateBindings();
dynamicState_.setTopology(primitiveTypeToVkPrimitiveTopology(primitiveType));
bindPipeline();
Expand All @@ -680,6 +690,8 @@ void RenderCommandEncoder::multiDrawIndexedIndirect(PrimitiveType primitiveType,
uint32_t stride) {
IGL_PROFILER_FUNCTION();

ensureVertexBuffers();

binder_.updateBindings();
dynamicState_.setTopology(primitiveTypeToVkPrimitiveTopology(primitiveType));
bindPipeline();
Expand Down Expand Up @@ -723,5 +735,32 @@ bool RenderCommandEncoder::setDrawCallCountEnabled(bool value) {
return returnVal;
}

void RenderCommandEncoder::ensureVertexBuffers() {
const igl::vulkan::RenderPipelineState* rps =
static_cast<igl::vulkan::RenderPipelineState*>(currentPipeline_.get());

if (!IGL_VERIFY(rps)) {
return;
}

const igl::vulkan::VertexInputState* vi = static_cast<igl::vulkan::VertexInputState*>(
rps->getRenderPipelineDesc().vertexInputState.get());

if (!vi) {
// no vertex input is perfectly valid
return;
}

const VertexInputStateDesc& desc = vi->desc_;

for (size_t i = 0; i != desc.numInputBindings; i++) {
if (!IGL_VERIFY(isVertexBufferBound_[i])) {
IGL_ASSERT_MSG(false,
"Did you forget to call bindBuffer() for one of your vertex input buffers?");
IGL_LOG_ERROR("Did you forget to call bindBuffer() for one of your vertex input buffers?");
}
}
}

} // namespace vulkan
} // namespace igl
3 changes: 3 additions & 0 deletions src/igl/vulkan/RenderCommandEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class RenderCommandEncoder : public IRenderCommandEncoder {

private:
void bindPipeline();
void ensureVertexBuffers();

private:
VulkanContext& ctx_;
Expand All @@ -116,6 +117,8 @@ class RenderCommandEncoder : public IRenderCommandEncoder {
* 1: All other times */
uint32_t drawCallCountEnabled_ = 1u;

bool isVertexBufferBound_[IGL_VERTEX_BUFFER_MAX] = {};

private:
RenderCommandEncoder(const std::shared_ptr<CommandBuffer>& commandBuffer, VulkanContext& ctx);

Expand Down
1 change: 1 addition & 0 deletions src/igl/vulkan/VertexInputState.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class VertexInputState final : public IVertexInputState {
~VertexInputState() override = default;

friend class Device;
friend class RenderCommandEncoder;
friend class RenderPipelineState;

private:
Expand Down

0 comments on commit 4d22eb6

Please sign in to comment.