diff --git a/res/shaders/common.hlsl b/res/shaders/common.hlsl index 2a5bced2..c1e397f3 100644 --- a/res/shaders/common.hlsl +++ b/res/shaders/common.hlsl @@ -1,6 +1,9 @@ #define DECL(t, n) t n : n #define DESV(t, n, s) t n : s +#define PI 3.14159265359 +#define GOLDEN 1.61803398875 + /* Linear color from normalized sRGB */ float4 linear_from_srgb(float4 srgb) { diff --git a/res/shaders/grid.hlsl b/res/shaders/grid.hlsl index 1c7b6e7a..19ef928c 100644 --- a/res/shaders/grid.hlsl +++ b/res/shaders/grid.hlsl @@ -28,7 +28,7 @@ struct ps_input { * Globals * ========================== */ - StructuredBuffer G_instance_buffer : register(t0); +StructuredBuffer G_instance_buffer : register(t0); cbuffer constants : register(b0) { @@ -40,7 +40,7 @@ cbuffer constants : register(b0) * Vertex shader * ========================== */ - static const float2 G_quad_verts[4] = { +static const float2 G_quad_verts[4] = { float2(-0.5f, -0.5f), float2( 0.5f, -0.5f), float2( 0.5f, 0.5f), diff --git a/res/shaders/test.hlsl b/res/shaders/test.hlsl new file mode 100644 index 00000000..da522318 --- /dev/null +++ b/res/shaders/test.hlsl @@ -0,0 +1,51 @@ +#include "shaders/common.hlsl" + +struct vs_instance { + float2x3 xf; +}; + +struct ps_input { + DESV(float4, screen_pos, SV_POSITION); +}; + +/* ========================== * + * Globals + * ========================== */ + +StructuredBuffer G_instance_buffer : register(t0); + +cbuffer constants : register(b0) +{ + float4x4 G_projection; + uint G_instance_offset; +}; + +/* ========================== * + * Vertex shader + * ========================== */ + +static const float2 G_quad_verts[4] = { + float2(-0.5f, -0.5f), + float2( 0.5f, -0.5f), + float2( 0.5f, 0.5f), + float2(-0.5f, 0.5f) +}; + +ps_input vs_main(uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID) +{ + vs_instance instance = G_instance_buffer[G_instance_offset + instance_id]; + float2 vert = G_quad_verts[vertex_id]; + float2 world_pos = mul(instance.xf, float3(vert, 1)).xy; + ps_input output; + output.screen_pos = mul(G_projection, float4(world_pos, 0, 1)); + return output; +} + +/* ========================== * + * Pixel shader + * ========================== */ + +float4 ps_main(ps_input input) : SV_TARGET +{ + return float4(0, 0, 0, 0); +} diff --git a/res/shaders/texture.hlsl b/res/shaders/texture.hlsl index 05d336ec..5f054343 100644 --- a/res/shaders/texture.hlsl +++ b/res/shaders/texture.hlsl @@ -17,12 +17,12 @@ struct ps_input { * Globals * ========================== */ +StructuredBuffer G_instance_buffer : register(t0); + +Texture2D G_texture : register(t1); + SamplerState G_sampler : register(s0); -Texture2D G_Texture : register(t0); - -StructuredBuffer G_instance_buffer : register(t1); - cbuffer constants : register(b0) { float4x4 G_projection; @@ -68,6 +68,6 @@ ps_input vs_main(uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID) float4 ps_main(ps_input 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; } diff --git a/src/gpu.h b/src/gpu.h index f1bff74e..4c9d08c7 100644 --- a/src/gpu.h +++ b/src/gpu.h @@ -66,8 +66,9 @@ enum gpu_cmd_kind { GPU_CMD_KIND_DRAW_MESH, GPU_CMD_KIND_DRAW_TEXTURE, GPU_CMD_KIND_DRAW_GRID, + GPU_CMD_KIND_TEST, - NU + NUM_GPU_CMD_KINDS }; struct gpu_cmd_params { @@ -96,6 +97,9 @@ struct gpu_cmd_params { u32 x_color; u32 y_color; } grid; + struct { + struct xform xf; + } test; }; }; diff --git a/src/gpu_dx11.c b/src/gpu_dx11.c index 9fb3fb27..1cf86161 100644 --- a/src/gpu_dx11.c +++ b/src/gpu_dx11.c @@ -47,6 +47,7 @@ enum dx11_shader_kind { DX11_SHADER_KIND_MESH, DX11_SHADER_KIND_TEXTURE, DX11_SHADER_KIND_GRID, + DX11_SHADER_KIND_TEST, NUM_DX11_SHADER_KINDS }; @@ -109,6 +110,10 @@ struct dx11_cmd { u32 instance_offset; u32 instance_count; } grid; + struct { + u32 instance_offset; + u32 instance_count; + } test; }; struct dx11_cmd *next; @@ -135,6 +140,9 @@ struct dx11_cmd_store { struct { struct dx11_buffer *instance_buffer; } grid; + struct { + struct dx11_buffer *instance_buffer; + } test; } buffers; struct dx11_cmd_store *next_free; @@ -492,11 +500,9 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window) } /* ========================== * - * Shader table + * Mesh shader structs * ========================== */ -/* Mesh structs */ - PACK(struct dx11_mesh_uniform { struct mat4x4 vp; }); @@ -506,7 +512,9 @@ PACK(struct dx11_mesh_vertex { u32 color_srgb; }); -/* Texture structs */ +/* ========================== * + * Texture shader structs + * ========================== */ PACK(struct dx11_texture_uniform { struct mat4x4 vp; @@ -520,7 +528,9 @@ PACK(struct dx11_texture_instance { u32 tint_srgb; }); -/* Grid structs */ +/* ========================== * + * Grid shader structs + * ========================== */ PACK(struct dx11_grid_uniform { struct mat4x4 vp; @@ -539,6 +549,23 @@ PACK(struct dx11_grid_instance { u32 y_srgb; }); +/* ========================== * + * Test shader structs + * ========================== */ + +PACK(struct dx11_test_uniform { + struct mat4x4 vp; + u32 instance_offset; +}); + +PACK(struct dx11_test_instance { + struct xform xf; +}); + +/* ========================== * + * Shader table + * ========================== */ + INTERNAL void init_shader_table(void) { MEMZERO_ARRAY(G.shader_info); @@ -565,6 +592,12 @@ INTERNAL void init_shader_table(void) .name_cstr = "shaders/grid.hlsl" }; + /* Test shader layout */ + G.shader_info[DX11_SHADER_KIND_TEST] = (struct dx11_shader_desc) { + .kind = DX11_SHADER_KIND_TEST, + .name_cstr = "shaders/test.hlsl" + }; + #if RESOURCE_RELOADING for (u64 i = 0; i < ARRAY_COUNT(G.shader_info); ++i) { struct dx11_shader_desc *desc = &G.shader_info[i]; @@ -733,7 +766,7 @@ INTERNAL struct string shader_alloc(struct arena *arena, struct dx11_shader *sha u32 flags = 0; #if DX11_SHADER_DEBUG - flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS; + flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_ENABLE_STRICTNESS; #else flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; #endif @@ -772,10 +805,12 @@ INTERNAL struct string shader_alloc(struct arena *arena, struct dx11_shader *sha } /* Create device layout */ - 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"); + 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"); + } } } else { success = false; @@ -1098,6 +1133,13 @@ struct gpu_cmd_store gpu_cmd_store_alloc(void) desc.StructureByteStride = sizeof(struct dx11_grid_instance); store->buffers.grid.instance_buffer = dx11_buffer_alloc(desc, NULL); } + + /* Test buffers */ + { + struct D3D11_BUFFER_DESC desc = structured_buffer_desc; + desc.StructureByteStride = sizeof(struct dx11_test_instance); + store->buffers.test.instance_buffer = dx11_buffer_alloc(desc, NULL); + } } struct gpu_cmd_store res = ZI; @@ -1238,6 +1280,24 @@ void gpu_push_cmd(struct gpu_cmd_store gpu_cmd_store, struct gpu_cmd_params para instance->x_srgb = params.grid.x_color; instance->y_srgb = params.grid.y_color; } break; + + case GPU_CMD_KIND_TEST: + { + struct dx11_cmd *cmd = arena_push(&store->cpu_cmds_arena, struct dx11_cmd); + cmd->kind = params.kind; + cmd->test.instance_offset = (store->buffers.test.instance_buffer->cpu_buffer_arena.pos / sizeof(struct dx11_test_instance)); + if (store->cpu_last_cmd) { + store->cpu_last_cmd->next = cmd; + } else { + store->cpu_first_cmd = cmd; + } + store->cpu_last_cmd = cmd; + + /* Push instance data */ + ++cmd->test.instance_count; + struct dx11_test_instance *instance = dx11_buffer_push(store->buffers.test.instance_buffer, sizeof(struct dx11_test_instance)); + instance->xf = params.test.xf; + } break; } } @@ -1267,6 +1327,79 @@ void gpu_submit_cmds(struct gpu_cmd_store gpu_cmd_store) /* Submit grid buffers */ dx11_buffer_submit(store->buffers.grid.instance_buffer); + + /* Submit test buffers */ + dx11_buffer_submit(store->buffers.test.instance_buffer); +} + +/* ========================== * + * Run + * ========================== */ + +enum dx11_unbind_flags { + DX11_UNBIND_NONE = 0, + DX11_UNBIND_VS = (1 << 0), + DX11_UNBIND_PS = (1 << 1), + DX11_UNBIND_IA = (1 << 2), + DX11_UNBIND_CBUFF = (1 << 3), + DX11_UNBIND_VBUFF = (1 << 4), + DX11_UNBIND_IBUFF = (1 << 5), + DX11_UNBIND_SRV = (1 << 6), + DX11_UNBIND_RTV = (1 << 7) +}; + +INTERNAL void dx11_unbind(u32 flags) +{ + __prof; + ID3D11RenderTargetView *null_rtvs[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + ID3D11ShaderResourceView *null_srvs[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + ID3D11Buffer *null_buffers[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + ID3D11InputLayout *null_ia = NULL; + ID3D11VertexShader *null_vs = NULL; + ID3D11PixelShader *null_ps = NULL; + u32 zero = 0; + + if (flags & DX11_UNBIND_RTV) { + ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 8, null_rtvs, NULL); + } + + if (flags & DX11_UNBIND_SRV) { + if (flags & DX11_UNBIND_VS) { + ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 8, null_srvs); + } + if (flags & DX11_UNBIND_VS) { + ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 8, null_srvs); + } + } + + if (flags & DX11_UNBIND_VBUFF) { + ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, null_buffers, &zero, &zero); + } + + if (flags & DX11_UNBIND_IBUFF) { + ID3D11DeviceContext_IASetIndexBuffer(G.devcon, null_buffers[0], DXGI_FORMAT_R16_UINT, zero); + } + + if (flags & DX11_UNBIND_IA) { + ID3D11DeviceContext_IASetInputLayout(G.devcon, null_ia); + } + + if (flags & DX11_UNBIND_CBUFF) { + if (flags & DX11_UNBIND_VS) { + ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 8, null_buffers); + } + if (flags & DX11_UNBIND_PS) { + ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 8, null_buffers); + } + } + + if (flags & DX11_UNBIND_VS) { + ID3D11DeviceContext_VSSetShader(G.devcon, null_vs, 0, 0); + } + + if (flags & DX11_UNBIND_PS) { + ID3D11DeviceContext_PSSetShader(G.devcon, null_ps, 0, 0); + } } /* TODO: Lock resources during run */ @@ -1276,13 +1409,9 @@ void gpu_run_cmds(struct gpu_cmd_store gpu_cmd_store, struct gpu_texture target, __profscope_dx11(G.profiling_ctx, Run, RGB_F(0.5, 0.2, 0.2)); struct sprite_scope *sprite_scope = sprite_scope_begin(); - ID3D11RenderTargetView *null_rtvs[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - ID3D11ShaderResourceView *null_srvs[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - struct dx11_cmd_store *store = (struct dx11_cmd_store *)gpu_cmd_store.handle; struct dx11_texture *target_texture = (struct dx11_texture *)target.handle; - /* Set render targets */ ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &target_texture->rtv, NULL); @@ -1348,9 +1477,8 @@ void gpu_run_cmds(struct gpu_cmd_store gpu_cmd_store, struct gpu_texture target, ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D11DeviceContext_DrawIndexed(G.devcon, index_count, index_offset, vertex_offset); - /* Unbind SRVs */ - ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 8, null_srvs); - ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 8, null_srvs); + /* Unbind */ + dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_IA | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF); } } break; @@ -1397,21 +1525,20 @@ void gpu_run_cmds(struct gpu_cmd_store gpu_cmd_store, struct gpu_texture target, 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 texture */ - ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 1, &texture->srv); - ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 1, &texture->srv); - /* Bind instance buffer */ - ID3D11DeviceContext_VSSetShaderResources(G.devcon, 1, 1, &instance_buffer->srv); - ID3D11DeviceContext_PSSetShaderResources(G.devcon, 1, 1, &instance_buffer->srv); + ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv); + ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv); + + /* Bind texture */ + ID3D11DeviceContext_VSSetShaderResources(G.devcon, 1, 1, &texture->srv); + ID3D11DeviceContext_PSSetShaderResources(G.devcon, 1, 1, &texture->srv); /* Draw */ ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); - /* Unbind SRVs */ - ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 8, null_srvs); - ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 8, null_srvs); + /* Unbind */ + dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV); } } } break; @@ -1454,16 +1581,58 @@ void gpu_run_cmds(struct gpu_cmd_store gpu_cmd_store, struct gpu_texture target, ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); - /* Unbind SRVs */ - ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 8, null_srvs); - ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 8, null_srvs); + /* Unbind */ + dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV); + } + } break; + + case GPU_CMD_KIND_TEST: + { + __profscope(Test); + __profscope_dx11(G.profiling_ctx, Test, RGB_F(1, 0.2, 1)); + struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEST]; + if (shader->valid) { + struct dx11_buffer *constant_buffer = store->buffers.constant_buffer; + struct dx11_buffer *instance_buffer = store->buffers.test.instance_buffer; + u32 instance_offset = cmd->test.instance_offset; + u32 instance_count = cmd->test.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_test_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_test_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 instance buffer */ + ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv); + ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv); + + /* 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); } } break; } } /* Unbind render target */ - ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 8, null_rtvs, NULL); + dx11_unbind(DX11_UNBIND_RTV); sprite_scope_end(sprite_scope); } diff --git a/src/sys_win32.c b/src/sys_win32.c index e58baf21..b3382a6e 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -2053,7 +2053,7 @@ void sys_message_box(enum sys_message_box_kind kind, struct string message) } break; } - logf_info("Showing message box: \"%F\"", FMT_STR(message)); + //logf_info("Showing message box: \"%F\"", FMT_STR(message)); MessageBoxExW(NULL, message_wstr, title, mbox_type, 0); scratch_end(scratch); diff --git a/src/user.c b/src/user.c index 691a61a8..bb688512 100644 --- a/src/user.c +++ b/src/user.c @@ -1032,7 +1032,7 @@ INTERNAL void user_update(void) } /* ========================== * - * Draw test grid + * Draw grid * ========================== */ { @@ -1048,6 +1048,19 @@ INTERNAL void user_update(void) draw_grid(G.world_gpu_cmd_store, xform_from_rect(RECT_FROM_V2(pos, size)), color0, color1, RGBA(0x3f, 0x3f, 0x3f, 0xFF), COLOR_RED, COLOR_GREEN, thickness, spacing, offset); } + /* ========================== * + * Draw test + * ========================== */ + + { + struct v2 pos = xform_invert_mul_v2(G.world_to_user_xf, V2(0, 0)); + struct v2 size = xform_basis_invert_mul_v2(G.world_to_user_xf, G.user_size); + struct gpu_cmd_params cmd = ZI; + cmd.kind = GPU_CMD_KIND_TEST; + cmd.test.xf = xform_from_rect(RECT_FROM_V2(pos, size)); + gpu_push_cmd(G.world_gpu_cmd_store, cmd); + } + #if 0 /* ========================== * * Alloc / release tile cache entries