Skip to content

Commit baf3cd5

Browse files
Add compute pipeline and compute queue
1 parent 2807738 commit baf3cd5

3 files changed

Lines changed: 122 additions & 41 deletions

File tree

samples/extensions/subgroups_operations/subgroups_operations.cpp

Lines changed: 66 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
#include "subgroups_operations.h"
19+
#include <chrono>
1920

2021
void SubgroupsOperations::Pipeline::destroy(VkDevice device)
2122
{
@@ -37,6 +38,7 @@ SubgroupsOperations::SubgroupsOperations()
3738

3839
camera.set_perspective(60.0f, static_cast<float>(width) / static_cast<float>(height), 0.1f, 256.0f);
3940
camera.set_position({0.0f, 0.0f, -2.0f});
41+
add_device_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
4042
add_device_extension(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME);
4143
add_device_extension(VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME); // is needed???
4244
add_device_extension(VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME); // is needed???
@@ -46,10 +48,10 @@ SubgroupsOperations::~SubgroupsOperations()
4648
{
4749
if (device)
4850
{
49-
// compute.pipelines._default.destroy(get_device().get_handle());
50-
// vkDestroyDescriptorSetLayout(get_device().get_handle(), compute.descriptor_set_layout, nullptr);
51-
// vkDestroySemaphore(get_device().get_handle(), compute.semaphore, nullptr);
52-
// vkDestroyCommandPool(get_device().get_handle(), compute.command_pool, nullptr);
51+
compute.pipelines._default.destroy(get_device().get_handle());
52+
vkDestroyDescriptorSetLayout(get_device().get_handle(), compute.descriptor_set_layout, nullptr);
53+
vkDestroySemaphore(get_device().get_handle(), compute.semaphore, nullptr);
54+
vkDestroyCommandPool(get_device().get_handle(), compute.command_pool, nullptr);
5355

5456
ocean.pipelines._default.destroy(get_device().get_handle());
5557
ocean.pipelines.wireframe.destroy(get_device().get_handle());
@@ -65,12 +67,11 @@ bool SubgroupsOperations::prepare(vkb::Platform &platform)
6567
}
6668

6769
load_assets();
68-
// prepare_compute();
69-
70-
// graphics pipeline
71-
generate_grid();
72-
prepare_uniform_buffers();
7370
setup_descriptor_pool();
71+
prepare_uniform_buffers();
72+
prepare_compute();
73+
74+
// grpahics pipeline
7475
create_descriptor_set_layout();
7576
create_descriptor_set();
7677
create_pipelines();
@@ -90,7 +91,7 @@ void SubgroupsOperations::prepare_compute()
9091
create_compute_descriptor_set();
9192
preapre_compute_pipeline_layout();
9293
prepare_compute_pipeline();
93-
// build_compute_command_buffer();
94+
build_compute_command_buffer();
9495
}
9596

9697
void SubgroupsOperations::create_compute_queue()
@@ -128,21 +129,30 @@ void SubgroupsOperations::create_compute_command_buffer()
128129

129130
void SubgroupsOperations::create_compute_descriptor_set_layout()
130131
{
131-
// std::vector<VkDescriptorSetLayoutBinding> set_layout_bindngs = {
132-
// vkb::initializers::descriptor_set_layout_binding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT, 0), // input image
133-
// vkb::initializers::descriptor_set_layout_binding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT, 1), // result image
134-
// vkb::initializers::descriptor_set_layout_binding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT, 2) // kernel matrix
135-
// };
136-
// VkDescriptorSetLayoutCreateInfo descriptor_layout = vkb::initializers::descriptor_set_layout_create_info(set_layout_bindngs);
137-
138-
// VK_CHECK(vkCreateDescriptorSetLayout(get_device().get_handle(), &descriptor_layout, nullptr, &compute.descriptor_set_layout));
132+
std::vector<VkDescriptorSetLayoutBinding> set_layout_bindngs = {
133+
vkb::initializers::descriptor_set_layout_binding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT, 0u), // time ubo
134+
vkb::initializers::descriptor_set_layout_binding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT, 1u), // input vertex
135+
vkb::initializers::descriptor_set_layout_binding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT, 2u) // output vertex
136+
};
137+
VkDescriptorSetLayoutCreateInfo descriptor_layout = vkb::initializers::descriptor_set_layout_create_info(set_layout_bindngs);
138+
139+
VK_CHECK(vkCreateDescriptorSetLayout(get_device().get_handle(), &descriptor_layout, nullptr, &compute.descriptor_set_layout));
139140
}
140141

141142
void SubgroupsOperations::create_compute_descriptor_set()
142143
{
143-
VkDescriptorSetAllocateInfo alloc_info = vkb::initializers::descriptor_set_allocate_info(descriptor_pool, &compute.descriptor_set_layout, 1);
144-
145-
// VK_CHECK(vkAllocateDescriptorSets(get_device().get_handle(), &alloc_info, &compute.descriptor_set));
144+
VkDescriptorSetAllocateInfo alloc_info = vkb::initializers::descriptor_set_allocate_info(descriptor_pool, &compute.descriptor_set_layout, 1u);
145+
VK_CHECK(vkAllocateDescriptorSets(get_device().get_handle(), &alloc_info, &compute.descriptor_set));
146+
147+
VkDescriptorBufferInfo time_ubo_buffer = create_descriptor(*time_ubo);
148+
VkDescriptorBufferInfo input_vertices_buffer = create_descriptor(*init_grid.vertex);
149+
VkDescriptorBufferInfo output_vertices_buffer = create_descriptor(*init_grid.vertex); // TODO: change on output buffer (temporary solution)
150+
std::vector<VkWriteDescriptorSet> wirte_descriptor_sets = {
151+
vkb::initializers::write_descriptor_set(compute.descriptor_set, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0u, &time_ubo_buffer),
152+
vkb::initializers::write_descriptor_set(compute.descriptor_set, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, &input_vertices_buffer),
153+
vkb::initializers::write_descriptor_set(compute.descriptor_set, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u, &output_vertices_buffer)
154+
};
155+
vkUpdateDescriptorSets(get_device().get_handle(), static_cast<uint32_t>(wirte_descriptor_sets.size()), wirte_descriptor_sets.data(), 0u, nullptr);
146156
}
147157

148158
void SubgroupsOperations::preapre_compute_pipeline_layout()
@@ -160,7 +170,7 @@ void SubgroupsOperations::prepare_compute_pipeline()
160170
VkComputePipelineCreateInfo computeInfo = {};
161171
computeInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
162172
computeInfo.layout = compute.pipelines._default.pipeline_layout;
163-
computeInfo.stage = load_shader("subgroups_operations/blur.comp", VK_SHADER_STAGE_COMPUTE_BIT);
173+
computeInfo.stage = load_shader("subgroups_operations/ocean_horizontal.comp", VK_SHADER_STAGE_COMPUTE_BIT);
164174

165175
VK_CHECK(vkCreateComputePipelines(get_device().get_handle(), pipeline_cache, 1u, &computeInfo, nullptr, &compute.pipelines._default.pipeline));
166176
}
@@ -178,7 +188,7 @@ void SubgroupsOperations::build_compute_command_buffer()
178188

179189
vkCmdBindPipeline(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelines._default.pipeline);
180190
vkCmdBindDescriptorSets(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelines._default.pipeline_layout, 0u, 1u, &compute.descriptor_set, 0u, nullptr);
181-
// vkCmdDispatch(compute.command_buffer, texture_object.texture.image->get_extent().width / 32u, texture_object.texture.image->get_extent().height / 32u, 1u);
191+
vkCmdDispatch(compute.command_buffer, grid_size / 16u, grid_size / 16u, 1u);
182192

183193
VK_CHECK(vkEndCommandBuffer(compute.command_buffer));
184194
}
@@ -189,6 +199,12 @@ void SubgroupsOperations::request_gpu_features(vkb::PhysicalDevice &gpu)
189199
{
190200
gpu.get_mutable_requested_features().samplerAnisotropy = VK_TRUE;
191201
}
202+
203+
if (gpu.get_features().fillModeNonSolid)
204+
{
205+
gpu.get_mutable_requested_features().fillModeNonSolid = VK_TRUE;
206+
}
207+
192208
subgroups_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
193209
subgroups_properties.pNext = VK_NULL_HANDLE;
194210

@@ -206,6 +222,7 @@ void SubgroupsOperations::load_assets()
206222
void SubgroupsOperations::prepare_uniform_buffers()
207223
{
208224
camera_ubo = std::make_unique<vkb::core::Buffer>(get_device(), sizeof(CameraUbo), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
225+
time_ubo = std::make_unique<vkb::core::Buffer>(get_device(), sizeof(TimeUbo), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
209226
update_uniform_buffers();
210227
}
211228

@@ -241,7 +258,7 @@ void SubgroupsOperations::generate_grid()
241258
}
242259
}
243260

244-
init_grid.index_count = static_cast<uint32_t>(grid_indices.size());
261+
ocean.grid.index_count = static_cast<uint32_t>(grid_indices.size());
245262
auto vertex_buffer_size = vkb::to_u32(grid_vertices.size() * sizeof(Vertex));
246263
auto index_buffer_size = vkb::to_u32(grid_indices.size() * sizeof(uint32_t));
247264
init_grid.vertex = std::make_unique<vkb::core::Buffer>(get_device(),
@@ -250,17 +267,18 @@ void SubgroupsOperations::generate_grid()
250267
VMA_MEMORY_USAGE_CPU_TO_GPU);
251268
init_grid.vertex->update(grid_vertices.data(), vertex_buffer_size);
252269

253-
init_grid.index = std::make_unique<vkb::core::Buffer>(get_device(),
270+
ocean.grid.index = std::make_unique<vkb::core::Buffer>(get_device(),
254271
index_buffer_size,
255272
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
256273
VMA_MEMORY_USAGE_CPU_TO_GPU);
257-
init_grid.index->update(grid_indices.data(), index_buffer_size);
274+
ocean.grid.index->update(grid_indices.data(), index_buffer_size);
258275
}
259276

260277
void SubgroupsOperations::setup_descriptor_pool()
261278
{
262279
std::vector<VkDescriptorPoolSize> pool_sizes = {
263-
vkb::initializers::descriptor_pool_size(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u)};
280+
vkb::initializers::descriptor_pool_size(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2u),
281+
vkb::initializers::descriptor_pool_size(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u)};
264282
VkDescriptorPoolCreateInfo descriptor_pool_create_info =
265283
vkb::initializers::descriptor_pool_create_info(
266284
static_cast<uint32_t>(pool_sizes.size()),
@@ -369,19 +387,26 @@ void SubgroupsOperations::create_pipelines()
369387
{
370388
rasterization_state.polygonMode = VK_POLYGON_MODE_LINE;
371389
VK_CHECK(vkCreateGraphicsPipelines(get_device().get_handle(), pipeline_cache, 1u, &pipeline_create_info, nullptr, &ocean.pipelines.wireframe.pipeline));
372-
373390
}
374391
}
375392

376393
void SubgroupsOperations::update_uniform_buffers()
377394
{
395+
auto t1 = std::chrono::high_resolution_clock::now();
378396
CameraUbo ubo;
379397
ubo.model = glm::mat4(1.0f);
380398
ubo.model = glm::translate(ubo.model, glm::vec3(0.0f));
381399
ubo.view = camera.matrices.view;
382400
ubo.projection = camera.matrices.perspective;
383401

384402
camera_ubo->convert_and_update(ubo);
403+
404+
TimeUbo t;
405+
auto t2 = std::chrono::high_resolution_clock::now();
406+
407+
std::chrono::duration<float> float_time = t1 - t2; // dummy time
408+
t.time = float_time.count();
409+
time_ubo->convert_and_update(t);
385410
}
386411

387412
void SubgroupsOperations::build_command_buffers()
@@ -421,9 +446,9 @@ void SubgroupsOperations::build_command_buffers()
421446

422447
VkDeviceSize offset[] = {0};
423448
vkCmdBindVertexBuffers(cmd_buff, 0u, 1u, init_grid.vertex->get(), offset);
424-
vkCmdBindIndexBuffer(cmd_buff, init_grid.index->get_handle(), VkDeviceSize(0), VK_INDEX_TYPE_UINT32);
449+
vkCmdBindIndexBuffer(cmd_buff, ocean.grid.index->get_handle(), VkDeviceSize(0), VK_INDEX_TYPE_UINT32);
425450

426-
vkCmdDrawIndexed(cmd_buff, init_grid.index_count, 1u, 0u, 0u, 0u);
451+
vkCmdDrawIndexed(cmd_buff, ocean.grid.index_count, 1u, 0u, 0u, 0u);
427452
}
428453

429454
draw_ui(cmd_buff);
@@ -443,11 +468,11 @@ void SubgroupsOperations::draw()
443468
ApiVulkanSample::prepare_frame();
444469
submit_info.commandBufferCount = 1;
445470
submit_info.pCommandBuffers = &draw_cmd_buffers[current_buffer];
446-
// submit_info.waitSemaphoreCount = 2;
447-
// submit_info.pWaitSemaphores = graphics_wait_semaphores;
448-
// submit_info.pWaitDstStageMask = graphics_wait_stage_masks;
449-
// submit_info.signalSemaphoreCount = 2;
450-
// submit_info.pSignalSemaphores = graphics_signal_semaphores;
471+
// submit_info.waitSemaphoreCount = 2;
472+
// submit_info.pWaitSemaphores = graphics_wait_semaphores;
473+
// submit_info.pWaitDstStageMask = graphics_wait_stage_masks;
474+
// submit_info.signalSemaphoreCount = 2;
475+
// submit_info.pSignalSemaphores = graphics_signal_semaphores;
451476
VK_CHECK(vkQueueSubmit(queue, 1u, &submit_info, VK_NULL_HANDLE));
452477
ApiVulkanSample::submit_frame();
453478

@@ -458,13 +483,13 @@ void SubgroupsOperations::draw()
458483
VkSubmitInfo compute_submit_info = vkb::initializers::submit_info();
459484
compute_submit_info.commandBufferCount = 1u;
460485
compute_submit_info.pCommandBuffers = &compute.command_buffer;
461-
compute_submit_info.waitSemaphoreCount = 1u;
486+
// compute_submit_info.waitSemaphoreCount = 1u;
462487

463-
compute_submit_info.pWaitDstStageMask = &wait_stage_mask;
464-
compute_submit_info.signalSemaphoreCount = 1u;
465-
compute_submit_info.pSignalSemaphores = &compute.semaphore;
488+
// compute_submit_info.pWaitDstStageMask = &wait_stage_mask;
489+
// compute_submit_info.signalSemaphoreCount = 1u;
490+
// compute_submit_info.pSignalSemaphores = &compute.semaphore;
466491

467-
// VK_CHECK(vkQueueSubmit(compute.queue, 1u, &compute_submit_info, VK_NULL_HANDLE));
492+
VK_CHECK(vkQueueSubmit(compute.queue, 1u, &compute_submit_info, VK_NULL_HANDLE));
468493
}
469494

470495
void SubgroupsOperations::on_update_ui_overlay(vkb::Drawer &drawer)
@@ -485,7 +510,7 @@ bool SubgroupsOperations::resize(const uint32_t width, const uint32_t height)
485510
{
486511
if (!ApiVulkanSample::resize(width, height))
487512
return false;
488-
// build_compute_command_buffer();
513+
build_compute_command_buffer();
489514
build_command_buffers();
490515
return true;
491516
}

samples/extensions/subgroups_operations/subgroups_operations.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ class SubgroupsOperations : public ApiVulkanSample
8181
alignas(16) glm::mat4 model;
8282
};
8383

84+
struct TimeUbo
85+
{
86+
alignas(4) float time;
87+
};
88+
8489
struct GuiConfig
8590
{
8691
bool wireframe = {false};
@@ -91,6 +96,7 @@ class SubgroupsOperations : public ApiVulkanSample
9196
uint32_t grid_size = {128u};
9297

9398
std::unique_ptr<vkb::core::Buffer> camera_ubo;
99+
std::unique_ptr<vkb::core::Buffer> time_ubo;
94100

95101
struct
96102
{
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#version 450
2+
#extension GL_KHR_shader_subgroup_basic : enable
3+
4+
/* Copyright (c) 2023, Mobica Limited
5+
*
6+
* SPDX-License-Identifier: Apache-2.0
7+
*
8+
* Licensed under the Apache License, Version 2.0 the "License";
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
22+
23+
struct Vertex {
24+
vec3 position;
25+
};
26+
27+
layout (binding = 0) uniform TimeUbo
28+
{
29+
float time;
30+
} uboTime;
31+
32+
layout (std140, binding = 1) readonly buffer VertexInBuffer
33+
{
34+
Vertex verticesIn[];
35+
};
36+
37+
layout (std140, binding = 2) buffer VertexOutBuffer
38+
{
39+
Vertex verticesOut[];
40+
};
41+
42+
void main()
43+
{
44+
uint idx = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y;
45+
Vertex inVertex = verticesIn[idx];
46+
inVertex.position.x = inVertex.position.x * sin(uboTime.time);
47+
// subgroupBarrier();
48+
verticesOut[idx].position = inVertex.position;
49+
50+
}

0 commit comments

Comments
 (0)