mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 05:52:11 +01:00
[dxvk] Added buffer copy and initial buffer barriers
This commit is contained in:
parent
d225744c98
commit
c82bddb932
@ -5,66 +5,90 @@ namespace dxvk {
|
||||
DxvkBarrierSet:: DxvkBarrierSet() { }
|
||||
DxvkBarrierSet::~DxvkBarrierSet() { }
|
||||
|
||||
bool DxvkBarrierSet::hasBarriers() const {
|
||||
return (m_srcFlags | m_dstFlags) != 0;
|
||||
}
|
||||
|
||||
|
||||
void DxvkBarrierSet::addMemoryBarrier(
|
||||
VkPipelineStageFlags srcFlags,
|
||||
VkPipelineStageFlags dstFlags,
|
||||
const VkMemoryBarrier& barrier) {
|
||||
m_srcFlags |= srcFlags;
|
||||
m_dstFlags |= dstFlags;
|
||||
m_memory.push_back(barrier);
|
||||
}
|
||||
|
||||
|
||||
void DxvkBarrierSet::addBufferBarrier(
|
||||
VkPipelineStageFlags srcFlags,
|
||||
VkPipelineStageFlags dstFlags,
|
||||
const VkBufferMemoryBarrier& barrier) {
|
||||
m_srcFlags |= srcFlags;
|
||||
m_dstFlags |= dstFlags;
|
||||
m_buffer.push_back(barrier);
|
||||
}
|
||||
|
||||
|
||||
void DxvkBarrierSet::addImageBarrier(
|
||||
VkPipelineStageFlags srcFlags,
|
||||
VkPipelineStageFlags dstFlags,
|
||||
const VkImageMemoryBarrier& barrier) {
|
||||
m_srcFlags |= srcFlags;
|
||||
m_dstFlags |= dstFlags;
|
||||
m_image.push_back(barrier);
|
||||
void DxvkBarrierSet::accessBuffer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize size,
|
||||
VkPipelineStageFlags stages,
|
||||
VkAccessFlags access) {
|
||||
const DxvkResourceAccessTypes accessTypes
|
||||
= this->getAccessTypes(access);
|
||||
|
||||
m_srcStages |= stages;
|
||||
m_dstStages |= buffer->info().stages;
|
||||
|
||||
if (accessTypes.test(DxvkResourceAccessType::Write)) {
|
||||
VkBufferMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
barrier.pNext = nullptr;
|
||||
barrier.srcAccessMask = access;
|
||||
barrier.dstAccessMask = buffer->info().access;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.buffer = buffer->handle();
|
||||
barrier.offset = offset;
|
||||
barrier.size = size;
|
||||
m_bufBarriers.push_back(barrier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkBarrierSet::recordCommands(
|
||||
DxvkRecorder& recorder) {
|
||||
VkPipelineStageFlags srcFlags = m_srcFlags;
|
||||
VkPipelineStageFlags dstFlags = m_dstFlags;
|
||||
|
||||
if (srcFlags == 0) srcFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
if (dstFlags == 0) dstFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
|
||||
recorder.cmdPipelineBarrier(
|
||||
srcFlags, dstFlags, 0,
|
||||
m_memory.size(), m_memory.data(),
|
||||
m_buffer.size(), m_buffer.data(),
|
||||
m_image.size(), m_image.data());
|
||||
|
||||
this->reset();
|
||||
DxvkRecorder& recorder) {
|
||||
if ((m_srcStages | m_dstStages) != 0) {
|
||||
VkPipelineStageFlags srcFlags = m_srcStages;
|
||||
VkPipelineStageFlags dstFlags = m_dstStages;
|
||||
|
||||
if (srcFlags == 0) srcFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
if (dstFlags == 0) dstFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
|
||||
recorder.cmdPipelineBarrier(
|
||||
srcFlags, dstFlags, 0,
|
||||
m_memBarriers.size(), m_memBarriers.data(),
|
||||
m_bufBarriers.size(), m_bufBarriers.data(),
|
||||
m_imgBarriers.size(), m_imgBarriers.data());
|
||||
|
||||
this->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkBarrierSet::reset() {
|
||||
m_srcFlags = 0;
|
||||
m_dstFlags = 0;
|
||||
m_srcStages = 0;
|
||||
m_dstStages = 0;
|
||||
|
||||
m_memory.resize(0);
|
||||
m_buffer.resize(0);
|
||||
m_image .resize(0);
|
||||
m_memBarriers.resize(0);
|
||||
m_bufBarriers.resize(0);
|
||||
m_imgBarriers.resize(0);
|
||||
}
|
||||
|
||||
|
||||
DxvkResourceAccessTypes DxvkBarrierSet::getAccessTypes(VkAccessFlags flags) const {
|
||||
const VkAccessFlags rflags
|
||||
= VK_ACCESS_INDIRECT_COMMAND_READ_BIT
|
||||
| VK_ACCESS_INDEX_READ_BIT
|
||||
| VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
|
||||
| VK_ACCESS_UNIFORM_READ_BIT
|
||||
| VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_SHADER_READ_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_TRANSFER_READ_BIT
|
||||
| VK_ACCESS_HOST_READ_BIT
|
||||
| VK_ACCESS_MEMORY_READ_BIT;
|
||||
|
||||
const VkAccessFlags wflags
|
||||
= VK_ACCESS_SHADER_WRITE_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
|
||||
| VK_ACCESS_TRANSFER_WRITE_BIT
|
||||
| VK_ACCESS_HOST_WRITE_BIT
|
||||
| VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
|
||||
DxvkResourceAccessTypes result;
|
||||
if (flags & rflags) result.set(DxvkResourceAccessType::Read);
|
||||
if (flags & wflags) result.set(DxvkResourceAccessType::Write);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxvk_buffer.h"
|
||||
#include "dxvk_image.h"
|
||||
#include "dxvk_recorder.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -17,37 +19,29 @@ namespace dxvk {
|
||||
|
||||
DxvkBarrierSet();
|
||||
~DxvkBarrierSet();
|
||||
|
||||
bool hasBarriers() const;
|
||||
|
||||
void addMemoryBarrier(
|
||||
VkPipelineStageFlags srcFlags,
|
||||
VkPipelineStageFlags dstFlags,
|
||||
const VkMemoryBarrier& barrier);
|
||||
|
||||
void addBufferBarrier(
|
||||
VkPipelineStageFlags srcFlags,
|
||||
VkPipelineStageFlags dstFlags,
|
||||
const VkBufferMemoryBarrier& barrier);
|
||||
|
||||
void addImageBarrier(
|
||||
VkPipelineStageFlags srcFlags,
|
||||
VkPipelineStageFlags dstFlags,
|
||||
const VkImageMemoryBarrier& barrier);
|
||||
|
||||
void accessBuffer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize size,
|
||||
VkPipelineStageFlags stages,
|
||||
VkAccessFlags access);
|
||||
|
||||
void recordCommands(
|
||||
DxvkRecorder& recorder);
|
||||
DxvkRecorder& recorder);
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
|
||||
VkPipelineStageFlags m_srcFlags = 0;
|
||||
VkPipelineStageFlags m_dstFlags = 0;
|
||||
VkPipelineStageFlags m_srcStages = 0;
|
||||
VkPipelineStageFlags m_dstStages = 0;
|
||||
|
||||
std::vector<VkMemoryBarrier> m_memory;
|
||||
std::vector<VkBufferMemoryBarrier> m_buffer;
|
||||
std::vector<VkImageMemoryBarrier> m_image;
|
||||
std::vector<VkMemoryBarrier> m_memBarriers;
|
||||
std::vector<VkBufferMemoryBarrier> m_bufBarriers;
|
||||
std::vector<VkImageMemoryBarrier> m_imgBarriers;
|
||||
|
||||
DxvkResourceAccessTypes getAccessTypes(VkAccessFlags flags) const;
|
||||
|
||||
};
|
||||
|
||||
|
@ -157,6 +157,17 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkCommandList::cmdCopyBuffer(
|
||||
VkBuffer srcBuffer,
|
||||
VkBuffer dstBuffer,
|
||||
uint32_t regionCount,
|
||||
const VkBufferCopy* pRegions) {
|
||||
m_vkd->vkCmdCopyBuffer(m_buffer,
|
||||
srcBuffer, dstBuffer,
|
||||
regionCount, pRegions);
|
||||
}
|
||||
|
||||
|
||||
void DxvkCommandList::cmdDispatch(
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -103,6 +103,12 @@ namespace dxvk {
|
||||
uint32_t rectCount,
|
||||
const VkClearRect* pRects) final;
|
||||
|
||||
void cmdCopyBuffer(
|
||||
VkBuffer srcBuffer,
|
||||
VkBuffer dstBuffer,
|
||||
uint32_t regionCount,
|
||||
const VkBufferCopy* pRegions) final;
|
||||
|
||||
void cmdDispatch(
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -177,6 +177,14 @@ namespace dxvk {
|
||||
uint32_t bindingCount,
|
||||
const VkVertexInputBindingDescription* bindingInfo);
|
||||
|
||||
uint32_t vertexAttributeCount() const {
|
||||
return m_attributes.size();
|
||||
}
|
||||
|
||||
uint32_t vertexBindingCount() const {
|
||||
return m_bindings.size();
|
||||
}
|
||||
|
||||
const VkPipelineVertexInputStateCreateInfo& info() const {
|
||||
return m_info;
|
||||
}
|
||||
|
@ -102,6 +102,8 @@ namespace dxvk {
|
||||
void DxvkContext::bindVertexBuffer(
|
||||
uint32_t binding,
|
||||
const DxvkBufferBinding& buffer) {
|
||||
TRACE(this, binding);
|
||||
|
||||
if (m_state.vi.vertexBuffers.at(binding) != buffer) {
|
||||
m_state.vi.vertexBuffers.at(binding) = buffer;
|
||||
m_state.flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
|
||||
@ -124,6 +126,43 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::copyBuffer(
|
||||
const Rc<DxvkBuffer>& dstBuffer,
|
||||
VkDeviceSize dstOffset,
|
||||
const Rc<DxvkBuffer>& srcBuffer,
|
||||
VkDeviceSize srcOffset,
|
||||
VkDeviceSize numBytes) {
|
||||
TRACE(this, dstBuffer, dstOffset, srcBuffer, srcOffset, numBytes);
|
||||
|
||||
if (numBytes != 0) {
|
||||
VkBufferCopy bufferRegion;
|
||||
bufferRegion.srcOffset = srcOffset;
|
||||
bufferRegion.dstOffset = dstOffset;
|
||||
bufferRegion.size = numBytes;
|
||||
|
||||
m_cmd->cmdCopyBuffer(
|
||||
srcBuffer->handle(),
|
||||
dstBuffer->handle(),
|
||||
1, &bufferRegion);
|
||||
|
||||
m_barriers.accessBuffer(
|
||||
srcBuffer, srcOffset, numBytes,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_READ_BIT);
|
||||
|
||||
m_barriers.accessBuffer(
|
||||
dstBuffer, dstOffset, numBytes,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
|
||||
m_barriers.recordCommands(*m_cmd);
|
||||
|
||||
m_cmd->trackResource(dstBuffer);
|
||||
m_cmd->trackResource(srcBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::dispatch(
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
@ -361,6 +400,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxvkContext::commitComputeState() {
|
||||
this->renderPassEnd();
|
||||
this->bindComputePipeline();
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,22 @@ namespace dxvk {
|
||||
const VkClearAttachment& attachment,
|
||||
const VkClearRect& clearArea);
|
||||
|
||||
/**
|
||||
* \brief Copies data from one buffer to another
|
||||
*
|
||||
* \param [in] dstBuffer Destination buffer
|
||||
* \param [in] dstOffset Destination data offset
|
||||
* \param [in] srcBuffer Source buffer
|
||||
* \param [in] srcOffset Source data offset
|
||||
* \param [in] numBytes Number of bytes to copy
|
||||
*/
|
||||
void copyBuffer(
|
||||
const Rc<DxvkBuffer>& dstBuffer,
|
||||
VkDeviceSize dstOffset,
|
||||
const Rc<DxvkBuffer>& srcBuffer,
|
||||
VkDeviceSize srcOffset,
|
||||
VkDeviceSize numBytes);
|
||||
|
||||
/**
|
||||
* \brief Starts compute jobs
|
||||
*
|
||||
@ -199,6 +215,7 @@ namespace dxvk {
|
||||
|
||||
Rc<DxvkRecorder> m_cmd;
|
||||
DxvkContextState m_state;
|
||||
DxvkBarrierSet m_barriers;
|
||||
|
||||
void renderPassBegin();
|
||||
void renderPassEnd();
|
||||
@ -218,6 +235,8 @@ namespace dxvk {
|
||||
DxvkShaderStageState* getShaderStage(
|
||||
VkShaderStageFlagBits stage);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -13,6 +13,8 @@ namespace dxvk {
|
||||
uint32_t numLayers;
|
||||
uint32_t mipLevels;
|
||||
VkImageUsageFlags usage;
|
||||
VkPipelineStageFlags stages;
|
||||
VkAccessFlags access;
|
||||
VkImageTiling tiling;
|
||||
};
|
||||
|
||||
|
@ -60,6 +60,12 @@ namespace dxvk {
|
||||
uint32_t rectCount,
|
||||
const VkClearRect* pRects) = 0;
|
||||
|
||||
virtual void cmdCopyBuffer(
|
||||
VkBuffer srcBuffer,
|
||||
VkBuffer dstBuffer,
|
||||
uint32_t regionCount,
|
||||
const VkBufferCopy* pRegions) = 0;
|
||||
|
||||
virtual void cmdDispatch(
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -4,6 +4,13 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
enum class DxvkResourceAccessType {
|
||||
Read = 0,
|
||||
Write = 1,
|
||||
};
|
||||
|
||||
using DxvkResourceAccessTypes = Flags<DxvkResourceAccessType>;
|
||||
|
||||
/**
|
||||
* \brief DXVK resource
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user