diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 8a9d5c0a5..07f38208f 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2054,6 +2054,37 @@ namespace dxvk { } + void DxvkContext::uploadBuffer( + const Rc& buffer, + const void* data) { + auto bufferSlice = buffer->getSliceHandle(); + + auto stagingSlice = m_staging.alloc(CACHE_LINE_SIZE, bufferSlice.length); + auto stagingHandle = stagingSlice.getSliceHandle(); + std::memcpy(stagingHandle.mapPtr, data, bufferSlice.length); + + VkBufferCopy region; + region.srcOffset = stagingHandle.offset; + region.dstOffset = bufferSlice.offset; + region.size = bufferSlice.length; + + m_cmd->cmdCopyBuffer(DxvkCmdBuffer::SdmaBuffer, + stagingHandle.handle, bufferSlice.handle, 1, ®ion); + + 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); + + m_cmd->trackResource(stagingSlice.buffer()); + m_cmd->trackResource(buffer); + } + + void DxvkContext::setViewports( uint32_t viewportCount, const VkViewport* viewports, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index d22b84d0d..013630cfc 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -772,6 +772,17 @@ namespace dxvk { VkDeviceSize pitchPerLayer, VkFormat format); + /** + * \brief Uses transfer queue to initialize buffer + * + * Only safe to use if the buffer is not in use by the GPU. + * \param [in] buffer The buffer to initialize + * \param [in] data The data to copy to the buffer + */ + void uploadBuffer( + const Rc& buffer, + const void* data); + /** * \brief Sets viewports *