mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 14:52:10 +01:00
[dxvk] Correctly use VK_SHARING_MODE_CONCURRENT for buffers
Fixes some out-of-spec behaviour introduced with the global buffer rework.
This commit is contained in:
parent
a278d6bf1d
commit
836e990dc5
@ -117,50 +117,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkBarrierSet::releaseBuffer(
|
||||
DxvkBarrierSet& acquire,
|
||||
const DxvkBufferSliceHandle& bufSlice,
|
||||
uint32_t srcQueue,
|
||||
VkPipelineStageFlags srcStages,
|
||||
VkAccessFlags srcAccess,
|
||||
uint32_t dstQueue,
|
||||
VkPipelineStageFlags dstStages,
|
||||
VkAccessFlags dstAccess) {
|
||||
auto& release = *this;
|
||||
|
||||
m_allBarrierSrcStages |= srcStages;
|
||||
|
||||
VkBufferMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 };
|
||||
barrier.srcStageMask = srcStages & vk::StageDeviceMask;
|
||||
barrier.srcAccessMask = srcAccess & vk::AccessWriteMask;
|
||||
barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
|
||||
barrier.dstAccessMask = 0;
|
||||
barrier.srcQueueFamilyIndex = srcQueue;
|
||||
barrier.dstQueueFamilyIndex = dstQueue;
|
||||
barrier.buffer = bufSlice.handle;
|
||||
barrier.offset = bufSlice.offset;
|
||||
barrier.size = bufSlice.length;
|
||||
release.m_bufBarriers.push_back(barrier);
|
||||
|
||||
barrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstStageMask = dstStages;
|
||||
barrier.dstAccessMask = dstAccess;
|
||||
acquire.m_bufBarriers.push_back(barrier);
|
||||
|
||||
if (dstAccess & vk::AccessHostMask) {
|
||||
acquire.m_hostBarrierSrcStages |= srcStages & vk::StageDeviceMask;
|
||||
acquire.m_hostBarrierDstAccess |= dstAccess & vk::AccessHostMask;
|
||||
}
|
||||
|
||||
DxvkAccessFlags access(DxvkAccess::Read, DxvkAccess::Write);
|
||||
release.m_bufSlices.insert(bufSlice.handle,
|
||||
DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access));
|
||||
acquire.m_bufSlices.insert(bufSlice.handle,
|
||||
DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access));
|
||||
}
|
||||
|
||||
|
||||
void DxvkBarrierSet::releaseImage(
|
||||
DxvkBarrierSet& acquire,
|
||||
const Rc<DxvkImage>& image,
|
||||
|
@ -533,16 +533,6 @@ namespace dxvk {
|
||||
VkPipelineStageFlags dstStages,
|
||||
VkAccessFlags dstAccess);
|
||||
|
||||
void releaseBuffer(
|
||||
DxvkBarrierSet& acquire,
|
||||
const DxvkBufferSliceHandle& bufSlice,
|
||||
uint32_t srcQueue,
|
||||
VkPipelineStageFlags srcStages,
|
||||
VkAccessFlags srcAccess,
|
||||
uint32_t dstQueue,
|
||||
VkPipelineStageFlags dstStages,
|
||||
VkAccessFlags dstAccess);
|
||||
|
||||
void releaseImage(
|
||||
DxvkBarrierSet& acquire,
|
||||
const Rc<DxvkImage>& image,
|
||||
|
@ -15,6 +15,7 @@ namespace dxvk {
|
||||
m_allocator (&allocator),
|
||||
m_properties (memFlags),
|
||||
m_shaderStages (util::shaderStages(createInfo.stages)),
|
||||
m_sharingMode (device->getSharingMode()),
|
||||
m_info (createInfo) {
|
||||
// Create and assign actual buffer resource
|
||||
assignSlice(allocateSlice());
|
||||
@ -31,12 +32,13 @@ namespace dxvk {
|
||||
m_allocator (&allocator),
|
||||
m_properties (memFlags),
|
||||
m_shaderStages (util::shaderStages(createInfo.stages)),
|
||||
m_sharingMode (device->getSharingMode()),
|
||||
m_info (createInfo) {
|
||||
VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
info.flags = m_info.flags;
|
||||
info.usage = m_info.usage;
|
||||
info.size = m_info.size;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
m_sharingMode.fill(info);
|
||||
|
||||
assignSlice(allocator.importBufferResource(info, importInfo));
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ namespace dxvk {
|
||||
info.flags = m_info.flags;
|
||||
info.usage = m_info.usage;
|
||||
info.size = m_info.size;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
m_sharingMode.fill(info);
|
||||
|
||||
return m_allocator->createBufferResource(info, m_properties, cache);
|
||||
}
|
||||
@ -391,6 +391,7 @@ namespace dxvk {
|
||||
DxvkMemoryAllocator* m_allocator = nullptr;
|
||||
VkMemoryPropertyFlags m_properties = 0u;
|
||||
VkShaderStageFlags m_shaderStages = 0u;
|
||||
DxvkSharingModeInfo m_sharingMode = { };
|
||||
|
||||
DxvkBufferCreateInfo m_info = { };
|
||||
|
||||
|
@ -1435,11 +1435,9 @@ namespace dxvk {
|
||||
slice.handle, slice.offset,
|
||||
dxvk::align(slice.length, 4), 0);
|
||||
|
||||
m_initBarriers.accessBuffer(slice,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
buffer->info().stages,
|
||||
buffer->info().access);
|
||||
m_initBarriers.accessMemory(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
buffer->info().stages, buffer->info().access);
|
||||
|
||||
m_cmd->trackResource<DxvkAccess::Write>(buffer);
|
||||
}
|
||||
@ -2556,15 +2554,23 @@ namespace dxvk {
|
||||
|
||||
m_cmd->cmdCopyBuffer(DxvkCmdBuffer::SdmaBuffer, ©Info);
|
||||
|
||||
m_sdmaBarriers.releaseBuffer(
|
||||
m_initBarriers, bufferSlice,
|
||||
m_device->queues().transfer.queueFamily,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
m_device->queues().graphics.queueFamily,
|
||||
buffer->info().stages,
|
||||
buffer->info().access);
|
||||
|
||||
if (m_device->hasDedicatedTransferQueue()) {
|
||||
// Buffers use SHARING_MODE_CONCURRENT, so no explicit queue
|
||||
// family ownership transfer is required. Access is serialized
|
||||
// via a semaphore.
|
||||
m_sdmaBarriers.accessMemory(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_NONE, VK_ACCESS_NONE);
|
||||
|
||||
m_initBarriers.accessMemory(
|
||||
VK_PIPELINE_STAGE_NONE, VK_ACCESS_NONE,
|
||||
buffer->info().stages, buffer->info().access);
|
||||
} else {
|
||||
m_sdmaBarriers.accessMemory(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
buffer->info().stages, buffer->info().access);
|
||||
}
|
||||
|
||||
m_cmd->trackResource<DxvkAccess::Read>(stagingSlice.buffer());
|
||||
m_cmd->trackResource<DxvkAccess::Write>(buffer);
|
||||
}
|
||||
|
@ -14,11 +14,11 @@ namespace dxvk {
|
||||
m_instance (instance),
|
||||
m_adapter (adapter),
|
||||
m_vkd (vkd),
|
||||
m_queues (queues),
|
||||
m_features (features),
|
||||
m_properties (adapter->devicePropertiesExt()),
|
||||
m_perfHints (getPerfHints()),
|
||||
m_objects (this),
|
||||
m_queues (queues),
|
||||
m_submissionQueue (this, queueCallback) {
|
||||
|
||||
}
|
||||
|
@ -134,7 +134,18 @@ namespace dxvk {
|
||||
return m_queues.transfer.queueHandle
|
||||
!= m_queues.graphics.queueHandle;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Queries sharing mode info
|
||||
* \returns Sharing mode info
|
||||
*/
|
||||
DxvkSharingModeInfo getSharingMode() const {
|
||||
DxvkSharingModeInfo result = { };
|
||||
result.queueFamilies[0] = m_queues.graphics.queueFamily;
|
||||
result.queueFamilies[1] = m_queues.transfer.queueFamily;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief The instance
|
||||
*
|
||||
@ -539,6 +550,8 @@ namespace dxvk {
|
||||
Rc<DxvkAdapter> m_adapter;
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
|
||||
DxvkDeviceQueueSet m_queues;
|
||||
|
||||
DxvkDeviceFeatures m_features;
|
||||
DxvkDeviceInfo m_properties;
|
||||
|
||||
@ -548,8 +561,6 @@ namespace dxvk {
|
||||
sync::Spinlock m_statLock;
|
||||
DxvkStatCounters m_statCounters;
|
||||
|
||||
DxvkDeviceQueueSet m_queues;
|
||||
|
||||
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
|
||||
|
||||
DxvkSubmissionQueue m_submissionQueue;
|
||||
|
@ -434,7 +434,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkMemoryAllocator::DxvkMemoryAllocator(DxvkDevice* device)
|
||||
: m_device(device) {
|
||||
: m_device(device), m_sharingModeInfo(m_device->getSharingMode()) {
|
||||
VkPhysicalDeviceMemoryProperties memInfo = m_device->adapter()->memoryProperties();
|
||||
|
||||
m_memTypeCount = memInfo.memoryTypeCount;
|
||||
@ -616,7 +616,7 @@ namespace dxvk {
|
||||
DxvkLocalAllocationCache* allocationCache) {
|
||||
Rc<DxvkResourceAllocation> allocation;
|
||||
|
||||
if (likely(!createInfo.flags && createInfo.sharingMode == VK_SHARING_MODE_EXCLUSIVE)) {
|
||||
if (likely(!createInfo.flags)) {
|
||||
VkMemoryRequirements memoryRequirements = { };
|
||||
memoryRequirements.size = createInfo.size;
|
||||
memoryRequirements.alignment = GlobalBufferAlignment;
|
||||
@ -998,7 +998,7 @@ namespace dxvk {
|
||||
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
bufferInfo.size = size;
|
||||
bufferInfo.usage = type.bufferUsage;
|
||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
m_sharingModeInfo.fill(bufferInfo);
|
||||
|
||||
VkResult status = vk->vkCreateBuffer(vk->device(), &bufferInfo, nullptr, &buffer);
|
||||
|
||||
@ -1499,7 +1499,7 @@ namespace dxvk {
|
||||
| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
m_sharingModeInfo.fill(bufferInfo);
|
||||
|
||||
if (getBufferMemoryRequirements(bufferInfo, requirements))
|
||||
typeMask &= requirements.memoryRequirements.memoryTypeBits;
|
||||
@ -1561,7 +1561,7 @@ namespace dxvk {
|
||||
// to be supported, but we need to be robust around buffer creation anyway.
|
||||
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
bufferInfo.size = 65536;
|
||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
m_sharingModeInfo.fill(bufferInfo);
|
||||
|
||||
VkMemoryRequirements2 requirements = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 };
|
||||
|
||||
|
@ -213,6 +213,33 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Sharing mode info
|
||||
*
|
||||
* Stores available queue families and provides methods
|
||||
* to fill in sharing mode infos for resource creation.
|
||||
*/
|
||||
struct DxvkSharingModeInfo {
|
||||
std::array<uint32_t, 2u> queueFamilies = { };
|
||||
|
||||
VkSharingMode sharingMode() const {
|
||||
return queueFamilies[0] != queueFamilies[1]
|
||||
? VK_SHARING_MODE_CONCURRENT
|
||||
: VK_SHARING_MODE_EXCLUSIVE;
|
||||
}
|
||||
|
||||
template<typename CreateInfo>
|
||||
void fill(CreateInfo& info) const {
|
||||
info.sharingMode = sharingMode();
|
||||
|
||||
if (info.sharingMode == VK_SHARING_MODE_CONCURRENT) {
|
||||
info.queueFamilyIndexCount = queueFamilies.size();
|
||||
info.pQueueFamilyIndices = queueFamilies.data();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Buffer view key
|
||||
*
|
||||
@ -1121,6 +1148,8 @@ namespace dxvk {
|
||||
|
||||
DxvkDevice* m_device;
|
||||
|
||||
DxvkSharingModeInfo m_sharingModeInfo;
|
||||
|
||||
dxvk::mutex m_mutex;
|
||||
dxvk::condition_variable m_cond;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user