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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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_command_buffer *rtGetCommandBuffer(rt_command_buffer_handle handle);
 | 
			
		||||
rt_buffer *rtGetBuffer(rt_buffer_handle handle);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -283,6 +283,7 @@ uint64_t RT_RENDERER_API_FN(GetSemaphoreValue)(rt_gpu_semaphore_handle sem) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
rt_gpu_semaphore_handle RT_RENDERER_API_FN(GetSwapchainAvailableSemaphore)(void) {
 | 
			
		||||
    return {1, 1};
 | 
			
		||||
}
 | 
			
		||||
@ -291,19 +292,6 @@ rt_gpu_semaphore_handle RT_RENDERER_API_FN(GetRenderFinishedSemaphore)(void) {
 | 
			
		||||
    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,
 | 
			
		||||
                                      const rt_cmd_begin_pass_info *info) {
 | 
			
		||||
    RT_UNUSED(cmd);
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ if get_option('build_dx11')
 | 
			
		||||
        'device_objects.hpp',
 | 
			
		||||
        'gpu.hpp',
 | 
			
		||||
 | 
			
		||||
        'buffers.cpp',
 | 
			
		||||
        'command_buffers.cpp',
 | 
			
		||||
        'helpers.cpp',
 | 
			
		||||
        'init.cpp',
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user