Skip to content

Commit

Permalink
Add pipeline barriers, update README file
Browse files Browse the repository at this point in the history
  • Loading branch information
Patryk-Jastrzebski-Mobica committed Nov 20, 2023
1 parent d09532f commit a9ca1fb
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 91 deletions.
30 changes: 9 additions & 21 deletions samples/extensions/subgroups_operations/README.adoc
Original file line number Diff line number Diff line change
@@ -1,38 +1,25 @@
<!--
- Copyright (c) 2023, Mobica Limited
-
- SPDX-License-Identifier: Apache-2.0
-
- Licensed under the Apache License, Version 2.0 the "License";
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-->
<!-- - Copyright (c) 2023, Mobica Limited - - SPDX-License-Identifier: Apache-2.0 - - Licensed under the Apache License, Version 2.0 the "License"; - you may not use this file except in compliance with the License.
- You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and - limitations under the License.
- -->

# Subgroups Operations


## Overview

This sample demonstrates how to use and enable the Subgroups operations feature.

image:image/image.png[]

## GLSL Shaders

In shader enable `GL_KHR_shader_subgroup_basic` extension.
TODO: add more description


## Enabling the Feature

To enable the subgroups feature in the Vulkan API you must create a Vulkan instance with a minimum version of version 1.1. Enable the extension `VK_EXT_subgroup_size_control` and get the subgroup properties of a physical device

```C++
VkPhysicalDeviceSubgroupProperties subgroups_properties;
subgroups_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
Expand All @@ -43,6 +30,7 @@ device_properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVI
device_properties2.pNext = &subgroups_properties;
vkGetPhysicalDeviceProperties2(gpu.get_handle(), &device_properties2);
```

TODO: add more description

## Additional information
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
137 changes: 135 additions & 2 deletions samples/extensions/subgroups_operations/subgroups_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,40 @@ void SubgroupsOperations::build_compute_command_buffer()
VkCommandBufferBeginInfo begin_info = vkb::initializers::command_buffer_begin_info();
VK_CHECK(vkBeginCommandBuffer(compute.command_buffer, &begin_info));

if (ocean.graphics_queue_family_index != compute.queue_family_index)
{
VkBufferMemoryBarrier memory_barrier = vkb::initializers::buffer_memory_barrier();
memory_barrier.buffer = bit_reverse_buffer->get_handle();
memory_barrier.offset = 0u;
memory_barrier.size = bit_reverse_buffer->get_size();
memory_barrier.srcAccessMask = 0u;
memory_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
memory_barrier.srcQueueFamilyIndex = ocean.graphics_queue_family_index;
memory_barrier.dstQueueFamilyIndex = compute.queue_family_index;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 1u, &memory_barrier, 0u, nullptr);
}

// butterfly texture
{
vkCmdBindPipeline(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, precompute.pipeline.pipeline);
vkCmdBindDescriptorSets(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, precompute.pipeline.pipeline_layout, 0u, 1u, &precompute.descriptor_set, 0u, nullptr);

vkCmdDispatch(compute.command_buffer, 1u, grid_size, 1u);
}

{
VkImageMemoryBarrier img_barrier = vkb::initializers::image_memory_barrier();
img_barrier.image = butterfly_precomp.image;
img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
img_barrier.subresourceRange.baseMipLevel = 0u;
img_barrier.subresourceRange.levelCount = 1u;
img_barrier.subresourceRange.baseArrayLayer = 0u;
img_barrier.subresourceRange.layerCount = 1u;
img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &img_barrier);
}
// initial tildes textures
{
vkCmdBindPipeline(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, initial_tildes.pipeline.pipeline);
Expand All @@ -210,6 +236,17 @@ void SubgroupsOperations::build_compute_command_buffer()
vkCmdDispatch(compute.command_buffer, grid_size / 32u, grid_size, 1u);
}

{
VkBufferMemoryBarrier memory_barrier = vkb::initializers::buffer_memory_barrier();
memory_barrier.buffer = fft_buffers.fft_input_random->get_handle();
memory_barrier.offset = 0u;
memory_barrier.size = fft_buffers.fft_input_random->get_size();
memory_barrier.srcAccessMask = 0u;
memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 1u, &memory_barrier, 0u, nullptr);
}

// tildes textures
{
vkCmdBindPipeline(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, tildes.pipeline.pipeline);
Expand All @@ -218,6 +255,20 @@ void SubgroupsOperations::build_compute_command_buffer()
vkCmdDispatch(compute.command_buffer, grid_size / 8u, grid_size, 1u);
}

{
VkImageMemoryBarrier img_barrier = vkb::initializers::image_memory_barrier();
img_barrier.image = fft_buffers.fft_input_htilde0->image;
img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
img_barrier.subresourceRange.baseMipLevel = 0u;
img_barrier.subresourceRange.levelCount = 1u;
img_barrier.subresourceRange.baseArrayLayer = 0u;
img_barrier.subresourceRange.layerCount = 1u;
img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &img_barrier);
}

// fft horizontal; for Y axis
{
vkCmdBindPipeline(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, fft.pipelines.horizontal.pipeline);
Expand Down Expand Up @@ -290,19 +341,63 @@ void SubgroupsOperations::build_compute_command_buffer()
}
}

{
VkImageMemoryBarrier img_barrier = vkb::initializers::image_memory_barrier();
img_barrier.image = fft_buffers.fft_tilde_h_kt_dy->image;
img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
img_barrier.subresourceRange.baseMipLevel = 0u;
img_barrier.subresourceRange.levelCount = 1u;
img_barrier.subresourceRange.baseArrayLayer = 0u;
img_barrier.subresourceRange.layerCount = 1u;
img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &img_barrier);
}

// fft inverse
{
vkCmdBindPipeline(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, fft_inversion.pipeline.pipeline);
vkCmdBindDescriptorSets(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, fft_inversion.pipeline.pipeline_layout, 0u, 1u, &fft_inversion.descriptor_set, 0u, nullptr);
vkCmdDispatch(compute.command_buffer, grid_size / 32u, grid_size, 1u);
}

{
VkImageMemoryBarrier img_barrier = vkb::initializers::image_memory_barrier();
img_barrier.image = fft_buffers.fft_displacement->image;
img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
img_barrier.subresourceRange.baseMipLevel = 0u;
img_barrier.subresourceRange.levelCount = 1u;
img_barrier.subresourceRange.baseArrayLayer = 0u;
img_barrier.subresourceRange.layerCount = 1u;
img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &img_barrier);
}
// fft normal map
{
vkCmdBindPipeline(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, fft_normal_map.pipeline.pipeline);
vkCmdBindDescriptorSets(compute.command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, fft_normal_map.pipeline.pipeline_layout, 0u, 1u, &fft_normal_map.descriptor_set, 0u, nullptr);
vkCmdDispatch(compute.command_buffer, grid_size / 32u, grid_size, 1u);
}
if (ocean.graphics_queue_family_index != compute.queue_family_index)
{
VkImageMemoryBarrier img_barrier = vkb::initializers::image_memory_barrier();
img_barrier.image = fft_buffers.fft_displacement->image;
img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
img_barrier.subresourceRange.baseMipLevel = 0u;
img_barrier.subresourceRange.levelCount = 1u;
img_barrier.subresourceRange.baseArrayLayer = 0u;
img_barrier.subresourceRange.layerCount = 1u;
img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
img_barrier.srcQueueFamilyIndex = compute.queue_family_index;
img_barrier.dstQueueFamilyIndex = ocean.graphics_queue_family_index;
img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
img_barrier.dstAccessMask = 0u;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &img_barrier);
}

VK_CHECK(vkEndCommandBuffer(compute.command_buffer));
}
Expand Down Expand Up @@ -880,6 +975,25 @@ void SubgroupsOperations::build_command_buffers()

VK_CHECK(vkBeginCommandBuffer(cmd_buff, &command_buffer_begin_info));

if (ocean.graphics_queue_family_index != compute.queue_family_index)
{
VkImageMemoryBarrier img_barrier = vkb::initializers::image_memory_barrier();
img_barrier.image = fft_buffers.fft_normal_map->image;
img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
img_barrier.subresourceRange.baseMipLevel = 0u;
img_barrier.subresourceRange.levelCount = 1u;
img_barrier.subresourceRange.baseArrayLayer = 0u;
img_barrier.subresourceRange.layerCount = 1u;
img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
img_barrier.srcQueueFamilyIndex = compute.queue_family_index;
img_barrier.dstQueueFamilyIndex = ocean.graphics_queue_family_index;
img_barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
img_barrier.srcAccessMask = 0u;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &img_barrier);
}

vkCmdBeginRenderPass(cmd_buff, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);

VkViewport viewport = vkb::initializers::viewport(static_cast<float>(width), static_cast<float>(height), 0.0f, 1.0f);
Expand Down Expand Up @@ -911,6 +1025,25 @@ void SubgroupsOperations::build_command_buffers()

vkCmdEndRenderPass(cmd_buff);

if (ocean.graphics_queue_family_index != compute.queue_family_index)
{
VkImageMemoryBarrier img_barrier = vkb::initializers::image_memory_barrier();
img_barrier.image = fft_buffers.fft_normal_map->image;
img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
img_barrier.subresourceRange.baseMipLevel = 0u;
img_barrier.subresourceRange.levelCount = 1u;
img_barrier.subresourceRange.baseArrayLayer = 0u;
img_barrier.subresourceRange.layerCount = 1u;
img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
img_barrier.srcQueueFamilyIndex = ocean.graphics_queue_family_index;
img_barrier.dstQueueFamilyIndex = compute.queue_family_index;
img_barrier.dstAccessMask = 0u;
img_barrier.srcAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;

vkCmdPipelineBarrier(compute.command_buffer, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &img_barrier);
}

VK_CHECK(vkEndCommandBuffer(cmd_buff));
}
}
Expand Down
Loading

0 comments on commit a9ca1fb

Please sign in to comment.