1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-12 13:08:50 +01:00

[dxvk] Create dummy sampler and buffer on demand

We only need the dummy buffer for transform feedback, all other cases
are handled by null descriptors. May save a memory allocation.
This commit is contained in:
Philip Rebohle 2023-03-01 12:10:48 +01:00
parent 2be0d6842e
commit f4b91817fe
2 changed files with 63 additions and 20 deletions

View File

@ -3,18 +3,57 @@
namespace dxvk { namespace dxvk {
DxvkUnboundResources::DxvkUnboundResources(DxvkDevice* dev) DxvkUnboundResources::DxvkUnboundResources(DxvkDevice* dev)
: m_sampler (createSampler(dev)), : m_device(dev) {
m_buffer (createBuffer(dev)) {
} }
DxvkUnboundResources::~DxvkUnboundResources() { DxvkUnboundResources::~DxvkUnboundResources() {
} }
Rc<DxvkSampler> DxvkUnboundResources::createSampler(DxvkDevice* dev) { VkBuffer DxvkUnboundResources::bufferHandle() {
VkBuffer buffer = m_bufferHandle.load();
if (likely(buffer != VK_NULL_HANDLE))
return buffer;
std::lock_guard lock(m_mutex);
buffer = m_bufferHandle.load();
if (buffer)
return buffer;
m_buffer = createBuffer();
buffer = m_buffer->getSliceHandle().handle;
m_bufferHandle.store(buffer, std::memory_order_release);
return buffer;
}
VkSampler DxvkUnboundResources::samplerHandle() {
VkSampler sampler = m_samplerHandle.load();
if (likely(sampler != VK_NULL_HANDLE))
return sampler;
std::lock_guard lock(m_mutex);
sampler = m_samplerHandle.load();
if (sampler)
return sampler;
m_sampler = createSampler();
sampler = m_sampler->handle();
m_samplerHandle.store(sampler, std::memory_order_release);
return sampler;
}
Rc<DxvkSampler> DxvkUnboundResources::createSampler() {
DxvkSamplerCreateInfo info; DxvkSamplerCreateInfo info;
info.minFilter = VK_FILTER_LINEAR; info.minFilter = VK_FILTER_LINEAR;
info.magFilter = VK_FILTER_LINEAR; info.magFilter = VK_FILTER_LINEAR;
@ -34,11 +73,11 @@ namespace dxvk {
info.usePixelCoord = VK_FALSE; info.usePixelCoord = VK_FALSE;
info.nonSeamless = VK_FALSE; info.nonSeamless = VK_FALSE;
return dev->createSampler(info); return m_device->createSampler(info);
} }
Rc<DxvkBuffer> DxvkUnboundResources::createBuffer(DxvkDevice* dev) { Rc<DxvkBuffer> DxvkUnboundResources::createBuffer() {
DxvkBufferCreateInfo info; DxvkBufferCreateInfo info;
info.size = MaxUniformBufferSize; info.size = MaxUniformBufferSize;
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
@ -50,12 +89,12 @@ namespace dxvk {
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT; | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
| dev->getShaderPipelineStages(); | m_device->getShaderPipelineStages();
info.access = VK_ACCESS_UNIFORM_READ_BIT info.access = VK_ACCESS_UNIFORM_READ_BIT
| VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_READ_BIT
| VK_ACCESS_SHADER_WRITE_BIT; | VK_ACCESS_SHADER_WRITE_BIT;
Rc<DxvkBuffer> buffer = dev->createBuffer(info, Rc<DxvkBuffer> buffer = m_device->createBuffer(info,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <mutex>
#include "dxvk_buffer.h" #include "dxvk_buffer.h"
#include "dxvk_image.h" #include "dxvk_image.h"
#include "dxvk_sampler.h" #include "dxvk_sampler.h"
@ -30,9 +32,7 @@ namespace dxvk {
* and index buffers. * and index buffers.
* \returns Dummy buffer handle * \returns Dummy buffer handle
*/ */
VkBuffer bufferHandle() const { VkBuffer bufferHandle();
return m_buffer->getSliceHandle().handle;
}
/** /**
* \brief Dummy sampler descriptor * \brief Dummy sampler descriptor
@ -42,18 +42,22 @@ namespace dxvk {
* still require different behaviour. * still require different behaviour.
* \returns Dummy sampler descriptor * \returns Dummy sampler descriptor
*/ */
VkSampler samplerHandle() const { VkSampler samplerHandle();
return m_sampler->handle();
}
private: private:
Rc<DxvkSampler> m_sampler; DxvkDevice* m_device;
Rc<DxvkBuffer> m_buffer;
std::atomic<VkSampler> m_samplerHandle = { VK_NULL_HANDLE };
std::atomic<VkBuffer> m_bufferHandle = { VK_NULL_HANDLE };
std::mutex m_mutex;
Rc<DxvkSampler> m_sampler;
Rc<DxvkBuffer> m_buffer;
Rc<DxvkSampler> createSampler(DxvkDevice* dev); Rc<DxvkSampler> createSampler();
Rc<DxvkBuffer> createBuffer(DxvkDevice* dev); Rc<DxvkBuffer> createBuffer();
}; };