mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[d3d9] Introduce D3D9ConstantBuffer
This commit is contained in:
parent
bcd2be0698
commit
e8d5ce94ea
121
src/d3d9/d3d9_constant_buffer.cpp
Normal file
121
src/d3d9/d3d9_constant_buffer.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#include "d3d9_constant_buffer.h"
|
||||
#include "d3d9_device.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D9ConstantBuffer::D3D9ConstantBuffer() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
D3D9ConstantBuffer::D3D9ConstantBuffer(
|
||||
D3D9DeviceEx* pDevice,
|
||||
DxsoProgramType ShaderStage,
|
||||
DxsoConstantBuffers BufferType,
|
||||
VkDeviceSize Size)
|
||||
: m_device (pDevice)
|
||||
, m_binding (computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, BufferType))
|
||||
, m_stages (GetShaderStage(ShaderStage))
|
||||
, m_size (Size)
|
||||
, m_align (getAlignment(pDevice->GetDXVKDevice())) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
D3D9ConstantBuffer::~D3D9ConstantBuffer() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void* D3D9ConstantBuffer::Alloc(VkDeviceSize size) {
|
||||
if (unlikely(m_buffer == nullptr)) {
|
||||
this->createBuffer();
|
||||
m_slice = m_buffer->getSliceHandle();
|
||||
}
|
||||
|
||||
size = align(size, m_align);
|
||||
|
||||
if (unlikely(m_offset + size > m_size)) {
|
||||
m_slice = m_buffer->allocSlice();
|
||||
m_offset = 0;
|
||||
|
||||
m_device->EmitCs([
|
||||
cBuffer = m_buffer,
|
||||
cSlice = m_slice
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->invalidateBuffer(cBuffer, cSlice);
|
||||
});
|
||||
}
|
||||
|
||||
m_device->EmitCs([
|
||||
cStages = m_stages,
|
||||
cBinding = m_binding,
|
||||
cOffset = m_offset,
|
||||
cLength = size
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->bindResourceBufferRange(cStages, cBinding, cOffset, cLength);
|
||||
});
|
||||
|
||||
void* mapPtr = reinterpret_cast<char*>(m_slice.mapPtr) + m_offset;
|
||||
m_offset += size;
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
|
||||
void* D3D9ConstantBuffer::AllocSlice() {
|
||||
if (unlikely(m_buffer == nullptr))
|
||||
this->createBuffer();
|
||||
|
||||
m_slice = m_buffer->allocSlice();
|
||||
|
||||
m_device->EmitCs([
|
||||
cBuffer = m_buffer,
|
||||
cSlice = m_slice
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->invalidateBuffer(cBuffer, cSlice);
|
||||
});
|
||||
|
||||
return m_slice.mapPtr;
|
||||
}
|
||||
|
||||
|
||||
void D3D9ConstantBuffer::createBuffer() {
|
||||
auto options = m_device->GetOptions();
|
||||
|
||||
// Buffer usage and access flags don't make much of a difference
|
||||
// in the backend, so set both STORAGE and UNIFORM usage/access.
|
||||
DxvkBufferCreateInfo bufferInfo;
|
||||
bufferInfo.size = align(m_size, m_align);
|
||||
bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT
|
||||
| VK_ACCESS_SHADER_READ_BIT;
|
||||
bufferInfo.stages = util::pipelineStages(m_stages);
|
||||
|
||||
VkMemoryPropertyFlags memoryFlags
|
||||
= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
||||
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||
|
||||
if (options->deviceLocalConstantBuffers)
|
||||
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
m_buffer = m_device->GetDXVKDevice()->createBuffer(bufferInfo, memoryFlags);
|
||||
|
||||
m_device->EmitCs([
|
||||
cStages = m_stages,
|
||||
cBinding = m_binding,
|
||||
cSlice = DxvkBufferSlice(m_buffer)
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->bindResourceBuffer(cStages, cBinding, cSlice);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
VkDeviceSize D3D9ConstantBuffer::getAlignment(const Rc<DxvkDevice>& device) const {
|
||||
return std::max(std::max(
|
||||
device->properties().core.properties.limits.minUniformBufferOffsetAlignment,
|
||||
device->properties().core.properties.limits.minStorageBufferOffsetAlignment),
|
||||
device->properties().extRobustness2.robustUniformBufferAccessSizeAlignment);
|
||||
}
|
||||
|
||||
}
|
77
src/d3d9/d3d9_constant_buffer.h
Normal file
77
src/d3d9/d3d9_constant_buffer.h
Normal file
@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include "../dxvk/dxvk_buffer.h"
|
||||
|
||||
#include "../dxso/dxso_util.h"
|
||||
|
||||
#include "../util/util_math.h"
|
||||
|
||||
#include "d3d9_include.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D9DeviceEx;
|
||||
|
||||
/**
|
||||
* \brief Constant buffer
|
||||
*/
|
||||
class D3D9ConstantBuffer {
|
||||
|
||||
public:
|
||||
|
||||
D3D9ConstantBuffer();
|
||||
|
||||
D3D9ConstantBuffer(
|
||||
D3D9DeviceEx* pDevice,
|
||||
DxsoProgramType ShaderStage,
|
||||
DxsoConstantBuffers BufferType,
|
||||
VkDeviceSize Size);
|
||||
|
||||
~D3D9ConstantBuffer();
|
||||
|
||||
/**
|
||||
* \brief Queries alignment
|
||||
*
|
||||
* Useful to pad copies with initialized data.
|
||||
* \returns Data alignment
|
||||
*/
|
||||
VkDeviceSize GetAlignment() const {
|
||||
return m_align;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates a given amount of memory
|
||||
*
|
||||
* \param [in] size Number of bytes to allocate
|
||||
* \returns Map pointer of the allocated region
|
||||
*/
|
||||
void* Alloc(VkDeviceSize size);
|
||||
|
||||
/**
|
||||
* \brief Allocates a full buffer slice
|
||||
*
|
||||
* This must not be called if \ref Alloc is used.
|
||||
* \returns Map pointer of the allocated region
|
||||
*/
|
||||
void* AllocSlice();
|
||||
|
||||
private:
|
||||
|
||||
D3D9DeviceEx* m_device = nullptr;
|
||||
|
||||
uint32_t m_binding = 0u;
|
||||
VkShaderStageFlags m_stages = 0u;
|
||||
VkDeviceSize m_size = 0ull;
|
||||
VkDeviceSize m_align = 0ull;
|
||||
VkDeviceSize m_offset = 0ull;
|
||||
|
||||
Rc<DxvkBuffer> m_buffer = nullptr;
|
||||
DxvkBufferSliceHandle m_slice = { };
|
||||
|
||||
void createBuffer();
|
||||
|
||||
VkDeviceSize getAlignment(const Rc<DxvkDevice>& device) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
#include "d3d9_format.h"
|
||||
#include "d3d9_multithread.h"
|
||||
#include "d3d9_adapter.h"
|
||||
#include "d3d9_constant_buffer.h"
|
||||
#include "d3d9_constant_set.h"
|
||||
|
||||
#include "d3d9_state.h"
|
||||
@ -99,6 +100,7 @@ namespace dxvk {
|
||||
constexpr static uint32_t NullStreamIdx = caps::MaxStreams;
|
||||
|
||||
friend class D3D9SwapChainEx;
|
||||
friend class D3D9ConstantBuffer;
|
||||
friend class D3D9UserDefinedAnnotation;
|
||||
public:
|
||||
|
||||
|
@ -20,6 +20,7 @@ d3d9_src = [
|
||||
'd3d9_swapchain.cpp',
|
||||
'd3d9_format.cpp',
|
||||
'd3d9_common_texture.cpp',
|
||||
'd3d9_constant_buffer.cpp',
|
||||
'd3d9_texture.cpp',
|
||||
'd3d9_surface.cpp',
|
||||
'd3d9_volume.cpp',
|
||||
|
Loading…
x
Reference in New Issue
Block a user