diff --git a/res/sh/material.hlsl b/res/sh/material.hlsl index 9dd88807..a7c0c504 100644 --- a/res/sh/material.hlsl +++ b/res/sh/material.hlsl @@ -38,6 +38,7 @@ struct vs_output { nointerpolation DECLS(int, grid_id); DECLS(float2, uv); DECLS(float4, tint_lin); + DECLS(float4, emittance_lin); DECLS(float4, SV_Position); }; @@ -60,6 +61,7 @@ SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) output.grid_id = instance.grid_id; output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); output.tint_lin = linear_from_srgb32(instance.tint_srgb); + output.emittance_lin = linear_from_srgb32(instance.emittance_srgb); return output; } @@ -72,17 +74,19 @@ struct ps_input { }; struct ps_output { - DECLS(float4, SV_Target); + DECLS(float4, SV_Target0); /* Albedo */ + DECLS(float4, SV_Target1); /* Emittance */ }; SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) { struct ps_output output; - output.SV_Target = input.vs.tint_lin; + float4 albedo = input.vs.tint_lin; + float4 emittance = input.vs.emittance_lin; /* Texture */ if (input.vs.tex_nurid >= 0) { - output.SV_Target *= g_textures[NURID(input.vs.tex_nurid)].Sample(g_sampler, input.vs.uv); + albedo *= g_textures[NURID(input.vs.tex_nurid)].Sample(g_sampler, input.vs.uv); } /* Grid */ @@ -113,8 +117,10 @@ SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) color_srgb = grid.bg1_srgb; } } - output.SV_Target *= linear_from_srgb32(color_srgb); + albedo = linear_from_srgb32(color_srgb); } + output.SV_Target0 = albedo; + output.SV_Target1 = emittance; return output; } diff --git a/res/sh/sh_common.h b/res/sh/sh_common.h index 1fe2f0a1..d0563b9f 100644 --- a/res/sh/sh_common.h +++ b/res/sh/sh_common.h @@ -98,7 +98,7 @@ SH_STRUCT(sh_material_instance { SH_DECL(float2, uv0); SH_DECL(float2, uv1); SH_DECL(uint, tint_srgb); - SH_DECL(float, emittance); + SH_DECL(uint, emittance_srgb); }); SH_STRUCT(sh_material_grid { diff --git a/res/sh/shade.hlsl b/res/sh/shade.hlsl index d72fbf49..3f0efef4 100644 --- a/res/sh/shade.hlsl +++ b/res/sh/shade.hlsl @@ -38,6 +38,10 @@ SH_ENTRY(ROOTSIG) void cs(struct cs_input input) if (job_id.x >= g_constants.tex_width || job_id.y >= g_constants.tex_height) { return; /* Overflow */ } - g_write_textures[g_constants.write_tex_urid][job_id.xy] += g_read_textures[g_constants.albedo_tex_urid][job_id.xy]; - //g_write_textures[g_constants.write_tex_urid][job_id.xy] = float4(1, 0, 0, 1); + float4 old_color = g_read_textures[g_constants.write_tex_urid][job_id.xy]; + float4 albedo = g_read_textures[g_constants.albedo_tex_urid][job_id.xy]; + float4 emittance = g_read_textures[g_constants.emittance_tex_urid][job_id.xy]; + float4 final_color = old_color + albedo + emittance; + + g_write_textures[g_constants.write_tex_urid][job_id.xy] = final_color; } diff --git a/src/draw.h b/src/draw.h index 5e0b1740..3fe1e772 100644 --- a/src/draw.h +++ b/src/draw.h @@ -25,7 +25,7 @@ struct draw_texture_params { struct sprite_tag sprite; struct clip_rect clip; u32 tint; - f32 emittance; + u32 emittance; }; void draw_texture(struct gp_sig *flow, struct draw_texture_params params); diff --git a/src/gp.h b/src/gp.h index 53517933..176172ae 100644 --- a/src/gp.h +++ b/src/gp.h @@ -71,7 +71,7 @@ struct gp_cmd_desc { struct gp_resource *texture; struct clip_rect clip; u32 tint; - f32 emittance; + u32 emittance; i32 grid_cmd_id; } material; struct { diff --git a/src/gp_dx12.c b/src/gp_dx12.c index 81bf017d..a592e2e2 100644 --- a/src/gp_dx12.c +++ b/src/gp_dx12.c @@ -83,6 +83,7 @@ struct pipeline_desc { struct shader_desc vs; struct shader_desc ps; D3D12_INPUT_ELEMENT_DESC ia[8]; + DXGI_FORMAT rtv_formats[8]; }; struct pipeline { @@ -680,6 +681,8 @@ INTERNAL void dx12_init_pipelines(void) desc->ps.file = LIT("sh/material.hlsl"); desc->vs.func = LIT("vs"); desc->ps.func = LIT("ps"); + desc->rtv_formats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + desc->rtv_formats[1] = DXGI_FORMAT_R8G8B8A8_UNORM; dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); } /* Shape pipeline */ @@ -692,6 +695,7 @@ INTERNAL void dx12_init_pipelines(void) desc->ps.func = LIT("ps"); desc->ia[0] = (D3D12_INPUT_ELEMENT_DESC) { "pos", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }; desc->ia[1] = (D3D12_INPUT_ELEMENT_DESC) { "color_srgb", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }; + desc->rtv_formats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); } /* Blit pipeilne */ @@ -702,6 +706,7 @@ INTERNAL void dx12_init_pipelines(void) desc->ps.file = LIT("sh/blit.hlsl"); desc->vs.func = LIT("vs"); desc->ps.func = LIT("ps"); + desc->rtv_formats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); } } @@ -1188,8 +1193,15 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job) pso_desc.DepthStencilState = depth_stencil_desc; pso_desc.InputLayout = input_layout_desc; pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - pso_desc.NumRenderTargets = 1; - pso_desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + for (i32 i = 0; i < (i32)countof(desc->rtv_formats); ++i) { + STATIC_ASSERT(countof(pso_desc.RTVFormats) <= countof(desc->rtv_formats)); + DXGI_FORMAT format = desc->rtv_formats[i]; + if (format == DXGI_FORMAT_UNKNOWN) { + break; + } else { + pso_desc.RTVFormats[pso_desc.NumRenderTargets++] = format; + } + } pso_desc.SampleDesc.Count = 1; pso_desc.SampleDesc.Quality = 0; hr = ID3D12Device_CreateGraphicsPipelineState(G.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso); @@ -1561,7 +1573,7 @@ struct material_instance_desc { struct dx12_resource *texture; struct clip_rect clip; u32 tint; - f32 emittance; + u32 emittance; i32 grid_id; }; @@ -1818,18 +1830,14 @@ INTERNAL void dx12_resource_barriers(ID3D12GraphicsCommandList *cl, i32 num_reso enum D3D12_RESOURCE_STATES old_state = resource->state; enum D3D12_RESOURCE_STATES new_state = states[i]; if (new_state != old_state) { - struct D3D12_RESOURCE_TRANSITION_BARRIER rtb = ZI; - rtb.pResource = resource->resource; - rtb.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - rtb.StateBefore = old_state; - rtb.StateAfter = new_state; - struct D3D12_RESOURCE_BARRIER *rb = &rbs[num_rbs++]; MEMZERO_STRUCT(rb); rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; rb->Flags = 0; - rb->Transition = rtb; - + rb->Transition.pResource = resource->resource; + rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + rb->Transition.StateBefore = old_state; + rb->Transition.StateAfter = new_state; resource->state = new_state; } } @@ -2669,7 +2677,7 @@ void gp_run(struct gp_run_params params) instance->uv0 = sh_float2_from_v2(desc->clip.p0); instance->uv1 = sh_float2_from_v2(desc->clip.p1); instance->tint_srgb = sh_uint_from_u32(desc->tint); - instance->emittance = sh_float_from_f32(desc->emittance); + instance->emittance_srgb = sh_uint_from_u32(desc->emittance); } } @@ -2699,6 +2707,8 @@ void gp_run(struct gp_run_params params) /* Upload descriptor heap */ struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); + ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; + ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps); /* Bind gbuffer RTVs */ { @@ -2736,8 +2746,6 @@ void gp_run(struct gp_run_params params) command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); /* Set descriptor tables */ - ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; - ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); /* Set instance buffer */ @@ -2803,8 +2811,6 @@ void gp_run(struct gp_run_params params) command_list_set_compute_root_constant(cl, &constants, sizeof(constants)); /* Set descriptor tables */ - ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; - ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 2, descriptor_heap->start_gpu_handle); @@ -3063,6 +3069,8 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s /* Upload descriptor heap */ struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); + ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; + ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps); struct rect viewport_rect = RECT_FROM_V2(V2(0, 0), V2(swapchain->resolution.x, swapchain->resolution.y)); D3D12_VIEWPORT viewport = viewport_from_rect(viewport_rect); @@ -3101,8 +3109,6 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); /* Set descriptor tables */ - ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; - ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); /* Setup Rasterizer State */ diff --git a/src/user.c b/src/user.c index 69b7067b..598f65d1 100644 --- a/src/user.c +++ b/src/user.c @@ -1196,7 +1196,7 @@ INTERNAL void user_update(struct sys_window *window) /* TODO: Fade in placeholder if texture isn't loaded */ if (sheet->loaded) { b32 is_light = sim_ent_has_prop(ent, SEPROP_LIGHT_TEST); - f32 emittance = is_light ? 1.0 : 0.0; + u32 emittance = is_light ? COLOR_WHITE : 0; u32 tint = ent->sprite_tint; struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, ent->animation_frame); struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.xf = sprite_xform, .sprite = sprite, .tint = tint, .clip = frame.clip, .emittance = emittance); @@ -1219,7 +1219,7 @@ INTERNAL void user_update(struct sys_window *window) struct v2i32 world_tile_index = sim_world_tile_index_from_local_tile_index(chunk_index, local_tile_index); struct v2 pos = sim_pos_from_world_tile_index(world_tile_index); struct xform tile_xf = xform_from_rect(RECT_FROM_V2(pos, V2(tile_size, tile_size))); - struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.xf = tile_xf, .sprite = tile_sprite); + struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.xf = tile_xf, .sprite = tile_sprite, .emittance = COLOR_BLACK); draw_texture(G.world_gp_sig, params); } }