add grid to material shader
This commit is contained in:
parent
520dd6c874
commit
5bdaba67e7
@ -5,7 +5,7 @@
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#define ROOTSIG \
|
#define ROOTSIG \
|
||||||
"RootConstants(num32BitConstants=17, b0), " \
|
"RootConstants(num32BitConstants=18, b0), " \
|
||||||
"DescriptorTable(SRV(t0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
"DescriptorTable(SRV(t0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
||||||
"StaticSampler(s0, " \
|
"StaticSampler(s0, " \
|
||||||
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
||||||
@ -15,7 +15,7 @@
|
|||||||
"maxAnisotropy = 1)"
|
"maxAnisotropy = 1)"
|
||||||
|
|
||||||
ConstantBuffer<struct sh_blit_constants> g_constants : register(b0);
|
ConstantBuffer<struct sh_blit_constants> g_constants : register(b0);
|
||||||
Texture2D g_nuri_textures[] : register(t0);
|
Texture2D g_textures[] : register(t0);
|
||||||
|
|
||||||
SamplerState g_sampler : register(s0);
|
SamplerState g_sampler : register(s0);
|
||||||
|
|
||||||
@ -64,6 +64,7 @@ struct ps_output {
|
|||||||
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
||||||
{
|
{
|
||||||
struct ps_output output;
|
struct ps_output output;
|
||||||
output.SV_Target = g_nuri_textures[g_constants.texture_id].Sample(g_sampler, input.vs.uv);
|
const float gamma = g_constants.gamma;
|
||||||
|
output.SV_Target = pow(g_textures[g_constants.tex_urid].Sample(g_sampler, input.vs.uv), 1/gamma);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#define GOLDEN 1.61803398875
|
#define GOLDEN 1.61803398875
|
||||||
|
|
||||||
#define DECL(t, n) t n : n
|
#define DECL(t, n) t n : n
|
||||||
#define NURI(i) NonUniformResourceIndex(i)
|
#define NURID(i) NonUniformResourceIndex(i)
|
||||||
|
|
||||||
#if !SH_CPU
|
#if !SH_CPU
|
||||||
# define INLINE /* For intellisense */
|
# define INLINE /* For intellisense */
|
||||||
|
|||||||
@ -7,7 +7,8 @@
|
|||||||
#define ROOTSIG \
|
#define ROOTSIG \
|
||||||
"RootConstants(num32BitConstants=16, b0), " \
|
"RootConstants(num32BitConstants=16, b0), " \
|
||||||
"SRV(t0), " \
|
"SRV(t0), " \
|
||||||
"DescriptorTable(SRV(t1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
"SRV(t1), " \
|
||||||
|
"DescriptorTable(SRV(t2, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
||||||
"StaticSampler(s0, " \
|
"StaticSampler(s0, " \
|
||||||
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
||||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||||
@ -17,7 +18,8 @@
|
|||||||
|
|
||||||
ConstantBuffer<struct sh_material_constants> g_constants : register(b0);
|
ConstantBuffer<struct sh_material_constants> g_constants : register(b0);
|
||||||
StructuredBuffer<struct sh_material_instance> g_instances : register(t0);
|
StructuredBuffer<struct sh_material_instance> g_instances : register(t0);
|
||||||
Texture2D g_nuri_textures[] : register(t1);
|
StructuredBuffer<struct sh_material_grid> g_grids : register(t1);
|
||||||
|
Texture2D g_textures[] : register(t2);
|
||||||
|
|
||||||
SamplerState g_sampler : register(s0);
|
SamplerState g_sampler : register(s0);
|
||||||
|
|
||||||
@ -31,10 +33,12 @@ struct vs_input {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct vs_output {
|
struct vs_output {
|
||||||
DECL(float4, SV_Position);
|
nointerpolation DECL(uint, flags);
|
||||||
|
nointerpolation DECL(int, tex_nurid);
|
||||||
|
nointerpolation DECL(int, grid_id);
|
||||||
DECL(float2, uv);
|
DECL(float2, uv);
|
||||||
DECL(float4, tint_lin);
|
DECL(float4, tint_lin);
|
||||||
DECL(uint, texture_nuri);
|
DECL(float4, SV_Position);
|
||||||
};
|
};
|
||||||
|
|
||||||
SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input)
|
SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input)
|
||||||
@ -52,9 +56,11 @@ SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input)
|
|||||||
|
|
||||||
struct vs_output output;
|
struct vs_output output;
|
||||||
output.SV_Position = mul(g_constants.projection, float4(world_pos, 0, 1));
|
output.SV_Position = mul(g_constants.projection, float4(world_pos, 0, 1));
|
||||||
|
output.flags = instance.flags;
|
||||||
|
output.tex_nurid = instance.tex_nurid;
|
||||||
|
output.grid_id = instance.grid_id;
|
||||||
output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0));
|
output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0));
|
||||||
output.tint_lin = linear_from_srgb32(instance.tint_srgb);
|
output.tint_lin = linear_from_srgb32(instance.tint_srgb);
|
||||||
output.texture_nuri = instance.texture_nuri;
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +79,44 @@ struct ps_output {
|
|||||||
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
||||||
{
|
{
|
||||||
struct ps_output output;
|
struct ps_output output;
|
||||||
output.SV_Target = g_nuri_textures[NURI(input.vs.texture_nuri)].Sample(g_sampler, input.vs.uv) * input.vs.tint_lin * 1;
|
output.SV_Target = float4(1, 1, 1, 1);
|
||||||
|
|
||||||
|
/* Texture */
|
||||||
|
if (input.vs.tex_nurid >= 0) {
|
||||||
|
output.SV_Target *= g_textures[NURID(input.vs.tex_nurid)].Sample(g_sampler, input.vs.uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grid */
|
||||||
|
if (input.vs.grid_id >= 0) {
|
||||||
|
struct sh_material_grid grid = g_grids[input.vs.grid_id];
|
||||||
|
float2 grid_pos = input.vs.SV_Position.xy + grid.offset;
|
||||||
|
float half_thickness = grid.line_thickness / 2;
|
||||||
|
float spacing = grid.line_spacing;
|
||||||
|
float4 color = linear_from_srgb32(grid.bg0_srgb);
|
||||||
|
float2 v = abs(round(grid_pos / spacing) * spacing - grid_pos);
|
||||||
|
float dist = min(v.x, v.y);
|
||||||
|
if (grid_pos.y <= half_thickness && grid_pos.y >= -half_thickness) {
|
||||||
|
color = linear_from_srgb32(grid.x_srgb);
|
||||||
|
} else if (grid_pos.x <= half_thickness && grid_pos.x >= -half_thickness) {
|
||||||
|
color = linear_from_srgb32(grid.y_srgb);
|
||||||
|
} else if (dist < half_thickness) {
|
||||||
|
color = linear_from_srgb32(grid.line_srgb);
|
||||||
|
} else {
|
||||||
|
bool checker = false;
|
||||||
|
uint cell_x = (uint)(abs(grid_pos.x) / spacing) + (grid_pos.x < 0);
|
||||||
|
uint cell_y = (uint)(abs(grid_pos.y) / spacing) + (grid_pos.y < 0);
|
||||||
|
if (cell_x % 2 == 0) {
|
||||||
|
checker = cell_y % 2 == 0;
|
||||||
|
} else {
|
||||||
|
checker = cell_y % 2 == 1;
|
||||||
|
}
|
||||||
|
if (checker) {
|
||||||
|
color = linear_from_srgb32(grid.bg1_srgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.SV_Target *= color;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.SV_Target *= input.vs.tint_lin;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,12 @@ INLINE struct sh_uint sh_uint_from_u32(u32 v)
|
|||||||
return (struct sh_uint) { .v = v };
|
return (struct sh_uint) { .v = v };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sh_int { i32 v; };
|
||||||
|
INLINE struct sh_int sh_int_from_i32(i32 v)
|
||||||
|
{
|
||||||
|
return (struct sh_int) { .v = v };
|
||||||
|
}
|
||||||
|
|
||||||
struct sh_float { f32 v; };
|
struct sh_float { f32 v; };
|
||||||
INLINE struct sh_float sh_float_from_f32(f32 v)
|
INLINE struct sh_float sh_float_from_f32(f32 v)
|
||||||
{
|
{
|
||||||
@ -56,24 +62,40 @@ INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v)
|
|||||||
|
|
||||||
SH_STRUCT(sh_blit_constants {
|
SH_STRUCT(sh_blit_constants {
|
||||||
SH_DECL(float4x4, projection);
|
SH_DECL(float4x4, projection);
|
||||||
SH_DECL(uint, texture_id);
|
SH_DECL(uint, tex_urid);
|
||||||
|
SH_DECL(float, gamma);
|
||||||
});
|
});
|
||||||
SH_ASSERT_32BIT(struct sh_blit_constants, 17); /* Expected 32bit root constant size in shader */
|
SH_ASSERT_32BIT(struct sh_blit_constants, 18); /* Expected 32bit root constant size in shader */
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Material shader structures
|
* Material shader structures
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
|
#define SH_MATERIAL_FLAG_NONE (0)
|
||||||
|
|
||||||
SH_STRUCT(sh_material_constants {
|
SH_STRUCT(sh_material_constants {
|
||||||
SH_DECL(float4x4, projection);
|
SH_DECL(float4x4, projection);
|
||||||
});
|
});
|
||||||
SH_ASSERT_32BIT(struct sh_material_constants, 16); /* Expected 32bit root constant size in shader */
|
SH_ASSERT_32BIT(struct sh_material_constants, 16); /* Expected 32bit root constant size in shader */
|
||||||
|
|
||||||
SH_STRUCT(sh_material_instance {
|
SH_STRUCT(sh_material_instance {
|
||||||
|
SH_DECL(uint, flags);
|
||||||
|
SH_DECL(int, tex_nurid);
|
||||||
|
SH_DECL(int, grid_id);
|
||||||
SH_DECL(float2x3, xf);
|
SH_DECL(float2x3, xf);
|
||||||
SH_DECL(float2, uv0);
|
SH_DECL(float2, uv0);
|
||||||
SH_DECL(float2, uv1);
|
SH_DECL(float2, uv1);
|
||||||
SH_DECL(uint, texture_nuri);
|
|
||||||
SH_DECL(uint, tint_srgb);
|
SH_DECL(uint, tint_srgb);
|
||||||
SH_DECL(float, emittance);
|
SH_DECL(float, emittance);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
SH_STRUCT(sh_material_grid {
|
||||||
|
SH_DECL(float, line_thickness);
|
||||||
|
SH_DECL(float, line_spacing);
|
||||||
|
SH_DECL(float2, offset);
|
||||||
|
SH_DECL(uint, bg0_srgb);
|
||||||
|
SH_DECL(uint, bg1_srgb);
|
||||||
|
SH_DECL(uint, line_srgb);
|
||||||
|
SH_DECL(uint, x_srgb);
|
||||||
|
SH_DECL(uint, y_srgb);
|
||||||
|
});
|
||||||
|
|||||||
30
src/draw.c
30
src/draw.c
@ -30,7 +30,7 @@ struct draw_startup_receipt draw_startup(struct gp_startup_receipt *gp_sr,
|
|||||||
|
|
||||||
void draw_texture(struct gp_handle flow, struct draw_texture_params params)
|
void draw_texture(struct gp_handle flow, struct draw_texture_params params)
|
||||||
{
|
{
|
||||||
struct gp_cmd_params cmd = ZI;
|
struct gp_cmd_desc cmd = ZI;
|
||||||
cmd.kind = GP_CMD_KIND_DRAW_TEXTURE;
|
cmd.kind = GP_CMD_KIND_DRAW_TEXTURE;
|
||||||
cmd.texture.xf = params.xf;
|
cmd.texture.xf = params.xf;
|
||||||
cmd.texture.sprite = params.sprite;
|
cmd.texture.sprite = params.sprite;
|
||||||
@ -47,7 +47,7 @@ void draw_texture(struct gp_handle flow, struct draw_texture_params params)
|
|||||||
|
|
||||||
void draw_poly_ex(struct gp_handle flow, struct v2_array vertices, struct gp_indices indices, u32 color)
|
void draw_poly_ex(struct gp_handle flow, struct v2_array vertices, struct gp_indices indices, u32 color)
|
||||||
{
|
{
|
||||||
struct gp_cmd_params cmd = ZI;
|
struct gp_cmd_desc cmd = ZI;
|
||||||
cmd.kind = GP_CMD_KIND_DRAW_MESH;
|
cmd.kind = GP_CMD_KIND_DRAW_MESH;
|
||||||
cmd.mesh.vertices = vertices;
|
cmd.mesh.vertices = vertices;
|
||||||
cmd.mesh.indices = indices;
|
cmd.mesh.indices = indices;
|
||||||
@ -260,17 +260,21 @@ void draw_collider_line(struct gp_handle flow, struct collider_shape shape, stru
|
|||||||
|
|
||||||
void draw_grid(struct gp_handle 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_handle 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)
|
||||||
{
|
{
|
||||||
struct gp_cmd_params cmd = ZI;
|
struct gp_grid_desc grid = ZI;
|
||||||
cmd.kind = GP_CMD_KIND_DRAW_GRID;
|
grid.bg0_color = bg0_color;
|
||||||
cmd.grid.xf = xf;
|
grid.bg1_color = bg1_color;
|
||||||
cmd.grid.bg0_color = bg0_color;
|
grid.line_color = line_color;
|
||||||
cmd.grid.bg1_color = bg1_color;
|
grid.x_color = x_color;
|
||||||
cmd.grid.line_color = line_color;
|
grid.y_color = y_color;
|
||||||
cmd.grid.x_color = x_color;
|
grid.line_thickness = thickness;
|
||||||
cmd.grid.y_color = y_color;
|
grid.line_spacing = spacing;
|
||||||
cmd.grid.line_thickness = thickness;
|
grid.offset = offset;
|
||||||
cmd.grid.line_spacing = spacing;
|
|
||||||
cmd.grid.offset = offset;
|
struct gp_cmd_desc cmd = ZI;
|
||||||
|
cmd.kind = GP_CMD_KIND_DRAW_TEXTURE;
|
||||||
|
cmd.texture.xf = xf;
|
||||||
|
cmd.texture.tint = COLOR_WHITE;
|
||||||
|
cmd.texture.grid = &grid;
|
||||||
gp_push_cmd(flow, cmd);
|
gp_push_cmd(flow, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
28
src/gp.h
28
src/gp.h
@ -72,13 +72,23 @@ enum gp_cmd_kind {
|
|||||||
GP_CMD_KIND_NONE,
|
GP_CMD_KIND_NONE,
|
||||||
GP_CMD_KIND_DRAW_MESH,
|
GP_CMD_KIND_DRAW_MESH,
|
||||||
GP_CMD_KIND_DRAW_TEXTURE,
|
GP_CMD_KIND_DRAW_TEXTURE,
|
||||||
GP_CMD_KIND_DRAW_GRID,
|
|
||||||
GP_CMD_KIND_TEST,
|
GP_CMD_KIND_TEST,
|
||||||
|
|
||||||
NUM_GP_CMD_KINDS
|
NUM_GP_CMD_KINDS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gp_cmd_params {
|
struct gp_grid_desc {
|
||||||
|
f32 line_thickness;
|
||||||
|
f32 line_spacing;
|
||||||
|
struct v2 offset;
|
||||||
|
u32 bg0_color;
|
||||||
|
u32 bg1_color;
|
||||||
|
u32 line_color;
|
||||||
|
u32 x_color;
|
||||||
|
u32 y_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gp_cmd_desc {
|
||||||
enum gp_cmd_kind kind;
|
enum gp_cmd_kind kind;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
@ -93,18 +103,8 @@ struct gp_cmd_params {
|
|||||||
struct clip_rect clip;
|
struct clip_rect clip;
|
||||||
u32 tint;
|
u32 tint;
|
||||||
f32 emittance;
|
f32 emittance;
|
||||||
|
struct gp_grid_desc *grid;
|
||||||
} texture;
|
} texture;
|
||||||
struct {
|
|
||||||
struct xform xf;
|
|
||||||
f32 line_thickness;
|
|
||||||
f32 line_spacing;
|
|
||||||
struct v2 offset;
|
|
||||||
u32 bg0_color;
|
|
||||||
u32 bg1_color;
|
|
||||||
u32 line_color;
|
|
||||||
u32 x_color;
|
|
||||||
u32 y_color;
|
|
||||||
} grid;
|
|
||||||
struct {
|
struct {
|
||||||
struct xform xf;
|
struct xform xf;
|
||||||
} test;
|
} test;
|
||||||
@ -121,7 +121,7 @@ struct gp_dispatch_params {
|
|||||||
|
|
||||||
struct gp_handle gp_flow_alloc(void);
|
struct gp_handle gp_flow_alloc(void);
|
||||||
|
|
||||||
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_params params);
|
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc params);
|
||||||
|
|
||||||
void gp_dispatch(struct gp_dispatch_params params);
|
void gp_dispatch(struct gp_dispatch_params params);
|
||||||
|
|
||||||
|
|||||||
@ -1372,7 +1372,7 @@ struct gp_handle gp_flow_alloc(void)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_params params)
|
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc params)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct dx11_flow *flow = (struct dx11_flow *)gp_flow.v;
|
struct dx11_flow *flow = (struct dx11_flow *)gp_flow.v;
|
||||||
|
|||||||
158
src/gp_dx12.c
158
src/gp_dx12.c
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
#define DX12_SWAPCHAIN_BUFFER_COUNT (3)
|
#define DX12_SWAPCHAIN_BUFFER_COUNT (3)
|
||||||
#define DX12_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM)
|
#define DX12_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM)
|
||||||
//#define DX12_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
|
//#define DX12_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
|
||||||
|
|
||||||
/* Arbitrary limits */
|
/* Arbitrary limits */
|
||||||
#define DX12_NUM_CBV_SRV_UAV_DESCRIPTORS (1024 * 64)
|
#define DX12_NUM_CBV_SRV_UAV_DESCRIPTORS (1024 * 64)
|
||||||
@ -80,10 +80,12 @@ struct pipeline {
|
|||||||
|
|
||||||
struct pipeline_error *first_error;
|
struct pipeline_error *first_error;
|
||||||
struct pipeline_error *last_error;
|
struct pipeline_error *last_error;
|
||||||
i64 compilation_time;
|
i64 compilation_time_ns;
|
||||||
|
|
||||||
|
/* Dict with shader source & included file names as keys */
|
||||||
struct dict *dependencies;
|
struct dict *dependencies;
|
||||||
|
|
||||||
/* Lock global pipelines mutex before accessing */
|
/* Lock global pipelines mutex when accessing */
|
||||||
i64 refcount;
|
i64 refcount;
|
||||||
|
|
||||||
struct pipeline_desc desc;
|
struct pipeline_desc desc;
|
||||||
@ -625,9 +627,7 @@ INTERNAL void dx12_init_objects(void)
|
|||||||
* Dx12 pipeline initialization
|
* Dx12 pipeline initialization
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL READONLY struct pipeline g_nil_pipeline = ZI;
|
INTERNAL void pipeline_alloc_from_desc(u64 num_pipelines, struct pipeline_desc *descs, struct pipeline **pipelines_out);
|
||||||
|
|
||||||
INTERNAL void pipeline_alloc_from_descs(u64 num_pipelines, struct pipeline_desc *descs, struct pipeline **pipelines_out);
|
|
||||||
INTERNAL void pipeline_release(struct pipeline *pipeline);
|
INTERNAL void pipeline_release(struct pipeline *pipeline);
|
||||||
INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines);
|
INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines);
|
||||||
|
|
||||||
@ -669,12 +669,13 @@ INTERNAL void dx12_init_pipelines(void)
|
|||||||
++num_pipelines;
|
++num_pipelines;
|
||||||
}
|
}
|
||||||
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
||||||
pipeline_alloc_from_descs(num_pipelines, descs, pipelines);
|
pipeline_alloc_from_desc(num_pipelines, descs, pipelines);
|
||||||
for (u32 i = 0; i < num_pipelines; ++i) {
|
for (u32 i = 0; i < num_pipelines; ++i) {
|
||||||
struct pipeline *pipeline = pipelines[i];
|
struct pipeline *pipeline = pipelines[i];
|
||||||
if (!pipeline->success) {
|
if (!pipeline->success) {
|
||||||
struct string msg = pipeline->first_error ? pipeline->first_error->msg : LIT("Unknown error");
|
struct string error = pipeline->first_error ? pipeline->first_error->msg : LIT("Unknown error");
|
||||||
sys_panic(msg);
|
struct string msg = string_format(scratch.arena, LIT("Error creating pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(error));
|
||||||
|
sys_message_box(SYS_MESSAGE_BOX_KIND_WARNING, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pipeline_register(num_pipelines, pipelines);
|
pipeline_register(num_pipelines, pipelines);
|
||||||
@ -1073,7 +1074,7 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
|
|||||||
|
|
||||||
pipeline->pso = pso;
|
pipeline->pso = pso;
|
||||||
pipeline->rootsig = rootsig;
|
pipeline->rootsig = rootsig;
|
||||||
pipeline->compilation_time = sys_time_ns() - start_ns;
|
pipeline->compilation_time_ns = sys_time_ns() - start_ns;
|
||||||
pipeline->success = success;
|
pipeline->success = success;
|
||||||
|
|
||||||
resource_close(&vs_res);
|
resource_close(&vs_res);
|
||||||
@ -1099,8 +1100,7 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
|
|||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expects `descs` and `pipelines_out` to be arrays of length `num_pipelines` */
|
INTERNAL void pipeline_alloc_from_desc(u64 num_pipelines, struct pipeline_desc *descs, struct pipeline **pipelines_out)
|
||||||
INTERNAL void pipeline_alloc_from_descs(u64 num_pipelines, struct pipeline_desc *descs, struct pipeline **pipelines_out)
|
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct work_slate ws = work_slate_begin();
|
struct work_slate ws = work_slate_begin();
|
||||||
@ -1180,28 +1180,31 @@ INTERNAL void pipeline_scope_end(struct pipeline_scope *scope)
|
|||||||
sys_mutex_unlock(&lock);
|
sys_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL READONLY struct pipeline g_nil_pipeline = ZI;
|
||||||
INTERNAL struct pipeline *pipeline_from_name(struct pipeline_scope *scope, struct string name)
|
INTERNAL struct pipeline *pipeline_from_name(struct pipeline_scope *scope, struct string name)
|
||||||
{
|
{
|
||||||
struct pipeline *pipeline = NULL;
|
struct pipeline *res = &g_nil_pipeline;
|
||||||
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name);
|
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name);
|
||||||
|
|
||||||
pipeline = dict_get(scope->refs, hash);
|
struct pipeline *tmp = dict_get(scope->refs, hash);
|
||||||
if (!pipeline) {
|
if (tmp) {
|
||||||
|
res = tmp;
|
||||||
|
} else {
|
||||||
{
|
{
|
||||||
struct sys_lock lock = sys_mutex_lock_e(G.pipelines_mutex);
|
struct sys_lock lock = sys_mutex_lock_e(G.pipelines_mutex);
|
||||||
struct pipeline *res = dict_get(G.top_successful_pipelines, hash);
|
tmp = dict_get(G.top_successful_pipelines, hash);
|
||||||
if (res) {
|
if (tmp) {
|
||||||
pipeline = res;
|
++tmp->refcount;
|
||||||
++pipeline->refcount;
|
|
||||||
}
|
}
|
||||||
sys_mutex_unlock(&lock);
|
sys_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
if (pipeline) {
|
if (tmp) {
|
||||||
dict_set(scope->arena, scope->refs, hash, (u64)pipeline);
|
dict_set(scope->arena, scope->refs, hash, (u64)tmp);
|
||||||
|
res = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pipeline ? pipeline : &g_nil_pipeline;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines)
|
INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines)
|
||||||
@ -1248,6 +1251,7 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name
|
|||||||
for (struct dict_entry *entry = G.top_pipelines->first; entry; entry = entry->next) {
|
for (struct dict_entry *entry = G.top_pipelines->first; entry; entry = entry->next) {
|
||||||
struct pipeline *pipeline = (struct pipeline *)entry->value;
|
struct pipeline *pipeline = (struct pipeline *)entry->value;
|
||||||
if (dict_get(pipeline->dependencies, hash) == 1) {
|
if (dict_get(pipeline->dependencies, hash) == 1) {
|
||||||
|
logf_debug("Change detected in shader source file \"%F\", recompiling pipeline \"%F\"", FMT_STR(name), FMT_STR(pipeline->name));
|
||||||
*arena_push(scratch.arena, struct pipeline_desc) = pipeline->desc;
|
*arena_push(scratch.arena, struct pipeline_desc) = pipeline->desc;
|
||||||
++num_pipelines;
|
++num_pipelines;
|
||||||
}
|
}
|
||||||
@ -1257,12 +1261,35 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name
|
|||||||
|
|
||||||
/* Recompile dirty pipelines */
|
/* Recompile dirty pipelines */
|
||||||
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
||||||
pipeline_alloc_from_descs(num_pipelines, pipeline_descs, pipelines);
|
pipeline_alloc_from_desc(num_pipelines, pipeline_descs, pipelines);
|
||||||
|
{
|
||||||
|
struct sys_lock lock = sys_mutex_lock_s(G.pipelines_mutex);
|
||||||
|
for (u32 i = 0; i < num_pipelines; ++i) {
|
||||||
|
struct pipeline *pipeline = pipelines[i];
|
||||||
|
if (pipeline->success) {
|
||||||
|
logf_success("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SECONDS_FROM_NS(pipeline->compilation_time_ns)));
|
||||||
|
} else {
|
||||||
|
struct pipeline *old_pipeline = dict_get(G.top_successful_pipelines, pipeline->hash);
|
||||||
|
if (old_pipeline) {
|
||||||
|
struct string error = pipeline->first_error ? pipeline->first_error->msg : LIT("Unknown error");
|
||||||
|
struct string msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(error));
|
||||||
|
log_error(msg);
|
||||||
|
} else {
|
||||||
|
/* If no previously successful pipeline exists, then show a message box rather than logging since logs may not be visible to user */
|
||||||
|
struct string error = pipeline->first_error ? pipeline->first_error->msg : LIT("Unknown error");
|
||||||
|
struct string msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(error));
|
||||||
|
sys_message_box(SYS_MESSAGE_BOX_KIND_WARNING, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&lock);
|
||||||
|
}
|
||||||
pipeline_register(num_pipelines, pipelines);
|
pipeline_register(num_pipelines, pipelines);
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Descriptor
|
* Descriptor
|
||||||
@ -1321,7 +1348,6 @@ INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRI
|
|||||||
if (num_descriptors == 0 || descriptor_size == 0) {
|
if (num_descriptors == 0 || descriptor_size == 0) {
|
||||||
sys_panic(LIT("Unsupported CPU descriptor type"));
|
sys_panic(LIT("Unsupported CPU descriptor type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
dh->num_descriptors_capacity = num_descriptors;
|
dh->num_descriptors_capacity = num_descriptors;
|
||||||
dh->descriptor_size = descriptor_size;
|
dh->descriptor_size = descriptor_size;
|
||||||
|
|
||||||
@ -1355,6 +1381,7 @@ struct flow {
|
|||||||
/* Below fields are reset each dispatch */
|
/* Below fields are reset each dispatch */
|
||||||
struct sprite_scope *sprite_scope;
|
struct sprite_scope *sprite_scope;
|
||||||
struct arena *material_instances_arena;
|
struct arena *material_instances_arena;
|
||||||
|
struct arena *material_grids_arena;
|
||||||
|
|
||||||
struct flow *next_free;
|
struct flow *next_free;
|
||||||
};
|
};
|
||||||
@ -1370,40 +1397,73 @@ INTERNAL struct flow *flow_alloc(void)
|
|||||||
|
|
||||||
flow->sprite_scope = sprite_scope_begin();
|
flow->sprite_scope = sprite_scope_begin();
|
||||||
flow->material_instances_arena = arena_alloc(GIGABYTE(1));
|
flow->material_instances_arena = arena_alloc(GIGABYTE(1));
|
||||||
|
flow->material_grids_arena = arena_alloc(GIGABYTE(1));
|
||||||
|
|
||||||
return flow;
|
return flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL void flow_reset(struct flow *flow)
|
||||||
|
{
|
||||||
|
sprite_scope_end(flow->sprite_scope);
|
||||||
|
flow->sprite_scope = sprite_scope_begin();
|
||||||
|
arena_reset(flow->material_instances_arena);
|
||||||
|
arena_reset(flow->material_grids_arena);
|
||||||
|
}
|
||||||
|
|
||||||
struct gp_handle gp_flow_alloc(void)
|
struct gp_handle gp_flow_alloc(void)
|
||||||
{
|
{
|
||||||
struct flow *flow = flow_alloc();
|
struct flow *flow = flow_alloc();
|
||||||
return handle_alloc(DX12_HANDLE_KIND_FLOW, flow);
|
return handle_alloc(DX12_HANDLE_KIND_FLOW, flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_params params)
|
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc desc)
|
||||||
{
|
{
|
||||||
struct flow *flow = handle_get_data(gp_flow, DX12_HANDLE_KIND_FLOW);
|
struct flow *flow = handle_get_data(gp_flow, DX12_HANDLE_KIND_FLOW);
|
||||||
if (flow) {
|
if (flow) {
|
||||||
switch (params.kind) {
|
switch (desc.kind) {
|
||||||
default: break;
|
default: break;
|
||||||
|
|
||||||
case GP_CMD_KIND_DRAW_TEXTURE:
|
case GP_CMD_KIND_DRAW_TEXTURE:
|
||||||
{
|
{
|
||||||
struct dx12_resource *texture = NULL;
|
i32 texture_id = -1;
|
||||||
if (params.texture.texture.gen != 0) {
|
{
|
||||||
texture = handle_get_data(params.texture.texture, DX12_HANDLE_KIND_RESOURCE);
|
struct dx12_resource *texture = NULL;
|
||||||
} else if (params.texture.sprite.hash != 0) {
|
if (desc.texture.texture.gen != 0) {
|
||||||
struct sprite_texture *st = sprite_texture_from_tag_async(flow->sprite_scope, params.texture.sprite);
|
texture = handle_get_data(desc.texture.texture, DX12_HANDLE_KIND_RESOURCE);
|
||||||
texture = handle_get_data(st->texture, DX12_HANDLE_KIND_RESOURCE);
|
} else if (desc.texture.sprite.hash != 0) {
|
||||||
|
struct sprite_texture *st = sprite_texture_from_tag_async(flow->sprite_scope, desc.texture.sprite);
|
||||||
|
texture = handle_get_data(st->texture, DX12_HANDLE_KIND_RESOURCE);
|
||||||
|
}
|
||||||
|
if (texture) {
|
||||||
|
texture_id = texture->srv_descriptor->index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (texture) {
|
|
||||||
|
i32 grid_id = -1;
|
||||||
|
if (desc.texture.grid) {
|
||||||
|
struct gp_grid_desc *grid_desc = desc.texture.grid;
|
||||||
|
struct sh_material_grid *grid = arena_push(flow->material_grids_arena, struct sh_material_grid);
|
||||||
|
grid->line_thickness = sh_float_from_f32(grid_desc->line_thickness);
|
||||||
|
grid->line_spacing = sh_float_from_f32(grid_desc->line_spacing);
|
||||||
|
grid->offset = sh_float2_from_v2(grid_desc->offset);
|
||||||
|
grid->bg0_srgb = sh_uint_from_u32(grid_desc->bg0_color);
|
||||||
|
grid->bg1_srgb = sh_uint_from_u32(grid_desc->bg1_color);
|
||||||
|
grid->line_srgb = sh_uint_from_u32(grid_desc->line_color);
|
||||||
|
grid->x_srgb = sh_uint_from_u32(grid_desc->x_color);
|
||||||
|
grid->y_srgb = sh_uint_from_u32(grid_desc->y_color);
|
||||||
|
grid_id = ((u8 *)grid - arena_base(flow->material_grids_arena)) / sizeof(grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture_id >= 0 || grid_id >= 0) {
|
||||||
struct sh_material_instance *instance = arena_push(flow->material_instances_arena, struct sh_material_instance);
|
struct sh_material_instance *instance = arena_push(flow->material_instances_arena, struct sh_material_instance);
|
||||||
instance->xf = sh_float2x3_from_xform(params.texture.xf);
|
instance->flags = sh_uint_from_u32(SH_MATERIAL_FLAG_NONE);
|
||||||
instance->uv0 = sh_float2_from_v2(params.texture.clip.p0);
|
instance->tex_nurid = sh_int_from_i32(texture_id);
|
||||||
instance->uv1 = sh_float2_from_v2(params.texture.clip.p1);
|
instance->grid_id = sh_int_from_i32(grid_id);
|
||||||
instance->texture_nuri = sh_uint_from_u32(texture->srv_descriptor->index);
|
instance->xf = sh_float2x3_from_xform(desc.texture.xf);
|
||||||
instance->tint_srgb = sh_uint_from_u32(params.texture.tint);
|
instance->uv0 = sh_float2_from_v2(desc.texture.clip.p0);
|
||||||
instance->emittance = sh_float_from_f32(params.texture.emittance);
|
instance->uv1 = sh_float2_from_v2(desc.texture.clip.p1);
|
||||||
|
instance->tint_srgb = sh_uint_from_u32(desc.texture.tint);
|
||||||
|
instance->emittance = sh_float_from_f32(desc.texture.emittance);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -2173,8 +2233,9 @@ void gp_dispatch(struct gp_dispatch_params params)
|
|||||||
quad_index_buffer_view.Format = DXGI_FORMAT_R16_UINT;
|
quad_index_buffer_view.Format = DXGI_FORMAT_R16_UINT;
|
||||||
quad_index_buffer_view.SizeInBytes = sizeof(quad_indices);
|
quad_index_buffer_view.SizeInBytes = sizeof(quad_indices);
|
||||||
|
|
||||||
/* Upload instance buffer */
|
/* Upload buffers */
|
||||||
struct command_buffer *instance_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_instances_arena));
|
struct command_buffer *instance_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_instances_arena));
|
||||||
|
struct command_buffer *grid_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_grids_arena));
|
||||||
|
|
||||||
/* Upload descriptor heap */
|
/* Upload descriptor heap */
|
||||||
struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap);
|
struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap);
|
||||||
@ -2211,10 +2272,13 @@ void gp_dispatch(struct gp_dispatch_params params)
|
|||||||
/* Bind instance buffer */
|
/* Bind instance buffer */
|
||||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, instance_buffer->resource->gpu_address);
|
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, instance_buffer->resource->gpu_address);
|
||||||
|
|
||||||
|
/* Bind grid buffer */
|
||||||
|
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, grid_buffer->resource->gpu_address);
|
||||||
|
|
||||||
/* Bind descriptor heap */
|
/* Bind descriptor heap */
|
||||||
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
||||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps);
|
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps);
|
||||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 2, descriptor_heap->gp_handle);
|
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 3, descriptor_heap->gp_handle);
|
||||||
|
|
||||||
/* Setup Rasterizer State */
|
/* Setup Rasterizer State */
|
||||||
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
|
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
|
||||||
@ -2237,12 +2301,7 @@ void gp_dispatch(struct gp_dispatch_params params)
|
|||||||
command_list_close(cl);
|
command_list_close(cl);
|
||||||
}
|
}
|
||||||
pipeline_scope_end(pipeline_scope);
|
pipeline_scope_end(pipeline_scope);
|
||||||
|
flow_reset(flow);
|
||||||
/* Reset flow */
|
|
||||||
sprite_scope_end(flow->sprite_scope);
|
|
||||||
flow->sprite_scope = sprite_scope_begin();
|
|
||||||
arena_reset(flow->material_instances_arena);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -2447,7 +2506,8 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src,
|
|||||||
/* Set root constants */
|
/* Set root 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.texture_id = 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);
|
||||||
command_list_set_root_constant(cl, &constants, sizeof(constants));
|
command_list_set_root_constant(cl, &constants, sizeof(constants));
|
||||||
|
|
||||||
/* Bind descriptor heap */
|
/* Bind descriptor heap */
|
||||||
|
|||||||
@ -2088,7 +2088,7 @@ void sys_message_box(enum sys_message_box_kind kind, struct string message)
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//logf_info("Showing message box: \"%F\"", FMT_STR(message));
|
logf_info("Showing message box kind %F with text \"%F\"", FMT_SINT(kind), FMT_STR(message));
|
||||||
MessageBoxExW(NULL, message_wstr, title, mbox_type, 0);
|
MessageBoxExW(NULL, message_wstr, title, mbox_type, 0);
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
|
|||||||
@ -1060,7 +1060,7 @@ INTERNAL void user_update(void)
|
|||||||
{
|
{
|
||||||
struct v2 pos = xform_invert_mul_v2(G.world_to_user_xf, V2(0, 0));
|
struct v2 pos = xform_invert_mul_v2(G.world_to_user_xf, V2(0, 0));
|
||||||
struct v2 size = xform_basis_invert_mul_v2(G.world_to_user_xf, G.user_size);
|
struct v2 size = xform_basis_invert_mul_v2(G.world_to_user_xf, G.user_size);
|
||||||
struct gp_cmd_params cmd = ZI;
|
struct gp_cmd_desc cmd = ZI;
|
||||||
cmd.kind = GP_CMD_KIND_TEST;
|
cmd.kind = GP_CMD_KIND_TEST;
|
||||||
cmd.test.xf = xform_from_rect(RECT_FROM_V2(pos, size));
|
cmd.test.xf = xform_from_rect(RECT_FROM_V2(pos, size));
|
||||||
gp_push_cmd(G.world_gp_flow, cmd);
|
gp_push_cmd(G.world_gp_flow, cmd);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user