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

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

393 lines
14 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"
#include "vk_state_manager.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
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
if (is_allocated()) {
const VKDevice &device = VKBackend::get().device_get();
vmaDestroyImage(device.mem_allocator_get(), vk_image_, allocation_);
vkDestroyImageView(device.device_get(), vk_image_view_, vk_allocation_callbacks);
}
}
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::init(VkImage vk_image, VkImageLayout layout)
{
vk_image_ = vk_image;
current_layout_ = layout;
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::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(
device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
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
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)
{
if (mip != 0) {
/* TODO: not implemented yet. */
return;
}
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;
int3 extent = int3(extent_[0], max_ii(extent_[1], 1), max_ii(extent_[2], 1));
size_t sample_len = extent.x * extent.y * extent.z;
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
size_t device_memory_size = sample_len * to_bytesize(format_);
staging_buffer.create(
device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
uint buffer_row_length = context.state_manager_get().texture_unpack_row_length_get();
if (buffer_row_length) {
/* Use custom row length #GPU_texture_unpack_row_length */
convert_host_to_device(staging_buffer.mapped_memory_get(),
data,
uint2(extent),
buffer_row_length,
format,
format_);
}
else {
convert_host_to_device(staging_buffer.mapped_memory_get(), data, sample_len, format, format_);
}
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
VkBufferImageCopy region = {};
region.imageExtent.width = extent.x;
region.imageExtent.height = extent.y;
region.imageExtent.depth = extent.z;
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
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(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_SRC_BIT |
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_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);
}
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
/* Disable some usages based on the given format flag to support more devices. */
if (format_flag & GPU_FORMAT_SRGB) {
/* NVIDIA devices don't create SRGB textures when it storage bit is set. */
result = static_cast<VkImageUsageFlagBits>(result & ~VK_IMAGE_USAGE_STORAGE_BIT);
}
if (format_flag & (GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL)) {
/* NVIDIA devices don't create depth textures when it storage bit is set. */
result = static_cast<VkImageUsageFlagBits>(result & ~VK_IMAGE_USAGE_STORAGE_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(vk_image_ == VK_NULL_HANDLE);
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
BLI_assert(!is_allocated());
int extent[3] = {1, 1, 1};
mip_size_get(0, extent);
VKContext &context = *VKContext::get();
const VKDevice &device = VKBackend::get().device_get();
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
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(device.physical_device_get(),
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.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(device.mem_allocator_get(),
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,
&allocCreateInfo,
&vk_image_,
&allocation_,
nullptr);
if (result != VK_SUCCESS) {
return false;
}
debug::object_label(vk_image_, name_);
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
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(
device.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_);
debug::object_label(vk_image_view_, name_);
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 result == VK_SUCCESS;
}
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
// TODO: move texture/image bindings to shader.
void VKTexture::bind(int unit, VKSampler &sampler)
{
if (!is_allocated()) {
allocate();
}
VKContext &context = *VKContext::get();
VKShader *shader = static_cast<VKShader *>(context.shader);
const VKShaderInterface &shader_interface = shader->interface_get();
const std::optional<VKDescriptorSet::Location> location =
shader_interface.descriptor_set_location(
shader::ShaderCreateInfo::Resource::BindType::SAMPLER, unit);
if (location) {
VKDescriptorSetTracker &descriptor_set = shader->pipeline_get().descriptor_set_get();
descriptor_set.bind(*this, *location, sampler);
}
}
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::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 std::optional<VKDescriptorSet::Location> location =
shader_interface.descriptor_set_location(shader::ShaderCreateInfo::Resource::BindType::IMAGE,
binding);
if (location) {
VKDescriptorSetTracker &descriptor_set = shader->pipeline_get().descriptor_set_get();
descriptor_set.image_bind(*this, *location);
}
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
}
/* -------------------------------------------------------------------- */
/** \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