Skip to content

Commit b56067b

Browse files
committed
Enable drawIndirectFirstInstance feature
Code cleanup Fixes SaschaWillems#1198
1 parent 9a562a5 commit b56067b

File tree

1 file changed

+25
-27
lines changed

1 file changed

+25
-27
lines changed

examples/computecullandlod/computecullandlod.cpp

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Vulkan Example - Compute shader culling and LOD using indirect rendering
33
*
4-
* Copyright (C) 2016-2023 by Sascha Willems - www.saschawillems.de
4+
* Copyright (C) 2016-2025 by Sascha Willems - www.saschawillems.de
55
*
66
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
77
*
@@ -14,12 +14,12 @@
1414

1515
// Total number of objects (^3) in the scene
1616
#if defined(__ANDROID__)
17-
#define OBJECT_COUNT 32
17+
constexpr auto OBJECT_COUNT 32;
1818
#else
19-
#define OBJECT_COUNT 64
19+
constexpr auto OBJECT_COUNT = 64;
2020
#endif
2121

22-
#define MAX_LOD_LEVEL 5
22+
constexpr auto MAX_LOD_LEVEL = 5;
2323

2424
class VulkanExample : public VulkanExampleBase
2525
{
@@ -31,8 +31,8 @@ class VulkanExample : public VulkanExampleBase
3131

3232
// Per-instance data block
3333
struct InstanceData {
34-
glm::vec3 pos;
35-
float scale;
34+
glm::vec3 pos{ 0.0f };
35+
float scale{ 1.0f };
3636
};
3737

3838
// Contains the instanced data
@@ -61,13 +61,10 @@ class VulkanExample : public VulkanExampleBase
6161
vks::Buffer scene;
6262
} uniformData;
6363

64-
struct {
65-
VkPipeline plants;
66-
} pipelines;
67-
68-
VkPipelineLayout pipelineLayout;
69-
VkDescriptorSet descriptorSet;
70-
VkDescriptorSetLayout descriptorSetLayout;
64+
VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE };
65+
VkPipeline pipeline{ VK_NULL_HANDLE };
66+
VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE };
67+
VkDescriptorSet descriptorSet{ VK_NULL_HANDLE };
7168

7269
// Resources for the compute part of the example
7370
struct {
@@ -81,7 +78,7 @@ class VulkanExample : public VulkanExampleBase
8178
VkDescriptorSet descriptorSet; // Compute shader bindings
8279
VkPipelineLayout pipelineLayout; // Layout of the compute pipeline
8380
VkPipeline pipeline; // Compute pipeline for updating particle positions
84-
} compute;
81+
} compute{};
8582

8683
// View frustum for culling invisible objects
8784
vks::Frustum frustum;
@@ -101,7 +98,7 @@ class VulkanExample : public VulkanExampleBase
10198
~VulkanExample()
10299
{
103100
if (device) {
104-
vkDestroyPipeline(device, pipelines.plants, nullptr);
101+
vkDestroyPipeline(device, pipeline, nullptr);
105102
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
106103
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
107104
instanceBuffer.destroy();
@@ -124,13 +121,15 @@ class VulkanExample : public VulkanExampleBase
124121
if (deviceFeatures.multiDrawIndirect) {
125122
enabledFeatures.multiDrawIndirect = VK_TRUE;
126123
}
124+
// This is required for for using firstInstance
125+
enabledFeatures.drawIndirectFirstInstance = VK_TRUE;
127126
}
128127

129128
void buildCommandBuffers()
130129
{
131130
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
132131

133-
VkClearValue clearValues[2];
132+
VkClearValue clearValues[2]{};
134133
clearValues[0].color = { { 0.18f, 0.27f, 0.5f, 0.0f } };
135134
clearValues[1].depthStencil = { 1.0f, 0 };
136135

@@ -186,7 +185,7 @@ class VulkanExample : public VulkanExampleBase
186185
vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL);
187186

188187
// Mesh containing the LODs
189-
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.plants);
188+
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
190189
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &lodModel.vertices.buffer, offsets);
191190
vkCmdBindVertexBuffers(drawCmdBuffers[i], 1, 1, &instanceBuffer.buffer, offsets);
192191

@@ -400,6 +399,7 @@ class VulkanExample : public VulkanExampleBase
400399
inputState.vertexBindingDescriptionCount = static_cast<uint32_t>(bindingDescriptions.size());
401400
inputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
402401

402+
// Indirect (and instanced) pipeline
403403
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE);
404404
VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
405405
VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
@@ -409,9 +409,11 @@ class VulkanExample : public VulkanExampleBase
409409
VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0);
410410
std::vector<VkDynamicState> dynamicStateEnables = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
411411
VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables);
412-
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
413-
414412
VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass);
413+
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = {
414+
loadShader(getShadersPath() + "computecullandlod/indirectdraw.vert.spv", VK_SHADER_STAGE_VERTEX_BIT),
415+
loadShader(getShadersPath() + "computecullandlod/indirectdraw.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT)
416+
};
415417
pipelineCreateInfo.pVertexInputState = &inputState;
416418
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
417419
pipelineCreateInfo.pRasterizationState = &rasterizationState;
@@ -422,11 +424,7 @@ class VulkanExample : public VulkanExampleBase
422424
pipelineCreateInfo.pDynamicState = &dynamicState;
423425
pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
424426
pipelineCreateInfo.pStages = shaderStages.data();
425-
426-
// Indirect (and instanced) pipeline for the plants
427-
shaderStages[0] = loadShader(getShadersPath() + "computecullandlod/indirectdraw.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
428-
shaderStages[1] = loadShader(getShadersPath() + "computecullandlod/indirectdraw.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
429-
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.plants));
427+
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline));
430428
}
431429

432430
void prepareBuffers()
@@ -555,7 +553,7 @@ class VulkanExample : public VulkanExampleBase
555553
uint32_t n = 0;
556554
for (auto node : lodModel.nodes)
557555
{
558-
LOD lod;
556+
LOD lod{};
559557
lod.firstIndex = node->mesh->primitives[0]->firstIndex; // First index for this LOD
560558
lod.indexCount = node->mesh->primitives[0]->indexCount; // Index count for this LOD
561559
lod.distance = 5.0f + n * 5.0f; // Starting distance (to viewer) for this LOD
@@ -675,7 +673,7 @@ class VulkanExample : public VulkanExampleBase
675673
&compute.lodLevelsBuffers.descriptor)
676674
};
677675

678-
vkUpdateDescriptorSets(device, static_cast<uint32_t>(computeWriteDescriptorSets.size()), computeWriteDescriptorSets.data(), 0, NULL);
676+
vkUpdateDescriptorSets(device, static_cast<uint32_t>(computeWriteDescriptorSets.size()), computeWriteDescriptorSets.data(), 0, nullptr);
679677

680678
// Create pipeline
681679
VkComputePipelineCreateInfo computePipelineCreateInfo = vks::initializers::computePipelineCreateInfo(compute.pipelineLayout, 0);
@@ -689,7 +687,7 @@ class VulkanExample : public VulkanExampleBase
689687

690688
uint32_t specializationData = static_cast<uint32_t>(lodModel.nodes.size()) - 1;
691689

692-
VkSpecializationInfo specializationInfo;
690+
VkSpecializationInfo specializationInfo{};
693691
specializationInfo.mapEntryCount = 1;
694692
specializationInfo.pMapEntries = &specializationEntry;
695693
specializationInfo.dataSize = sizeof(specializationData);

0 commit comments

Comments
 (0)