[dxvk] Added buffer copy and initial buffer barriers

This commit is contained in:
Philip Rebohle 2017-11-26 13:24:01 +01:00
parent d225744c98
commit c82bddb932
10 changed files with 191 additions and 74 deletions

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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);
};
}

View File

@ -13,6 +13,8 @@ namespace dxvk {
uint32_t numLayers;
uint32_t mipLevels;
VkImageUsageFlags usage;
VkPipelineStageFlags stages;
VkAccessFlags access;
VkImageTiling tiling;
};

View File

@ -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,

View File

@ -4,6 +4,13 @@
namespace dxvk {
enum class DxvkResourceAccessType {
Read = 0,
Write = 1,
};
using DxvkResourceAccessTypes = Flags<DxvkResourceAccessType>;
/**
* \brief DXVK resource
*