1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-30 04:24:11 +01:00

[dxvk] Add SDMA command buffer

This new command buffer will be submitted to the transfer queue,
if available, otherwise it will be the first buffer submitted
to the graphics queue.
This commit is contained in:
Philip Rebohle 2019-06-28 01:36:12 +02:00
parent 4e0de6bc20
commit 4f3dcf2bc8
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 59 additions and 12 deletions

View File

@ -35,21 +35,41 @@ namespace dxvk {
throw DxvkError("DxvkCommandList: Failed to create transfer command pool");
}
VkCommandBufferAllocateInfo cmdInfo;
cmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmdInfo.pNext = nullptr;
cmdInfo.commandPool = m_graphicsPool;
cmdInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmdInfo.commandBufferCount = 1;
VkCommandBufferAllocateInfo cmdInfoGfx;
cmdInfoGfx.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmdInfoGfx.pNext = nullptr;
cmdInfoGfx.commandPool = m_graphicsPool;
cmdInfoGfx.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmdInfoGfx.commandBufferCount = 1;
if (m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfo, &m_execBuffer) != VK_SUCCESS
|| m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfo, &m_initBuffer) != VK_SUCCESS)
VkCommandBufferAllocateInfo cmdInfoDma;
cmdInfoDma.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmdInfoDma.pNext = nullptr;
cmdInfoDma.commandPool = m_transferPool ? m_transferPool : m_graphicsPool;
cmdInfoDma.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmdInfoDma.commandBufferCount = 1;
if (m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_execBuffer) != VK_SUCCESS
|| m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_initBuffer) != VK_SUCCESS
|| m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoDma, &m_sdmaBuffer) != VK_SUCCESS)
throw DxvkError("DxvkCommandList: Failed to allocate command buffer");
if (m_device->hasDedicatedTransferQueue()) {
VkSemaphoreCreateInfo semInfo;
semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semInfo.pNext = nullptr;
semInfo.flags = 0;
if (m_vkd->vkCreateSemaphore(m_vkd->device(), &semInfo, nullptr, &m_sdmaSemaphore) != VK_SUCCESS)
throw DxvkError("DxvkCommandList: Failed to create semaphore");
}
}
DxvkCommandList::~DxvkCommandList() {
this->reset();
m_vkd->vkDestroySemaphore(m_vkd->device(), m_sdmaSemaphore, nullptr);
m_vkd->vkDestroyCommandPool(m_vkd->device(), m_graphicsPool, nullptr);
m_vkd->vkDestroyCommandPool(m_vkd->device(), m_transferPool, nullptr);
@ -62,8 +82,26 @@ namespace dxvk {
VkSemaphore waitSemaphore,
VkSemaphore wakeSemaphore) {
const auto& graphics = m_device->queues().graphics;
const auto& transfer = m_device->queues().transfer;
DxvkQueueSubmission info = { };
DxvkQueueSubmission info = DxvkQueueSubmission();
if (m_cmdBuffersUsed.test(DxvkCmdBuffer::SdmaBuffer)) {
info.cmdBuffers[info.cmdBufferCount++] = m_sdmaBuffer;
if (m_device->hasDedicatedTransferQueue()) {
info.wakeSync[info.wakeCount++] = m_sdmaSemaphore;
VkResult status = submitToQueue(transfer.queueHandle, VK_NULL_HANDLE, info);
if (status != VK_SUCCESS)
return status;
info = DxvkQueueSubmission();
info.waitSync[info.waitCount] = m_sdmaSemaphore;
info.waitMask[info.waitCount] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
info.waitCount += 1;
}
}
if (m_cmdBuffersUsed.test(DxvkCmdBuffer::InitBuffer))
info.cmdBuffers[info.cmdBufferCount++] = m_initBuffer;
@ -108,7 +146,8 @@ namespace dxvk {
Logger::err("DxvkCommandList: Failed to reset command buffer");
if (m_vkd->vkBeginCommandBuffer(m_execBuffer, &info) != VK_SUCCESS
|| m_vkd->vkBeginCommandBuffer(m_initBuffer, &info) != VK_SUCCESS)
|| m_vkd->vkBeginCommandBuffer(m_initBuffer, &info) != VK_SUCCESS
|| m_vkd->vkBeginCommandBuffer(m_sdmaBuffer, &info) != VK_SUCCESS)
Logger::err("DxvkCommandList: Failed to begin command buffer");
if (m_vkd->vkResetFences(m_vkd->device(), 1, &m_fence) != VK_SUCCESS)
@ -122,7 +161,8 @@ namespace dxvk {
void DxvkCommandList::endRecording() {
if (m_vkd->vkEndCommandBuffer(m_execBuffer) != VK_SUCCESS
|| m_vkd->vkEndCommandBuffer(m_initBuffer) != VK_SUCCESS)
|| m_vkd->vkEndCommandBuffer(m_initBuffer) != VK_SUCCESS
|| m_vkd->vkEndCommandBuffer(m_sdmaBuffer) != VK_SUCCESS)
Logger::err("DxvkCommandList::endRecording: Failed to record command buffer");
}

View File

@ -25,6 +25,7 @@ namespace dxvk {
enum class DxvkCmdBuffer : uint32_t {
InitBuffer = 0,
ExecBuffer = 1,
SdmaBuffer = 2,
};
using DxvkCmdBufferFlags = Flags<DxvkCmdBuffer>;
@ -748,6 +749,9 @@ namespace dxvk {
VkCommandBuffer m_execBuffer = VK_NULL_HANDLE;
VkCommandBuffer m_initBuffer = VK_NULL_HANDLE;
VkCommandBuffer m_sdmaBuffer = VK_NULL_HANDLE;
VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE;
DxvkCmdBufferFlags m_cmdBuffersUsed;
DxvkLifetimeTracker m_resources;
@ -759,7 +763,10 @@ namespace dxvk {
DxvkStatCounters m_statCounters;
VkCommandBuffer getCmdBuffer(DxvkCmdBuffer cmdBuffer) const {
return cmdBuffer == DxvkCmdBuffer::ExecBuffer ? m_execBuffer : m_initBuffer;
if (cmdBuffer == DxvkCmdBuffer::ExecBuffer) return m_execBuffer;
if (cmdBuffer == DxvkCmdBuffer::InitBuffer) return m_initBuffer;
if (cmdBuffer == DxvkCmdBuffer::SdmaBuffer) return m_sdmaBuffer;
return VK_NULL_HANDLE;
}
VkResult submitToQueue(