Files
test2/source/blender/gpu/vulkan/vk_texture.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

330 lines
11 KiB
C++
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation */
/** \file
* \ingroup gpu
*/
#include "vk_texture.hh"
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
#include "vk_buffer.hh"
#include "vk_context.hh"
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
#include "vk_data_conversion.hh"
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
#include "vk_memory.hh"
#include "vk_shader.hh"
#include "vk_shader_interface.hh"
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
#include "BLI_math_vector.hh"
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
#include "BKE_global.h"
namespace blender::gpu {
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
VKTexture::~VKTexture()
{
VK_ALLOCATION_CALLBACKS
VKContext &context = *VKContext::get();
vmaDestroyImage(context.mem_allocator_get(), vk_image_, allocation_);
vkDestroyImageView(context.device_get(), vk_image_view_, vk_allocation_callbacks);
}
void VKTexture::generate_mipmap() {}
void VKTexture::copy_to(Texture * /*tex*/) {}
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
void VKTexture::clear(eGPUDataFormat format, const void *data)
{
if (!is_allocated()) {
allocate();
}
VKContext &context = *VKContext::get();
VKCommandBuffer &command_buffer = context.command_buffer_get();
VkClearColorValue clear_color = to_vk_clear_color_value(format, data);
VkImageSubresourceRange range = {0};
range.aspectMask = to_vk_image_aspect_flag_bits(format_);
range.levelCount = VK_REMAINING_MIP_LEVELS;
range.layerCount = VK_REMAINING_ARRAY_LAYERS;
layout_ensure(context, VK_IMAGE_LAYOUT_GENERAL);
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
command_buffer.clear(
vk_image_, current_layout_get(), clear_color, Span<VkImageSubresourceRange>(&range, 1));
}
void VKTexture::swizzle_set(const char /*swizzle_mask*/[4]) {}
void VKTexture::stencil_texture_mode_set(bool /*use_stencil*/) {}
void VKTexture::mip_range_set(int /*min*/, int /*max*/) {}
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
void *VKTexture::read(int mip, eGPUDataFormat format)
{
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
VKContext &context = *VKContext::get();
layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
/* Vulkan images cannot be directly mapped to host memory and requires a staging buffer. */
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
VKBuffer staging_buffer;
/* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
int extent[3] = {1, 1, 1};
mip_size_get(mip, extent);
size_t sample_len = extent[0] * extent[1] * extent[2];
size_t device_memory_size = sample_len * to_bytesize(format_);
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
size_t host_memory_size = sample_len * to_bytesize(format_, format);
staging_buffer.create(
context, device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
VkBufferImageCopy region = {};
region.imageExtent.width = extent[0];
region.imageExtent.height = extent[1];
region.imageExtent.depth = extent[2];
region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_);
region.imageSubresource.mipLevel = mip;
region.imageSubresource.layerCount = 1;
VKCommandBuffer &command_buffer = context.command_buffer_get();
command_buffer.copy(staging_buffer, *this, Span<VkBufferImageCopy>(&region, 1));
command_buffer.submit();
void *data = MEM_mallocN(host_memory_size, __func__);
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
convert_device_to_host(data, staging_buffer.mapped_memory_get(), sample_len, format, format_);
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
return data;
}
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
void VKTexture::update_sub(
int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data)
{
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
if (!is_allocated()) {
allocate();
}
/* Vulkan images cannot be directly mapped to host memory and requires a staging buffer. */
VKContext &context = *VKContext::get();
VKBuffer staging_buffer;
size_t sample_len = extent[0] * extent[1] * extent[2];
size_t device_memory_size = sample_len * to_bytesize(format_);
staging_buffer.create(
context, device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
convert_host_to_device(staging_buffer.mapped_memory_get(), data, sample_len, format, format_);
VkBufferImageCopy region = {};
region.imageExtent.width = extent[0];
region.imageExtent.height = extent[1];
region.imageExtent.depth = extent[2];
region.imageOffset.x = offset[0];
region.imageOffset.y = offset[1];
region.imageOffset.z = offset[2];
region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_);
region.imageSubresource.mipLevel = mip;
region.imageSubresource.layerCount = 1;
layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
VKCommandBuffer &command_buffer = context.command_buffer_get();
command_buffer.copy(*this, staging_buffer, Span<VkBufferImageCopy>(&region, 1));
command_buffer.submit();
}
void VKTexture::update_sub(int /*offset*/[3],
int /*extent*/[3],
eGPUDataFormat /*format*/,
GPUPixelBuffer * /*pixbuf*/)
{
}
/* TODO(fclem): Legacy. Should be removed at some point. */
uint VKTexture::gl_bindcode_get() const
{
return 0;
}
bool VKTexture::init_internal()
{
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
/* Initialization can only happen after the usage is known. By the current API this isn't set
* at this moment, so we cannot initialize here. The initialization is postponed until the
2023-02-27 21:44:59 +11:00
* allocation of the texture on the device. */
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
/* TODO: return false when texture format isn't supported. */
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
return true;
}
bool VKTexture::init_internal(GPUVertBuf * /*vbo*/)
{
return false;
}
bool VKTexture::init_internal(const GPUTexture * /*src*/, int /*mip_offset*/, int /*layer_offset*/)
{
return false;
}
void VKTexture::ensure_allocated()
{
if (!is_allocated()) {
allocate();
}
}
bool VKTexture::is_allocated() const
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
{
return vk_image_ != VK_NULL_HANDLE && allocation_ != VK_NULL_HANDLE;
}
static VkImageUsageFlagBits to_vk_image_usage(const eGPUTextureUsage usage,
const eGPUTextureFormatFlag format_flag)
{
VkImageUsageFlagBits result = static_cast<VkImageUsageFlagBits>(VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT);
if (usage & GPU_TEXTURE_USAGE_SHADER_READ) {
result = static_cast<VkImageUsageFlagBits>(result | VK_IMAGE_USAGE_STORAGE_BIT);
}
if (usage & GPU_TEXTURE_USAGE_SHADER_WRITE) {
result = static_cast<VkImageUsageFlagBits>(result | VK_IMAGE_USAGE_STORAGE_BIT);
}
if (usage & GPU_TEXTURE_USAGE_ATTACHMENT) {
if (format_flag & (GPU_FORMAT_NORMALIZED_INTEGER | GPU_FORMAT_COMPRESSED)) {
/* These formats aren't supported as an attachment. When using GPU_TEXTURE_USAGE_DEFAULT they
2023-04-05 14:38:26 +10:00
* are still being evaluated to be attachable. So we need to skip them. */
}
else {
if (format_flag & (GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL)) {
result = static_cast<VkImageUsageFlagBits>(result |
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
}
else {
result = static_cast<VkImageUsageFlagBits>(result | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
}
}
}
if (usage & GPU_TEXTURE_USAGE_HOST_READ) {
result = static_cast<VkImageUsageFlagBits>(result | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
}
return result;
}
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
bool VKTexture::allocate()
{
BLI_assert(!is_allocated());
int extent[3] = {1, 1, 1};
mip_size_get(0, extent);
VKContext &context = *VKContext::get();
VkImageCreateInfo image_info = {};
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_info.imageType = to_vk_image_type(type_);
image_info.extent.width = extent[0];
image_info.extent.height = extent[1];
image_info.extent.depth = extent[2];
image_info.mipLevels = 1;
image_info.arrayLayers = 1;
image_info.format = to_vk_format(format_);
/* Some platforms (NVIDIA) requires that attached textures are always tiled optimal.
*
* As image data are always accessed via an staging buffer we can enable optimal tiling for all
* texture. Tilings based on actual usages should be done in `VKFramebuffer`.
*/
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
image_info.usage = to_vk_image_usage(gpu_image_usage_flags_, format_flag_);
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
VkResult result;
Vulkan: Texture Data Conversions This PR adds basic support for texture update, read back and clearing for Vulkan. In Vulkan we need to convert each data type ourselves as vulkan buffers are untyped. Therefore this change mostly is about data conversions. Considerations: - Use a compute shader to do the conversions: - Leads to performance regression as compute pipeline can stall graphics pipeline - Lead to additional memory usage as two staging buffers are needed one to hold the CPU data, and one to hold the converted data. - Do inline conversion when sending the data to Vulkan using `eGPUDataFormat` - Additional CPU cycles required and not easy to optimize as it the implementation requires many branches. - Do inline conversion when sending the data to Vulkan (optimized for CPU) For this solution it was chosen to implement the 3rd option as it is fast and doesn't require additional memory what the other options do. **Use Imath/half.h** This patch uses `Imath/half.h` (dependency of OpenEXR) similar to alembic. But this makes vulkan dependent of the availability of OpenEXR. For now this isn't checked, but when we are closer to a working Vulkan backend we have to make a decision how to cope with this dependency. **Missing Features** *Framebuffer textures* This doesn't include all possible data transformations. Some of those transformation can only be tested after the VKFramebuffer has been implemented. Some texture types are only available when created for a framebuffer. These include the depth and stencil variations. *Component format* Is more relevant when implementing VKVertexBuffer. *SRGB textures* SRGB encoded textures aren't natively supported on all platforms, in all usages and might require workarounds. This should be done in a separate PR in a later stage when we are required to use SRGB textures. **Test cases** The added test cases gives an overview of the missing bits and pieces of the patch. When the implementation/direction is accepted more test cases can be enabled/implemented. Some of these test cases will skip depending on the actual support of platform the tests are running on. For example OpenGL/NVidia will skip the next test as it doesn't support the texture format on OpenGL, although it does support it on Vulkan. ``` [ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI ``` Pull Request: https://projects.blender.org/blender/blender/pulls/105762
2023-03-24 08:09:19 +01:00
if (G.debug & G_DEBUG_GPU) {
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
VkImageFormatProperties image_format = {};
result = vkGetPhysicalDeviceImageFormatProperties(context.physical_device_get(),
image_info.format,
image_info.imageType,
image_info.tiling,
image_info.usage,
image_info.flags,
&image_format);
if (result != VK_SUCCESS) {
printf("Image type not supported on device.\n");
return false;
}
}
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
allocCreateInfo.priority = 1.0f;
result = vmaCreateImage(context.mem_allocator_get(),
&image_info,
&allocCreateInfo,
&vk_image_,
&allocation_,
nullptr);
if (result != VK_SUCCESS) {
return false;
}
2023-02-27 21:44:59 +11:00
/* Promote image to the correct layout. */
layout_ensure(context, VK_IMAGE_LAYOUT_GENERAL);
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
VK_ALLOCATION_CALLBACKS
VkImageViewCreateInfo image_view_info = {};
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
image_view_info.image = vk_image_;
image_view_info.viewType = to_vk_image_view_type(type_);
image_view_info.format = to_vk_format(format_);
image_view_info.components = to_vk_component_mapping(format_);
image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_);
image_view_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
result = vkCreateImageView(
context.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_);
return result == VK_SUCCESS;
}
void VKTexture::image_bind(int binding)
{
if (!is_allocated()) {
allocate();
}
VKContext &context = *VKContext::get();
VKShader *shader = static_cast<VKShader *>(context.shader);
const VKShaderInterface &shader_interface = shader->interface_get();
const VKDescriptorSet::Location location = shader_interface.descriptor_set_location(
shader::ShaderCreateInfo::Resource::BindType::IMAGE, binding);
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
shader->pipeline_get().descriptor_set_get().image_bind(*this, location);
}
/* -------------------------------------------------------------------- */
/** \name Image Layout
* \{ */
VkImageLayout VKTexture::current_layout_get() const
{
return current_layout_;
}
void VKTexture::current_layout_set(const VkImageLayout new_layout)
{
current_layout_ = new_layout;
}
void VKTexture::layout_ensure(VKContext &context, const VkImageLayout requested_layout)
{
const VkImageLayout current_layout = current_layout_get();
if (current_layout == requested_layout) {
return;
}
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = current_layout;
barrier.newLayout = requested_layout;
barrier.image = vk_image_;
barrier.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_);
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
context.command_buffer_get().pipeline_barrier(Span<VkImageMemoryBarrier>(&barrier, 1));
current_layout_set(requested_layout);
}
/** \} */
2023-01-31 15:49:04 +11:00
} // namespace blender::gpu