validate dx12 root signature presence. create debug log arena before registering callback
This commit is contained in:
parent
c9cd9d0b18
commit
54a8a45835
@ -1,4 +1,4 @@
|
|||||||
#include "shaders/common.hlsl"
|
#include "gpu/common.hlsl"
|
||||||
|
|
||||||
struct instance {
|
struct instance {
|
||||||
float2x3 xf;
|
float2x3 xf;
|
||||||
@ -17,17 +17,17 @@ struct constants {
|
|||||||
* Root Signature
|
* Root Signature
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#define SIG \
|
#define ROOTSIG \
|
||||||
"CBV(b0), " \
|
"CBV(b0), " \
|
||||||
"DescriptorTable(SRV(t0), SRV(t1)), " \
|
"DescriptorTable(SRV(t0), SRV(t1)), " \
|
||||||
"DescriptorTable(Sampler(s0))"
|
"DescriptorTable(Sampler(s0))"
|
||||||
|
|
||||||
cbuffer c : register(b0)
|
cbuffer cbuff : register(b0)
|
||||||
{
|
{
|
||||||
struct constants g_constants;
|
struct constants g_constants;
|
||||||
};
|
};
|
||||||
|
|
||||||
StructuredBuffer<instance> g_instance_buffer : register(t0);
|
StructuredBuffer<struct instance> g_instances : register(t0);
|
||||||
|
|
||||||
Texture2D g_texture : register(t1);
|
Texture2D g_texture : register(t1);
|
||||||
|
|
||||||
@ -57,15 +57,15 @@ struct vs_output {
|
|||||||
DECL(float4, tint_lin);
|
DECL(float4, tint_lin);
|
||||||
};
|
};
|
||||||
|
|
||||||
[RootSignature(SIG)]
|
[RootSignature(ROOTSIG)]
|
||||||
vs_output vs_main(uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID)
|
struct vs_output vs(uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID)
|
||||||
{
|
{
|
||||||
instance instance = g_instance_buffer[g_constants.instance_offset + instance_id];
|
struct instance instance = g_instances[g_constants.instance_offset + instance_id];
|
||||||
float2 vert = g_quad_verts[vertex_id];
|
float2 vert = g_quad_verts[vertex_id];
|
||||||
float2 uv_factor = g_uv_factors[vertex_id];
|
float2 uv_factor = g_uv_factors[vertex_id];
|
||||||
float2 world_pos = mul(instance.xf, float3(vert, 1)).xy;
|
float2 world_pos = mul(instance.xf, float3(vert, 1)).xy;
|
||||||
|
|
||||||
vs_output output;
|
struct vs_output output;
|
||||||
output.screen_pos = mul(g_constants.projection, float4(world_pos, 0, 1));
|
output.screen_pos = mul(g_constants.projection, float4(world_pos, 0, 1));
|
||||||
output.uv = instance.uv0 + uv_factor * (instance.uv1 - instance.uv0);
|
output.uv = instance.uv0 + uv_factor * (instance.uv1 - instance.uv0);
|
||||||
output.tint_lin = linear_from_srgb32(instance.tint_srgb);
|
output.tint_lin = linear_from_srgb32(instance.tint_srgb);
|
||||||
@ -77,8 +77,8 @@ vs_output vs_main(uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID
|
|||||||
* Pixel shader
|
* Pixel shader
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
[RootSignature(SIG)]
|
[RootSignature(ROOTSIG)]
|
||||||
float4 ps_main(vs_output input) : SV_TARGET
|
float4 ps(struct vs_output input) : SV_TARGET
|
||||||
{
|
{
|
||||||
float4 color = g_texture.Sample(g_sampler, input.uv) * input.tint_lin;
|
float4 color = g_texture.Sample(g_sampler, input.uv) * input.tint_lin;
|
||||||
return color;
|
return color;
|
||||||
@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define DX12_TEST 0
|
#define DX12_TEST 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
294
src/gpu_dx12.c
294
src/gpu_dx12.c
@ -43,20 +43,23 @@
|
|||||||
# define DX12_SHADER_DEBUG 0
|
# define DX12_SHADER_DEBUG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum pipeline_desc_flags {
|
struct shader_desc {
|
||||||
PIPELINE_DESC_FLAG_NONE = 0,
|
char *file;
|
||||||
PIPELINE_DESC_FLAG_VS = (1 << 0),
|
char *func;
|
||||||
PIPELINE_DESC_FLAG_PS = (1 << 1)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pipeline_desc {
|
struct pipeline_desc {
|
||||||
char *shader;
|
char *name;
|
||||||
|
struct shader_desc vs;
|
||||||
|
struct shader_desc ps;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pipeline {
|
struct pipeline {
|
||||||
struct pipeline_desc desc;
|
struct pipeline_desc desc;
|
||||||
ID3D12PipelineState *pso;
|
ID3D12PipelineState *pso;
|
||||||
|
ID3D12RootSignature *rs;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pipeline_result {
|
struct pipeline_result {
|
||||||
@ -72,6 +75,7 @@ struct pipeline_error {
|
|||||||
enum dx12_handle_kind {
|
enum dx12_handle_kind {
|
||||||
DX12_HANDLE_KIND_NONE,
|
DX12_HANDLE_KIND_NONE,
|
||||||
DX12_HANDLE_KIND_TEXTURE,
|
DX12_HANDLE_KIND_TEXTURE,
|
||||||
|
DX12_HANDLE_KIND_COMMAND_LIST,
|
||||||
|
|
||||||
NUM_DX12_HANDLE_KINDS
|
NUM_DX12_HANDLE_KINDS
|
||||||
};
|
};
|
||||||
@ -216,6 +220,22 @@ INTERNAL struct dx12_handle_entry *handle_get_entry(struct gpu_handle handle, st
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL void *handle_get_data(struct gpu_handle handle, enum dx12_handle_kind kind)
|
||||||
|
{
|
||||||
|
void *data = NULL;
|
||||||
|
struct sys_lock lock = sys_mutex_lock_s(&G.handle_entries_mutex);
|
||||||
|
{
|
||||||
|
struct dx12_handle_entry *entry = handle_get_entry(handle, &lock);
|
||||||
|
data = entry->data;
|
||||||
|
#if RTC
|
||||||
|
/* Handle should match expected kind */
|
||||||
|
ASSERT(entry->kind == kind);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&lock);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: The GPU api should ensure that resources freed by the caller will not cause issues on the GPU (via fencing),
|
/* TODO: The GPU api should ensure that resources freed by the caller will not cause issues on the GPU (via fencing),
|
||||||
* however the caller is responsible for managing resource lifetimes on the CPU side (e.g. using sprites w/ sprite scopes
|
* however the caller is responsible for managing resource lifetimes on the CPU side (e.g. using sprites w/ sprite scopes
|
||||||
* to ensure freed textures aren't being used in pending command lists. */
|
* to ensure freed textures aren't being used in pending command lists. */
|
||||||
@ -315,7 +335,6 @@ INTERNAL void dx12_init_base(struct sys_window *window)
|
|||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
DXGI_ADAPTER_DESC1 desc;
|
DXGI_ADAPTER_DESC1 desc;
|
||||||
IDXGIAdapter1_GetDesc1(adapter, &desc);
|
IDXGIAdapter1_GetDesc1(adapter, &desc);
|
||||||
if (!(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) {
|
|
||||||
if (first_gpu_name.len == 0) {
|
if (first_gpu_name.len == 0) {
|
||||||
first_gpu_name = string_from_wstr_no_limit(scratch.arena, desc.Description);
|
first_gpu_name = string_from_wstr_no_limit(scratch.arena, desc.Description);
|
||||||
}
|
}
|
||||||
@ -325,7 +344,6 @@ INTERNAL void dx12_init_base(struct sys_window *window)
|
|||||||
adapter = NULL;
|
adapter = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ID3D12Device_Release(device);
|
ID3D12Device_Release(device);
|
||||||
IDXGIAdapter1_Release(adapter);
|
IDXGIAdapter1_Release(adapter);
|
||||||
adapter = NULL;
|
adapter = NULL;
|
||||||
@ -556,9 +574,9 @@ INTERNAL void dx12_init_pipelines(void)
|
|||||||
struct pipeline_desc pipeline_descs[] = {
|
struct pipeline_desc pipeline_descs[] = {
|
||||||
/* Texture pipeline */
|
/* Texture pipeline */
|
||||||
{
|
{
|
||||||
.shader = "shaders/texture.hlsl",
|
.name = "texture",
|
||||||
.flags = PIPELINE_DESC_FLAG_VS |
|
.vs = { "gpu/texture.hlsl", "vs" },
|
||||||
PIPELINE_DESC_FLAG_PS
|
.ps = { "gpu/texture.hlsl", "ps" }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -660,7 +678,8 @@ struct shader_compile_task_arg {
|
|||||||
/* In */
|
/* In */
|
||||||
enum shader_compile_task_kind kind;
|
enum shader_compile_task_kind kind;
|
||||||
struct pipeline *pipeline;
|
struct pipeline *pipeline;
|
||||||
struct resource *src_res;
|
struct shader_desc shader_desc;
|
||||||
|
struct resource *shader_res;
|
||||||
|
|
||||||
/* Out */
|
/* Out */
|
||||||
b32 success;
|
b32 success;
|
||||||
@ -673,24 +692,22 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw)
|
|||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct shader_compile_task_arg *comp_arg = (struct shader_compile_task_arg *)comp_arg_raw;
|
struct shader_compile_task_arg *comp_arg = (struct shader_compile_task_arg *)comp_arg_raw;
|
||||||
struct pipeline *pipeline = comp_arg->pipeline;
|
|
||||||
struct string shader_name = string_from_cstr_no_limit(pipeline->desc.shader);
|
|
||||||
enum shader_compile_task_kind kind = comp_arg->kind;
|
enum shader_compile_task_kind kind = comp_arg->kind;
|
||||||
struct resource *src_res = comp_arg->src_res;
|
struct pipeline *pipeline = comp_arg->pipeline;
|
||||||
|
struct shader_desc shader_desc = comp_arg->shader_desc;
|
||||||
|
struct resource *shader_res = comp_arg->shader_res;
|
||||||
|
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
{
|
{
|
||||||
b32 success = false;
|
b32 success = false;
|
||||||
ID3DBlob *blob = NULL;
|
ID3DBlob *blob = NULL;
|
||||||
ID3DBlob *error_blob = NULL;
|
ID3DBlob *error_blob = NULL;
|
||||||
struct dx12_include_handler include_handler = dx12_include_handler_alloc(pipeline);
|
|
||||||
|
|
||||||
if (resource_exists(src_res)) {
|
struct string file_name = string_from_cstr_no_limit(shader_desc.file);
|
||||||
#if 0
|
struct string func_name = string_from_cstr_no_limit(shader_desc.func);
|
||||||
#if RESOURCE_RELOADING
|
|
||||||
shader_reset_includes(shader_desc);
|
if (resource_exists(shader_res)) {
|
||||||
#endif
|
struct dx12_include_handler include_handler = dx12_include_handler_alloc(pipeline);
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 d3d_compile_flags = 0;
|
u32 d3d_compile_flags = 0;
|
||||||
#if DX12_SHADER_DEBUG
|
#if DX12_SHADER_DEBUG
|
||||||
@ -701,56 +718,33 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw)
|
|||||||
|
|
||||||
/* Compile shader */
|
/* Compile shader */
|
||||||
{
|
{
|
||||||
struct string shader_src = resource_get_data(src_res);
|
struct string shader_src = resource_get_data(shader_res);
|
||||||
logf_info("Compiling shader \"%F\"", FMT_STR(shader_name));
|
logf_info("Compiling shader \"%F:%F\"", FMT_STR(file_name), FMT_STR(func_name));
|
||||||
/* Compile shader */
|
/* Compile shader */
|
||||||
struct string friendly_name = string_cat(scratch.arena, LIT("res/"), shader_name);
|
struct string friendly_name = string_cat(scratch.arena, LIT("res/"), file_name);
|
||||||
char *friendly_name_cstr = cstr_from_string(scratch.arena, friendly_name);
|
char *friendly_name_cstr = cstr_from_string(scratch.arena, friendly_name);
|
||||||
char *entry_point = NULL;
|
|
||||||
char *target = NULL;
|
char *target = NULL;
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case SHADER_COMPILE_TASK_KIND_VS:
|
case SHADER_COMPILE_TASK_KIND_VS:
|
||||||
{
|
{
|
||||||
entry_point = "vs_main";
|
|
||||||
target = "vs_5_1";
|
target = "vs_5_1";
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SHADER_COMPILE_TASK_KIND_PS:
|
case SHADER_COMPILE_TASK_KIND_PS:
|
||||||
{
|
{
|
||||||
entry_point = "ps_main";
|
|
||||||
target = "ps_5_1";
|
target = "ps_5_1";
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
HRESULT hr = D3DCompile(shader_src.text, shader_src.len, friendly_name_cstr, NULL, (ID3DInclude *)&include_handler, entry_point, target, d3d_compile_flags, 0, &blob, &error_blob);
|
HRESULT hr = D3DCompile(shader_src.text, shader_src.len, friendly_name_cstr, NULL, (ID3DInclude *)&include_handler, shader_desc.func, target, d3d_compile_flags, 0, &blob, &error_blob);
|
||||||
success = SUCCEEDED(hr) && !error_blob;
|
success = SUCCEEDED(hr) && !error_blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
dx12_include_handler_release(&include_handler);
|
||||||
if (success) {
|
|
||||||
/* Get number of device layout elements from NULL terminated array */
|
|
||||||
u32 elem_count = 0;
|
|
||||||
for (; elem_count < ARRAY_COUNT(shader_desc->input_layout_desc); ++elem_count) {
|
|
||||||
const D3D11_INPUT_ELEMENT_DESC *d = &shader_desc->input_layout_desc[elem_count];
|
|
||||||
if (d->SemanticName == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create device layout */
|
|
||||||
if (elem_count > 0) {
|
|
||||||
HRESULT hr = ID3D11Device_CreateInputLayout(G.dev, shader_desc->input_layout_desc, elem_count, ID3D10Blob_GetBufferPointer(vs_blob), ID3D10Blob_GetBufferSize(vs_blob), &shader->input_layout);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
success = false;
|
|
||||||
error_str = LIT("Failed to create input layout");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (success) {
|
if (success) {
|
||||||
logf_success("Finished compiling shader \"%F\" in %F seconds", FMT_STR(shader_name), FMT_FLOAT(SECONDS_FROM_NS(sys_time_ns() - start_ns)));
|
logf_success("Finished compiling shader \"%F\" in %F seconds", FMT_STR(src_name), FMT_FLOAT(SECONDS_FROM_NS(sys_time_ns() - start_ns)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -762,7 +756,6 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw)
|
|||||||
shader->valid = true;
|
shader->valid = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dx12_include_handler_release(&include_handler);
|
|
||||||
}
|
}
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
@ -786,39 +779,100 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
|
|||||||
|
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
{
|
{
|
||||||
struct string shader_name = string_from_cstr_no_limit(desc.shader);
|
struct string pipeline_name = string_from_cstr_no_limit(desc.name);
|
||||||
logf_info("Loading pipeline from shader '%F'", FMT_STR(shader_name));
|
logf_info("Loading pipeline \"%F\"", FMT_STR(pipeline_name));
|
||||||
struct resource src_res = resource_open(shader_name);
|
HRESULT hr = 0;
|
||||||
|
|
||||||
struct string error_str = LIT("Unknown error");
|
struct string error_str = LIT("Unknown error");
|
||||||
|
|
||||||
|
struct string vs_filename = string_from_cstr_no_limit(desc.vs.file);
|
||||||
|
struct string ps_filename = string_from_cstr_no_limit(desc.ps.file);
|
||||||
|
|
||||||
|
b32 ps_res_is_shared = string_eq(vs_filename, ps_filename);
|
||||||
|
struct resource vs_res = resource_open(vs_filename);
|
||||||
|
struct resource ps_res = vs_res;
|
||||||
|
if (!ps_res_is_shared) {
|
||||||
|
ps_res = resource_open(ps_filename);
|
||||||
|
}
|
||||||
|
|
||||||
struct shader_compile_task_arg vs = ZI;
|
struct shader_compile_task_arg vs = ZI;
|
||||||
vs.kind = SHADER_COMPILE_TASK_KIND_VS;
|
vs.kind = SHADER_COMPILE_TASK_KIND_VS;
|
||||||
vs.src_res = &src_res;
|
|
||||||
vs.pipeline = pipeline;
|
vs.pipeline = pipeline;
|
||||||
|
vs.shader_desc = desc.vs;
|
||||||
|
vs.shader_res = &vs_res;
|
||||||
|
|
||||||
struct shader_compile_task_arg ps = ZI;
|
struct shader_compile_task_arg ps = ZI;
|
||||||
ps.kind = SHADER_COMPILE_TASK_KIND_PS;
|
ps.kind = SHADER_COMPILE_TASK_KIND_PS;
|
||||||
ps.src_res = &src_res;
|
|
||||||
ps.pipeline = pipeline;
|
ps.pipeline = pipeline;
|
||||||
|
ps.shader_desc = desc.ps;
|
||||||
|
ps.shader_res = &ps_res;
|
||||||
|
|
||||||
/* Compile shaders */
|
/* Compile shaders */
|
||||||
struct work_slate ws = work_slate_begin();
|
struct work_slate ws = work_slate_begin();
|
||||||
if (desc.flags & PIPELINE_DESC_FLAG_VS) {
|
|
||||||
work_slate_push_task(&ws, shader_compile_task, &vs);
|
work_slate_push_task(&ws, shader_compile_task, &vs);
|
||||||
}
|
|
||||||
if (desc.flags & PIPELINE_DESC_FLAG_PS) {
|
|
||||||
work_slate_push_task(&ws, shader_compile_task, &ps);
|
work_slate_push_task(&ws, shader_compile_task, &ps);
|
||||||
}
|
|
||||||
struct work_handle work = work_slate_end_and_help(&ws, WORK_PRIORITY_NORMAL);
|
struct work_handle work = work_slate_end_and_help(&ws, WORK_PRIORITY_NORMAL);
|
||||||
work_wait(work);
|
work_wait(work);
|
||||||
|
|
||||||
/* FIXME: Validate root signature blob exists in bytecode */
|
|
||||||
b32 success = vs.success && ps.success;
|
b32 success = vs.success && ps.success;
|
||||||
|
|
||||||
|
/* Get root signature blob
|
||||||
|
* NOTE: This isn't necessary for creating the RS (since it can just
|
||||||
|
* take the shader blob), however we'd like to verify that the root
|
||||||
|
* signature exists and matches between shaders. */
|
||||||
|
ID3D10Blob *rs_blob = NULL;
|
||||||
|
if (success) {
|
||||||
|
__profscope(Validate root signatures);
|
||||||
|
char *vs_rs_data = NULL;
|
||||||
|
char *ps_rs_data = NULL;
|
||||||
|
u32 vs_rs_data_len = 0;
|
||||||
|
u32 ps_rs_data_len = 0;
|
||||||
|
ID3D10Blob *vs_rs_blob = NULL;
|
||||||
|
ID3D10Blob *ps_rs_blob = NULL;
|
||||||
|
D3DGetBlobPart(ID3D10Blob_GetBufferPointer(vs.blob), ID3D10Blob_GetBufferSize(vs.blob), D3D_BLOB_ROOT_SIGNATURE, 0, &vs_rs_blob);
|
||||||
|
D3DGetBlobPart(ID3D10Blob_GetBufferPointer(ps.blob), ID3D10Blob_GetBufferSize(ps.blob), D3D_BLOB_ROOT_SIGNATURE, 0, &ps_rs_blob);
|
||||||
|
if (vs_rs_blob) {
|
||||||
|
vs_rs_data = ID3D10Blob_GetBufferPointer(vs_rs_blob);
|
||||||
|
vs_rs_data_len = ID3D10Blob_GetBufferSize(vs_rs_blob);
|
||||||
|
}
|
||||||
|
if (ps_rs_blob) {
|
||||||
|
ps_rs_data = ID3D10Blob_GetBufferPointer(ps_rs_blob);
|
||||||
|
ps_rs_data_len = ID3D10Blob_GetBufferSize(ps_rs_blob);
|
||||||
|
}
|
||||||
|
u32 cmp_len = min_u32(vs_rs_data_len, ps_rs_data_len);
|
||||||
|
if (vs_rs_data_len == 0) {
|
||||||
|
success = false;
|
||||||
|
error_str = LIT("Vertex shader is missing root signature");
|
||||||
|
} else if (ps_rs_data_len == 0) {
|
||||||
|
success = false;
|
||||||
|
error_str = LIT("Pixel shader is missing root signature");
|
||||||
|
} else if (!MEMEQ(vs_rs_data, ps_rs_data, cmp_len)) {
|
||||||
|
success = false;
|
||||||
|
error_str = LIT("Root signature mismatch between vertex and pixel shader");
|
||||||
|
} else {
|
||||||
|
rs_blob = vs_rs_blob;
|
||||||
|
}
|
||||||
|
if (ps_rs_blob) {
|
||||||
|
ID3D10Blob_Release(ps_rs_blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create root signature */
|
||||||
|
ID3D12RootSignature *rs = NULL;
|
||||||
|
if (success) {
|
||||||
|
__profscope(Create root signature);
|
||||||
|
hr = ID3D12Device_CreateRootSignature(G.device, 0, ID3D10Blob_GetBufferPointer(rs_blob), ID3D10Blob_GetBufferSize(rs_blob), &IID_ID3D12RootSignature, (void **)&rs);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
error_str = LIT("Failed to create root signature");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Create PSO */
|
/* Create PSO */
|
||||||
ID3D12PipelineState *pso = NULL;
|
ID3D12PipelineState *pso = NULL;
|
||||||
if (success) {
|
if (success) {
|
||||||
/* Default rasterizer state */
|
/* Default rasterizer state */
|
||||||
|
__profscope(Create PSO);
|
||||||
D3D12_RASTERIZER_DESC raster_desc = {
|
D3D12_RASTERIZER_DESC raster_desc = {
|
||||||
.FillMode = D3D12_FILL_MODE_SOLID,
|
.FillMode = D3D12_FILL_MODE_SOLID,
|
||||||
.CullMode = D3D12_CULL_MODE_BACK,
|
.CullMode = D3D12_CULL_MODE_BACK,
|
||||||
@ -855,7 +909,7 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
|
|||||||
|
|
||||||
/* PSO */
|
/* PSO */
|
||||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = { 0 };
|
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = { 0 };
|
||||||
pso_desc.pRootSignature = NULL; /* Use embedded root signature */
|
pso_desc.pRootSignature = rs;
|
||||||
if (vs.success) {
|
if (vs.success) {
|
||||||
pso_desc.VS.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs.blob);
|
pso_desc.VS.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs.blob);
|
||||||
pso_desc.VS.BytecodeLength = ID3D10Blob_GetBufferSize(vs.blob);
|
pso_desc.VS.BytecodeLength = ID3D10Blob_GetBufferSize(vs.blob);
|
||||||
@ -873,11 +927,10 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
|
|||||||
pso_desc.NumRenderTargets = 1;
|
pso_desc.NumRenderTargets = 1;
|
||||||
pso_desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
pso_desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
pso_desc.SampleDesc.Count = 1;
|
pso_desc.SampleDesc.Count = 1;
|
||||||
HRESULT hr = ID3D12Device_CreateGraphicsPipelineState(G.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
hr = ID3D12Device_CreateGraphicsPipelineState(G.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
error_str = LIT("Failed to create pipeline state object");
|
error_str = LIT("Failed to create pipeline state object");
|
||||||
success = false;
|
success = false;
|
||||||
ASSERT(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,7 +954,15 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pipeline->pso = pso;
|
pipeline->pso = pso;
|
||||||
|
pipeline->rs = rs;
|
||||||
|
|
||||||
|
resource_close(&vs_res);
|
||||||
|
if (!ps_res_is_shared) {
|
||||||
|
resource_close(&ps_res);
|
||||||
|
}
|
||||||
|
if (rs_blob) {
|
||||||
|
ID3D10Blob_Release(rs_blob);
|
||||||
|
}
|
||||||
if (vs.blob) {
|
if (vs.blob) {
|
||||||
ID3D10Blob_Release(vs.blob);
|
ID3D10Blob_Release(vs.blob);
|
||||||
}
|
}
|
||||||
@ -914,7 +975,6 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
|
|||||||
if (ps.error_blob) {
|
if (ps.error_blob) {
|
||||||
ID3D10Blob_Release(ps.error_blob);
|
ID3D10Blob_Release(ps.error_blob);
|
||||||
}
|
}
|
||||||
resource_close(&src_res);
|
|
||||||
}
|
}
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
@ -1022,11 +1082,114 @@ struct gpu_handle gpu_dispatch_state_alloc(void)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_params params, struct gpu_handle gpu_command_list)
|
||||||
|
{
|
||||||
|
(UNUSED)gpu_dispatch_state;
|
||||||
|
(UNUSED)params;
|
||||||
|
|
||||||
|
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
||||||
|
|
||||||
|
struct dx12_command_list *command_list = handle_get_data(gpu_command_list, DX12_HANDLE_KIND_COMMAND_LIST);
|
||||||
|
|
||||||
|
/* Texture pass */
|
||||||
|
{
|
||||||
|
struct pipeline *pipeline = dx12_get_pipeline(pipeline_scope, LIT("gpu/texture.hlsl"));
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline_scope_end(pipeline_scope);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
__prof;
|
||||||
|
struct sprite_scope *sprite_scope = sprite_scope_begin();
|
||||||
|
struct dx11_dispatch_state *state = (struct dx11_dispatch_state *)gpu_dispatch_state.v;
|
||||||
|
|
||||||
|
struct rect viewport = params.draw_target_viewport;
|
||||||
|
|
||||||
|
/* Set viewport */
|
||||||
|
D3D11_VIEWPORT d3d11_viewport = ZI;
|
||||||
|
d3d11_viewport.Width = viewport.width;
|
||||||
|
d3d11_viewport.Height = viewport.height;
|
||||||
|
d3d11_viewport.MinDepth = 0.0f;
|
||||||
|
d3d11_viewport.MaxDepth = 1.0f;
|
||||||
|
d3d11_viewport.TopLeftX = viewport.x;
|
||||||
|
d3d11_viewport.TopLeftY = viewport.y;
|
||||||
|
ID3D11DeviceContext_RSSetViewports(G.devcon, 1, &d3d11_viewport);
|
||||||
|
|
||||||
|
struct dx12_buffer *final_tex = (struct dx12_buffer *)params.draw_target.v;
|
||||||
|
struct v2i32 final_tex_size = final_tex->size;
|
||||||
|
|
||||||
|
/* Texture pass */
|
||||||
|
{
|
||||||
|
__profscope(Texture pass);
|
||||||
|
struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEXTURE];
|
||||||
|
if (shader->valid) {
|
||||||
|
struct dx12_buffer *texture = NULL;
|
||||||
|
if (cmd->texture.texture.v) {
|
||||||
|
/* Load texture if handle is set */
|
||||||
|
texture = (struct dx12_buffer *)cmd->texture.texture.v;
|
||||||
|
} else if (cmd->texture.sprite.hash) {
|
||||||
|
/* Otherwise load sprite */
|
||||||
|
struct sprite_texture *sprite_texture = sprite_texture_from_tag_async(sprite_scope, cmd->texture.sprite);
|
||||||
|
if (sprite_texture->loaded) {
|
||||||
|
texture = (struct dx12_buffer *)sprite_texture->texture.v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture && texture->srv) {
|
||||||
|
struct dx11_buffer *instance_buffer = list->buffers.texture.instance_buffer;
|
||||||
|
u32 instance_offset = cmd->texture.instance_offset;
|
||||||
|
u32 instance_count = cmd->texture.instance_count;
|
||||||
|
|
||||||
|
/* Bind shader */
|
||||||
|
ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0);
|
||||||
|
ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0);
|
||||||
|
|
||||||
|
/* Fill & bind constant buffer */
|
||||||
|
{
|
||||||
|
struct dx11_texture_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_texture_uniform));
|
||||||
|
uniform->vp = vp_matrix;
|
||||||
|
uniform->instance_offset = instance_offset;
|
||||||
|
dx11_buffer_submit(constant_buffer);
|
||||||
|
}
|
||||||
|
ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer);
|
||||||
|
ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer);
|
||||||
|
|
||||||
|
/* Bind dummy vertex buffer */
|
||||||
|
u32 zero = 0;
|
||||||
|
ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &G.dummy_vertex_buffer->gpu_buffer, &zero, &zero);
|
||||||
|
ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero);
|
||||||
|
|
||||||
|
/* Bind SRVs */
|
||||||
|
ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv, texture->srv };
|
||||||
|
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs);
|
||||||
|
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs);
|
||||||
|
|
||||||
|
/* Bind RTVs */
|
||||||
|
ID3D11RenderTargetView *rtvs[] = { final_tex->rtv };
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL);
|
||||||
|
|
||||||
|
/* Draw */
|
||||||
|
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
||||||
|
|
||||||
|
/* Unbind */
|
||||||
|
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprite_scope_end(sprite_scope);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_params params)
|
void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_params params)
|
||||||
{
|
{
|
||||||
(UNUSED)gpu_dispatch_state;
|
(UNUSED)gpu_dispatch_state;
|
||||||
(UNUSED)params;
|
(UNUSED)params;
|
||||||
|
(UNUSED)handle_get_data;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Backbuffer
|
* Backbuffer
|
||||||
@ -1065,6 +1228,7 @@ void gpu_swap_backbuffer(i32 vsync)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -264,10 +264,10 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr,
|
|||||||
G.user_dispatch_state = gpu_dispatch_state_alloc();
|
G.user_dispatch_state = gpu_dispatch_state_alloc();
|
||||||
G.backbuffer_dispatch_state = gpu_dispatch_state_alloc();
|
G.backbuffer_dispatch_state = gpu_dispatch_state_alloc();
|
||||||
|
|
||||||
//log_register_callback(debug_console_log_callback, LOG_LEVEL_SUCCESS);
|
|
||||||
log_register_callback(debug_console_log_callback, LOG_LEVEL_DEBUG);
|
|
||||||
G.console_logs_mutex = sys_mutex_alloc();
|
G.console_logs_mutex = sys_mutex_alloc();
|
||||||
G.console_logs_arena = arena_alloc(GIGABYTE(64));
|
G.console_logs_arena = arena_alloc(GIGABYTE(64));
|
||||||
|
//log_register_callback(debug_console_log_callback, LOG_LEVEL_SUCCESS);
|
||||||
|
log_register_callback(debug_console_log_callback, LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
G.window = window;
|
G.window = window;
|
||||||
sys_window_register_event_callback(G.window, &window_event_callback);
|
sys_window_register_event_callback(G.window, &window_event_callback);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user