pipelines
This commit is contained in:
		
							parent
							
								
									e7971e7bad
								
							
						
					
					
						commit
						4d575dc229
					
				@ -14,6 +14,25 @@ struct VSOutput
 | 
				
			|||||||
    float4 Pos : SV_POSITION;
 | 
					    float4 Pos : SV_POSITION;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VSOutput VsMain(VSInput input, uint vertexIndex : SV_VertexID) {
 | 
				
			||||||
 | 
					    VSOutput output = (VSOutput)0;
 | 
				
			||||||
 | 
					    return output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					            END
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            dx11 BEGIN
 | 
				
			||||||
 | 
					#include "common.hlsl"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct VSInput
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct VSOutput
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float4 Pos : SV_POSITION;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VSOutput VsMain(VSInput input, uint vertexIndex : SV_VertexID) {
 | 
					VSOutput VsMain(VSInput input, uint vertexIndex : SV_VertexID) {
 | 
				
			||||||
    VSOutput output = (VSOutput)0;
 | 
					    VSOutput output = (VSOutput)0;
 | 
				
			||||||
    return output;
 | 
					    return output;
 | 
				
			||||||
@ -27,6 +46,21 @@ struct PSOutput {
 | 
				
			|||||||
float4 Color : SV_TARGET0;
 | 
					float4 Color : SV_TARGET0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PSOutput PsMain(void) {
 | 
				
			||||||
 | 
					    PSOutput output = (PSOutput)0;
 | 
				
			||||||
 | 
					    output.Color[0] = 0;
 | 
				
			||||||
 | 
					    output.Color[1] = 0;
 | 
				
			||||||
 | 
					    output.Color[2] = 0;
 | 
				
			||||||
 | 
					    output.Color[3] = 0;
 | 
				
			||||||
 | 
					    return output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					            END
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            dx11 BEGIN
 | 
				
			||||||
 | 
					struct PSOutput {
 | 
				
			||||||
 | 
					float4 Color : SV_TARGET0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PSOutput PsMain(void) {
 | 
					PSOutput PsMain(void) {
 | 
				
			||||||
    PSOutput output = (PSOutput)0;
 | 
					    PSOutput output = (PSOutput)0;
 | 
				
			||||||
    output.Color[0] = 0;
 | 
					    output.Color[0] = 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -2,5 +2,6 @@ option('static_renderer', type : 'string', value : 'vk', description : 'Name of
 | 
				
			|||||||
option('use_xlib', type : 'boolean', value : false, description : 'Use Xlib for window creation under linux')
 | 
					option('use_xlib', type : 'boolean', value : false, description : 'Use Xlib for window creation under linux')
 | 
				
			||||||
option('error_report_debugbreak', type : 'boolean', value : true, description : 'Debugbreak in ReportError')
 | 
					option('error_report_debugbreak', type : 'boolean', value : true, description : 'Debugbreak in ReportError')
 | 
				
			||||||
option('enable_dxc_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dxc-based shader compiler.')
 | 
					option('enable_dxc_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dxc-based shader compiler.')
 | 
				
			||||||
 | 
					option('enable_dx11_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dx11-bases shader compiler.')
 | 
				
			||||||
option('game_as_subdir', type : 'boolean', value : false, description : 'If true, adds the directory "src/game" to the build.')
 | 
					option('game_as_subdir', type : 'boolean', value : false, description : 'If true, adds the directory "src/game" to the build.')
 | 
				
			||||||
option('build_dx11', type : 'boolean', value : true, description : 'Enables/disables the build of the dx11 renderer.')
 | 
					option('build_dx11', type : 'boolean', value : true, description : 'Enables/disables the build of the dx11 renderer.')
 | 
				
			||||||
@ -65,4 +65,4 @@ rt_shader_bytecode CompileShader(rt_shader_type type,
 | 
				
			|||||||
        return (rt_shader_bytecode){.bytes = NULL, .len = 0};
 | 
					        return (rt_shader_bytecode){.bytes = NULL, .len = 0};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return _compiler_funcs[type](stage, optimization, code, file_path, arena);
 | 
					    return _compiler_funcs[type](stage, optimization, code, file_path, arena);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -17,24 +17,24 @@ struct rt_render_target {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    rt_pixel_format format;
 | 
					    rt_pixel_format format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool HasStencilComponent() const {
 | 
					    uint32_t version;
 | 
				
			||||||
 | 
					    rt_render_target *next_free;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RT_INLINE bool HasStencilComponent() const {
 | 
				
			||||||
        return format == RT_PIXEL_FORMAT_DEPTH24_STENCIL8;
 | 
					        return format == RT_PIXEL_FORMAT_DEPTH24_STENCIL8;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool IsColorRenderTarget() const {
 | 
					    RT_INLINE bool IsColorRenderTarget() const {
 | 
				
			||||||
        RT_ASSERT(!(rtv != nullptr && dsv != nullptr),
 | 
					        RT_ASSERT(!(rtv != nullptr && dsv != nullptr),
 | 
				
			||||||
                  "A render target should not contain a render target and a depth stencil view");
 | 
					                  "A render target should not contain a render target and a depth stencil view");
 | 
				
			||||||
        return rtv != nullptr;
 | 
					        return rtv != nullptr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool IsDepthStencilTarget() const {
 | 
					    RT_INLINE bool IsDepthStencilTarget() const {
 | 
				
			||||||
        RT_ASSERT(!(rtv != nullptr && dsv != nullptr),
 | 
					        RT_ASSERT(!(rtv != nullptr && dsv != nullptr),
 | 
				
			||||||
                  "A render target should not contain a render target and a depth stencil view");
 | 
					                  "A render target should not contain a render target and a depth stencil view");
 | 
				
			||||||
        return dsv != nullptr;
 | 
					        return dsv != nullptr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    uint32_t version;
 | 
					 | 
				
			||||||
    rt_render_target *next_free;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct rt_command_buffer {
 | 
					struct rt_command_buffer {
 | 
				
			||||||
@ -55,8 +55,27 @@ struct rt_buffer {
 | 
				
			|||||||
    rt_buffer *next_free;
 | 
					    rt_buffer *next_free;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rt_pipeline {
 | 
				
			||||||
 | 
					    ID3D11InputLayout *input_layout;
 | 
				
			||||||
 | 
					    ID3D11VertexShader *vertex_shader;
 | 
				
			||||||
 | 
					    ID3D11PixelShader *pixel_shader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ID3D11ComputeShader *compute_shader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rt_pipeline *next_free;
 | 
				
			||||||
 | 
					    uint32_t version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RT_INLINE bool IsComputePipeline() const {
 | 
				
			||||||
 | 
					        RT_ASSERT(!(compute_shader && (vertex_shader || pixel_shader)),
 | 
				
			||||||
 | 
					                  "A pipeline should contain either a compute shader or graphics shaders.");
 | 
				
			||||||
 | 
					        return compute_shader != nullptr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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);
 | 
					rt_buffer *rtGetBuffer(rt_buffer_handle handle);
 | 
				
			||||||
 | 
					rt_pipeline *rtGetPipeline(rt_pipeline_handle handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -253,15 +253,6 @@ extern "C" {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define RETURN_HANDLE_ARRAY_STUB(out, count) RETURN_HANDLE_ARRAY_STUB2(out, count, 1)
 | 
					#define RETURN_HANDLE_ARRAY_STUB(out, count) RETURN_HANDLE_ARRAY_STUB2(out, count, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rt_pipeline_handle RT_RENDERER_API_FN(CompilePipeline)(const rt_pipeline_info *info) {
 | 
					 | 
				
			||||||
    RT_UNUSED(info);
 | 
					 | 
				
			||||||
    RETURN_HANDLE_STUB(rt_pipeline_handle);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void RT_RENDERER_API_FN(DestroyPipeline)(rt_pipeline_handle handle) {
 | 
					 | 
				
			||||||
    RT_UNUSED(handle);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rt_result RT_RENDERER_API_FN(CreateSemaphores)(uint32_t count,
 | 
					rt_result RT_RENDERER_API_FN(CreateSemaphores)(uint32_t count,
 | 
				
			||||||
                                               const rt_gpu_semaphore_info *info,
 | 
					                                               const rt_gpu_semaphore_info *info,
 | 
				
			||||||
                                               rt_gpu_semaphore_handle *p_semaphores) {
 | 
					                                               rt_gpu_semaphore_handle *p_semaphores) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										217
									
								
								src/renderer/dx11/pipelines.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								src/renderer/dx11/pipelines.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,217 @@
 | 
				
			|||||||
 | 
					#include <d3d11.h>
 | 
				
			||||||
 | 
					#include <d3d11_1.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gfx/effect.h"
 | 
				
			||||||
 | 
					#include "gfx/renderer_api.h"
 | 
				
			||||||
 | 
					#include "runtime/config.h"
 | 
				
			||||||
 | 
					#include "runtime/handles.h"
 | 
				
			||||||
 | 
					#include "runtime/mem_arena.h"
 | 
				
			||||||
 | 
					#include "runtime/threading_helpers.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "device_objects.hpp"
 | 
				
			||||||
 | 
					#include "gpu.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_CVAR_I(rt_Dx11MaxPipelines,
 | 
				
			||||||
 | 
					          "Maximum number of simultaneously existing pipelines. Default: 128",
 | 
				
			||||||
 | 
					          128);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static rt_pipeline *_pipelines;
 | 
				
			||||||
 | 
					static rt_pipeline *_first_free;
 | 
				
			||||||
 | 
					static rt_mutex *_lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rt_result InitPipelineManagement() {
 | 
				
			||||||
 | 
					    _pipelines =
 | 
				
			||||||
 | 
					        reinterpret_cast<rt_pipeline *>(calloc((size_t)rt_Dx11MaxPipelines.i, sizeof(rt_pipeline)));
 | 
				
			||||||
 | 
					    if (!_pipelines)
 | 
				
			||||||
 | 
					        return RT_OUT_OF_MEMORY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _first_free = _pipelines + 1;
 | 
				
			||||||
 | 
					    for (int i = 0; i < rt_Dx11MaxPipelines.i - 1; ++i)
 | 
				
			||||||
 | 
					        _pipelines[i].next_free = &_pipelines[i + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _lock = rtCreateMutex();
 | 
				
			||||||
 | 
					    if (!_lock) {
 | 
				
			||||||
 | 
					        free(_pipelines);
 | 
				
			||||||
 | 
					        return RT_UNKNOWN_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return RT_SUCCESS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShutdownPipelineManagement() {
 | 
				
			||||||
 | 
					    for (int i = 0; i < rt_Dx11MaxPipelines.i; ++i) {
 | 
				
			||||||
 | 
					        if (_pipelines[i].compute_shader)
 | 
				
			||||||
 | 
					            _pipelines[i].compute_shader->Release();
 | 
				
			||||||
 | 
					        if (_pipelines[i].vertex_shader)
 | 
				
			||||||
 | 
					            _pipelines[i].vertex_shader->Release();
 | 
				
			||||||
 | 
					        if (_pipelines[i].pixel_shader)
 | 
				
			||||||
 | 
					            _pipelines[i].pixel_shader->Release();
 | 
				
			||||||
 | 
					        if (_pipelines[i].input_layout)
 | 
				
			||||||
 | 
					            _pipelines[i].input_layout->Release();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    free(_pipelines);
 | 
				
			||||||
 | 
					    rtDestroyMutex(_lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rt_result GetShader(rt_resource_id id, rt_shader_info **p_shader, rt_arena *arena) {
 | 
				
			||||||
 | 
					    size_t shader_size = rtGetResourceSize(id);
 | 
				
			||||||
 | 
					    if (shader_size == 0)
 | 
				
			||||||
 | 
					        return RT_INVALID_VALUE;
 | 
				
			||||||
 | 
					    void *buffer = rtArenaPush(arena, shader_size);
 | 
				
			||||||
 | 
					    if (!buffer)
 | 
				
			||||||
 | 
					        return RT_OUT_OF_MEMORY;
 | 
				
			||||||
 | 
					    rt_result res = rtGetResource(id, buffer);
 | 
				
			||||||
 | 
					    if (res != RT_SUCCESS) {
 | 
				
			||||||
 | 
					        rtArenaPop(arena, shader_size);
 | 
				
			||||||
 | 
					        return res;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rt_resource *resource = reinterpret_cast<rt_resource *>(buffer);
 | 
				
			||||||
 | 
					    RT_ASSERT(resource->type == RT_RESOURCE_SHADER, "Expected a shader");
 | 
				
			||||||
 | 
					    *p_shader = reinterpret_cast<rt_shader_info *>(resource->data);
 | 
				
			||||||
 | 
					    return RT_SUCCESS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" rt_pipeline_handle RT_RENDERER_API_FN(CompilePipeline)(const rt_pipeline_info *info) {
 | 
				
			||||||
 | 
					    rt_pipeline *slot = nullptr;
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        auto lg = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        slot = _first_free;
 | 
				
			||||||
 | 
					        if (slot)
 | 
				
			||||||
 | 
					            _first_free = slot->next_free;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!slot) {
 | 
				
			||||||
 | 
					        rtLog("dx11", "Could not create pipeline, because no slots are available.");
 | 
				
			||||||
 | 
					        return RT_INVALID_HANDLE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rt_temp_arena temp = rtGetTemporaryArena(NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (info->vertex_shader != RT_INVALID_RESOURCE_ID) {
 | 
				
			||||||
 | 
					        rt_shader_info *vs;
 | 
				
			||||||
 | 
					        if (GetShader(info->vertex_shader, &vs, temp.arena) != RT_SUCCESS) {
 | 
				
			||||||
 | 
					            rtReportError("dx11", "Could not retrieve vertex shader data.");
 | 
				
			||||||
 | 
					            auto lg         = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					            slot->next_free = _first_free;
 | 
				
			||||||
 | 
					            _first_free     = slot;
 | 
				
			||||||
 | 
					            return RT_INVALID_HANDLE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void *bytecode = rtResolveRelptr(&vs->bytecode);
 | 
				
			||||||
 | 
					        if (FAILED(g_gpu.device->CreateVertexShader(bytecode,
 | 
				
			||||||
 | 
					                                                    vs->bytecode_length,
 | 
				
			||||||
 | 
					                                                    NULL,
 | 
				
			||||||
 | 
					                                                    &slot->vertex_shader))) {
 | 
				
			||||||
 | 
					            rtReportError("dx11", "Vertex shader creation failed");
 | 
				
			||||||
 | 
					            auto lg         = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					            slot->next_free = _first_free;
 | 
				
			||||||
 | 
					            _first_free     = slot;
 | 
				
			||||||
 | 
					            return RT_INVALID_HANDLE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: effects should specify the expected vertex layout
 | 
				
			||||||
 | 
					        // For now, we use a default
 | 
				
			||||||
 | 
					        /* clang-format off */
 | 
				
			||||||
 | 
					        D3D11_INPUT_ELEMENT_DESC default_layout[] = {
 | 
				
			||||||
 | 
					            {"POSITION", 0,  DXGI_FORMAT_R32G32B32_FLOAT, 0,                            0, D3D11_INPUT_PER_VERTEX_DATA, 0},
 | 
				
			||||||
 | 
					            {"NORMAL",   0,  DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
 | 
				
			||||||
 | 
					            {"TANGENT",  0,  DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
 | 
				
			||||||
 | 
					            {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,     0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        /* clang-format on */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (FAILED(g_gpu.device->CreateInputLayout(default_layout,
 | 
				
			||||||
 | 
					                                                   RT_ARRAY_COUNT(default_layout),
 | 
				
			||||||
 | 
					                                                   bytecode,
 | 
				
			||||||
 | 
					                                                   vs->bytecode_length,
 | 
				
			||||||
 | 
					                                                   &slot->input_layout))) {
 | 
				
			||||||
 | 
					            rtReportError("dx11", "Failed to create the vertex layout.");
 | 
				
			||||||
 | 
					            auto lg         = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					            slot->next_free = _first_free;
 | 
				
			||||||
 | 
					            _first_free     = slot;
 | 
				
			||||||
 | 
					            return RT_INVALID_HANDLE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (info->fragment_shader != RT_INVALID_RESOURCE_ID) {
 | 
				
			||||||
 | 
					        rt_shader_info *vs;
 | 
				
			||||||
 | 
					        if (GetShader(info->fragment_shader, &vs, temp.arena) != RT_SUCCESS) {
 | 
				
			||||||
 | 
					            rtReportError("dx11", "Could not retrieve fragment shader data.");
 | 
				
			||||||
 | 
					            auto lg         = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					            slot->next_free = _first_free;
 | 
				
			||||||
 | 
					            _first_free     = slot;
 | 
				
			||||||
 | 
					            return RT_INVALID_HANDLE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void *bytecode = rtResolveRelptr(&vs->bytecode);
 | 
				
			||||||
 | 
					        if (FAILED(g_gpu.device->CreatePixelShader(bytecode,
 | 
				
			||||||
 | 
					                                                   vs->bytecode_length,
 | 
				
			||||||
 | 
					                                                   NULL,
 | 
				
			||||||
 | 
					                                                   &slot->pixel_shader))) {
 | 
				
			||||||
 | 
					            rtReportError("dx11", "Fragment shader creation failed");
 | 
				
			||||||
 | 
					            auto lg         = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					            slot->next_free = _first_free;
 | 
				
			||||||
 | 
					            _first_free     = slot;
 | 
				
			||||||
 | 
					            return RT_INVALID_HANDLE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (info->compute_shader != RT_INVALID_RESOURCE_ID) {
 | 
				
			||||||
 | 
					        rt_shader_info *vs;
 | 
				
			||||||
 | 
					        if (GetShader(info->compute_shader, &vs, temp.arena) != RT_SUCCESS) {
 | 
				
			||||||
 | 
					            rtReportError("dx11", "Could not retrieve compute shader data.");
 | 
				
			||||||
 | 
					            auto lg         = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					            slot->next_free = _first_free;
 | 
				
			||||||
 | 
					            _first_free     = slot;
 | 
				
			||||||
 | 
					            return RT_INVALID_HANDLE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void *bytecode = rtResolveRelptr(&vs->bytecode);
 | 
				
			||||||
 | 
					        if (FAILED(g_gpu.device->CreateComputeShader(bytecode,
 | 
				
			||||||
 | 
					                                                     vs->bytecode_length,
 | 
				
			||||||
 | 
					                                                     NULL,
 | 
				
			||||||
 | 
					                                                     &slot->compute_shader))) {
 | 
				
			||||||
 | 
					            rtReportError("dx11", "Compute shader creation failed");
 | 
				
			||||||
 | 
					            auto lg         = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					            slot->next_free = _first_free;
 | 
				
			||||||
 | 
					            _first_free     = slot;
 | 
				
			||||||
 | 
					            return RT_INVALID_HANDLE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    slot->version  = (slot->version + 1) % RT_RENDER_BACKEND_HANDLE_MAX_VERSION;
 | 
				
			||||||
 | 
					    uint32_t index = static_cast<uint32_t>(slot - _pipelines);
 | 
				
			||||||
 | 
					    return {slot->version, index};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" void RT_RENDERER_API_FN(DestroyPipeline)(rt_pipeline_handle handle) {
 | 
				
			||||||
 | 
					    if (!RT_IS_HANDLE_VALID(handle) || (int)handle.index >= rt_Dx11MaxPipelines.i)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    auto lg = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					    if (handle.version != _pipelines[handle.index].version)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_pipelines[handle.index].compute_shader)
 | 
				
			||||||
 | 
					        _pipelines[handle.index].compute_shader->Release();
 | 
				
			||||||
 | 
					    if (_pipelines[handle.index].vertex_shader)
 | 
				
			||||||
 | 
					        _pipelines[handle.index].vertex_shader->Release();
 | 
				
			||||||
 | 
					    if (_pipelines[handle.index].pixel_shader)
 | 
				
			||||||
 | 
					        _pipelines[handle.index].pixel_shader->Release();
 | 
				
			||||||
 | 
					    if (_pipelines[handle.index].input_layout)
 | 
				
			||||||
 | 
					        _pipelines[handle.index].input_layout->Release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _pipelines[handle.index].next_free = _first_free;
 | 
				
			||||||
 | 
					    _pipelines[handle.index].version =
 | 
				
			||||||
 | 
					        (_pipelines[handle.index].version + 1) % RT_RENDER_BACKEND_HANDLE_MAX_VERSION;
 | 
				
			||||||
 | 
					    _first_free = &_pipelines[handle.index];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rt_pipeline *rtGetPipeline(rt_pipeline_handle handle) {
 | 
				
			||||||
 | 
					    if (!RT_IS_HANDLE_VALID(handle) || (int)handle.index >= rt_Dx11MaxPipelines.i)
 | 
				
			||||||
 | 
					        return nullptr;
 | 
				
			||||||
 | 
					    auto lg = rtAutoLock(_lock);
 | 
				
			||||||
 | 
					    if (handle.version != _pipelines[handle.index].version)
 | 
				
			||||||
 | 
					        return nullptr;
 | 
				
			||||||
 | 
					    return &_pipelines[handle.index];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user