gbuffer testing

This commit is contained in:
jacob 2025-07-16 17:00:38 -05:00
parent f58bcd52ee
commit 9770cb0a84
14 changed files with 479 additions and 322 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@
*.rdbg
*.10x
*.cap
*.wpix
*.tracy
*.pdb
*.exe

View File

@ -483,7 +483,7 @@ void OnBuild(StringList cli_args)
"-Wno-cast-qual -Wno-missing-noreturn "
"-Wno-initializer-overrides "
"-Wno-c99-extensions -Wno-c++98-compat-pedantic -Wno-c++98-compat "
"-Wno-switch-enum -Wno-switch-default "
"-Wno-switch-enum -Wno-assign-enum -Wno-switch-default "
"-Wno-reserved-identifier -Wno-reserved-macro-identifier "
"-Wno-missing-designated-field-initializers "
"-Wno-unsafe-buffer-usage "

View File

@ -5,8 +5,9 @@
* ========================== */
#define ROOTSIG \
"RootConstants(num32BitConstants=18, b0), " \
"DescriptorTable(SRV(t0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
"RootConstants(num32BitConstants = 18, b0), " \
"DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
\
"StaticSampler(s0, " \
"filter = FILTER_MIN_MAG_MIP_POINT, " \
"addressU = TEXTURE_ADDRESS_CLAMP, " \

View File

@ -1,33 +0,0 @@
#include "sh/common.hlsl"
/* ========================== *
* Root signature
* ========================== */
#define ROOTSIG \
"RootConstants(num32BitConstants=16, b0), " \
"DescriptorTable(SRV(t0, 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_jfa_constants> g_constants : register(b0);
Texture2D g_textures[] : register(t0);
SamplerState g_sampler : register(s0);
/* ========================== *
* Compute shader
* ========================== */
struct cs_input {
DECLS(uint, SV_DispatchThreadID);
};
[numthreads(32, 1, 1)]
SH_ENTRY(ROOTSIG) void cs(struct cs_input input)
{
}

View File

@ -5,10 +5,11 @@
* ========================== */
#define ROOTSIG \
"RootConstants(num32BitConstants=16, b0), " \
"SRV(t0), " \
"SRV(t1), " \
"DescriptorTable(SRV(t2, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
"RootConstants(num32BitConstants = 16, b0), " \
"DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
"SRV(t0, space = 1), " \
"SRV(t0, space = 2), " \
\
"StaticSampler(s0, " \
"filter = FILTER_MIN_MAG_MIP_POINT, " \
"addressU = TEXTURE_ADDRESS_CLAMP, " \
@ -17,9 +18,9 @@
"maxAnisotropy = 1)"
ConstantBuffer<struct sh_material_constants> g_constants : register(b0);
StructuredBuffer<struct sh_material_instance> g_instances : register(t0);
StructuredBuffer<struct sh_material_grid> g_grids : register(t1);
Texture2D g_textures[] : register(t2);
Texture2D g_textures[] : register(t0, space0);
StructuredBuffer<struct sh_material_instance> g_instances : register(t0, space1);
StructuredBuffer<struct sh_material_grid> g_grids : register(t0, space2);
SamplerState g_sampler : register(s0);

View File

@ -70,12 +70,17 @@ SH_STRUCT(sh_blit_constants {
SH_ASSERT_32BIT(struct sh_blit_constants, 18); /* Expected 32bit root constant size in shader */
/* ========================== *
* JFA shader structures
* Shade shader structures
* ========================== */
SH_STRUCT(sh_jfa_constants {
SH_DECL(float4x4, projection);
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

43
res/sh/shade.hlsl Normal file
View File

@ -0,0 +1,43 @@
#include "sh/common.hlsl"
/* ========================== *
* Root signature
* ========================== */
#define ROOTSIG \
"RootConstants(num32BitConstants = 5, 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_shade_constants> g_constants : register(b0);
Texture2D g_read_textures[] : register(t0, space0);
RWTexture2D<float4> g_write_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)
{
uint3 job_id = input.SV_DispatchThreadID;
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);
}

View File

@ -26,7 +26,7 @@ struct draw_startup_receipt draw_startup(struct font_startup_receipt *font_sr)
* Texture
* ========================== */
void draw_texture(struct gp_flow *flow, struct draw_texture_params params)
void draw_texture(struct gp_sig *flow, struct draw_texture_params params)
{
struct gp_cmd_desc cmd = ZI;
cmd.kind = GP_CMD_KIND_DRAW_MATERIAL;
@ -43,7 +43,7 @@ void draw_texture(struct gp_flow *flow, struct draw_texture_params params)
* Fill shapes
* ========================== */
void draw_poly_ex(struct gp_flow *flow, struct v2_array vertices, struct gp_indices indices, u32 color)
void draw_poly_ex(struct gp_sig *flow, struct v2_array vertices, struct gp_indices indices, u32 color)
{
struct gp_cmd_desc cmd = ZI;
cmd.kind = GP_CMD_KIND_DRAW_SHAPE;
@ -54,7 +54,7 @@ void draw_poly_ex(struct gp_flow *flow, struct v2_array vertices, struct gp_indi
}
/* Draws a filled polygon using triangles in a fan pattern */
void draw_poly(struct gp_flow *flow, struct v2_array vertices, u32 color)
void draw_poly(struct gp_sig *flow, struct v2_array vertices, u32 color)
{
if (vertices.count >= 3) {
struct arena_temp scratch = scratch_begin_no_conflict();
@ -80,7 +80,7 @@ void draw_poly(struct gp_flow *flow, struct v2_array vertices, u32 color)
}
}
void draw_circle(struct gp_flow *flow, struct v2 pos, f32 radius, u32 color, u32 detail)
void draw_circle(struct gp_sig *flow, struct v2 pos, f32 radius, u32 color, u32 detail)
{
struct arena_temp scratch = scratch_begin_no_conflict();
@ -103,7 +103,7 @@ void draw_circle(struct gp_flow *flow, struct v2 pos, f32 radius, u32 color, u32
scratch_end(scratch);
}
void draw_quad(struct gp_flow *flow, struct quad quad, u32 color)
void draw_quad(struct gp_sig *flow, struct quad quad, u32 color)
{
LOCAL_PERSIST u32 indices_array[6] = {
0, 1, 2,
@ -118,7 +118,7 @@ void draw_quad(struct gp_flow *flow, struct quad quad, u32 color)
* Line shapes
* ========================== */
void draw_gradient_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color)
void draw_gradient_line(struct gp_sig *flow, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color)
{
#if 0
struct quad quad = quad_from_line(start, end, thickness);
@ -131,19 +131,19 @@ void draw_gradient_line(struct gp_flow *flow, struct v2 start, struct v2 end, f3
#endif
}
void draw_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, u32 color)
void draw_line(struct gp_sig *flow, struct v2 start, struct v2 end, f32 thickness, u32 color)
{
struct quad quad = quad_from_line(start, end, thickness);
draw_quad(flow, quad, color);
}
void draw_ray(struct gp_flow *flow, struct v2 pos, struct v2 rel, f32 thickness, u32 color)
void draw_ray(struct gp_sig *flow, struct v2 pos, struct v2 rel, f32 thickness, u32 color)
{
struct quad quad = quad_from_ray(pos, rel, thickness);
draw_quad(flow, quad, color);
}
void draw_poly_line(struct gp_flow *flow, struct v2_array points, b32 loop, f32 thickness, u32 color)
void draw_poly_line(struct gp_sig *flow, struct v2_array points, b32 loop, f32 thickness, u32 color)
{
if (points.count >= 2) {
for (u64 i = 1; i < points.count; ++i) {
@ -161,7 +161,7 @@ void draw_poly_line(struct gp_flow *flow, struct v2_array points, b32 loop, f32
}
}
void draw_circle_line(struct gp_flow *flow, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
void draw_circle_line(struct gp_sig *flow, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
{
struct arena_temp scratch = scratch_begin_no_conflict();
@ -184,14 +184,14 @@ void draw_circle_line(struct gp_flow *flow, struct v2 pos, f32 radius, f32 thick
scratch_end(scratch);
}
void draw_quad_line(struct gp_flow *flow, struct quad quad, f32 thickness, u32 color)
void draw_quad_line(struct gp_sig *flow, struct quad quad, f32 thickness, u32 color)
{
struct v2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
struct v2_array a = { .points = points, .count = countof(points) };
draw_poly_line(flow, a, 1, thickness, color);
}
void draw_arrow_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color)
void draw_arrow_line(struct gp_sig *flow, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color)
{
const f32 head_width_ratio = 0.5f; /* Width of arrowhead relative to its length */
@ -221,13 +221,13 @@ void draw_arrow_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 t
draw_quad(flow, line_quad, color);
}
void draw_arrow_ray(struct gp_flow *flow, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color)
void draw_arrow_ray(struct gp_sig *flow, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color)
{
struct v2 end = v2_add(pos, rel);
draw_arrow_line(flow, pos, end, thickness, arrowhead_height, color);
}
void draw_collider_line(struct gp_flow *flow, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail)
void draw_collider_line(struct gp_sig *flow, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail)
{
struct arena_temp scratch = scratch_begin_no_conflict();
struct v2_array poly = ZI;
@ -256,7 +256,7 @@ void draw_collider_line(struct gp_flow *flow, struct collider_shape shape, struc
* Grid
* ========================== */
void draw_grid(struct gp_flow *flow, struct xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, struct v2 offset)
void draw_grid(struct gp_sig *flow, struct xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, struct v2 offset)
{
i32 grid_id = 0;
{
@ -286,7 +286,7 @@ void draw_grid(struct gp_flow *flow, struct xform xf, u32 bg0_color, u32 bg1_col
* ========================== */
/* Returns the rect of the text area */
struct rect draw_text(struct gp_flow *flow, struct draw_text_params params)
struct rect draw_text(struct gp_sig *flow, struct draw_text_params params)
{
struct arena_temp scratch = scratch_begin_no_conflict();

View File

@ -28,47 +28,47 @@ struct draw_texture_params {
f32 emittance;
};
void draw_texture(struct gp_flow *flow, struct draw_texture_params params);
void draw_texture(struct gp_sig *flow, struct draw_texture_params params);
/* ========================== *
* Fill shapes
* ========================== */
void draw_poly_ex(struct gp_flow *flow, struct v2_array vertices, struct gp_indices indices, u32 color);
void draw_poly_ex(struct gp_sig *flow, struct v2_array vertices, struct gp_indices indices, u32 color);
void draw_poly(struct gp_flow *flow, struct v2_array points, u32 color);
void draw_poly(struct gp_sig *flow, struct v2_array points, u32 color);
void draw_circle(struct gp_flow *flow, struct v2 pos, f32 radius, u32 color, u32 detail);
void draw_circle(struct gp_sig *flow, struct v2 pos, f32 radius, u32 color, u32 detail);
void draw_quad(struct gp_flow *flow, struct quad quad, u32 color);
void draw_quad(struct gp_sig *flow, struct quad quad, u32 color);
/* ========================== *
* Line shapes
* ========================== */
void draw_gradient_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color);
void draw_gradient_line(struct gp_sig *flow, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color);
void draw_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, u32 color);
void draw_line(struct gp_sig *flow, struct v2 start, struct v2 end, f32 thickness, u32 color);
void draw_ray(struct gp_flow *flow, struct v2 pos, struct v2 rel, f32 thickness, u32 color);
void draw_ray(struct gp_sig *flow, struct v2 pos, struct v2 rel, f32 thickness, u32 color);
void draw_poly_line(struct gp_flow *flow, struct v2_array points, b32 loop, f32 thickness, u32 color);
void draw_poly_line(struct gp_sig *flow, struct v2_array points, b32 loop, f32 thickness, u32 color);
void draw_circle_line(struct gp_flow *flow, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
void draw_circle_line(struct gp_sig *flow, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
void draw_quad_line(struct gp_flow *flow, struct quad quad, f32 thickness, u32 color);
void draw_quad_line(struct gp_sig *flow, struct quad quad, f32 thickness, u32 color);
void draw_arrow_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color);
void draw_arrow_line(struct gp_sig *flow, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color);
void draw_arrow_ray(struct gp_flow *flow, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color);
void draw_arrow_ray(struct gp_sig *flow, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color);
void draw_collider_line(struct gp_flow *flow, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail);
void draw_collider_line(struct gp_sig *flow, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail);
/* ========================== *
* Grid
* ========================== */
void draw_grid(struct gp_flow *flow, struct xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, struct v2 offset);
void draw_grid(struct gp_sig *flow, struct xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, struct v2 offset);
/* ========================== *
* Text
@ -116,6 +116,6 @@ struct draw_text_params {
struct string str;
};
struct rect draw_text(struct gp_flow *flow, struct draw_text_params params);
struct rect draw_text(struct gp_sig *flow, struct draw_text_params params);
#endif

View File

@ -17,9 +17,10 @@ void gp_startup(void);
struct gp_resource;
/* NOTE: Internally, the layer will make sure to not release any resources
* until after the GPU finishes using them. However, it is up to the caller
* to make sure the released resources aren't then referenced in any flow
* dispatches. */
* until after any in-flight GPU runs finish using them. However, it is up to
* the caller to make sure the released resources aren't then referenced in
* any runs
*/
void gp_resource_release(struct gp_resource *resource);
/* ========================== *
@ -91,20 +92,20 @@ struct gp_cmd_desc {
};
};
struct gp_dispatch_params {
struct gp_flow *flow;
struct gp_run_params {
struct gp_sig *sig;
struct gp_resource *draw_target;
struct rect draw_target_viewport;
struct xform draw_target_view;
b32 clear_target;
};
struct gp_flow *gp_flow_alloc(void);
struct gp_sig *gp_sig_alloc(void);
/* Returns a cmd id internal to the flow */
i32 gp_push_cmd(struct gp_flow *gp_flow, struct gp_cmd_desc *desc);
i32 gp_push_cmd(struct gp_sig *gp_sig, struct gp_cmd_desc *desc);
void gp_dispatch(struct gp_dispatch_params params);
void gp_run(struct gp_run_params params);
/* ========================== *
* Memory info

View File

@ -172,8 +172,8 @@ struct command_list {
struct command_descriptor_heap {
D3D12_DESCRIPTOR_HEAP_TYPE type;
ID3D12DescriptorHeap *heap;
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
D3D12_CPU_DESCRIPTOR_HANDLE start_cpu_handle;
D3D12_GPU_DESCRIPTOR_HANDLE start_gpu_handle;
struct command_descriptor_heap *next_in_command_list;
@ -664,11 +664,11 @@ INTERNAL void dx12_init_pipelines(void)
/* Register pipeline descs */
{
/* JFA pipeline */
/* Shade pipeline */
{
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("jfa");
desc->cs.file = LIT("sh/jfa.hlsl");
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);
}
@ -762,7 +762,7 @@ INTERNAL HRESULT dx12_include_open(ID3DInclude *d3d_handler, D3D_INCLUDE_TYPE in
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name);
if (handler->num_open_resources >= countof(handler->open_resources)) {
sys_panic(LIT("Dx12 include handler resource overflow"));
sys_panic(LIT("Dx12 include handler resource oversig"));
}
struct snc_lock lock = snc_lock_e(&handler->pipeline_mutex);
@ -1202,7 +1202,7 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
/* Copy error */
if (!success) {
ID3D10Blob *error_blob = vs.error_blob ? vs.error_blob : ps.error_blob;
ID3D10Blob *error_blob = cs.error_blob ? cs.error_blob : (vs.error_blob ? vs.error_blob : ps.error_blob);
if (error_blob) {
u64 error_blob_cstr_len = ID3D10Blob_GetBufferSize(error_blob);
char *error_blob_cstr = (char *)ID3D10Blob_GetBufferPointer(error_blob);
@ -1529,10 +1529,10 @@ INTERNAL void cpu_descriptor_heap_release(struct cpu_descriptor_heap *dh)
#endif
/* ========================== *
* Flow
* Sig
* ========================== */
struct flow {
struct sig {
struct arena *arena;
/* Material instances */
@ -1547,7 +1547,12 @@ struct flow {
struct arena *shape_verts_arena;
struct arena *shape_indices_arena;
struct flow *next_free;
/* Resources */
struct v2i32 old_size;
struct dx12_resource *albedo;
struct dx12_resource *emittance;
struct sig *next_free;
};
struct material_instance_desc {
@ -1571,59 +1576,59 @@ struct material_grid_desc {
u32 y_color;
};
INTERNAL struct flow *flow_alloc(void)
INTERNAL struct sig *sig_alloc(void)
{
__prof;
struct flow *flow = 0;
struct sig *sig = 0;
{
struct arena *arena = arena_alloc(MEBI(64));
flow = arena_push(arena, struct flow);
flow->arena = arena;
sig = arena_push(arena, struct sig);
sig->arena = arena;
}
flow->material_instance_descs_arena = arena_alloc(GIBI(1));
flow->material_grid_descs_arena = arena_alloc(GIBI(1));
flow->shape_verts_arena = arena_alloc(GIBI(1));
flow->shape_indices_arena = arena_alloc(GIBI(1));
sig->material_instance_descs_arena = arena_alloc(GIBI(1));
sig->material_grid_descs_arena = arena_alloc(GIBI(1));
sig->shape_verts_arena = arena_alloc(GIBI(1));
sig->shape_indices_arena = arena_alloc(GIBI(1));
return flow;
return sig;
}
INTERNAL void flow_reset(struct flow *flow)
INTERNAL void sig_reset(struct sig *sig)
{
__prof;
/* Reset material instances */
flow->num_material_instance_descs = 0;
arena_reset(flow->material_instance_descs_arena);
sig->num_material_instance_descs = 0;
arena_reset(sig->material_instance_descs_arena);
/* Reset grids */
flow->num_material_grid_descs = 0;
arena_reset(flow->material_grid_descs_arena);
sig->num_material_grid_descs = 0;
arena_reset(sig->material_grid_descs_arena);
/* Reset shapes */
arena_reset(flow->shape_verts_arena);
arena_reset(flow->shape_indices_arena);
arena_reset(sig->shape_verts_arena);
arena_reset(sig->shape_indices_arena);
}
struct gp_flow *gp_flow_alloc(void)
struct gp_sig *gp_sig_alloc(void)
{
__prof;
struct flow *flow = flow_alloc();
return (struct gp_flow *)flow;
struct sig *sig = sig_alloc();
return (struct gp_sig *)sig;
}
i32 gp_push_cmd(struct gp_flow *gp_flow, struct gp_cmd_desc *cmd_desc)
i32 gp_push_cmd(struct gp_sig *gp_sig, struct gp_cmd_desc *cmd_desc)
{
i32 ret = 0;
struct flow *flow = (struct flow *)gp_flow;
if (flow) {
struct sig *sig = (struct sig *)gp_sig;
if (sig) {
switch (cmd_desc->kind) {
default: break;
case GP_CMD_KIND_DRAW_MATERIAL:
{
struct material_instance_desc *instance_desc = arena_push(flow->material_instance_descs_arena, struct material_instance_desc);
struct material_instance_desc *instance_desc = arena_push(sig->material_instance_descs_arena, struct material_instance_desc);
instance_desc->xf = cmd_desc->material.xf;
instance_desc->sprite = cmd_desc->material.sprite;
instance_desc->texture = (struct dx12_resource *)cmd_desc->material.texture;
@ -1631,20 +1636,20 @@ i32 gp_push_cmd(struct gp_flow *gp_flow, struct gp_cmd_desc *cmd_desc)
instance_desc->tint = cmd_desc->material.tint;
instance_desc->emittance = cmd_desc->material.emittance;
instance_desc->grid_id = cmd_desc->material.grid_cmd_id - 1;
ret = ++flow->num_material_instance_descs;
ret = ++sig->num_material_instance_descs;
} break;
case GP_CMD_KIND_DRAW_SHAPE:
{
u32 color = cmd_desc->shape.color;
struct sh_shape_vert *verts = arena_push_array_no_zero(flow->shape_verts_arena, struct sh_shape_vert, cmd_desc->shape.vertices.count);
u32 *indices = arena_push_array_no_zero(flow->shape_indices_arena, u32, cmd_desc->shape.indices.count);
struct sh_shape_vert *verts = arena_push_array_no_zero(sig->shape_verts_arena, struct sh_shape_vert, cmd_desc->shape.vertices.count);
u32 *indices = arena_push_array_no_zero(sig->shape_indices_arena, u32, cmd_desc->shape.indices.count);
for (u32 i = 0; i < cmd_desc->shape.vertices.count; ++i) {
struct sh_shape_vert *v = &verts[i];
v->pos = sh_float2_from_v2(cmd_desc->shape.vertices.points[i]);
v->color_srgb = sh_uint_from_u32(color);
}
u32 vert_offset = verts - (struct sh_shape_vert *)arena_base(flow->shape_verts_arena);
u32 vert_offset = verts - (struct sh_shape_vert *)arena_base(sig->shape_verts_arena);
for (u32 i = 0; i < cmd_desc->shape.indices.count; ++i) {
indices[i] = cmd_desc->shape.indices.indices[i] + vert_offset;
}
@ -1652,7 +1657,7 @@ i32 gp_push_cmd(struct gp_flow *gp_flow, struct gp_cmd_desc *cmd_desc)
case GP_CMD_KIND_PUSH_GRID:
{
struct material_grid_desc *grid_desc = arena_push(flow->material_grid_descs_arena, struct material_grid_desc);
struct material_grid_desc *grid_desc = arena_push(sig->material_grid_descs_arena, struct material_grid_desc);
grid_desc->line_thickness = cmd_desc->grid.line_thickness;
grid_desc->line_spacing = cmd_desc->grid.line_spacing;
grid_desc->offset = cmd_desc->grid.offset;
@ -1661,7 +1666,7 @@ i32 gp_push_cmd(struct gp_flow *gp_flow, struct gp_cmd_desc *cmd_desc)
grid_desc->line_color = cmd_desc->grid.line_color;
grid_desc->x_color = cmd_desc->grid.x_color;
grid_desc->y_color = cmd_desc->grid.y_color;
ret = ++flow->num_material_grid_descs;
ret = ++sig->num_material_grid_descs;
} break;
}
}
@ -1717,7 +1722,7 @@ enum dx12_resource_view_flags {
DX12_RESOURCE_VIEW_FLAG_RTV = (1 << 4)
};
INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_props, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_DESC desc, D3D12_RESOURCE_STATES initial_state, enum dx12_resource_view_flags view_flags)
INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_props, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_DESC desc, D3D12_RESOURCE_STATES initial_state, i32 view_flags)
{
__prof;
struct dx12_resource *r = 0;
@ -1801,27 +1806,39 @@ INTERNAL void dx12_resource_release_now(struct dx12_resource *t)
snc_unlock(&lock);
}
INTERNAL enum D3D12_RESOURCE_STATES dx12_resource_barrier(ID3D12GraphicsCommandList *cl, struct dx12_resource *resource, enum D3D12_RESOURCE_STATES state)
INTERNAL void dx12_resource_barriers(ID3D12GraphicsCommandList *cl, i32 num_resources, struct dx12_resource **resources, enum D3D12_RESOURCE_STATES *states)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
i32 num_rbs = 0;
struct D3D12_RESOURCE_BARRIER *rbs = arena_push_array_no_zero(scratch.arena, struct D3D12_RESOURCE_BARRIER, num_resources);
for (i32 i = 0; i < num_resources; ++i) {
struct dx12_resource *resource = resources[i];
enum D3D12_RESOURCE_STATES old_state = resource->state;
if (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 = resource->state;
rtb.StateAfter = state;
rtb.StateBefore = old_state;
rtb.StateAfter = new_state;
struct D3D12_RESOURCE_BARRIER rb = ZI;
rb.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
rb.Flags = 0;
rb.Transition = rtb;
struct D3D12_RESOURCE_BARRIER *rb = &rbs[num_rbs++];
MEMZERO_STRUCT(rb);
rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
rb->Flags = 0;
rb->Transition = rtb;
ID3D12GraphicsCommandList_ResourceBarrier(cl, 1, &rb);
resource->state = state;
resource->state = new_state;
}
return old_state;
}
if (num_rbs > 0) {
ID3D12GraphicsCommandList_ResourceBarrier(cl, num_rbs, rbs);
}
scratch_end(scratch);
}
void gp_resource_release(struct gp_resource *resource)
@ -2067,8 +2084,8 @@ INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struc
/* Allocate GPU heap */
struct command_descriptor_heap *cdh = 0;
ID3D12DescriptorHeap *old_heap = 0;
D3D12_CPU_DESCRIPTOR_HANDLE old_cpu_handle = ZI;
D3D12_GPU_DESCRIPTOR_HANDLE old_gpu_handle = ZI;
D3D12_CPU_DESCRIPTOR_HANDLE old_start_cpu_handle = ZI;
D3D12_GPU_DESCRIPTOR_HANDLE old_start_gpu_handle = ZI;
{
struct snc_lock lock = snc_lock_e(&G.command_descriptor_heaps_mutex);
/* Find first heap ready for reuse */
@ -2083,8 +2100,8 @@ INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struc
if (cdh) {
/* Remove from submitted list */
old_heap = cdh->heap;
old_cpu_handle = cdh->cpu_handle;
old_gpu_handle = cdh->gpu_handle;
old_start_cpu_handle = cdh->start_cpu_handle;
old_start_gpu_handle = cdh->start_gpu_handle;
struct command_descriptor_heap *prev = cdh->prev_submitted;
struct command_descriptor_heap *next = cdh->next_submitted;
if (prev) {
@ -2107,8 +2124,8 @@ INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struc
if (old_heap) {
cdh->heap = old_heap;
cdh->cpu_handle = old_cpu_handle;
cdh->gpu_handle = old_gpu_handle;
cdh->start_cpu_handle = old_start_cpu_handle;
cdh->start_gpu_handle = old_start_gpu_handle;
} else {
D3D12_DESCRIPTOR_HEAP_DESC desc = ZI;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
@ -2118,14 +2135,14 @@ INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struc
if (FAILED(hr)) {
sys_panic(LIT("Failed to create GPU descriptor heap"));
}
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cdh->heap, &cdh->cpu_handle);
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(cdh->heap, &cdh->gpu_handle);
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cdh->heap, &cdh->start_cpu_handle);
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(cdh->heap, &cdh->start_gpu_handle);
}
/* Copy CPU heap */
{
struct snc_lock lock = snc_lock_s(&dh_cpu->mutex);
ID3D12Device_CopyDescriptorsSimple(G.device, dh_cpu->num_descriptors_reserved, cdh->cpu_handle, dh_cpu->handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
ID3D12Device_CopyDescriptorsSimple(G.device, dh_cpu->num_descriptors_reserved, cdh->start_cpu_handle, dh_cpu->handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
snc_unlock(&lock);
}
@ -2272,7 +2289,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl
* Util
* ========================== */
INTERNAL void command_list_set_root_constant(struct command_list *cl, void *src, u32 size)
INTERNAL void command_list_set_graphics_root_constant(struct command_list *cl, void *src, u32 size)
{
__prof;
if (size % 4 == 0) {
@ -2288,6 +2305,22 @@ INTERNAL void command_list_set_root_constant(struct command_list *cl, void *src,
}
}
INTERNAL void command_list_set_compute_root_constant(struct command_list *cl, void *src, u32 size)
{
__prof;
if (size % 4 == 0) {
u32 num32bit = size / 4;
for (u32 i = 0; i < num32bit; ++i) {
u32 val = 0;
MEMCPY(&val, (((u32 *)src) + i), 4);
ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(cl->cl, 0, val, i);
}
} else {
/* Root constant structs must pad to 32 bits */
ASSERT(0);
}
}
INTERNAL struct D3D12_VIEWPORT viewport_from_rect(struct rect r)
{
struct D3D12_VIEWPORT viewport = ZI;
@ -2360,6 +2393,9 @@ INTERNAL SYS_JOB_DEF(dx12_wait_fence_job, job)
struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data)
{
__prof;
if (size.x <= 0 || size.y <= 0) {
sys_panic(LIT("Tried to create texture with dimension <= 0"));
}
struct dxgi_format_info { DXGI_FORMAT format; u32 size; };
LOCAL_PERSIST const struct dxgi_format_info formats[] = {
[GP_TEXTURE_FORMAT_R8G8B8A8_UNORM] = { DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
@ -2398,8 +2434,8 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
if (flags & GP_TEXTURE_FLAG_TARGETABLE) {
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV;
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV | DX12_RESOURCE_VIEW_FLAG_UAV;
}
D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_COPY_DEST;
@ -2443,20 +2479,6 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
upload = dx12_resource_alloc(upload_heap_props, upload_heap_flags, upload_desc, upload_initial_state, upload_view_flags);
/* Copy to upload heap */
#if 0
/* FIXME: Copy based on footprint */
{
D3D12_RANGE read_range = ZI;
void *dst = 0;
HRESULT hr = ID3D12Resource_Map(upload->resource, 0, &read_range, &dst);
if (FAILED(hr) || !dst) {
/* TODO: Don't panic */
sys_panic(LIT("Failed to map texture upload resource"));
}
MEMCPY(dst, initial_data, size.x * size.y * pixel_size);
ID3D12Resource_Unmap(upload->resource, 0, 0);
}
#else
/* FIXME: Copy based on footprint */
{
D3D12_RANGE read_range = ZI;
@ -2473,7 +2495,6 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
}
ID3D12Resource_Unmap(upload->resource, 0, 0);
}
#endif
}
/* Copy from upload heap to texture */
@ -2494,8 +2515,6 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
};
ID3D12GraphicsCommandList_CopyTextureRegion(cl->cl, &dst_loc, 0, 0, 0, &src_loc, 0);
/* FIXME: Better barrier? */
//dx12_resource_barrier(cl->cl, r, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE);
}
u64 fence_target = command_list_close(cl);
@ -2521,9 +2540,38 @@ struct v2i32 gp_texture_get_size(struct gp_resource *resource)
}
/* ========================== *
* Dispatch
* Run
* ========================== */
INTERNAL struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, struct v2i32 size)
{
__prof;
D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
D3D12_RESOURCE_DESC desc = ZI;
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
desc.Format = format;
desc.Alignment = 0;
desc.Width = size.x;
desc.Height = size.y;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
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);
r->texture_size = size;
return r;
}
/* Calculate the view projection matrix */
INLINE struct mat4x4 calculate_vp(struct xform view, f32 viewport_width, f32 viewport_height)
{
@ -2532,22 +2580,58 @@ INLINE struct mat4x4 calculate_vp(struct xform view, f32 viewport_width, f32 vie
return mat4x4_mul(projection, view4x4);
}
void gp_dispatch(struct gp_dispatch_params params)
INTERNAL D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_from_descriptor(struct descriptor *descriptor, struct command_descriptor_heap *cdh)
{
struct D3D12_GPU_DESCRIPTOR_HANDLE res = ZI;
res.ptr = cdh->start_gpu_handle.ptr + descriptor->index * G.desc_sizes[descriptor->heap->type];
return res;
}
void gp_run(struct gp_run_params params)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
struct flow *flow = (struct flow *)params.flow;
struct dx12_resource *target = (struct dx12_resource *)params.draw_target;
struct sig *sig = (struct sig *)params.sig;
struct dx12_resource *final_target = (struct dx12_resource *)params.draw_target;
struct v2i32 final_target_size = final_target->texture_size;
/* Allocate resources */
if (!v2i32_eq(sig->old_size, final_target_size)) {
__profn("Allocate buffers");
/* Allocate albedo buffer */
if (sig->albedo) {
fenced_release(sig->albedo, FENCED_RELEASE_KIND_RESOURCE);
}
sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size);
/* Allocate emittance buffer */
if (sig->emittance) {
fenced_release(sig->emittance, FENCED_RELEASE_KIND_RESOURCE);
}
sig->emittance = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size);
}
struct dx12_resource *gbuffers[] = {
sig->albedo,
sig->emittance
};
D3D12_CPU_DESCRIPTOR_HANDLE gbuffer_rtvs[] = {
sig->albedo->rtv_descriptor->handle,
sig->emittance->rtv_descriptor->handle
};
STATIC_ASSERT(countof(gbuffers) == countof(gbuffer_rtvs));
struct sprite_scope *sprite_scope = sprite_scope_begin();
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
//struct pipeline *jfa_pipeline = pipeline_from_name(pipeline_scope, LIT("jfa"));
struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, LIT("material"));
struct pipeline *shade_pipeline = pipeline_from_name(pipeline_scope, LIT("shade"));
struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, LIT("shape"));
struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT];
struct command_list *cl = command_list_open(cq->cl_pool);
{
__profnc_dx12(cl->cq->prof, cl->cl, "Dispatch", RGB32_F(0.5, 0.2, 0.2));
__profnc_dx12(cl->cq->prof, cl->cl, "Run", RGB32_F(0.5, 0.2, 0.2));
struct mat4x4 vp_matrix = calculate_vp(params.draw_target_view, params.draw_target_viewport.width, params.draw_target_viewport.height);
/* Upload dummmy vert & index buffer */
@ -2557,17 +2641,17 @@ void gp_dispatch(struct gp_dispatch_params params)
struct command_buffer *dummy_vertex_buffer = command_list_push_buffer(cl, STRING(0, 0));
struct command_buffer *quad_index_buffer = command_list_push_buffer(cl, STRING_FROM_ARRAY(quad_indices));
/* Process flow data into uploadable data */
struct sh_material_instance *material_instances = arena_push_array_no_zero(scratch.arena, struct sh_material_instance, flow->num_material_instance_descs);
struct sh_material_grid *grids = arena_push_array_no_zero(scratch.arena, struct sh_material_grid, flow->num_material_grid_descs);
/* Process sig data into uploadable data */
struct sh_material_instance *material_instances = arena_push_array_no_zero(scratch.arena, struct sh_material_instance, sig->num_material_instance_descs);
struct sh_material_grid *grids = arena_push_array_no_zero(scratch.arena, struct sh_material_grid, sig->num_material_grid_descs);
{
__profn("Process flow data");
__profn("Process sig data");
/* Process material instances */
{
__profn("Process material instances");
for (u32 i = 0; i < flow->num_material_instance_descs; ++i) {
struct material_instance_desc *desc = &((struct material_instance_desc *)arena_base(flow->material_instance_descs_arena))[i];
for (u32 i = 0; i < sig->num_material_instance_descs; ++i) {
struct material_instance_desc *desc = &((struct material_instance_desc *)arena_base(sig->material_instance_descs_arena))[i];
struct sh_material_instance *instance = &material_instances[i];
i32 texture_id = -1;
if (desc->texture != 0) {
@ -2592,8 +2676,8 @@ void gp_dispatch(struct gp_dispatch_params params)
/* Process grids */
{
__profn("Process grids");
for (u32 i = 0; i < flow->num_material_grid_descs; ++i) {
struct material_grid_desc *desc = &((struct material_grid_desc *)arena_base(flow->material_grid_descs_arena))[i];
for (u32 i = 0; i < sig->num_material_grid_descs; ++i) {
struct material_grid_desc *desc = &((struct material_grid_desc *)arena_base(sig->material_grid_descs_arena))[i];
struct sh_material_grid *grid = &grids[i];
grid->line_thickness = sh_float_from_f32(desc->line_thickness);
grid->line_spacing = sh_float_from_f32(desc->line_spacing);
@ -2608,60 +2692,34 @@ void gp_dispatch(struct gp_dispatch_params params)
}
/* Upload buffers */
struct command_buffer *material_instance_buffer = command_list_push_buffer(cl, STRING(sizeof(*material_instances) * flow->num_material_instance_descs, (u8 *)material_instances));
struct command_buffer *grid_buffer = command_list_push_buffer(cl, STRING(sizeof(*grids) * flow->num_material_grid_descs, (u8 *)grids));
struct command_buffer *shape_verts_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->shape_verts_arena));
struct command_buffer *shape_indices_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->shape_indices_arena));
struct command_buffer *material_instance_buffer = command_list_push_buffer(cl, STRING(sizeof(*material_instances) * sig->num_material_instance_descs, (u8 *)material_instances));
struct command_buffer *grid_buffer = command_list_push_buffer(cl, STRING(sizeof(*grids) * sig->num_material_grid_descs, (u8 *)grids));
struct command_buffer *shape_verts_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(sig->shape_verts_arena));
struct command_buffer *shape_indices_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(sig->shape_indices_arena));
/* Upload descriptor heap */
struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap);
/* Transition render target */
enum D3D12_RESOURCE_STATES target_old_state = dx12_resource_barrier(cl->cl, target, D3D12_RESOURCE_STATE_RENDER_TARGET);
/* Bind gbuffer RTVs */
{
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &target->rtv_descriptor->handle, 0, 0);
if (params.clear_target) {
enum D3D12_RESOURCE_STATES states[] = {
D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_RENDER_TARGET
};
STATIC_ASSERT(countof(states) == countof(gbuffers));
dx12_resource_barriers(cl->cl, countof(gbuffers), gbuffers, states);
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, countof(gbuffer_rtvs), gbuffer_rtvs, 0, 0);
/* Clear */
{
__profn("Clear gbuffers");
__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 };
ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, target->rtv_descriptor->handle, clear_color, 0, 0);
for (i32 i = 0; i < (i32)countof(gbuffers); ++i) {
struct dx12_resource *gb = gbuffers[i];
ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, gb->rtv_descriptor->handle, clear_color, 0, 0);
}
}
#if 0
/* JFA pass */
if (jfa_pipeline->success) {
__profn("JFA pass");
__profnc_dx12(cl->cq->prof, cl->cl, "JFA pass", RGB32_F(0.5, 0.2, 0.2));
/* Bind pipeline */
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, jfa_pipeline->pso);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, jfa_pipeline->rootsig);
/* Set constants */
struct sh_material_constants constants = ZI;
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
command_list_set_root_constant(cl, &constants, sizeof(constants));
/* Set instance buffer */
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, material_instance_buffer->resource->gpu_address);
/* Set grid buffer */
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, grid_buffer->resource->gpu_address);
/* Set descriptor heap */
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps);
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 3, descriptor_heap->gpu_handle);
/* 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);
}
#endif
/* Material pass */
if (material_pipeline->success) {
@ -2675,18 +2733,18 @@ void gp_dispatch(struct gp_dispatch_params params)
/* Set constants */
struct sh_material_constants constants = ZI;
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
command_list_set_root_constant(cl, &constants, sizeof(constants));
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants));
/* Set instance buffer */
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, material_instance_buffer->resource->gpu_address);
/* Set grid buffer */
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, grid_buffer->resource->gpu_address);
/* Set descriptor heap */
/* Set descriptor tables */
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps);
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 3, descriptor_heap->gpu_handle);
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);
@ -2704,6 +2762,63 @@ void gp_dispatch(struct gp_dispatch_params params)
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0);
}
/* Transition gbuffers to SRV */
{
enum D3D12_RESOURCE_STATES states[] = {
D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE,
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 */
{
enum D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
dx12_resource_barriers(cl->cl, 1, &final_target, &state);
if (params.clear_target) {
__profn("Clear target");
__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 };
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 */
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);
/* Dispatch */
ID3D12GraphicsCommandList_Dispatch(cl->cl, (final_target_size.x + 7) / 8, (final_target_size.y + 7) / 8, 1);
}
/* Bind final target as RTV */
{
enum D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_RENDER_TARGET;
dx12_resource_barriers(cl->cl, 1, &final_target, &state);
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &final_target->rtv_descriptor->handle, 0, 0);
}
/* Shape pass */
if (shape_pipeline->success) {
__profn("Shape pass");
@ -2716,7 +2831,7 @@ void gp_dispatch(struct gp_dispatch_params params)
/* Set constants */
struct sh_shape_constants constants = ZI;
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
command_list_set_root_constant(cl, &constants, sizeof(constants));
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants));
/* Setup Rasterizer State */
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
@ -2733,17 +2848,13 @@ void gp_dispatch(struct gp_dispatch_params params)
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, index_count, 1, 0, 0, 0);
}
/* Reset render target */
{
dx12_resource_barrier(cl->cl, target, target_old_state);
}
}
command_list_close(cl);
pipeline_scope_end(pipeline_scope);
sprite_scope_end(sprite_scope);
flow_reset(flow);
sig->old_size = final_target_size;
sig_reset(sig);
scratch_end(scratch);
}
@ -2987,12 +3098,12 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
constants.tex_urid = sh_uint_from_u32(src->srv_descriptor->index);
constants.gamma = sh_float_from_f32(2.2);
command_list_set_root_constant(cl, &constants, sizeof(constants));
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants));
/* Set descriptor heap */
/* Set descriptor tables */
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps);
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->gpu_handle);
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle);
/* Setup Rasterizer State */
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);

View File

@ -1060,19 +1060,34 @@ INTERNAL THREAD_DEF(job_worker_entry, worker_ctx_arg)
HANDLE thread_handle = GetCurrentThread();
if (pool->thread_priority) {
__profn("Set priority");
b32 success = SetThreadPriority(thread_handle, pool->thread_priority) != 0;
ASSERT(success);
(UNUSED)success;
}
if (pool->thread_affinity_mask) {
__profn("Set affinity");
b32 success = SetThreadAffinityMask(thread_handle, pool->thread_affinity_mask) != 0;
#if RTC || PROFILING
{
/* Retry until external tools can set correct process affinity */
i32 delay_ms = 16;
while (!success && delay_ms <= 1024) {
__profn("Affinity retry");
Sleep(delay_ms);
success = SetThreadAffinityMask(thread_handle, pool->thread_affinity_mask) != 0;
delay_ms *= 2;
}
}
#endif
ASSERT(success);
(UNUSED)success;
}
if (pool->thread_is_audio) {
/* https://learn.microsoft.com/en-us/windows/win32/procthread/multimedia-class-scheduler-service#registry-settings */
__profn("Set mm thread characteristics");
DWORD task = 0;
HANDLE mmc_handle = AvSetMmThreadCharacteristics(L"Pro Audio", &task);
ASSERT(mmc_handle);
@ -3394,7 +3409,18 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
if (SUCCEEDED(hr)) {
u64 thread_name_len = wstr_len_no_limit(thread_name_wstr);
if (thread_name_len >= prefix_name_wstr_len && MEMEQ(thread_name_wstr, prefix_name_wstr, prefix_name_wstr_len)) {
__profn("Set profiler thread affinity");
b32 success = SetThreadAffinityMask(thread, PROFILER_THREAD_AFFINITY_MASK) != 0;
{
/* Retry until external tools can set correct process affinity */
i32 delay_ms = 16;
while (!success && delay_ms <= 1024) {
__profn("Profiler thread affinity retry");
Sleep(delay_ms);
success = SetThreadAffinityMask(thread, PROFILER_THREAD_AFFINITY_MASK) != 0;
delay_ms *= 2;
}
}
ASSERT(success);
(UNUSED)success;
}

View File

@ -69,8 +69,8 @@ GLOBAL struct {
/* Gpu resources */
struct gp_resource *user_texture;
struct gp_flow *world_gp_flow;
struct gp_flow *ui_gp_flow;
struct gp_sig *world_gp_sig;
struct gp_sig *ui_gp_sig;
struct xform world_to_user_xf;
@ -149,7 +149,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = {
[SYS_BTN_S] = USER_BIND_KIND_MOVE_DOWN,
[SYS_BTN_A] = USER_BIND_KIND_MOVE_LEFT,
[SYS_BTN_D] = USER_BIND_KIND_MOVE_RIGHT,
[SYS_BTN_ALT] = USER_BIND_KIND_WALK,
//[SYS_BTN_ALT] = USER_BIND_KIND_WALK,
[SYS_BTN_M1] = USER_BIND_KIND_FIRE,
[SYS_BTN_M2] = USER_BIND_KIND_FIRE_ALT,
@ -173,7 +173,8 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = {
[SYS_BTN_F2] = USER_BIND_KIND_DEBUG_CAMERA,
[SYS_BTN_F3] = USER_BIND_KIND_DEBUG_DRAW,
[SYS_BTN_GRAVE_ACCENT] = USER_BIND_KIND_DEBUG_CONSOLE,
[SYS_BTN_F11] = USER_BIND_KIND_FULLSCREEN,
[SYS_BTN_ALT] = USER_BIND_KIND_FULLSCREEN_MOD,
[SYS_BTN_ENTER] = USER_BIND_KIND_FULLSCREEN,
[SYS_BTN_MWHEELUP] = USER_BIND_KIND_ZOOM_IN,
[SYS_BTN_MWHEELDOWN] = USER_BIND_KIND_ZOOM_OUT,
[SYS_BTN_M3] = USER_BIND_KIND_PAN,
@ -236,8 +237,8 @@ struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr,
/* GPU handles */
G.world_to_user_xf = XFORM_IDENT;
G.world_gp_flow = gp_flow_alloc();
G.ui_gp_flow = gp_flow_alloc();
G.world_gp_sig = gp_sig_alloc();
G.ui_gp_sig = gp_sig_alloc();
G.console_logs_arena = arena_alloc(GIBI(64));
//log_register_callback(debug_console_log_callback, LOG_LEVEL_SUCCESS);
@ -283,13 +284,13 @@ INTERNAL void debug_draw_xform(struct xform xf, u32 color_x, u32 color_y)
x_ray = v2_mul(x_ray, ray_scale);
y_ray = v2_mul(y_ray, ray_scale);
draw_arrow_ray(G.ui_gp_flow, pos, x_ray, thickness, arrowhead_len, color_x);
draw_arrow_ray(G.ui_gp_flow, pos, y_ray, thickness, arrowhead_len, color_y);
draw_arrow_ray(G.ui_gp_sig, pos, x_ray, thickness, arrowhead_len, color_x);
draw_arrow_ray(G.ui_gp_sig, pos, y_ray, thickness, arrowhead_len, color_y);
//u32 color_quad = RGBA32_F(0, 1, 1, 0.3);
//struct quad quad = quad_from_rect(RECT(0, 0, 1, -1));
//quad = xform_mul_quad(xf, quad_scale(quad, 0.075f));
//draw_quad(G.ui_gp_flow, quad, color);
//draw_quad(G.ui_gp_sig, quad, color);
}
INTERNAL void debug_draw_movement(struct sim_ent *ent)
@ -306,7 +307,7 @@ INTERNAL void debug_draw_movement(struct sim_ent *ent)
struct v2 vel_ray = xform_basis_mul_v2(G.world_to_user_xf, velocity);
if (v2_len(vel_ray) > 0.00001) {
draw_arrow_ray(G.ui_gp_flow, pos, vel_ray, thickness, arrow_len, color_vel);
draw_arrow_ray(G.ui_gp_sig, pos, vel_ray, thickness, arrow_len, color_vel);
}
}
@ -478,7 +479,7 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized)
if (log->level <= level) {
/* Draw background */
u32 color = colors[log->level][log->color_index];
draw_quad(G.ui_gp_flow, quad_from_rect(log->bounds), ALPHA32_F(color, opacity));
draw_quad(G.ui_gp_sig, quad_from_rect(log->bounds), ALPHA32_F(color, opacity));
/* Draw text */
struct string text = log->msg;
@ -495,7 +496,7 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized)
}
struct draw_text_params params = DRAW_TEXT_PARAMS(.font = font, .pos = draw_pos, .offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM, .color = ALPHA32_F(COLOR_WHITE, opacity), .str = text);
struct rect bounds = draw_text(G.ui_gp_flow, params);
struct rect bounds = draw_text(G.ui_gp_sig, params);
struct rect draw_bounds = bounds;
draw_bounds.x -= bg_margin;
@ -798,8 +799,7 @@ INTERNAL void user_update(struct sys_window *window)
/* Test fullscreen */
{
struct bind_state state = G.bind_states[USER_BIND_KIND_FULLSCREEN];
if (state.num_presses) {
if (G.bind_states[USER_BIND_KIND_FULLSCREEN].num_presses && G.bind_states[USER_BIND_KIND_FULLSCREEN_MOD].is_held) {
struct sys_window_settings settings = sys_window_get_settings(window);
settings.flags ^= SYS_WINDOW_SETTINGS_FLAG_FULLSCREEN;
sys_window_update_settings(window, &settings);
@ -1000,7 +1000,7 @@ INTERNAL void user_update(struct sys_window *window)
struct v2 size = xform_basis_invert_mul_v2(G.world_to_user_xf, G.user_size);
u32 color0 = RGBA32_F(0.17f, 0.17f, 0.17f, 1.f);
u32 color1 = RGBA32_F(0.15f, 0.15f, 0.15f, 1.f);
draw_grid(G.world_gp_flow, xform_from_rect(RECT_FROM_V2(pos, size)), color0, color1, RGBA32(0x3f, 0x3f, 0x3f, 0xFF), COLOR_RED, COLOR_GREEN, thickness, spacing, offset);
draw_grid(G.world_gp_sig, xform_from_rect(RECT_FROM_V2(pos, size)), color0, color1, RGBA32(0x3f, 0x3f, 0x3f, 0xFF), COLOR_RED, COLOR_GREEN, thickness, spacing, offset);
}
#if 0
@ -1182,9 +1182,9 @@ INTERNAL void user_update(struct sys_window *window)
u32 color_end = RGBA32_F(1, 0.8, 0.4, opacity_b);
if (opacity_b > 0.99f) {
draw_circle(G.world_gp_flow, b, thickness / 2, color_end, 20);
draw_circle(G.world_gp_sig, b, thickness / 2, color_end, 20);
}
draw_gradient_line(G.world_gp_flow, a, b, thickness, color_start, color_end);
draw_gradient_line(G.world_gp_sig, a, b, thickness, color_start, color_end);
}
@ -1200,7 +1200,7 @@ INTERNAL void user_update(struct sys_window *window)
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);
draw_texture(G.world_gp_flow, params);
draw_texture(G.world_gp_sig, params);
}
}
@ -1220,7 +1220,7 @@ INTERNAL void user_update(struct sys_window *window)
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);
draw_texture(G.world_gp_flow, params);
draw_texture(G.world_gp_sig, params);
}
}
}
@ -1248,7 +1248,7 @@ INTERNAL void user_update(struct sys_window *window)
u32 color = RGBA32_F(1, 0, 1, 0.5);
struct quad quad = quad_from_aabb(aabb);
quad = xform_mul_quad(G.world_to_user_xf, quad);
draw_quad_line(G.ui_gp_flow, quad, thickness, color);
draw_quad_line(G.ui_gp_sig, quad, thickness, color);
}
/* Draw focus arrow */
@ -1259,7 +1259,7 @@ INTERNAL void user_update(struct sys_window *window)
start = xform_mul_v2(G.world_to_user_xf, start);
struct v2 end = v2_add(xf.og, ent->control.focus);
end = xform_mul_v2(G.world_to_user_xf, end);
draw_arrow_line(G.ui_gp_flow, start, end, 3, 10, RGBA32_F(1, 1, 1, 0.5));
draw_arrow_line(G.ui_gp_sig, start, end, 3, 10, RGBA32_F(1, 1, 1, 0.5));
}
#if 0
@ -1285,16 +1285,16 @@ INTERNAL void user_update(struct sys_window *window)
struct quad quad = quad_from_rect(slice.rect);
quad = xform_mul_quad(sprite_xform, quad);
quad = xform_mul_quad(G.world_to_user_xf, quad);
draw_quad_line(G.ui_gp_flow, quad, 2, quad_color);
draw_quad_line(G.ui_gp_sig, quad, 2, quad_color);
}
draw_circle(G.ui_gp_flow, center, 3, point_color, 20);
draw_circle(G.ui_gp_sig, center, 3, point_color, 20);
if (slice.has_ray) {
struct v2 ray = xform_basis_mul_v2(sprite_xform, slice.dir);
ray = xform_basis_mul_v2(G.world_to_user_xf, ray);
ray = v2_with_len(ray, 25);
draw_arrow_ray(G.ui_gp_flow, center, ray, 2, 10, ray_color);
draw_arrow_ray(G.ui_gp_sig, center, ray, 2, 10, ray_color);
}
}
}
@ -1311,7 +1311,7 @@ INTERNAL void user_update(struct sys_window *window)
f32 radius = 3;
struct v2 point = xform_mul_v2(e1_xf, ent->weld_joint_data.point_local_e1);
point = xform_mul_v2(G.world_to_user_xf, point);
draw_circle(G.ui_gp_flow, point, radius, color, 10);
draw_circle(G.ui_gp_sig, point, radius, color, 10);
DEBUGBREAKABLE;
}
@ -1326,8 +1326,8 @@ INTERNAL void user_update(struct sys_window *window)
struct v2 point_end = G.world_cursor;
point_start = xform_mul_v2(G.world_to_user_xf, point_start);
point_end = xform_mul_v2(G.world_to_user_xf, point_end);
draw_arrow_line(G.ui_gp_flow, point_start, point_end, 3, 10, color);
draw_circle(G.ui_gp_flow, point_start, 4, color, 10);
draw_arrow_line(G.ui_gp_sig, point_start, point_end, 3, 10, color);
draw_circle(G.ui_gp_sig, point_start, 4, color, 10);
}
/* Draw collider */
@ -1339,13 +1339,13 @@ INTERNAL void user_update(struct sys_window *window)
/* Draw collider using support points */
u32 detail = 32;
struct xform collider_draw_xf = xform_mul(G.world_to_user_xf, xf);
draw_collider_line(G.ui_gp_flow, collider, collider_draw_xf, thickness, color, detail);
draw_collider_line(G.ui_gp_sig, collider, collider_draw_xf, thickness, color, detail);
}
{
/* Draw collider shape points */
for (u32 i = 0; i < collider.count; ++i) {
struct v2 p = xform_mul_v2(xform_mul(G.world_to_user_xf, xf), collider.points[i]);
draw_circle(G.ui_gp_flow, p, 3, COLOR_BLUE, 10);
draw_circle(G.ui_gp_sig, p, 3, COLOR_BLUE, 10);
}
}
if (collider.count == 1 && collider.radius > 0) {
@ -1354,14 +1354,14 @@ INTERNAL void user_update(struct sys_window *window)
struct v2 end = collider_get_support_point(&collider, xf, v2_neg(xf.by)).p;
start = xform_mul_v2(G.world_to_user_xf, start);
end = xform_mul_v2(G.world_to_user_xf, end);
draw_line(G.ui_gp_flow, start, end, thickness, color);
draw_line(G.ui_gp_sig, start, end, thickness, color);
}
#if 0
/* Draw support point at focus dir */
{
struct v2 p = collider_support_point(&collider, xf, ent->control.focus);
p = xform_mul_v2(G.world_to_user_xf, p);
draw_circle(G.ui_gp_flow, p, 3, COLOR_RED, 10);
draw_circle(G.ui_gp_sig, p, 3, COLOR_RED, 10);
}
#endif
}
@ -1385,7 +1385,7 @@ INTERNAL void user_update(struct sys_window *window)
/* Draw point */
{
draw_circle(G.ui_gp_flow, xform_mul_v2(G.world_to_user_xf, dbg_pt), radius, color, 10);
draw_circle(G.ui_gp_sig, xform_mul_v2(G.world_to_user_xf, dbg_pt), radius, color, 10);
}
/* Draw normal */
@ -1395,7 +1395,7 @@ INTERNAL void user_update(struct sys_window *window)
f32 arrow_height = 5;
struct v2 start = xform_mul_v2(G.world_to_user_xf, dbg_pt);
struct v2 end = xform_mul_v2(G.world_to_user_xf, v2_add(dbg_pt, v2_mul(v2_norm(data->normal), len)));
draw_arrow_line(G.ui_gp_flow, start, end, arrow_thickness, arrow_height, color);
draw_arrow_line(G.ui_gp_sig, start, end, arrow_thickness, arrow_height, color);
}
#if 0
/* Draw contact info */
@ -1425,7 +1425,7 @@ INTERNAL void user_update(struct sys_window *window)
FMT_UINT(data->num_points));
draw_text(G.ui_gp_flow, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_user_xf, dbg_pt)), V2(0, offset_px)), text);
draw_text(G.ui_gp_sig, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_user_xf, dbg_pt)), V2(0, offset_px)), text);
}
}
#endif
@ -1453,8 +1453,8 @@ INTERNAL void user_update(struct sys_window *window)
u32 color = RGBA32_F(1, 1, 0, 0.5);
struct v2 a = xform_mul_v2(G.world_to_user_xf, data->closest0);
struct v2 b = xform_mul_v2(G.world_to_user_xf, data->closest1);
draw_circle(G.ui_gp_flow, a, radius, color, 10);
draw_circle(G.ui_gp_flow, b, radius, color, 10);
draw_circle(G.ui_gp_sig, a, radius, color, 10);
draw_circle(G.ui_gp_sig, b, radius, color, 10);
}
#endif
@ -1471,28 +1471,28 @@ INTERNAL void user_update(struct sys_window *window)
{
struct v2 a = xform_mul_v2(G.world_to_user_xf, collider_res.a0);
struct v2 b = xform_mul_v2(G.world_to_user_xf, collider_res.b0);
draw_line(G.ui_gp_flow, a, b, thickness, color_line);
draw_circle(G.ui_gp_flow, a, radius, color_a, 10);
draw_circle(G.ui_gp_flow, b, radius, color_b, 10);
draw_line(G.ui_gp_sig, a, b, thickness, color_line);
draw_circle(G.ui_gp_sig, a, radius, color_a, 10);
draw_circle(G.ui_gp_sig, b, radius, color_b, 10);
struct v2 a_clipped = xform_mul_v2(G.world_to_user_xf, collider_res.a0_clipped);
struct v2 b_clipped = xform_mul_v2(G.world_to_user_xf, collider_res.b0_clipped);
draw_line(G.ui_gp_flow, a_clipped, b_clipped, thickness, color_line_clipped);
draw_circle(G.ui_gp_flow, a_clipped, radius, color_a_clipped, 10);
draw_circle(G.ui_gp_flow, b_clipped, radius, color_b_clipped, 10);
draw_line(G.ui_gp_sig, a_clipped, b_clipped, thickness, color_line_clipped);
draw_circle(G.ui_gp_sig, a_clipped, radius, color_a_clipped, 10);
draw_circle(G.ui_gp_sig, b_clipped, radius, color_b_clipped, 10);
}
{
struct v2 a = xform_mul_v2(G.world_to_user_xf, collider_res.a1);
struct v2 b = xform_mul_v2(G.world_to_user_xf, collider_res.b1);
draw_line(G.ui_gp_flow, a, b, thickness, color_line);
draw_circle(G.ui_gp_flow, a, radius, color_a, 10);
draw_circle(G.ui_gp_flow, b, radius, color_b, 10);
draw_line(G.ui_gp_sig, a, b, thickness, color_line);
draw_circle(G.ui_gp_sig, a, radius, color_a, 10);
draw_circle(G.ui_gp_sig, b, radius, color_b, 10);
struct v2 a_clipped = xform_mul_v2(G.world_to_user_xf, collider_res.a1_clipped);
struct v2 b_clipped = xform_mul_v2(G.world_to_user_xf, collider_res.b1_clipped);
draw_line(G.ui_gp_flow, a_clipped, b_clipped, thickness, color_line_clipped);
draw_circle(G.ui_gp_flow, a_clipped, radius, color_a_clipped, 10);
draw_circle(G.ui_gp_flow, b_clipped, radius, color_b_clipped, 10);
draw_line(G.ui_gp_sig, a_clipped, b_clipped, thickness, color_line_clipped);
draw_circle(G.ui_gp_sig, a_clipped, radius, color_a_clipped, 10);
draw_circle(G.ui_gp_sig, b_clipped, radius, color_b_clipped, 10);
}
}
@ -1533,7 +1533,7 @@ INTERNAL void user_update(struct sys_window *window)
FMT_FLOAT_P(xform_get_rotation(e1_xf), 24));
draw_text(G.ui_gp_flow, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_user_xf, V2(0, 0))), V2(0, offset_px)), text);
draw_text(G.ui_gp_sig, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_user_xf, V2(0, 0))), V2(0, offset_px)), text);
}
}
#endif
@ -1549,8 +1549,8 @@ INTERNAL void user_update(struct sys_window *window)
struct v2_array m = menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail);
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_to_user_xf, m.points[i]);
draw_poly_line(G.ui_gp_flow, m, 1, thickness, color);
//draw_poly(G.ui_gp_flow, m, color);
draw_poly_line(G.ui_gp_sig, m, 1, thickness, color);
//draw_poly(G.ui_gp_sig, m, color);
}
/* Draw cloud */
@ -1562,7 +1562,7 @@ INTERNAL void user_update(struct sys_window *window)
for (u64 i = 0; i < m.count; ++i) {
struct v2 p = xform_mul_v2(G.world_to_user_xf, m.points[i]);
draw_circle(G.ui_gp_flow, p, radius, color, 10);
draw_circle(G.ui_gp_sig, p, radius, color, 10);
}
}
@ -1576,8 +1576,8 @@ INTERNAL void user_update(struct sys_window *window)
.count = collider_res.prototype.len
};
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_to_user_xf, m.points[i]);
draw_poly_line(G.ui_gp_flow, m, 1, thickness, color);
for (u64 i = 0; i < m.count; ++i) draw_circle(G.ui_gp_flow, m.points[i], 10, color, 10);
draw_poly_line(G.ui_gp_sig, m, 1, thickness, color);
for (u64 i = 0; i < m.count; ++i) draw_circle(G.ui_gp_sig, m.points[i], 10, color, 10);
}
/* Draw simplex */
@ -1595,18 +1595,18 @@ INTERNAL void user_update(struct sys_window *window)
if (simplex.len >= 1) {
u32 color = simplex.len == 1 ? color_first : (simplex.len == 2 ? color_second : color_third);
draw_circle(G.ui_gp_flow, simplex_array.points[0], thickness * 3, color, 10);
draw_circle(G.ui_gp_sig, simplex_array.points[0], thickness * 3, color, 10);
}
if (simplex.len >= 2) {
u32 color = simplex.len == 2 ? color_first : color_second;
draw_circle(G.ui_gp_flow, simplex_array.points[1], thickness * 3, color, 10);
draw_circle(G.ui_gp_sig, simplex_array.points[1], thickness * 3, color, 10);
}
if (simplex.len >= 3) {
u32 color = color_first;
draw_circle(G.ui_gp_flow, simplex_array.points[2], thickness * 3, color, 10);
draw_circle(G.ui_gp_sig, simplex_array.points[2], thickness * 3, color, 10);
}
if (simplex.len >= 2) {
draw_poly_line(G.ui_gp_flow, simplex_array, simplex.len > 2, thickness, line_color);
draw_poly_line(G.ui_gp_sig, simplex_array, simplex.len > 2, thickness, line_color);
}
}
@ -1618,7 +1618,7 @@ INTERNAL void user_update(struct sys_window *window)
f32 arrowhead_height = 10;
struct v2 start = xform_mul_v2(G.world_to_user_xf, V2(0, 0));
struct v2 end = xform_mul_v2(G.world_to_user_xf, v2_mul(v2_norm(collider_res.normal), len));
draw_arrow_line(G.ui_gp_flow, start, end, arrow_thickness, arrowhead_height, color);
draw_arrow_line(G.ui_gp_sig, start, end, arrow_thickness, arrowhead_height, color);
}
}
#endif
@ -1633,7 +1633,7 @@ INTERNAL void user_update(struct sys_window *window)
struct v2 start = xform_mul_v2(G.world_to_user_xf, xf.og);
struct v2 end = xform_mul_v2(G.world_to_user_xf, parent_xf.og);
draw_arrow_line(G.ui_gp_flow, start, end, thickness, arrow_height, color);
draw_arrow_line(G.ui_gp_sig, start, end, thickness, arrow_height, color);
}
/* Draw camera rect */
@ -1645,7 +1645,7 @@ INTERNAL void user_update(struct sys_window *window)
struct quad quad = xform_mul_quad(quad_xf, QUAD_UNIT_SQUARE_CENTERED);
quad = xform_mul_quad(G.world_to_user_xf, quad);
draw_quad_line(G.ui_gp_flow, quad, thickness, color);
draw_quad_line(G.ui_gp_sig, quad, thickness, color);
}
arena_temp_end(temp);
@ -1661,7 +1661,7 @@ INTERNAL void user_update(struct sys_window *window)
struct sprite_texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair);
struct v2 size = V2(t->width, t->height);
struct xform xf = XFORM_TRS(.t = crosshair_pos, .s = size);
draw_texture(G.ui_gp_flow, DRAW_TEXTURE_PARAMS(.xf = xf, .sprite = crosshair));
draw_texture(G.ui_gp_sig, DRAW_TEXTURE_PARAMS(.xf = xf, .sprite = crosshair));
}
/* FIXME: Enable this */
@ -1868,7 +1868,7 @@ INTERNAL void user_update(struct sys_window *window)
struct string dbg_text = ZI;
dbg_text.text = arena_push_dry(temp.arena, u8);
dbg_text.len += get_ent_debug_text(temp.arena, ent).len;
draw_text(G.ui_gp_flow, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = dbg_text));
draw_text(G.ui_gp_sig, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = dbg_text));
arena_temp_end(temp);
}
@ -1977,16 +1977,16 @@ INTERNAL void user_update(struct sys_window *window)
//text.len += string_copy(temp.arena, LIT("\n")).len;
#if COLLIDER_DEBUG
draw_text(G.ui_gp_flow, font, pos, string_format(temp.arena, LIT("collider gjk steps: %F"), FMT_UINT(collider_debug_steps)));
draw_text(G.ui_gp_sig, font, pos, string_format(temp.arena, LIT("collider gjk steps: %F"), FMT_UINT(collider_debug_steps)));
pos.y += spacing;
#endif
//draw_text(G.ui_gp_flow, font, pos, string_format(temp.arena, LIT("blended world entities: %F/%F"), FMT_UINT(G.ss_blended->num_ents_allocated), FMT_UINT(G.ss_blended->num_ents_reserved)));
//draw_text(G.ui_gp_flow, font, pos, text);
//draw_text(G.ui_gp_sig, font, pos, string_format(temp.arena, LIT("blended world entities: %F/%F"), FMT_UINT(G.ss_blended->num_ents_allocated), FMT_UINT(G.ss_blended->num_ents_reserved)));
//draw_text(G.ui_gp_sig, font, pos, text);
struct v2 pos = V2(10, G.user_size.y);
enum draw_text_offset_y offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM;
draw_text(G.ui_gp_flow, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = COLOR_WHITE));
draw_text(G.ui_gp_sig, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = COLOR_WHITE));
arena_temp_end(temp);
}
}
@ -2024,23 +2024,23 @@ INTERNAL void user_update(struct sys_window *window)
/* Render world to user texture */
{
struct gp_dispatch_params params = ZI;
params.flow = G.world_gp_flow;
struct gp_run_params params = ZI;
params.sig = G.world_gp_sig;
params.draw_target = G.user_texture;
params.draw_target_viewport = user_viewport;
params.draw_target_view = G.world_to_user_xf;
params.clear_target = 1;
gp_dispatch(params);
gp_run(params);
}
/* Render ui to user texture */
{
struct gp_dispatch_params params = ZI;
params.flow = G.ui_gp_flow;
struct gp_run_params params = ZI;
params.sig = G.ui_gp_sig;
params.draw_target = G.user_texture;
params.draw_target_viewport = user_viewport;
params.draw_target_view = XFORM_IDENT;
gp_dispatch(params);
gp_run(params);
}
/* Present */

View File

@ -43,6 +43,7 @@ enum user_bind_kind {
USER_BIND_KIND_DEBUG_DELETE,
USER_BIND_KIND_DEBUG_TELEPORT,
USER_BIND_KIND_DEBUG_EXPLODE,
USER_BIND_KIND_FULLSCREEN_MOD,
USER_BIND_KIND_FULLSCREEN,
USER_BIND_KIND_ZOOM_IN,
USER_BIND_KIND_ZOOM_OUT,