This commit is contained in:
Kevin Trogant 2024-04-03 21:54:09 +02:00
parent 565c330f71
commit 2651ce2e9d
4 changed files with 158 additions and 13 deletions

View File

@ -0,0 +1,146 @@
#include <d3d11.h>
#include <d3d11_1.h>
#include "gfx/renderer_api.h"
#include "runtime/config.h"
#include "runtime/handles.h"
#include "runtime/threading_helpers.hpp"
#include "device_objects.hpp"
#include "gpu.hpp"
RT_CVAR_I(rt_Dx11MaxBuffers,
"Maximum number of simultaneously existing buffers. Default: 4096",
4096);
static rt_buffer *_buffers;
static rt_buffer *_first_free;
static rt_mutex *_lock;
rt_result InitBufferManagement() {
_buffers =
reinterpret_cast<rt_buffer *>(calloc((size_t)rt_Dx11MaxBuffers.i, sizeof(rt_buffer)));
if (!_buffers) {
return RT_OUT_OF_MEMORY;
}
_lock = rtCreateMutex();
if (!_lock) {
free(_buffers);
return RT_UNKNOWN_ERROR;
}
_first_free = _buffers + 2;
for (int i = 0; i < rt_Dx11MaxBuffers.i; ++i) {
_buffers[i].next_free = &_buffers[i + 1];
}
return RT_SUCCESS;
}
void ShutdownBufferManagement() {
for (int i = 0; i < rt_Dx11MaxBuffers.i; ++i) {
if (_buffers[i].buffer)
_buffers[i].buffer->Release();
}
free(_buffers);
rtDestroyMutex(_lock);
}
rt_buffer *rtGetBuffer(rt_buffer_handle handle) {
if (!RT_IS_HANDLE_VALID(handle) || (int)handle.index >= rt_Dx11MaxBuffers.i)
return nullptr;
auto lg = rtAutoLock(_lock);
if (handle.version != _buffers[handle.index].version)
return nullptr;
return &_buffers[handle.index];
}
extern "C" rt_result RT_RENDERER_API_FN(CreateBuffers)(uint32_t count,
const rt_buffer_info *info,
rt_buffer_handle *p_buffers) {
for (uint32_t i = 0; i < count; ++i) {
rtLockMutex(_lock);
rt_buffer *slot = _first_free;
if (slot)
_first_free = slot->next_free;
rtUnlockMutex(_lock);
if (!slot) {
rtLog("dx11", "Failed to allocate a command buffer slot.");
rtLockMutex(_lock);
for (uint32_t j = 0; j < i; ++j) {
rt_buffer *s = &_buffers[p_buffers[j].index];
s->next_free = _first_free;
_first_free = s;
_first_free = s;
}
rtUnlockMutex(_lock);
return RT_OUT_OF_MEMORY;
}
D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
if (info[i].usage == RT_BUFFER_USAGE_STATIC) {
usage = D3D11_USAGE_IMMUTABLE;
} else if (info[i].usage == RT_BUFFER_USAGE_DYNAMIC) {
usage = D3D11_USAGE_DEFAULT;
} else if (info[i].usage == RT_BUFFER_USAGE_TRANSIENT) {
usage = D3D11_USAGE_DYNAMIC;
}
UINT bind_flags = D3D11_BIND_UNORDERED_ACCESS;
if (info[i].type == RT_BUFFER_TYPE_VERTEX)
bind_flags = D3D11_BIND_VERTEX_BUFFER;
else if (info[i].type == RT_BUFFER_TYPE_INDEX)
bind_flags = D3D11_BIND_INDEX_BUFFER;
else if (info[i].type == RT_BUFFER_TYPE_UNIFORM)
bind_flags = D3D11_BIND_CONSTANT_BUFFER;
else if (info[i].type == RT_BUFFER_TYPE_STORAGE)
bind_flags = D3D11_BIND_UNORDERED_ACCESS;
D3D11_BUFFER_DESC desc = {};
desc.ByteWidth = static_cast<UINT>(((info[i].size + 15) / 16) * 16);
desc.Usage = usage;
desc.BindFlags = bind_flags;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.StructureByteStride = 1;
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = info->data;
data.SysMemPitch = 0;
data.SysMemSlicePitch = 0;
if (FAILED(
g_gpu.device->CreateBuffer(&desc, info[i].data ? &data : nullptr, &slot->buffer))) {
rtLog("dx11", "Failed to create a deferred context.");
auto lock_guard = rtAutoLock(_lock);
for (uint32_t j = 0; j < i; ++j) {
rt_buffer *s = &_buffers[p_buffers[j].index];
s->next_free = _first_free;
_first_free = s;
}
return RT_UNKNOWN_ERROR;
}
slot->version = (slot->version + 1) % RT_RENDER_BACKEND_HANDLE_MAX_VERSION;
const uint32_t index = (uint32_t)(slot - _buffers);
p_buffers[i].version = slot->version;
p_buffers[i].index = index;
}
return RT_SUCCESS;
}
extern "C" void RT_RENDERER_API_FN(DestroyBuffers)(uint32_t count, rt_buffer_handle *buffers) {
for (uint32_t i = 0; i < count; ++i) {
if (!RT_IS_HANDLE_VALID(buffers[i]) || (int)buffers[i].index >= rt_Dx11MaxBuffers.i)
continue;
auto lg = rtAutoLock(_lock);
if (buffers[i].version != _buffers[buffers[i].index].version)
continue;
_buffers[buffers[i].index].buffer->Release();
_buffers[buffers[i].index].next_free = _first_free;
_first_free = &_buffers[buffers[i].index];
}
}

View File

@ -39,7 +39,17 @@ struct rt_command_buffer {
rt_command_buffer *next_free; rt_command_buffer *next_free;
}; };
struct rt_buffer {
ID3D11Buffer *buffer;
rt_buffer_type type;
rt_buffer_usage usage;
uint32_t version;
rt_buffer *next_free;
};
rt_render_target *rtGetRenderTarget(rt_render_target_handle handle); rt_render_target *rtGetRenderTarget(rt_render_target_handle handle);
rt_command_buffer *rtGetCommandBuffer(rt_command_buffer_handle handle); rt_command_buffer *rtGetCommandBuffer(rt_command_buffer_handle handle);
rt_buffer *rtGetBuffer(rt_buffer_handle handle);
#endif #endif

View File

@ -283,6 +283,7 @@ uint64_t RT_RENDERER_API_FN(GetSemaphoreValue)(rt_gpu_semaphore_handle sem) {
return 0; return 0;
} }
rt_gpu_semaphore_handle RT_RENDERER_API_FN(GetSwapchainAvailableSemaphore)(void) { rt_gpu_semaphore_handle RT_RENDERER_API_FN(GetSwapchainAvailableSemaphore)(void) {
return {1, 1}; return {1, 1};
} }
@ -291,19 +292,6 @@ rt_gpu_semaphore_handle RT_RENDERER_API_FN(GetRenderFinishedSemaphore)(void) {
return {1, 2}; return {1, 2};
} }
rt_result RT_RENDERER_API_FN(CreateBuffers)(uint32_t count,
const rt_buffer_info *info,
rt_buffer_handle *p_buffers) {
RT_UNUSED(info);
RETURN_HANDLE_ARRAY_STUB(p_buffers, count);
return RT_SUCCESS;
}
void RT_RENDERER_API_FN(DestroyBuffers)(uint32_t count, rt_buffer_handle *buffers) {
RT_UNUSED(count);
RT_UNUSED(buffers);
}
void RT_RENDERER_API_FN(CmdBeginPass)(rt_command_buffer_handle cmd, void RT_RENDERER_API_FN(CmdBeginPass)(rt_command_buffer_handle cmd,
const rt_cmd_begin_pass_info *info) { const rt_cmd_begin_pass_info *info) {
RT_UNUSED(cmd); RT_UNUSED(cmd);

View File

@ -4,6 +4,7 @@ if get_option('build_dx11')
'device_objects.hpp', 'device_objects.hpp',
'gpu.hpp', 'gpu.hpp',
'buffers.cpp',
'command_buffers.cpp', 'command_buffers.cpp',
'helpers.cpp', 'helpers.cpp',
'init.cpp', 'init.cpp',