Skip to content

Commit

Permalink
Sort meshes by texture index to avoid unnecessary texture binds
Browse files Browse the repository at this point in the history
- This reduces the texture bind count form 103 to 25 in the Sponza scene.
  • Loading branch information
Nelarius committed Apr 2, 2024
1 parent 6832f91 commit 2f779e1
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/common/gltf_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,10 @@ GltfModel::GltfModel(const fs::path gltfPath)
}

cgltf_free(data);

std::sort(meshes.begin(), meshes.end(), [](const GltfMesh& a, const GltfMesh& b) -> bool {
return a.baseColorTextureIndex < b.baseColorTextureIndex;
});
}

GltfModel::GltfModel(std::vector<GltfMesh> meshes, std::vector<Texture> baseColorTextures)
Expand Down
6 changes: 6 additions & 0 deletions src/common/gltf_model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ struct GltfMesh
{
}

GltfMesh(const GltfMesh&) = delete;
GltfMesh& operator=(const GltfMesh&) = delete;

GltfMesh(GltfMesh&&) noexcept = default;
GltfMesh& operator=(GltfMesh&&) noexcept = default;

std::vector<glm::vec3> positions;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> texCoords;
Expand Down
13 changes: 9 additions & 4 deletions src/pt/deferred_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@ void DeferredRenderer::GbufferPass::render(
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, mUniformBindGroup.ptr(), 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, mSamplerBindGroup.ptr(), 0, nullptr);

std::size_t currentTextureIdx = ~static_cast<std::size_t>(0);
for (std::size_t idx = 0; idx < mPositionBuffers.size(); ++idx)
{
const GpuBuffer& positionBuffer = mPositionBuffers[idx];
Expand All @@ -818,10 +819,14 @@ void DeferredRenderer::GbufferPass::render(
0,
indexBuffer.buffer.byteSize());

const std::size_t textureIdx = mBaseColorTextureIndices[idx];
const GpuBindGroup& baseColorBindGroup = mBaseColorTextureBindGroups[textureIdx];
wgpuRenderPassEncoderSetBindGroup(
renderPassEncoder, 2, baseColorBindGroup.ptr(), 0, nullptr);
const std::size_t textureIdx = mBaseColorTextureIndices[idx];
if (textureIdx != currentTextureIdx)
{
currentTextureIdx = textureIdx;
const GpuBindGroup& baseColorBindGroup = mBaseColorTextureBindGroups[textureIdx];
wgpuRenderPassEncoderSetBindGroup(
renderPassEncoder, 2, baseColorBindGroup.ptr(), 0, nullptr);
}

wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, indexBuffer.count, 1, 0, 0, 0);
}
Expand Down

0 comments on commit 2f779e1

Please sign in to comment.