mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[dxvk] Implement clearBufferView and clearImageView
This commit is contained in:
parent
cce578d67a
commit
9d84e1bfaa
@ -301,6 +301,19 @@ namespace dxvk {
|
|||||||
return m_physView->handle();
|
return m_physView->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Element cound
|
||||||
|
*
|
||||||
|
* Number of typed elements contained
|
||||||
|
* in the buffer view. Depends on the
|
||||||
|
* buffer view format.
|
||||||
|
* \returns Element count
|
||||||
|
*/
|
||||||
|
VkDeviceSize elementCount() const {
|
||||||
|
auto format = imageFormatInfo(m_info.format);
|
||||||
|
return m_info.rangeLength / format->elementSize;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Buffer view properties
|
* \brief Buffer view properties
|
||||||
* \returns Buffer view properties
|
* \returns Buffer view properties
|
||||||
|
@ -182,6 +182,15 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void updateDescriptorSets(
|
||||||
|
uint32_t descriptorWriteCount,
|
||||||
|
const VkWriteDescriptorSet* pDescriptorWrites) {
|
||||||
|
m_vkd->vkUpdateDescriptorSets(m_vkd->device(),
|
||||||
|
descriptorWriteCount, pDescriptorWrites,
|
||||||
|
0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void updateDescriptorSetWithTemplate(
|
void updateDescriptorSetWithTemplate(
|
||||||
VkDescriptorSet descriptorSet,
|
VkDescriptorSet descriptorSet,
|
||||||
VkDescriptorUpdateTemplateKHR descriptorTemplate,
|
VkDescriptorUpdateTemplateKHR descriptorTemplate,
|
||||||
|
@ -242,7 +242,66 @@ namespace dxvk {
|
|||||||
VkDeviceSize offset,
|
VkDeviceSize offset,
|
||||||
VkDeviceSize length,
|
VkDeviceSize length,
|
||||||
VkClearColorValue value) {
|
VkClearColorValue value) {
|
||||||
|
this->renderPassEnd();
|
||||||
|
this->unbindComputePipeline();
|
||||||
|
|
||||||
|
// Query pipeline objects to use for this clear operation
|
||||||
|
DxvkMetaClearPipeline pipeInfo = m_metaClear->getClearBufferPipeline(
|
||||||
|
imageFormatInfo(bufferView->info().format)->flags);
|
||||||
|
|
||||||
|
// Create a descriptor set pointing to the view
|
||||||
|
VkBufferView viewObject = bufferView->handle();
|
||||||
|
|
||||||
|
VkDescriptorSet descriptorSet =
|
||||||
|
m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
|
||||||
|
|
||||||
|
VkWriteDescriptorSet descriptorWrite;
|
||||||
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptorWrite.pNext = nullptr;
|
||||||
|
descriptorWrite.dstSet = descriptorSet;
|
||||||
|
descriptorWrite.dstBinding = 0;
|
||||||
|
descriptorWrite.dstArrayElement = 0;
|
||||||
|
descriptorWrite.descriptorCount = 1;
|
||||||
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
|
||||||
|
descriptorWrite.pImageInfo = nullptr;
|
||||||
|
descriptorWrite.pBufferInfo = nullptr;
|
||||||
|
descriptorWrite.pTexelBufferView = &viewObject;
|
||||||
|
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
||||||
|
|
||||||
|
// Prepare shader arguments
|
||||||
|
DxvkMetaClearArgs pushArgs;
|
||||||
|
pushArgs.clearValue = value;
|
||||||
|
pushArgs.offset = VkOffset3D { int32_t(offset), 0, 0 };
|
||||||
|
pushArgs.extent = VkExtent3D { uint32_t(length), 1, 1 };
|
||||||
|
|
||||||
|
VkExtent3D workgroups = util::computeBlockCount(
|
||||||
|
pushArgs.extent, pipeInfo.workgroupSize);
|
||||||
|
|
||||||
|
m_cmd->cmdBindPipeline(
|
||||||
|
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||||
|
pipeInfo.pipeline);
|
||||||
|
m_cmd->cmdBindDescriptorSet(
|
||||||
|
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||||
|
pipeInfo.pipeLayout, descriptorSet);
|
||||||
|
m_cmd->cmdPushConstants(
|
||||||
|
pipeInfo.pipeLayout,
|
||||||
|
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
|
0, sizeof(pushArgs), &pushArgs);
|
||||||
|
m_cmd->cmdDispatch(
|
||||||
|
workgroups.width,
|
||||||
|
workgroups.height,
|
||||||
|
workgroups.depth);
|
||||||
|
|
||||||
|
m_barriers.accessBuffer(
|
||||||
|
bufferView->physicalSlice(),
|
||||||
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
bufferView->bufferInfo().stages,
|
||||||
|
bufferView->bufferInfo().access);
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
|
m_cmd->trackResource(bufferView->viewResource());
|
||||||
|
m_cmd->trackResource(bufferView->bufferResource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -367,11 +426,81 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxvkContext::clearImageView(
|
void DxvkContext::clearImageView(
|
||||||
const Rc<DxvkBufferView>& bufferView,
|
const Rc<DxvkImageView>& imageView,
|
||||||
VkOffset3D offset,
|
VkOffset3D offset,
|
||||||
VkExtent3D extent,
|
VkExtent3D extent,
|
||||||
VkClearColorValue value) {
|
VkClearColorValue value) {
|
||||||
|
this->renderPassEnd();
|
||||||
|
this->unbindComputePipeline();
|
||||||
|
|
||||||
|
// Query pipeline objects to use for this clear operation
|
||||||
|
DxvkMetaClearPipeline pipeInfo = m_metaClear->getClearImagePipeline(
|
||||||
|
imageView->type(), imageFormatInfo(imageView->info().format)->flags);
|
||||||
|
|
||||||
|
// Create a descriptor set pointing to the view
|
||||||
|
VkDescriptorSet descriptorSet =
|
||||||
|
m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
|
||||||
|
|
||||||
|
VkDescriptorImageInfo viewInfo;
|
||||||
|
viewInfo.sampler = VK_NULL_HANDLE;
|
||||||
|
viewInfo.imageView = imageView->handle();
|
||||||
|
viewInfo.imageLayout = imageView->imageInfo().layout;
|
||||||
|
|
||||||
|
VkWriteDescriptorSet descriptorWrite;
|
||||||
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptorWrite.pNext = nullptr;
|
||||||
|
descriptorWrite.dstSet = descriptorSet;
|
||||||
|
descriptorWrite.dstBinding = 0;
|
||||||
|
descriptorWrite.dstArrayElement = 0;
|
||||||
|
descriptorWrite.descriptorCount = 1;
|
||||||
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
|
descriptorWrite.pImageInfo = &viewInfo;
|
||||||
|
descriptorWrite.pBufferInfo = nullptr;
|
||||||
|
descriptorWrite.pTexelBufferView = nullptr;
|
||||||
|
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
||||||
|
|
||||||
|
// Prepare shader arguments
|
||||||
|
DxvkMetaClearArgs pushArgs;
|
||||||
|
pushArgs.clearValue = value;
|
||||||
|
pushArgs.offset = offset;
|
||||||
|
pushArgs.extent = extent;
|
||||||
|
|
||||||
|
VkExtent3D workgroups = util::computeBlockCount(
|
||||||
|
pushArgs.extent, pipeInfo.workgroupSize);
|
||||||
|
|
||||||
|
if (imageView->type() == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
|
||||||
|
workgroups.height = imageView->subresources().layerCount;
|
||||||
|
else if (imageView->type() == VK_IMAGE_VIEW_TYPE_2D_ARRAY)
|
||||||
|
workgroups.depth = imageView->subresources().layerCount;
|
||||||
|
|
||||||
|
m_cmd->cmdBindPipeline(
|
||||||
|
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||||
|
pipeInfo.pipeline);
|
||||||
|
m_cmd->cmdBindDescriptorSet(
|
||||||
|
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||||
|
pipeInfo.pipeLayout, descriptorSet);
|
||||||
|
m_cmd->cmdPushConstants(
|
||||||
|
pipeInfo.pipeLayout,
|
||||||
|
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
|
0, sizeof(pushArgs), &pushArgs);
|
||||||
|
m_cmd->cmdDispatch(
|
||||||
|
workgroups.width,
|
||||||
|
workgroups.height,
|
||||||
|
workgroups.depth);
|
||||||
|
|
||||||
|
m_barriers.accessImage(
|
||||||
|
imageView->image(),
|
||||||
|
imageView->subresources(),
|
||||||
|
imageView->imageInfo().layout,
|
||||||
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
imageView->imageInfo().layout,
|
||||||
|
imageView->imageInfo().stages,
|
||||||
|
imageView->imageInfo().access);
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
|
m_cmd->trackResource(imageView);
|
||||||
|
m_cmd->trackResource(imageView->image());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1402,6 +1531,16 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::unbindComputePipeline() {
|
||||||
|
m_flags.set(
|
||||||
|
DxvkContextFlag::CpDirtyPipeline,
|
||||||
|
DxvkContextFlag::CpDirtyPipelineState,
|
||||||
|
DxvkContextFlag::CpDirtyResources);
|
||||||
|
|
||||||
|
m_cpActivePipeline = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::updateComputePipeline() {
|
void DxvkContext::updateComputePipeline() {
|
||||||
if (m_flags.test(DxvkContextFlag::CpDirtyPipeline)) {
|
if (m_flags.test(DxvkContextFlag::CpDirtyPipeline)) {
|
||||||
m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
|
m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
|
||||||
|
@ -227,13 +227,13 @@ namespace dxvk {
|
|||||||
* Can be used to clear sub-regions of storage images
|
* Can be used to clear sub-regions of storage images
|
||||||
* that are not going to be used as render targets.
|
* that are not going to be used as render targets.
|
||||||
* Implicit format conversion will be applied.
|
* Implicit format conversion will be applied.
|
||||||
* \param [in] bufferView The buffer view
|
* \param [in] imageView The image view
|
||||||
* \param [in] offset Offset of the rect to clear
|
* \param [in] offset Offset of the rect to clear
|
||||||
* \param [in] extent Extent of the rect to clear
|
* \param [in] extent Extent of the rect to clear
|
||||||
* \param [in] value The clear value
|
* \param [in] value The clear value
|
||||||
*/
|
*/
|
||||||
void clearImageView(
|
void clearImageView(
|
||||||
const Rc<DxvkBufferView>& bufferView,
|
const Rc<DxvkImageView>& imageView,
|
||||||
VkOffset3D offset,
|
VkOffset3D offset,
|
||||||
VkExtent3D extent,
|
VkExtent3D extent,
|
||||||
VkClearColorValue value);
|
VkClearColorValue value);
|
||||||
@ -628,6 +628,8 @@ namespace dxvk {
|
|||||||
const Rc<DxvkFramebuffer>& framebuffer);
|
const Rc<DxvkFramebuffer>& framebuffer);
|
||||||
void renderPassUnbindFramebuffer();
|
void renderPassUnbindFramebuffer();
|
||||||
|
|
||||||
|
void unbindComputePipeline();
|
||||||
|
|
||||||
void updateComputePipeline();
|
void updateComputePipeline();
|
||||||
void updateComputePipelineState();
|
void updateComputePipelineState();
|
||||||
|
|
||||||
|
@ -70,6 +70,47 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkMetaClearPipeline DxvkMetaClearObjects::getClearBufferPipeline(
|
||||||
|
DxvkFormatFlags formatFlags) const {
|
||||||
|
DxvkMetaClearPipeline result;
|
||||||
|
result.dsetLayout = m_clearBufDsetLayout;
|
||||||
|
result.pipeLayout = m_clearBufPipeLayout;
|
||||||
|
result.pipeline = formatFlags.test(DxvkFormatFlag::SampledInteger)
|
||||||
|
? m_clearPipesU32.clearBuf
|
||||||
|
: m_clearPipesF32.clearBuf;
|
||||||
|
result.workgroupSize = VkExtent3D { 128, 1, 1 };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkMetaClearPipeline DxvkMetaClearObjects::getClearImagePipeline(
|
||||||
|
VkImageViewType viewType,
|
||||||
|
DxvkFormatFlags formatFlags) const {
|
||||||
|
const DxvkMetaClearPipelines& pipes
|
||||||
|
= formatFlags.test(DxvkFormatFlag::SampledInteger)
|
||||||
|
? m_clearPipesU32 : m_clearPipesF32;
|
||||||
|
|
||||||
|
DxvkMetaClearPipeline result;
|
||||||
|
result.dsetLayout = m_clearImgDsetLayout;
|
||||||
|
result.pipeLayout = m_clearImgPipeLayout;
|
||||||
|
|
||||||
|
auto pipeInfo = [&pipes, viewType] () -> std::pair<VkPipeline, VkExtent3D> {
|
||||||
|
switch (viewType) {
|
||||||
|
case VK_IMAGE_VIEW_TYPE_1D: return { pipes.clearImg1D, VkExtent3D { 64, 1, 1 } };
|
||||||
|
case VK_IMAGE_VIEW_TYPE_2D: return { pipes.clearImg2D, VkExtent3D { 8, 8, 1 } };
|
||||||
|
case VK_IMAGE_VIEW_TYPE_3D: return { pipes.clearImg3D, VkExtent3D { 4, 4, 4 } };
|
||||||
|
case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return { pipes.clearImg1DArray, VkExtent3D { 64, 1, 1 } };
|
||||||
|
case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return { pipes.clearImg2DArray, VkExtent3D { 8, 8, 1 } };
|
||||||
|
default: return { VkPipeline(VK_NULL_HANDLE), VkExtent3D { 0, 0, 0, } };
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
result.pipeline = pipeInfo.first;
|
||||||
|
result.workgroupSize = pipeInfo.second;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VkDescriptorSetLayout DxvkMetaClearObjects::createDescriptorSetLayout(
|
VkDescriptorSetLayout DxvkMetaClearObjects::createDescriptorSetLayout(
|
||||||
VkDescriptorType descriptorType) {
|
VkDescriptorType descriptorType) {
|
||||||
VkDescriptorSetLayoutBinding bindInfo;
|
VkDescriptorSetLayoutBinding bindInfo;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dxvk_barrier.h"
|
#include "dxvk_format.h"
|
||||||
#include "dxvk_cmdlist.h"
|
#include "dxvk_include.h"
|
||||||
#include "dxvk_resource.h"
|
|
||||||
|
|
||||||
#include "../spirv/spirv_code_buffer.h"
|
#include "../spirv/spirv_code_buffer.h"
|
||||||
|
|
||||||
@ -22,6 +21,20 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Pipeline-related objects
|
||||||
|
*
|
||||||
|
* Use this to bind the pipeline
|
||||||
|
* and allocate a descriptor set.
|
||||||
|
*/
|
||||||
|
struct DxvkMetaClearPipeline {
|
||||||
|
VkDescriptorSetLayout dsetLayout;
|
||||||
|
VkPipelineLayout pipeLayout;
|
||||||
|
VkPipeline pipeline;
|
||||||
|
VkExtent3D workgroupSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clear shaders and related objects
|
* \brief Clear shaders and related objects
|
||||||
*
|
*
|
||||||
@ -36,6 +49,30 @@ namespace dxvk {
|
|||||||
DxvkMetaClearObjects(const Rc<vk::DeviceFn>& vkd);
|
DxvkMetaClearObjects(const Rc<vk::DeviceFn>& vkd);
|
||||||
~DxvkMetaClearObjects();
|
~DxvkMetaClearObjects();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves objects to use for buffers
|
||||||
|
*
|
||||||
|
* Returns the pipeline, pipeline layout and descriptor
|
||||||
|
* set layout which are required to perform a meta clear
|
||||||
|
* operation on a buffer resource with the given format.
|
||||||
|
* \param [in] viewType The image virw type
|
||||||
|
*/
|
||||||
|
DxvkMetaClearPipeline getClearBufferPipeline(
|
||||||
|
DxvkFormatFlags formatFlags) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves objects for a given image view type
|
||||||
|
*
|
||||||
|
* Returns the pipeline, pipeline layout and descriptor
|
||||||
|
* set layout which are required to perform a meta clear
|
||||||
|
* operation on a resource with the given view type.
|
||||||
|
* \param [in] viewType The image virw type
|
||||||
|
* \returns The pipeline-related objects to use
|
||||||
|
*/
|
||||||
|
DxvkMetaClearPipeline getClearImagePipeline(
|
||||||
|
VkImageViewType viewType,
|
||||||
|
DxvkFormatFlags formatFlags) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct DxvkMetaClearPipelines {
|
struct DxvkMetaClearPipelines {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user