flood testing

This commit is contained in:
jacob 2025-07-17 14:52:57 -05:00
parent acbc25b6a2
commit 2b3ca4bbaf
5 changed files with 488 additions and 220 deletions

94
res/sh/flood.hlsl Normal file
View File

@ -0,0 +1,94 @@
#include "sh/common.hlsl"
/* ========================== *
* Root signature
* ========================== */
#define ROOTSIG \
"RootConstants(num32BitConstants = 6, b0), " \
"DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
"DescriptorTable(UAV(u0, space = 1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
\
\
"StaticSampler(s0, " \
"filter = FILTER_MIN_MAG_MIP_POINT, " \
"addressU = TEXTURE_ADDRESS_CLAMP, " \
"addressV = TEXTURE_ADDRESS_CLAMP, " \
"addressW = TEXTURE_ADDRESS_CLAMP, " \
"maxAnisotropy = 1)"
ConstantBuffer<struct sh_flood_constants> g_constants : register(b0);
Texture2D<float4> g_emittance_textures[] : register(t0, space0);
RWTexture2D<int2> g_flood_textures[]: register(u0, space1);
SamplerState g_sampler : register(s0);
/* ========================== *
* Compute shader
* ========================== */
struct cs_input {
DECLS(uint3, SV_DispatchThreadID);
};
[numthreads(8, 8, 1)]
SH_ENTRY(ROOTSIG) void cs(struct cs_input input)
{
uint2 id = input.SV_DispatchThreadID.xy;
uint2 tex_size = uint2(g_constants.tex_width, g_constants.tex_height);
if (id.x >= tex_size.x || id.y >= tex_size.y) {
return; /* Overflow */
}
int step_len = g_constants.step_len;
if (step_len == -1) {
/* Seed */
float4 emittance = g_emittance_textures[g_constants.emittance_tex_urid][id];
int2 seed = int2(-1, -1);
if (emittance.a > 0) {
seed = id.xy;
}
g_flood_textures[g_constants.flood_read_tex_urid][id] = seed;
g_flood_textures[g_constants.flood_write_tex_urid][id] = seed;
} else {
/* Flood */
int2 seed = g_flood_textures[g_constants.flood_read_tex_urid][id];
if (seed.x >= 0 && seed.y >= 0) {
int2 flood_coords[2] = {
int2((int)id.x - step_len, (int)id.y ), /* cl */
int2((int)id.x + step_len, (int)id.y ), /* cr */
};
for (int i = 0; i < 2; ++i) {
int2 coord = flood_coords[i];
if (coord.x >= 0 && coord.x < (int)tex_size.x && coord.y >= 0 && coord.y < (int)tex_size.y) {
int2 old_flood = g_flood_textures[g_constants.flood_read_tex_urid][coord];
// if (old_flood.x < 0 || old_flood.y < 0) {
g_flood_textures[g_constants.flood_write_tex_urid][coord] = seed;
// }
}
}
}
// if (seed.x >= 0 && seed.y >= 0) {
// int2 flood_coords[8] = {
// int2((int)id.x - step_len, (int)id.y - step_len), /* tl */
// int2((int)id.x , (int)id.y - step_len), /* tc */
// int2((int)id.x + step_len, (int)id.y - step_len), /* tr */
// int2((int)id.x - step_len, (int)id.y ), /* cl */
// int2((int)id.x + step_len, (int)id.y ), /* cr */
// int2((int)id.x - step_len, (int)id.y + step_len), /* bl */
// int2((int)id.x , (int)id.y + step_len), /* bc */
// int2((int)id.x + step_len, (int)id.y + step_len) /* br */
// };
// for (int i = 0; i < 8; ++i) {
// int2 coord = flood_coords[i];
// if (coord.x >= 0 && coord.x < (int)tex_size.x && coord.y >= 0 && coord.y < (int)tex_size.y) {
// int2 old_flood = g_flood_textures[g_constants.flood_read_tex_urid][coord];
// if (old_flood.x < 0 || old_flood.y < 0) {
// g_flood_textures[g_constants.flood_write_tex_urid][coord] = seed;
// }
// }
// }
// }
}
}

View File

@ -69,19 +69,6 @@ SH_STRUCT(sh_blit_constants {
}); });
SH_ASSERT_32BIT(struct sh_blit_constants, 18); /* Expected 32bit root constant size in shader */ SH_ASSERT_32BIT(struct sh_blit_constants, 18); /* Expected 32bit root constant size in shader */
/* ========================== *
* Shade shader structures
* ========================== */
SH_STRUCT(sh_shade_constants {
SH_DECL(uint, albedo_tex_urid);
SH_DECL(uint, emittance_tex_urid);
SH_DECL(uint, write_tex_urid);
SH_DECL(uint, tex_width);
SH_DECL(uint, tex_height);
});
SH_ASSERT_32BIT(struct sh_shade_constants, 5); /* Expected 32bit root constant size in shader */
/* ========================== * /* ========================== *
* Material shader structures * Material shader structures
* ========================== */ * ========================== */
@ -112,6 +99,34 @@ SH_STRUCT(sh_material_grid {
SH_DECL(uint, y_srgb); SH_DECL(uint, y_srgb);
}); });
/* ========================== *
* Flood shader structures
* ========================== */
SH_STRUCT(sh_flood_constants {
SH_DECL(int, step_len);
SH_DECL(uint, emittance_tex_urid);
SH_DECL(uint, flood_read_tex_urid);
SH_DECL(uint, flood_write_tex_urid);
SH_DECL(uint, tex_width);
SH_DECL(uint, tex_height);
});
SH_ASSERT_32BIT(struct sh_flood_constants, 6); /* Expected 32bit root constant size in shader */
/* ========================== *
* Shade shader structures
* ========================== */
SH_STRUCT(sh_shade_constants {
SH_DECL(uint, albedo_tex_urid);
SH_DECL(uint, emittance_tex_urid);
SH_DECL(uint, emittance_flood_tex_urid);
SH_DECL(uint, write_tex_urid);
SH_DECL(uint, tex_width);
SH_DECL(uint, tex_height);
});
SH_ASSERT_32BIT(struct sh_shade_constants, 6); /* Expected 32bit root constant size in shader */
/* ========================== * /* ========================== *
* Shape shader structures * Shape shader structures
* ========================== */ * ========================== */

View File

@ -5,9 +5,10 @@
* ========================== */ * ========================== */
#define ROOTSIG \ #define ROOTSIG \
"RootConstants(num32BitConstants = 5, b0), " \ "RootConstants(num32BitConstants = 6, b0), " \
"DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
"DescriptorTable(UAV(u0, space = 1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ "DescriptorTable(SRV(t0, space = 1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
"DescriptorTable(UAV(u0, space = 2, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
\ \
\ \
"StaticSampler(s0, " \ "StaticSampler(s0, " \
@ -18,8 +19,9 @@
"maxAnisotropy = 1)" "maxAnisotropy = 1)"
ConstantBuffer<struct sh_shade_constants> g_constants : register(b0); ConstantBuffer<struct sh_shade_constants> g_constants : register(b0);
Texture2D g_read_textures[] : register(t0, space0); Texture2D<float4> g_gbuff_textures[] : register(t0, space0);
RWTexture2D<float4> g_write_textures[]: register(u0, space1); Texture2D<int2> g_emittance_flood_textures[] : register(t0, space1);
RWTexture2D<float4> g_write_textures[]: register(u0, space2);
SamplerState g_sampler : register(s0); SamplerState g_sampler : register(s0);
@ -34,14 +36,18 @@ struct cs_input {
[numthreads(8, 8, 1)] [numthreads(8, 8, 1)]
SH_ENTRY(ROOTSIG) void cs(struct cs_input input) SH_ENTRY(ROOTSIG) void cs(struct cs_input input)
{ {
uint3 job_id = input.SV_DispatchThreadID; uint2 id = input.SV_DispatchThreadID.xy;
if (job_id.x >= g_constants.tex_width || job_id.y >= g_constants.tex_height) { if (id.x >= g_constants.tex_width || id.y >= g_constants.tex_height) {
return; /* Overflow */ return; /* Overflow */
} }
float4 old_color = g_read_textures[g_constants.write_tex_urid][job_id.xy]; float4 old_color = g_gbuff_textures[g_constants.write_tex_urid][id];
float4 albedo = g_read_textures[g_constants.albedo_tex_urid][job_id.xy]; float4 albedo = g_gbuff_textures[g_constants.albedo_tex_urid][id];
float4 emittance = g_read_textures[g_constants.emittance_tex_urid][job_id.xy]; float4 emittance = g_gbuff_textures[g_constants.emittance_tex_urid][id];
float4 final_color = old_color + albedo + emittance;
g_write_textures[g_constants.write_tex_urid][job_id.xy] = final_color; int2 emittance_flood = g_emittance_flood_textures[g_constants.emittance_flood_tex_urid][id];
emittance_flood *= (emittance_flood.x >= 0 && emittance_flood.y >= 0);
float4 final_color = old_color + albedo + float4(float(emittance_flood.x) / float(g_constants.tex_width), float(emittance_flood.y) / float(g_constants.tex_height), 0, 1);
g_write_textures[g_constants.write_tex_urid][id] = final_color;
} }

View File

@ -77,13 +77,18 @@ struct shader_desc {
struct string func; struct string func;
}; };
struct pipeline_rtv_desc {
DXGI_FORMAT format;
b32 blending;
};
struct pipeline_desc { struct pipeline_desc {
struct string name; struct string name;
struct shader_desc cs; struct shader_desc cs;
struct shader_desc vs; struct shader_desc vs;
struct shader_desc ps; struct shader_desc ps;
D3D12_INPUT_ELEMENT_DESC ia[8]; D3D12_INPUT_ELEMENT_DESC ia[8];
DXGI_FORMAT rtv_formats[8]; struct pipeline_rtv_desc rtvs[8];
}; };
struct pipeline { struct pipeline {
@ -665,14 +670,6 @@ INTERNAL void dx12_init_pipelines(void)
/* Register pipeline descs */ /* Register pipeline descs */
{ {
/* Shade pipeline */
{
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("shade");
desc->cs.file = LIT("sh/shade.hlsl");
desc->cs.func = LIT("cs");
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
}
/* Material pipeline */ /* Material pipeline */
{ {
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc); struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
@ -681,8 +678,26 @@ INTERNAL void dx12_init_pipelines(void)
desc->ps.file = LIT("sh/material.hlsl"); desc->ps.file = LIT("sh/material.hlsl");
desc->vs.func = LIT("vs"); desc->vs.func = LIT("vs");
desc->ps.func = LIT("ps"); desc->ps.func = LIT("ps");
desc->rtv_formats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc->rtv_formats[1] = DXGI_FORMAT_R8G8B8A8_UNORM; desc->rtvs[0].blending = 1;
desc->rtvs[1].format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc->rtvs[1].blending = 1;
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
}
/* Flood pipeline */
{
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("flood");
desc->cs.file = LIT("sh/flood.hlsl");
desc->cs.func = LIT("cs");
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
}
/* Shade pipeline */
{
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("shade");
desc->cs.file = LIT("sh/shade.hlsl");
desc->cs.func = LIT("cs");
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
} }
/* Shape pipeline */ /* Shape pipeline */
@ -695,7 +710,8 @@ INTERNAL void dx12_init_pipelines(void)
desc->ps.func = LIT("ps"); 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[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->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; desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc->rtvs[0].blending = 1;
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
} }
/* Blit pipeilne */ /* Blit pipeilne */
@ -706,7 +722,8 @@ INTERNAL void dx12_init_pipelines(void)
desc->ps.file = LIT("sh/blit.hlsl"); desc->ps.file = LIT("sh/blit.hlsl");
desc->vs.func = LIT("vs"); desc->vs.func = LIT("vs");
desc->ps.func = LIT("ps"); desc->ps.func = LIT("ps");
desc->rtv_formats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc->rtvs[0].blending = 1;
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
} }
} }
@ -871,11 +888,11 @@ INTERNAL SYS_JOB_DEF(shader_compile_job, job)
char *func_cstr = cstr_from_string(scratch.arena, shader_desc.func); char *func_cstr = cstr_from_string(scratch.arena, shader_desc.func);
u32 d3d_compile_flags = D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES; u32 d3d_compile_flags = D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES;
#if DX12_SHADER_DEBUG #if DX12_SHADER_DEBUG
d3d_compile_flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_ENABLE_STRICTNESS; d3d_compile_flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_ENABLE_STRICTNESS;
#else #else
d3d_compile_flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; d3d_compile_flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3;
#endif #endif
/* Compile shader */ /* Compile shader */
{ {
@ -913,11 +930,11 @@ INTERNAL SYS_JOB_DEF(shader_compile_job, job)
dx12_include_handler_release(include_handler); dx12_include_handler_release(include_handler);
} }
#if 0 #if 0
if (success) { if (success) {
logf_success("Finished compiling shader \"%F\" in %F seconds", FMT_STR(src_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
param->success = success; param->success = success;
param->blob = blob; param->blob = blob;
@ -1159,16 +1176,24 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
/* Blend state */ /* Blend state */
D3D12_BLEND_DESC blend_desc = { D3D12_BLEND_DESC blend_desc = {
.AlphaToCoverageEnable = 0, .AlphaToCoverageEnable = 0,
.IndependentBlendEnable = 0 .IndependentBlendEnable = 1
}; };
blend_desc.RenderTarget[0].BlendEnable = 1; for (i32 i = 0; i < (i32)countof(desc->rtvs); ++i) {
blend_desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; STATIC_ASSERT(countof(blend_desc.RenderTarget) <= countof(desc->rtvs));
blend_desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; if (desc->rtvs[i].format != DXGI_FORMAT_UNKNOWN) {
blend_desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; b32 blending_enabled = desc->rtvs[i].blending;
blend_desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE; blend_desc.RenderTarget[i].BlendEnable = blending_enabled;
blend_desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; blend_desc.RenderTarget[i].SrcBlend = D3D12_BLEND_SRC_ALPHA;
blend_desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; blend_desc.RenderTarget[i].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; blend_desc.RenderTarget[i].BlendOp = D3D12_BLEND_OP_ADD;
blend_desc.RenderTarget[i].SrcBlendAlpha = D3D12_BLEND_ONE;
blend_desc.RenderTarget[i].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
blend_desc.RenderTarget[i].BlendOpAlpha = D3D12_BLEND_OP_ADD;
blend_desc.RenderTarget[i].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
} else {
break;
}
}
/* Disable depth stencil */ /* Disable depth stencil */
D3D12_DEPTH_STENCIL_DESC depth_stencil_desc = { D3D12_DEPTH_STENCIL_DESC depth_stencil_desc = {
@ -1193,13 +1218,13 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
pso_desc.DepthStencilState = depth_stencil_desc; pso_desc.DepthStencilState = depth_stencil_desc;
pso_desc.InputLayout = input_layout_desc; pso_desc.InputLayout = input_layout_desc;
pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
for (i32 i = 0; i < (i32)countof(desc->rtv_formats); ++i) { for (i32 i = 0; i < (i32)countof(desc->rtvs); ++i) {
STATIC_ASSERT(countof(pso_desc.RTVFormats) <= countof(desc->rtv_formats)); STATIC_ASSERT(countof(pso_desc.RTVFormats) <= countof(desc->rtvs));
DXGI_FORMAT format = desc->rtv_formats[i]; DXGI_FORMAT format = desc->rtvs[i].format;
if (format == DXGI_FORMAT_UNKNOWN) { if (format != DXGI_FORMAT_UNKNOWN) {
break;
} else {
pso_desc.RTVFormats[pso_desc.NumRenderTargets++] = format; pso_desc.RTVFormats[pso_desc.NumRenderTargets++] = format;
} else {
break;
} }
} }
pso_desc.SampleDesc.Count = 1; pso_desc.SampleDesc.Count = 1;
@ -1563,6 +1588,8 @@ struct sig {
struct v2i32 old_size; struct v2i32 old_size;
struct dx12_resource *albedo; struct dx12_resource *albedo;
struct dx12_resource *emittance; struct dx12_resource *emittance;
struct dx12_resource *emittance_flood_a;
struct dx12_resource *emittance_flood_b;
struct sig *next_free; struct sig *next_free;
}; };
@ -1701,25 +1728,31 @@ INTERNAL void fenced_release(void *data, enum fenced_release_kind kind)
for (u32 i = 0; i < countof(G.command_queues); ++i) { for (u32 i = 0; i < countof(G.command_queues); ++i) {
struct command_queue *cq = G.command_queues[i]; struct command_queue *cq = G.command_queues[i];
struct snc_lock lock = snc_lock_s(&cq->submit_fence_mutex); struct snc_lock lock = snc_lock_s(&cq->submit_fence_mutex);
fr_targets[i] = cq->submit_fence_target; {
fr_targets[i] = cq->submit_fence_target;
}
snc_unlock(&lock); snc_unlock(&lock);
} }
/* Push data to release queue */ /* Push data to release queue */
{ {
struct snc_lock lock = snc_lock_e(&G.fenced_releases_mutex); struct snc_lock lock = snc_lock_e(&G.fenced_releases_mutex);
*arena_push(G.fenced_releases_arena, struct fenced_release_data) = fr; {
MEMCPY(G.fenced_release_targets, fr_targets, sizeof(fr_targets)); *arena_push(G.fenced_releases_arena, struct fenced_release_data) = fr;
MEMCPY(G.fenced_release_targets, fr_targets, sizeof(fr_targets));
}
snc_unlock(&lock); snc_unlock(&lock);
} }
/* Wake evictor */ /* Wake evictor */
struct snc_lock lock = snc_lock_e(&G.evictor_wake_mutex);
{ {
++G.evictor_wake_gen; struct snc_lock lock = snc_lock_e(&G.evictor_wake_mutex);
snc_cv_signal(&G.evictor_wake_cv, I32_MAX); {
++G.evictor_wake_gen;
snc_cv_signal(&G.evictor_wake_cv, I32_MAX);
}
snc_unlock(&lock);
} }
snc_unlock(&lock);
} }
/* ========================== * /* ========================== *
@ -1818,27 +1851,56 @@ INTERNAL void dx12_resource_release_now(struct dx12_resource *t)
snc_unlock(&lock); snc_unlock(&lock);
} }
INTERNAL void dx12_resource_barriers(ID3D12GraphicsCommandList *cl, i32 num_resources, struct dx12_resource **resources, enum D3D12_RESOURCE_STATES *states) void gp_resource_release(struct gp_resource *resource)
{
struct dx12_resource *r = (struct dx12_resource *)resource;
fenced_release(r, FENCED_RELEASE_KIND_RESOURCE);
}
/* ========================== *
* Resource barrier
* ========================== */
struct dx12_resource_barrier_desc {
enum D3D12_RESOURCE_BARRIER_TYPE type;
struct dx12_resource *resource;
enum D3D12_RESOURCE_STATES new_state; /* 0 if type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION */
};
INTERNAL void dx12_resource_barriers(ID3D12GraphicsCommandList *cl, i32 num_barriers, struct dx12_resource_barrier_desc *descs)
{ {
__prof; __prof;
struct arena_temp scratch = scratch_begin_no_conflict(); struct arena_temp scratch = scratch_begin_no_conflict();
i32 num_rbs = 0; i32 num_rbs = 0;
struct D3D12_RESOURCE_BARRIER *rbs = arena_push_array_no_zero(scratch.arena, struct D3D12_RESOURCE_BARRIER, num_resources); struct D3D12_RESOURCE_BARRIER *rbs = arena_push_array_no_zero(scratch.arena, struct D3D12_RESOURCE_BARRIER, num_barriers);
for (i32 i = 0; i < num_resources; ++i) { for (i32 i = 0; i < num_barriers; ++i) {
struct dx12_resource *resource = resources[i]; struct dx12_resource_barrier_desc *desc = &descs[i];
enum D3D12_RESOURCE_STATES old_state = resource->state; struct dx12_resource *resource = desc->resource;
enum D3D12_RESOURCE_STATES new_state = states[i]; enum D3D12_RESOURCE_BARRIER_TYPE type = desc->type;
if (new_state != old_state) { if (type == D3D12_RESOURCE_BARRIER_TYPE_TRANSITION) {
enum D3D12_RESOURCE_STATES old_state = resource->state;
enum D3D12_RESOURCE_STATES new_state = desc->new_state;
if (new_state != old_state) {
struct D3D12_RESOURCE_BARRIER *rb = &rbs[num_rbs++];
MEMZERO_STRUCT(rb);
rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
rb->Flags = 0;
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;
}
} else if (type == D3D12_RESOURCE_BARRIER_TYPE_UAV) {
struct D3D12_RESOURCE_BARRIER *rb = &rbs[num_rbs++]; struct D3D12_RESOURCE_BARRIER *rb = &rbs[num_rbs++];
MEMZERO_STRUCT(rb); MEMZERO_STRUCT(rb);
rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; rb->Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
rb->Flags = 0; rb->Flags = 0;
rb->Transition.pResource = resource->resource; rb->UAV.pResource = resource->resource;
rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; } else {
rb->Transition.StateBefore = old_state; /* Unknown barrier */
rb->Transition.StateAfter = new_state; ASSERT(0);
resource->state = new_state;
} }
} }
@ -1849,12 +1911,6 @@ INTERNAL void dx12_resource_barriers(ID3D12GraphicsCommandList *cl, i32 num_reso
scratch_end(scratch); scratch_end(scratch);
} }
void gp_resource_release(struct gp_resource *resource)
{
struct dx12_resource *r = (struct dx12_resource *)resource;
fenced_release(r, FENCED_RELEASE_KIND_RESOURCE);
}
/* ========================== * /* ========================== *
* Command queue * Command queue
* ========================== */ * ========================== */
@ -2551,7 +2607,7 @@ struct v2i32 gp_texture_get_size(struct gp_resource *resource)
* Run * Run
* ========================== */ * ========================== */
INTERNAL struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, struct v2i32 size) INTERNAL struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, struct v2i32 size, D3D12_RESOURCE_STATES initial_state)
{ {
__prof; __prof;
D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
@ -2573,14 +2629,12 @@ INTERNAL struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, struct v2i32 size
desc.SampleDesc.Quality = 0; desc.SampleDesc.Quality = 0;
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_RENDER_TARGET;
struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, DX12_RESOURCE_VIEW_FLAG_SRV | DX12_RESOURCE_VIEW_FLAG_UAV | DX12_RESOURCE_VIEW_FLAG_RTV); struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, DX12_RESOURCE_VIEW_FLAG_SRV | DX12_RESOURCE_VIEW_FLAG_UAV | DX12_RESOURCE_VIEW_FLAG_RTV);
r->texture_size = size; r->texture_size = size;
return r; return r;
} }
/* Calculate the view projection matrix */ /* Calculate the view projection matrix */
INLINE struct mat4x4 calculate_vp(struct xform view, f32 viewport_width, f32 viewport_height) INLINE struct mat4x4 calculate_vp(struct xform view, f32 viewport_width, f32 viewport_height)
{ {
struct mat4x4 projection = mat4x4_from_ortho(0.0, viewport_width, viewport_height, 0.0, -1.0, 1.0); struct mat4x4 projection = mat4x4_from_ortho(0.0, viewport_width, viewport_height, 0.0, -1.0, 1.0);
@ -2611,29 +2665,30 @@ void gp_run(struct gp_run_params params)
if (sig->albedo) { if (sig->albedo) {
fenced_release(sig->albedo, FENCED_RELEASE_KIND_RESOURCE); fenced_release(sig->albedo, FENCED_RELEASE_KIND_RESOURCE);
} }
sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size); sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size, D3D12_RESOURCE_STATE_RENDER_TARGET);
/* Allocate emittance buffer */ /* Allocate emittance buffer */
if (sig->emittance) { if (sig->emittance) {
fenced_release(sig->emittance, FENCED_RELEASE_KIND_RESOURCE); fenced_release(sig->emittance, FENCED_RELEASE_KIND_RESOURCE);
} }
sig->emittance = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size); sig->emittance = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
struct dx12_resource *gbuffers[] = { /* Allocate emittance field buffers */
sig->albedo, if (sig->emittance_flood_a) {
sig->emittance fenced_release(sig->emittance_flood_a, FENCED_RELEASE_KIND_RESOURCE);
}; }
D3D12_CPU_DESCRIPTOR_HANDLE gbuffer_rtvs[] = { if (sig->emittance_flood_b) {
sig->albedo->rtv_descriptor->handle, fenced_release(sig->emittance_flood_b, FENCED_RELEASE_KIND_RESOURCE);
sig->emittance->rtv_descriptor->handle }
}; sig->emittance_flood_a = gbuff_alloc(DXGI_FORMAT_R16G16_SINT, final_target_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
STATIC_ASSERT(countof(gbuffers) == countof(gbuffer_rtvs)); sig->emittance_flood_b = gbuff_alloc(DXGI_FORMAT_R16G16_SINT, final_target_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
struct sprite_scope *sprite_scope = sprite_scope_begin(); struct sprite_scope *sprite_scope = sprite_scope_begin();
struct pipeline_scope *pipeline_scope = pipeline_scope_begin(); struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, LIT("material")); struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, LIT("material"));
struct pipeline *flood_pipeline = pipeline_from_name(pipeline_scope, LIT("flood"));
struct pipeline *shade_pipeline = pipeline_from_name(pipeline_scope, LIT("shade")); struct pipeline *shade_pipeline = pipeline_from_name(pipeline_scope, LIT("shade"));
struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, LIT("shape")); struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, LIT("shape"));
struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT]; struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT];
@ -2710,149 +2765,246 @@ void gp_run(struct gp_run_params params)
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps); ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps);
/* Bind gbuffer RTVs */ /* Material pass */
{ {
enum D3D12_RESOURCE_STATES states[] = { __profn("Material pass");
D3D12_RESOURCE_STATE_RENDER_TARGET, __profnc_dx12(cl->cq->prof, cl->cl, "Material pass", RGB32_F(0.5, 0.2, 0.2));
D3D12_RESOURCE_STATE_RENDER_TARGET
}; /* Bind gbuffers */
STATIC_ASSERT(countof(states) == countof(gbuffers)); {
dx12_resource_barriers(cl->cl, countof(gbuffers), gbuffers, states); struct dx12_resource_barrier_desc barriers[] = {
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, countof(gbuffer_rtvs), gbuffer_rtvs, 0, 0); { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->albedo, D3D12_RESOURCE_STATE_RENDER_TARGET },
/* Clear */ { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance, D3D12_RESOURCE_STATE_RENDER_TARGET }
};
D3D12_CPU_DESCRIPTOR_HANDLE rtvs[] = {
sig->albedo->rtv_descriptor->handle,
sig->emittance->rtv_descriptor->handle,
};
dx12_resource_barriers(cl->cl, countof(barriers), barriers);
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, countof(rtvs), rtvs, 0, 0);
}
/* Clear gbuffers */
{ {
__profn("Clear gbuffers"); __profn("Clear gbuffers");
__profnc_dx12(cl->cq->prof, cl->cl, "Clear gbuffers", RGB32_F(0.5, 0.2, 0.2)); __profnc_dx12(cl->cq->prof, cl->cl, "Clear gbuffers", RGB32_F(0.5, 0.2, 0.2));
f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f };
for (i32 i = 0; i < (i32)countof(gbuffers); ++i) { ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, sig->albedo->rtv_descriptor->handle, clear_color, 0, 0);
struct dx12_resource *gb = gbuffers[i]; ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, sig->emittance->rtv_descriptor->handle, clear_color, 0, 0);
ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, gb->rtv_descriptor->handle, clear_color, 0, 0); }
/* Dispatch */
if (material_pipeline->success) {
__profn("Material pass run");
__profnc_dx12(cl->cq->prof, cl->cl, "Material pass run", RGB32_F(0.5, 0.2, 0.2));
/* Bind pipeline */
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, material_pipeline->pso);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, material_pipeline->rootsig);
/* Set Rasterizer State */
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport);
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
/* Set constants */
struct sh_material_constants constants = ZI;
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
/* Set parameters */
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants));
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle);
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, material_instance_buffer->resource->gpu_address);
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 3, grid_buffer->resource->gpu_address);
/* Draw */
u32 instance_count = material_instance_buffer->size / sizeof(struct sh_material_instance);
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0);
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(quad_index_buffer, DXGI_FORMAT_R16_UINT);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv);
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0);
}
}
/* Flood pass */
struct dx12_resource *emittance_flood_read = sig->emittance_flood_a;
struct dx12_resource *emittance_flood_write = sig->emittance_flood_b;
{
__profn("Flood pass");
__profnc_dx12(cl->cq->prof, cl->cl, "Flood pass", RGB32_F(0.5, 0.2, 0.2));
/* Transition emittance & emittance flood */
{
struct dx12_resource_barrier_desc barriers[] = {
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE },
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, emittance_flood_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS },
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, emittance_flood_write, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }
};
dx12_resource_barriers(cl->cl, countof(barriers), barriers);
}
/* Clear emittance floods */
if (params.clear_target) {
__profn("Clear emittance floods");
__profnc_dx12(cl->cq->prof, cl->cl, "Clear emittance floods", RGB32_F(0.5, 0.2, 0.2));
f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f };
ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(cl->cl, gpu_handle_from_descriptor(emittance_flood_read->uav_descriptor, descriptor_heap), emittance_flood_read->uav_descriptor->handle, emittance_flood_read->resource, clear_color, 0, 0);
ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(cl->cl, gpu_handle_from_descriptor(emittance_flood_write->uav_descriptor, descriptor_heap), emittance_flood_write->uav_descriptor->handle, emittance_flood_write->resource, clear_color, 0, 0);
}
/* Dispatch */
if (flood_pipeline->success) {
/* Bind pipeline */
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, flood_pipeline->pso);
ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, flood_pipeline->rootsig);
i32 step_length = -1;
while (step_length != 0) {
__profn("Flood step");
__profnc_dx12(cl->cq->prof, cl->cl, "Flood step", RGB32_F(0.5, 0.2, 0.2));
/* UAV barrier */
{
struct dx12_resource_barrier_desc barriers[] = {
{ D3D12_RESOURCE_BARRIER_TYPE_UAV, emittance_flood_read, 0 },
/* TODO: Remove this barrier */
{ D3D12_RESOURCE_BARRIER_TYPE_UAV, emittance_flood_write, 0 }
};
dx12_resource_barriers(cl->cl, countof(barriers), barriers);
}
/* Set constants */
struct sh_flood_constants constants = ZI;
constants.step_len = sh_int_from_i32(step_length);
constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index);
constants.flood_read_tex_urid = sh_uint_from_u32(emittance_flood_read->uav_descriptor->index);
constants.flood_write_tex_urid = sh_uint_from_u32(emittance_flood_write->uav_descriptor->index);
constants.tex_width = sh_uint_from_u32(final_target_size.x);
constants.tex_height = sh_uint_from_u32(final_target_size.y);
/* Set parameters */
command_list_set_compute_root_constant(cl, &constants, sizeof(constants));
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle);
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 2, descriptor_heap->start_gpu_handle);
/* Dispatch */
ID3D12GraphicsCommandList_Dispatch(cl->cl, (final_target_size.x + 7) / 8, (final_target_size.y + 7) / 8, 1);
/* Swap & increment */
struct dx12_resource *swp = emittance_flood_read;
emittance_flood_read = emittance_flood_write;
emittance_flood_write = swp;
if (step_length == -1) {
step_length = max_i32(final_target_size.x, final_target_size.y) / 2;
} else {
step_length /= 2;
}
} }
} }
} }
/* Material pass */ /* Shade pass */
if (material_pipeline->success) {
__profn("Material pass");
__profnc_dx12(cl->cq->prof, cl->cl, "Material pass", RGB32_F(0.5, 0.2, 0.2));
/* Bind pipeline */
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, material_pipeline->pso);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, material_pipeline->rootsig);
/* Set constants */
struct sh_material_constants constants = ZI;
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants));
/* Set descriptor tables */
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle);
/* Set instance buffer */
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, material_instance_buffer->resource->gpu_address);
/* Set grid buffer */
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 3, grid_buffer->resource->gpu_address);
/* Setup Rasterizer State */
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport);
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
/* Draw */
u32 instance_count = material_instance_buffer->size / sizeof(struct sh_material_instance);
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0);
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(quad_index_buffer, DXGI_FORMAT_R16_UINT);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv);
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0);
}
/* Transition gbuffers to SRV */
{ {
enum D3D12_RESOURCE_STATES states[] = { __profn("Shade pass");
D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE, __profnc_dx12(cl->cq->prof, cl->cl, "Shade pass", RGB32_F(0.5, 0.2, 0.2));
D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE
};
STATIC_ASSERT(countof(states) == countof(gbuffers));
dx12_resource_barriers(cl->cl, countof(gbuffers), gbuffers, states);
}
/* Transition final target to UAV */ /* Transition gbuffers & final target */
{ {
enum D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; struct dx12_resource_barrier_desc barriers[] = {
dx12_resource_barriers(cl->cl, 1, &final_target, &state); { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->albedo, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE },
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE },
{ D3D12_RESOURCE_BARRIER_TYPE_UAV, emittance_flood_read, 0 },
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, emittance_flood_read, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE },
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, final_target, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }
};
dx12_resource_barriers(cl->cl, countof(barriers), barriers);
}
/* Clear final target */
if (params.clear_target) { if (params.clear_target) {
__profn("Clear target"); __profn("Clear target");
__profnc_dx12(cl->cq->prof, cl->cl, "Clear target", RGB32_F(0.5, 0.2, 0.2)); __profnc_dx12(cl->cq->prof, cl->cl, "Clear target", RGB32_F(0.5, 0.2, 0.2));
f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f };
ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(cl->cl, gpu_handle_from_descriptor(final_target->uav_descriptor, descriptor_heap), final_target->uav_descriptor->handle, final_target->resource, clear_color, 0, 0); ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(cl->cl, gpu_handle_from_descriptor(final_target->uav_descriptor, descriptor_heap), final_target->uav_descriptor->handle, final_target->resource, clear_color, 0, 0);
} }
}
/* Shade pass */
if (shade_pipeline->success) {
__profn("Shade pass");
__profnc_dx12(cl->cq->prof, cl->cl, "Shade pass", RGB32_F(0.5, 0.2, 0.2));
/* Bind pipeline */
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, shade_pipeline->pso);
ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, shade_pipeline->rootsig);
/* Set constants */
struct sh_shade_constants constants = ZI;
constants.albedo_tex_urid = sh_uint_from_u32(sig->albedo->srv_descriptor->index);
constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index);
constants.write_tex_urid = sh_uint_from_u32(final_target->uav_descriptor->index);
constants.tex_width = sh_uint_from_u32(final_target_size.x);
constants.tex_height = sh_uint_from_u32(final_target_size.y);
command_list_set_compute_root_constant(cl, &constants, sizeof(constants));
/* Set descriptor tables */
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle);
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 2, descriptor_heap->start_gpu_handle);
/* Dispatch */ /* Dispatch */
ID3D12GraphicsCommandList_Dispatch(cl->cl, (final_target_size.x + 7) / 8, (final_target_size.y + 7) / 8, 1); if (shade_pipeline->success) {
} __profn("Shade pass run");
__profnc_dx12(cl->cq->prof, cl->cl, "Shade pass run", RGB32_F(0.5, 0.2, 0.2));
/* Bind final target as RTV */ /* Bind pipeline */
{ ID3D12GraphicsCommandList_SetPipelineState(cl->cl, shade_pipeline->pso);
enum D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_RENDER_TARGET; ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, shade_pipeline->rootsig);
dx12_resource_barriers(cl->cl, 1, &final_target, &state);
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &final_target->rtv_descriptor->handle, 0, 0); /* Set constants */
struct sh_shade_constants constants = ZI;
constants.albedo_tex_urid = sh_uint_from_u32(sig->albedo->srv_descriptor->index);
constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index);
constants.emittance_flood_tex_urid = sh_uint_from_u32(emittance_flood_read->srv_descriptor->index);
constants.write_tex_urid = sh_uint_from_u32(final_target->uav_descriptor->index);
constants.tex_width = sh_uint_from_u32(final_target_size.x);
constants.tex_height = sh_uint_from_u32(final_target_size.y);
/* Set parameters */
command_list_set_compute_root_constant(cl, &constants, sizeof(constants));
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle);
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 2, descriptor_heap->start_gpu_handle);
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 3, descriptor_heap->start_gpu_handle);
/* Dispatch */
ID3D12GraphicsCommandList_Dispatch(cl->cl, (final_target_size.x + 7) / 8, (final_target_size.y + 7) / 8, 1);
}
} }
/* Shape pass */ /* Shape pass */
if (shape_pipeline->success) { {
__profn("Shape pass"); __profn("Shape pass");
__profnc_dx12(cl->cq->prof, cl->cl, "Shape pass", RGB32_F(0.5, 0.2, 0.2)); __profnc_dx12(cl->cq->prof, cl->cl, "Shape pass", RGB32_F(0.5, 0.2, 0.2));
/* Bind pipeline */ /* Bind final target as RTV */
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, shape_pipeline->pso); {
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, shape_pipeline->rootsig); struct dx12_resource_barrier_desc barriers[] = {
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, final_target, D3D12_RESOURCE_STATE_RENDER_TARGET },
};
dx12_resource_barriers(cl->cl, countof(barriers), barriers);
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &final_target->rtv_descriptor->handle, 0, 0);
}
/* Set constants */ /* Dispatch */
struct sh_shape_constants constants = ZI; if (shape_pipeline->success) {
constants.projection = sh_float4x4_from_mat4x4(vp_matrix); __profn("Shape pass run");
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); __profnc_dx12(cl->cq->prof, cl->cl, "Shape pass run", RGB32_F(0.5, 0.2, 0.2));
/* Setup Rasterizer State */ /* Bind pipeline */
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport); ID3D12GraphicsCommandList_SetPipelineState(cl->cl, shape_pipeline->pso);
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport); ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, shape_pipeline->rootsig);
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
/* Draw */ /* Set Rasterizer State */
u32 index_count = shape_indices_buffer->size / sizeof(u32); D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(shape_verts_buffer, sizeof(struct sh_shape_vert)); D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport);
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(shape_indices_buffer, DXGI_FORMAT_R32_UINT); ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv);
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv); /* Set constants */
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, index_count, 1, 0, 0, 0); struct sh_shape_constants constants = ZI;
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
/* Set parameters */
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants));
/* Draw */
u32 index_count = shape_indices_buffer->size / sizeof(u32);
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(shape_verts_buffer, sizeof(struct sh_shape_vert));
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(shape_indices_buffer, DXGI_FORMAT_R32_UINT);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv);
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, index_count, 1, 0, 0, 0);
}
} }
} }
command_list_close(cl); command_list_close(cl);
@ -3101,20 +3253,20 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, blit_pipeline->pso); ID3D12GraphicsCommandList_SetPipelineState(cl->cl, blit_pipeline->pso);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, blit_pipeline->rootsig); ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, blit_pipeline->rootsig);
/* Set Rasterizer State */
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
/* Set constants */ /* Set constants */
struct sh_blit_constants constants = ZI; struct sh_blit_constants constants = ZI;
constants.projection = sh_float4x4_from_mat4x4(vp_matrix); constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
constants.tex_urid = sh_uint_from_u32(src->srv_descriptor->index); constants.tex_urid = sh_uint_from_u32(src->srv_descriptor->index);
constants.gamma = sh_float_from_f32(2.2); constants.gamma = sh_float_from_f32(2.2);
/* Set parameters */
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); command_list_set_graphics_root_constant(cl, &constants, sizeof(constants));
/* Set descriptor tables */
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle);
/* Setup Rasterizer State */
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
/* Draw */ /* Draw */
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0); D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0);
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(quad_index_buffer, DXGI_FORMAT_R16_UINT); D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(quad_index_buffer, DXGI_FORMAT_R16_UINT);

View File

@ -1691,7 +1691,8 @@ INTERNAL void user_update(struct sys_window *window)
{ {
/* Queue player move cmd */ /* Queue player move cmd */
f32 move_speed = 1.0f; f32 move_speed = 1.0f;
if (G.bind_states[USER_BIND_KIND_WALK].is_held) { //if (G.bind_states[USER_BIND_KIND_WALK].is_held) {
if (G.bind_states[USER_BIND_KIND_FULLSCREEN_MOD].is_held) {
//const f32 walk_ratio = 0.25f; //const f32 walk_ratio = 0.25f;
const f32 walk_ratio = 0.05f; const f32 walk_ratio = 0.05f;
move_speed *= walk_ratio; move_speed *= walk_ratio;