buffers
This commit is contained in:
parent
565c330f71
commit
2651ce2e9d
146
src/renderer/dx11/buffers.cpp
Normal file
146
src/renderer/dx11/buffers.cpp
Normal 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];
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
@ -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);
|
||||||
|
@ -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',
|
||||||
|
Loading…
Reference in New Issue
Block a user