mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxvk] Add meta copy pipeline for packed buffer image copies
This commit is contained in:
parent
9f7a5a077f
commit
27155539b6
@ -5,6 +5,7 @@
|
|||||||
#include <dxvk_fullscreen_vert.h>
|
#include <dxvk_fullscreen_vert.h>
|
||||||
#include <dxvk_fullscreen_layer_vert.h>
|
#include <dxvk_fullscreen_layer_vert.h>
|
||||||
|
|
||||||
|
#include <dxvk_copy_buffer_image.h>
|
||||||
#include <dxvk_copy_color_1d.h>
|
#include <dxvk_copy_color_1d.h>
|
||||||
#include <dxvk_copy_color_2d.h>
|
#include <dxvk_copy_color_2d.h>
|
||||||
#include <dxvk_copy_color_ms.h>
|
#include <dxvk_copy_color_ms.h>
|
||||||
@ -179,6 +180,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
DxvkMetaCopyObjects::~DxvkMetaCopyObjects() {
|
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) {
|
for (const auto& pair : m_pipelines) {
|
||||||
m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr);
|
m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr);
|
||||||
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr);
|
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr);
|
||||||
@ -250,6 +255,16 @@ namespace dxvk {
|
|||||||
m_pipelines.insert({ key, pipeline });
|
m_pipelines.insert({ key, pipeline });
|
||||||
return 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 {
|
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(
|
DxvkMetaCopyPipeline DxvkMetaCopyObjects::createPipeline(
|
||||||
const DxvkMetaCopyPipelineKey& key) {
|
const DxvkMetaCopyPipelineKey& key) {
|
||||||
DxvkMetaCopyPipeline pipeline;
|
DxvkMetaCopyPipeline pipeline;
|
||||||
|
@ -14,6 +14,17 @@ namespace dxvk {
|
|||||||
|
|
||||||
class DxvkDevice;
|
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
|
* \brief Copy pipeline
|
||||||
*
|
*
|
||||||
@ -135,6 +146,12 @@ namespace dxvk {
|
|||||||
VkFormat dstFormat,
|
VkFormat dstFormat,
|
||||||
VkSampleCountFlagBits dstSamples);
|
VkSampleCountFlagBits dstSamples);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates pipeline for buffer image copy
|
||||||
|
* \returns Compute pipeline for buffer image copies
|
||||||
|
*/
|
||||||
|
DxvkMetaCopyPipeline getCopyBufferImagePipeline();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct FragShaders {
|
struct FragShaders {
|
||||||
@ -160,12 +177,16 @@ namespace dxvk {
|
|||||||
DxvkMetaCopyPipelineKey,
|
DxvkMetaCopyPipelineKey,
|
||||||
DxvkMetaCopyPipeline,
|
DxvkMetaCopyPipeline,
|
||||||
DxvkHash, DxvkEq> m_pipelines;
|
DxvkHash, DxvkEq> m_pipelines;
|
||||||
|
|
||||||
|
DxvkMetaCopyPipeline m_copyBufferImagePipeline = { };
|
||||||
|
|
||||||
VkSampler createSampler() const;
|
VkSampler createSampler() const;
|
||||||
|
|
||||||
VkShaderModule createShaderModule(
|
VkShaderModule createShaderModule(
|
||||||
const SpirvCodeBuffer& code) const;
|
const SpirvCodeBuffer& code) const;
|
||||||
|
|
||||||
|
DxvkMetaCopyPipeline createCopyBufferImagePipeline();
|
||||||
|
|
||||||
DxvkMetaCopyPipeline createPipeline(
|
DxvkMetaCopyPipeline createPipeline(
|
||||||
const DxvkMetaCopyPipelineKey& key);
|
const DxvkMetaCopyPipelineKey& key);
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ dxvk_shaders = files([
|
|||||||
'shaders/dxvk_clear_image3d_u.comp',
|
'shaders/dxvk_clear_image3d_u.comp',
|
||||||
'shaders/dxvk_clear_image3d_f.comp',
|
'shaders/dxvk_clear_image3d_f.comp',
|
||||||
|
|
||||||
|
'shaders/dxvk_copy_buffer_image.comp',
|
||||||
'shaders/dxvk_copy_color_1d.frag',
|
'shaders/dxvk_copy_color_1d.frag',
|
||||||
'shaders/dxvk_copy_color_2d.frag',
|
'shaders/dxvk_copy_color_2d.frag',
|
||||||
'shaders/dxvk_copy_color_ms.frag',
|
'shaders/dxvk_copy_color_ms.frag',
|
||||||
|
30
src/dxvk/shaders/dxvk_copy_buffer_image.comp
Normal file
30
src/dxvk/shaders/dxvk_copy_buffer_image.comp
Normal 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)));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user