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,8 +3,7 @@
namespace dxvk {
DxvkUnboundResources::DxvkUnboundResources(DxvkDevice* dev)
: m_sampler (createSampler(dev)),
m_buffer (createBuffer(dev)) {
: m_device(dev) {
}
@ -14,7 +13,47 @@ namespace dxvk {
}
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;
info.minFilter = VK_FILTER_LINEAR;
info.magFilter = VK_FILTER_LINEAR;
@ -34,11 +73,11 @@ namespace dxvk {
info.usePixelCoord = 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;
info.size = MaxUniformBufferSize;
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
@ -50,12 +89,12 @@ namespace dxvk {
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
| dev->getShaderPipelineStages();
| m_device->getShaderPipelineStages();
info.access = VK_ACCESS_UNIFORM_READ_BIT
| VK_ACCESS_SHADER_READ_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_COHERENT_BIT |
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

View File

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