1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-18 02:52:10 +01:00

[dxvk] Add meta copy pipeline for packed buffer image copies

This commit is contained in:
Philip Rebohle 2021-06-23 16:01:47 +02:00
parent 9f7a5a077f
commit 27155539b6
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 127 additions and 1 deletions

View File

@ -5,6 +5,7 @@
#include <dxvk_fullscreen_vert.h>
#include <dxvk_fullscreen_layer_vert.h>
#include <dxvk_copy_buffer_image.h>
#include <dxvk_copy_color_1d.h>
#include <dxvk_copy_color_2d.h>
#include <dxvk_copy_color_ms.h>
@ -179,6 +180,10 @@ namespace dxvk {
DxvkMetaCopyObjects::~DxvkMetaCopyObjects() {
m_vkd->vkDestroyPipeline(m_vkd->device(), m_copyBufferImagePipeline.pipeHandle, nullptr);
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_copyBufferImagePipeline.pipeLayout, nullptr);
m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_copyBufferImagePipeline.dsetLayout, nullptr);
for (const auto& pair : m_pipelines) {
m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr);
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr);
@ -250,6 +255,16 @@ namespace dxvk {
m_pipelines.insert({ key, pipeline });
return pipeline;
}
DxvkMetaCopyPipeline DxvkMetaCopyObjects::getCopyBufferImagePipeline() {
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_copyBufferImagePipeline.pipeHandle)
m_copyBufferImagePipeline = createCopyBufferImagePipeline();
return m_copyBufferImagePipeline;
}
VkSampler DxvkMetaCopyObjects::createSampler() const {
@ -296,6 +311,65 @@ namespace dxvk {
}
DxvkMetaCopyPipeline DxvkMetaCopyObjects::createCopyBufferImagePipeline() {
DxvkMetaCopyPipeline pipeline;
pipeline.renderPass = VK_NULL_HANDLE;
std::array<VkDescriptorSetLayoutBinding, 2> bindings = {{
{ 0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
{ 1, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
}};
VkDescriptorSetLayoutCreateInfo setLayoutInfo;
setLayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
setLayoutInfo.pNext = nullptr;
setLayoutInfo.flags = 0;
setLayoutInfo.bindingCount = bindings.size();
setLayoutInfo.pBindings = bindings.data();
if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), &setLayoutInfo, nullptr, &pipeline.dsetLayout) != VK_SUCCESS)
throw DxvkError("DxvkMetaCopyObjects: Failed to create descriptor set layout");
VkPushConstantRange pushRange = { VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(DxvkCopyBufferImageArgs) };
VkPipelineLayoutCreateInfo pipelineLayoutInfo;
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.pNext = nullptr;
pipelineLayoutInfo.flags = 0;
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &pipeline.dsetLayout;
pipelineLayoutInfo.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &pushRange;
if (m_vkd->vkCreatePipelineLayout(m_vkd->device(), &pipelineLayoutInfo, nullptr, &pipeline.pipeLayout) != VK_SUCCESS)
throw DxvkError("DxvkMetaCopyObjects: Failed to create pipeline layout");
VkShaderModule shaderModule = createShaderModule(dxvk_copy_buffer_image);
VkComputePipelineCreateInfo pipelineInfo;
pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
pipelineInfo.pNext = nullptr;
pipelineInfo.flags = 0;
pipelineInfo.layout = pipeline.pipeLayout;
pipelineInfo.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
pipelineInfo.stage.pNext = nullptr;
pipelineInfo.stage.flags = 0;
pipelineInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
pipelineInfo.stage.module = shaderModule;
pipelineInfo.stage.pName = "main";
pipelineInfo.stage.pSpecializationInfo = nullptr;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
pipelineInfo.basePipelineIndex = -1;
if (m_vkd->vkCreateComputePipelines(m_vkd->device(), VK_NULL_HANDLE,
1, &pipelineInfo, nullptr, &pipeline.pipeHandle) != VK_SUCCESS)
throw DxvkError("DxvkMetaCopyObjects: Failed to create compute pipeline");
m_vkd->vkDestroyShaderModule(m_vkd->device(), shaderModule, nullptr);
return pipeline;
}
DxvkMetaCopyPipeline DxvkMetaCopyObjects::createPipeline(
const DxvkMetaCopyPipelineKey& key) {
DxvkMetaCopyPipeline pipeline;

View File

@ -14,6 +14,17 @@ namespace dxvk {
class DxvkDevice;
/**
* \brief Push constants for buffer image copies
*/
struct DxvkCopyBufferImageArgs {
VkOffset3D dstOffset; uint32_t pad0;
VkOffset3D srcOffset; uint32_t pad1;
VkExtent3D extent; uint32_t pad2;
VkExtent2D dstSize;
VkExtent2D srcSize;
};
/**
* \brief Copy pipeline
*
@ -135,6 +146,12 @@ namespace dxvk {
VkFormat dstFormat,
VkSampleCountFlagBits dstSamples);
/**
* \brief Creates pipeline for buffer image copy
* \returns Compute pipeline for buffer image copies
*/
DxvkMetaCopyPipeline getCopyBufferImagePipeline();
private:
struct FragShaders {
@ -160,12 +177,16 @@ namespace dxvk {
DxvkMetaCopyPipelineKey,
DxvkMetaCopyPipeline,
DxvkHash, DxvkEq> m_pipelines;
DxvkMetaCopyPipeline m_copyBufferImagePipeline = { };
VkSampler createSampler() const;
VkShaderModule createShaderModule(
const SpirvCodeBuffer& code) const;
DxvkMetaCopyPipeline createCopyBufferImagePipeline();
DxvkMetaCopyPipeline createPipeline(
const DxvkMetaCopyPipelineKey& key);

View File

@ -16,6 +16,7 @@ dxvk_shaders = files([
'shaders/dxvk_clear_image3d_u.comp',
'shaders/dxvk_clear_image3d_f.comp',
'shaders/dxvk_copy_buffer_image.comp',
'shaders/dxvk_copy_color_1d.frag',
'shaders/dxvk_copy_color_2d.frag',
'shaders/dxvk_copy_color_ms.frag',

View File

@ -0,0 +1,30 @@
#version 450
layout(
local_size_x = 8,
local_size_y = 8,
local_size_z = 1) in;
layout(binding = 0) writeonly uniform uimageBuffer u_dst;
layout(binding = 1) uniform usamplerBuffer u_src;
layout(push_constant)
uniform u_info_t {
uvec3 dst_offset;
uvec3 src_offset;
uvec3 extent;
uvec2 dst_size;
uvec2 src_size;
} u_info;
void main() {
if (all(lessThan(gl_GlobalInvocationID, u_info.extent))) {
uvec3 dst_coord = u_info.dst_offset + gl_GlobalInvocationID;
uvec3 src_coord = u_info.src_offset + gl_GlobalInvocationID;
uint dst_index = dst_coord.x + u_info.dst_size.x * (dst_coord.y + u_info.dst_size.y * dst_coord.z);
uint src_index = src_coord.x + u_info.src_size.x * (src_coord.y + u_info.src_size.y * src_coord.z);
imageStore(u_dst, int(dst_index), texelFetch(u_src, int(src_index)));
}
}