diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 041f758a3..66baa6add 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -429,6 +429,13 @@ namespace dxvk { m_initializer->NotifyContextFlush(); } + void InitShaderIcb( + D3D11CommonShader* pShader, + size_t IcbSize, + const void* pIcbData) { + return m_initializer->InitShaderIcb(pShader, IcbSize, pIcbData); + } + VkPipelineStageFlags GetEnabledShaderStages() const { return m_dxvkDevice->getShaderPipelineStages(); } diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index 60e6fda5f..13b9cb6b0 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -77,6 +77,33 @@ namespace dxvk { } + void D3D11Initializer::InitShaderIcb( + D3D11CommonShader* pShader, + size_t IcbSize, + const void* pIcbData) { + std::lock_guard lock(m_mutex); + m_transferCommands += 1; + + auto icbSlice = pShader->GetIcb(); + auto srcSlice = m_stagingBuffer.alloc(icbSlice.length()); + + std::memcpy(srcSlice.mapPtr(0), pIcbData, IcbSize); + + if (IcbSize < icbSlice.length()) + std::memset(srcSlice.mapPtr(IcbSize), 0, icbSlice.length() - IcbSize); + + EmitCs([ + cIcbSlice = std::move(icbSlice), + cSrcSlice = std::move(srcSlice) + ] (DxvkContext* ctx) { + ctx->copyBuffer(cIcbSlice.buffer(), cIcbSlice.offset(), + cSrcSlice.buffer(), cSrcSlice.offset(), cIcbSlice.length()); + }); + + ThrottleAllocationLocked(); + } + + void D3D11Initializer::InitDeviceLocalBuffer( D3D11Buffer* pBuffer, const D3D11_SUBRESOURCE_DATA* pInitialData) { diff --git a/src/d3d11/d3d11_initializer.h b/src/d3d11/d3d11_initializer.h index b8fbee7cc..04e1aa61f 100644 --- a/src/d3d11/d3d11_initializer.h +++ b/src/d3d11/d3d11_initializer.h @@ -3,7 +3,9 @@ #include "../dxvk/dxvk_staging.h" #include "d3d11_buffer.h" +#include "d3d11_shader.h" #include "d3d11_texture.h" +#include "d3d11_view_uav.h" namespace dxvk { @@ -57,6 +59,11 @@ namespace dxvk { void InitUavCounter( D3D11UnorderedAccessView* pUav); + void InitShaderIcb( + D3D11CommonShader* pShader, + size_t IcbSize, + const void* pIcbData); + private: dxvk::mutex m_mutex; @@ -117,4 +124,4 @@ namespace dxvk { }; -} \ No newline at end of file +} diff --git a/src/d3d11/d3d11_shader.cpp b/src/d3d11/d3d11_shader.cpp index e83f0dee5..cfa11d313 100644 --- a/src/d3d11/d3d11_shader.cpp +++ b/src/d3d11/d3d11_shader.cpp @@ -64,19 +64,17 @@ namespace dxvk { if (icb.size) { DxvkBufferCreateInfo info = { }; info.size = align(icb.size, 256u); - info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT + | VK_BUFFER_USAGE_TRANSFER_DST_BIT; info.stages = util::pipelineStages(m_shader->info().stage); - info.access = VK_ACCESS_UNIFORM_READ_BIT; + info.access = VK_ACCESS_UNIFORM_READ_BIT + | VK_ACCESS_TRANSFER_WRITE_BIT; info.debugName = "Icb"; - VkMemoryPropertyFlags memFlags - = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT - | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT - | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - - m_buffer = pDevice->GetDXVKDevice()->createBuffer(info, memFlags); - std::memcpy(m_buffer->mapPtr(0), icb.data, icb.size); - std::memset(m_buffer->mapPtr(icb.size), 0, info.size - icb.size); + m_buffer = pDevice->GetDXVKDevice()->createBuffer(info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + // Upload immediate constant buffer to VRAM + pDevice->InitShaderIcb(this, icb.size, icb.data); } pDevice->GetDXVKDevice()->registerShader(m_shader);