push & process commands separately
This commit is contained in:
parent
e503fc9bdf
commit
9e0696d183
@ -33,7 +33,6 @@ struct vs_input {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct vs_output {
|
struct vs_output {
|
||||||
nointerpolation DECLS(uint, flags);
|
|
||||||
nointerpolation DECLS(int, tex_nurid);
|
nointerpolation DECLS(int, tex_nurid);
|
||||||
nointerpolation DECLS(int, grid_id);
|
nointerpolation DECLS(int, grid_id);
|
||||||
DECLS(float2, uv);
|
DECLS(float2, uv);
|
||||||
@ -56,7 +55,6 @@ 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.tex_nurid = instance.tex_nurid;
|
||||||
output.grid_id = instance.grid_id;
|
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));
|
||||||
|
|||||||
@ -73,15 +73,12 @@ SH_ASSERT_32BIT(struct sh_blit_constants, 18); /* Expected 32bit root constant
|
|||||||
* 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, tex_nurid);
|
||||||
SH_DECL(int, grid_id);
|
SH_DECL(int, grid_id);
|
||||||
SH_DECL(float2x3, xf);
|
SH_DECL(float2x3, xf);
|
||||||
|
|||||||
63
src/draw.c
63
src/draw.c
@ -28,7 +28,7 @@ struct draw_startup_receipt draw_startup(struct gp_startup_receipt *gp_sr,
|
|||||||
* Texture
|
* Texture
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_texture(struct gp_handle flow, struct draw_texture_params params)
|
void draw_texture(struct gp_flow *flow, struct draw_texture_params params)
|
||||||
{
|
{
|
||||||
struct gp_cmd_desc cmd = ZI;
|
struct gp_cmd_desc cmd = ZI;
|
||||||
cmd.kind = GP_CMD_KIND_DRAW_MATERIAL;
|
cmd.kind = GP_CMD_KIND_DRAW_MATERIAL;
|
||||||
@ -38,25 +38,25 @@ void draw_texture(struct gp_handle flow, struct draw_texture_params params)
|
|||||||
cmd.material.clip = params.clip;
|
cmd.material.clip = params.clip;
|
||||||
cmd.material.tint = params.tint;
|
cmd.material.tint = params.tint;
|
||||||
cmd.material.emittance = params.emittance;
|
cmd.material.emittance = params.emittance;
|
||||||
gp_push_cmd(flow, cmd);
|
gp_push_cmd(flow, &cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Fill shapes
|
* Fill shapes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_poly_ex(struct gp_handle flow, struct v2_array vertices, struct gp_indices indices, u32 color)
|
void draw_poly_ex(struct gp_flow *flow, struct v2_array vertices, struct gp_indices indices, u32 color)
|
||||||
{
|
{
|
||||||
struct gp_cmd_desc cmd = ZI;
|
struct gp_cmd_desc cmd = ZI;
|
||||||
cmd.kind = GP_CMD_KIND_DRAW_SHAPE;
|
cmd.kind = GP_CMD_KIND_DRAW_SHAPE;
|
||||||
cmd.shape.vertices = vertices;
|
cmd.shape.vertices = vertices;
|
||||||
cmd.shape.indices = indices;
|
cmd.shape.indices = indices;
|
||||||
cmd.shape.color = color;
|
cmd.shape.color = color;
|
||||||
gp_push_cmd(flow, cmd);
|
gp_push_cmd(flow, &cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draws a filled polygon using triangles in a fan pattern */
|
/* Draws a filled polygon using triangles in a fan pattern */
|
||||||
void draw_poly(struct gp_handle flow, struct v2_array vertices, u32 color)
|
void draw_poly(struct gp_flow *flow, struct v2_array vertices, u32 color)
|
||||||
{
|
{
|
||||||
if (vertices.count >= 3) {
|
if (vertices.count >= 3) {
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
@ -82,7 +82,7 @@ void draw_poly(struct gp_handle flow, struct v2_array vertices, u32 color)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_circle(struct gp_handle flow, struct v2 pos, f32 radius, u32 color, u32 detail)
|
void draw_circle(struct gp_flow *flow, struct v2 pos, f32 radius, u32 color, u32 detail)
|
||||||
{
|
{
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ void draw_circle(struct gp_handle flow, struct v2 pos, f32 radius, u32 color, u3
|
|||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_quad(struct gp_handle flow, struct quad quad, u32 color)
|
void draw_quad(struct gp_flow *flow, struct quad quad, u32 color)
|
||||||
{
|
{
|
||||||
LOCAL_PERSIST u32 indices_array[6] = {
|
LOCAL_PERSIST u32 indices_array[6] = {
|
||||||
0, 1, 2,
|
0, 1, 2,
|
||||||
@ -120,7 +120,7 @@ void draw_quad(struct gp_handle flow, struct quad quad, u32 color)
|
|||||||
* Line shapes
|
* Line shapes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_gradient_line(struct gp_handle flow, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color)
|
void draw_gradient_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
struct quad quad = quad_from_line(start, end, thickness);
|
struct quad quad = quad_from_line(start, end, thickness);
|
||||||
@ -133,19 +133,19 @@ void draw_gradient_line(struct gp_handle flow, struct v2 start, struct v2 end, f
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_line(struct gp_handle flow, struct v2 start, struct v2 end, f32 thickness, u32 color)
|
void draw_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, u32 color)
|
||||||
{
|
{
|
||||||
struct quad quad = quad_from_line(start, end, thickness);
|
struct quad quad = quad_from_line(start, end, thickness);
|
||||||
draw_quad(flow, quad, color);
|
draw_quad(flow, quad, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_ray(struct gp_handle flow, struct v2 pos, struct v2 rel, f32 thickness, u32 color)
|
void draw_ray(struct gp_flow *flow, struct v2 pos, struct v2 rel, f32 thickness, u32 color)
|
||||||
{
|
{
|
||||||
struct quad quad = quad_from_ray(pos, rel, thickness);
|
struct quad quad = quad_from_ray(pos, rel, thickness);
|
||||||
draw_quad(flow, quad, color);
|
draw_quad(flow, quad, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_poly_line(struct gp_handle flow, struct v2_array points, b32 loop, f32 thickness, u32 color)
|
void draw_poly_line(struct gp_flow *flow, struct v2_array points, b32 loop, f32 thickness, u32 color)
|
||||||
{
|
{
|
||||||
if (points.count >= 2) {
|
if (points.count >= 2) {
|
||||||
for (u64 i = 1; i < points.count; ++i) {
|
for (u64 i = 1; i < points.count; ++i) {
|
||||||
@ -163,7 +163,7 @@ void draw_poly_line(struct gp_handle flow, struct v2_array points, b32 loop, f32
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_circle_line(struct gp_handle flow, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
|
void draw_circle_line(struct gp_flow *flow, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
|
||||||
{
|
{
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
|
|
||||||
@ -186,14 +186,14 @@ void draw_circle_line(struct gp_handle flow, struct v2 pos, f32 radius, f32 thic
|
|||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_quad_line(struct gp_handle flow, struct quad quad, f32 thickness, u32 color)
|
void draw_quad_line(struct gp_flow *flow, struct quad quad, f32 thickness, u32 color)
|
||||||
{
|
{
|
||||||
struct v2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
|
struct v2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
|
||||||
struct v2_array a = { .points = points, .count = ARRAY_COUNT(points) };
|
struct v2_array a = { .points = points, .count = ARRAY_COUNT(points) };
|
||||||
draw_poly_line(flow, a, true, thickness, color);
|
draw_poly_line(flow, a, true, thickness, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_arrow_line(struct gp_handle flow, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color)
|
void draw_arrow_line(struct gp_flow *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 */
|
const f32 head_width_ratio = 0.5f; /* Width of arrowhead relative to its length */
|
||||||
|
|
||||||
@ -223,13 +223,13 @@ void draw_arrow_line(struct gp_handle flow, struct v2 start, struct v2 end, f32
|
|||||||
draw_quad(flow, line_quad, color);
|
draw_quad(flow, line_quad, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_arrow_ray(struct gp_handle flow, struct v2 pos, struct v2 rel, 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)
|
||||||
{
|
{
|
||||||
struct v2 end = v2_add(pos, rel);
|
struct v2 end = v2_add(pos, rel);
|
||||||
draw_arrow_line(flow, pos, end, thickness, arrowhead_height, color);
|
draw_arrow_line(flow, pos, end, thickness, arrowhead_height, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_collider_line(struct gp_handle flow, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail)
|
void draw_collider_line(struct gp_flow *flow, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail)
|
||||||
{
|
{
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
struct v2_array poly = ZI;
|
struct v2_array poly = ZI;
|
||||||
@ -258,24 +258,29 @@ void draw_collider_line(struct gp_handle flow, struct collider_shape shape, stru
|
|||||||
* Grid
|
* Grid
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
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_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)
|
||||||
{
|
{
|
||||||
struct gp_grid_desc grid = ZI;
|
i32 grid_id = 0;
|
||||||
grid.bg0_color = bg0_color;
|
{
|
||||||
grid.bg1_color = bg1_color;
|
struct gp_cmd_desc cmd = ZI;
|
||||||
grid.line_color = line_color;
|
cmd.kind = GP_CMD_KIND_PUSH_GRID;
|
||||||
grid.x_color = x_color;
|
cmd.grid.bg0_color = bg0_color;
|
||||||
grid.y_color = y_color;
|
cmd.grid.bg1_color = bg1_color;
|
||||||
grid.line_thickness = thickness;
|
cmd.grid.line_color = line_color;
|
||||||
grid.line_spacing = spacing;
|
cmd.grid.x_color = x_color;
|
||||||
grid.offset = offset;
|
cmd.grid.y_color = y_color;
|
||||||
|
cmd.grid.line_thickness = thickness;
|
||||||
|
cmd.grid.line_spacing = spacing;
|
||||||
|
cmd.grid.offset = offset;
|
||||||
|
grid_id = gp_push_cmd(flow, &cmd);
|
||||||
|
}
|
||||||
|
|
||||||
struct gp_cmd_desc cmd = ZI;
|
struct gp_cmd_desc cmd = ZI;
|
||||||
cmd.kind = GP_CMD_KIND_DRAW_MATERIAL;
|
cmd.kind = GP_CMD_KIND_DRAW_MATERIAL;
|
||||||
cmd.material.xf = xf;
|
cmd.material.xf = xf;
|
||||||
cmd.material.tint = COLOR_WHITE;
|
cmd.material.tint = COLOR_WHITE;
|
||||||
cmd.material.grid = &grid;
|
cmd.material.grid_cmd_id = grid_id;
|
||||||
gp_push_cmd(flow, cmd);
|
gp_push_cmd(flow, &cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -283,7 +288,7 @@ void draw_grid(struct gp_handle flow, struct xform xf, u32 bg0_color, u32 bg1_co
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
/* Returns the rect of the text area */
|
/* Returns the rect of the text area */
|
||||||
struct rect draw_text(struct gp_handle flow, struct draw_text_params params)
|
struct rect draw_text(struct gp_flow *flow, struct draw_text_params params)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
|
|||||||
32
src/draw.h
32
src/draw.h
@ -29,47 +29,47 @@ struct draw_texture_params {
|
|||||||
f32 emittance;
|
f32 emittance;
|
||||||
};
|
};
|
||||||
|
|
||||||
void draw_texture(struct gp_handle flow, struct draw_texture_params params);
|
void draw_texture(struct gp_flow *flow, struct draw_texture_params params);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Fill shapes
|
* Fill shapes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_poly_ex(struct gp_handle flow, struct v2_array vertices, struct gp_indices indices, u32 color);
|
void draw_poly_ex(struct gp_flow *flow, struct v2_array vertices, struct gp_indices indices, u32 color);
|
||||||
|
|
||||||
void draw_poly(struct gp_handle flow, struct v2_array points, u32 color);
|
void draw_poly(struct gp_flow *flow, struct v2_array points, u32 color);
|
||||||
|
|
||||||
void draw_circle(struct gp_handle flow, struct v2 pos, f32 radius, u32 color, u32 detail);
|
void draw_circle(struct gp_flow *flow, struct v2 pos, f32 radius, u32 color, u32 detail);
|
||||||
|
|
||||||
void draw_quad(struct gp_handle flow, struct quad quad, u32 color);
|
void draw_quad(struct gp_flow *flow, struct quad quad, u32 color);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Line shapes
|
* Line shapes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_gradient_line(struct gp_handle flow, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color);
|
void draw_gradient_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color);
|
||||||
|
|
||||||
void draw_line(struct gp_handle flow, struct v2 start, struct v2 end, f32 thickness, u32 color);
|
void draw_line(struct gp_flow *flow, struct v2 start, struct v2 end, f32 thickness, u32 color);
|
||||||
|
|
||||||
void draw_ray(struct gp_handle flow, struct v2 pos, struct v2 rel, f32 thickness, u32 color);
|
void draw_ray(struct gp_flow *flow, struct v2 pos, struct v2 rel, f32 thickness, u32 color);
|
||||||
|
|
||||||
void draw_poly_line(struct gp_handle flow, struct v2_array points, b32 loop, f32 thickness, u32 color);
|
void draw_poly_line(struct gp_flow *flow, struct v2_array points, b32 loop, f32 thickness, u32 color);
|
||||||
|
|
||||||
void draw_circle_line(struct gp_handle flow, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
|
void draw_circle_line(struct gp_flow *flow, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
|
||||||
|
|
||||||
void draw_quad_line(struct gp_handle flow, struct quad quad, f32 thickness, u32 color);
|
void draw_quad_line(struct gp_flow *flow, struct quad quad, f32 thickness, u32 color);
|
||||||
|
|
||||||
void draw_arrow_line(struct gp_handle flow, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, 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_ray(struct gp_handle flow, struct v2 pos, struct v2 rel, 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_collider_line(struct gp_handle flow, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail);
|
void draw_collider_line(struct gp_flow *flow, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Grid
|
* Grid
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
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_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);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Text
|
* Text
|
||||||
@ -117,6 +117,6 @@ struct draw_text_params {
|
|||||||
struct string str;
|
struct string str;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rect draw_text(struct gp_handle flow, struct draw_text_params params);
|
struct rect draw_text(struct gp_flow *flow, struct draw_text_params params);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
37
src/gp.h
37
src/gp.h
@ -63,28 +63,18 @@ struct v2i32 gp_texture_get_size(struct gp_handle texture);
|
|||||||
* Flow
|
* Flow
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct gp_indices {
|
|
||||||
u32 count;
|
|
||||||
u32 *indices;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum gp_cmd_kind {
|
enum gp_cmd_kind {
|
||||||
GP_CMD_KIND_NONE,
|
GP_CMD_KIND_NONE,
|
||||||
GP_CMD_KIND_DRAW_SHAPE,
|
GP_CMD_KIND_DRAW_SHAPE,
|
||||||
GP_CMD_KIND_DRAW_MATERIAL,
|
GP_CMD_KIND_DRAW_MATERIAL,
|
||||||
|
GP_CMD_KIND_PUSH_GRID,
|
||||||
|
|
||||||
NUM_GP_CMD_KINDS
|
NUM_GP_CMD_KINDS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gp_grid_desc {
|
struct gp_indices {
|
||||||
f32 line_thickness;
|
u32 count;
|
||||||
f32 line_spacing;
|
u32 *indices;
|
||||||
struct v2 offset;
|
|
||||||
u32 bg0_color;
|
|
||||||
u32 bg1_color;
|
|
||||||
u32 line_color;
|
|
||||||
u32 x_color;
|
|
||||||
u32 y_color;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gp_cmd_desc {
|
struct gp_cmd_desc {
|
||||||
@ -97,27 +87,38 @@ struct gp_cmd_desc {
|
|||||||
struct clip_rect clip;
|
struct clip_rect clip;
|
||||||
u32 tint;
|
u32 tint;
|
||||||
f32 emittance;
|
f32 emittance;
|
||||||
struct gp_grid_desc *grid;
|
i32 grid_cmd_id;
|
||||||
} material;
|
} material;
|
||||||
struct {
|
struct {
|
||||||
struct v2_array vertices;
|
struct v2_array vertices;
|
||||||
struct gp_indices indices;
|
struct gp_indices indices;
|
||||||
u32 color;
|
u32 color;
|
||||||
} shape;
|
} shape;
|
||||||
|
struct {
|
||||||
|
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 gp_dispatch_params {
|
struct gp_dispatch_params {
|
||||||
struct gp_handle flow;
|
struct gp_flow *flow;
|
||||||
struct gp_handle draw_target;
|
struct gp_handle draw_target;
|
||||||
struct rect draw_target_viewport;
|
struct rect draw_target_viewport;
|
||||||
struct xform draw_target_view;
|
struct xform draw_target_view;
|
||||||
b32 clear_target;
|
b32 clear_target;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gp_handle gp_flow_alloc(void);
|
struct gp_flow *gp_flow_alloc(void);
|
||||||
|
|
||||||
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc params);
|
/* Returns a cmd id internal to the flow */
|
||||||
|
i32 gp_push_cmd(struct gp_flow *gp_flow, struct gp_cmd_desc *desc);
|
||||||
|
|
||||||
void gp_dispatch(struct gp_dispatch_params params);
|
void gp_dispatch(struct gp_dispatch_params params);
|
||||||
|
|
||||||
|
|||||||
526
src/gp_dx12.c
526
src/gp_dx12.c
@ -121,13 +121,14 @@ struct command_queue {
|
|||||||
D3D12_COMMAND_LIST_TYPE type;
|
D3D12_COMMAND_LIST_TYPE type;
|
||||||
ID3D12CommandQueue *cq;
|
ID3D12CommandQueue *cq;
|
||||||
struct arena *arena;
|
struct arena *arena;
|
||||||
struct sys_mutex *mutex;
|
|
||||||
|
|
||||||
|
struct sys_mutex *submitted_command_lists_mutex;
|
||||||
struct command_list *first_submitted_command_list;
|
struct command_list *first_submitted_command_list;
|
||||||
struct command_list *last_submitted_command_list;
|
struct command_list *last_submitted_command_list;
|
||||||
|
|
||||||
struct atomic_u64 fence_target;
|
struct sys_mutex *submit_fence_mutex;
|
||||||
ID3D12Fence *fence;
|
u64 submit_fence_target;
|
||||||
|
ID3D12Fence *submit_fence;
|
||||||
|
|
||||||
#if PROFILING
|
#if PROFILING
|
||||||
struct __prof_dx12_ctx *prof;
|
struct __prof_dx12_ctx *prof;
|
||||||
@ -138,7 +139,7 @@ struct command_list {
|
|||||||
struct command_queue *cq;
|
struct command_queue *cq;
|
||||||
struct ID3D12CommandAllocator *ca;
|
struct ID3D12CommandAllocator *ca;
|
||||||
struct ID3D12GraphicsCommandList *cl;
|
struct ID3D12GraphicsCommandList *cl;
|
||||||
struct sys_lock global_lock;
|
struct sys_lock global_record_lock;
|
||||||
|
|
||||||
struct command_descriptor_heap *first_command_descriptor_heap;
|
struct command_descriptor_heap *first_command_descriptor_heap;
|
||||||
struct command_buffer *first_command_buffer;
|
struct command_buffer *first_command_buffer;
|
||||||
@ -195,17 +196,10 @@ struct descriptor {
|
|||||||
struct dx12_resource {
|
struct dx12_resource {
|
||||||
ID3D12Resource *resource;
|
ID3D12Resource *resource;
|
||||||
enum D3D12_RESOURCE_STATES state;
|
enum D3D12_RESOURCE_STATES state;
|
||||||
#if 0
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE cbv_handle;
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE srv_handle;
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE uav_handle;
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
|
|
||||||
#else
|
|
||||||
struct descriptor *cbv_descriptor;
|
struct descriptor *cbv_descriptor;
|
||||||
struct descriptor *srv_descriptor;
|
struct descriptor *srv_descriptor;
|
||||||
struct descriptor *uav_descriptor;
|
struct descriptor *uav_descriptor;
|
||||||
struct descriptor *rtv_descriptor;
|
struct descriptor *rtv_descriptor;
|
||||||
#endif
|
|
||||||
|
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS gpu_address; /* NOTE: 0 for textures */
|
D3D12_GPU_VIRTUAL_ADDRESS gpu_address; /* NOTE: 0 for textures */
|
||||||
|
|
||||||
@ -213,6 +207,20 @@ struct dx12_resource {
|
|||||||
struct dx12_resource *next_free;
|
struct dx12_resource *next_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct swapchain_buffer {
|
||||||
|
struct swapchain *swapchain;
|
||||||
|
ID3D12Resource *resource;
|
||||||
|
struct descriptor *rtv_descriptor;
|
||||||
|
D3D12_RESOURCE_STATES state;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct swapchain {
|
||||||
|
IDXGISwapChain3 *swapchain;
|
||||||
|
HWND hwnd;
|
||||||
|
struct v2i32 resolution;
|
||||||
|
struct swapchain_buffer buffers[DX12_SWAPCHAIN_BUFFER_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
struct cpu_descriptor_heap {
|
struct cpu_descriptor_heap {
|
||||||
enum D3D12_DESCRIPTOR_HEAP_TYPE type;
|
enum D3D12_DESCRIPTOR_HEAP_TYPE type;
|
||||||
struct arena *arena;
|
struct arena *arena;
|
||||||
@ -231,7 +239,6 @@ struct cpu_descriptor_heap {
|
|||||||
enum handle_kind {
|
enum handle_kind {
|
||||||
DX12_HANDLE_KIND_NONE,
|
DX12_HANDLE_KIND_NONE,
|
||||||
DX12_HANDLE_KIND_RESOURCE,
|
DX12_HANDLE_KIND_RESOURCE,
|
||||||
DX12_HANDLE_KIND_FLOW,
|
|
||||||
|
|
||||||
NUM_DX12_HANDLE_KINDS
|
NUM_DX12_HANDLE_KINDS
|
||||||
};
|
};
|
||||||
@ -299,18 +306,15 @@ GLOBAL struct {
|
|||||||
|
|
||||||
/* Command queues */
|
/* Command queues */
|
||||||
/* TODO: Add optional mode to route everything to direct queue */
|
/* TODO: Add optional mode to route everything to direct queue */
|
||||||
struct sys_mutex *global_command_list_mutex;
|
struct sys_mutex *global_command_list_record_mutex;
|
||||||
|
struct sys_mutex *global_command_list_submit_mutex;
|
||||||
struct command_queue *cq_direct;
|
struct command_queue *cq_direct;
|
||||||
struct command_queue *cq_compute;
|
struct command_queue *cq_compute;
|
||||||
struct command_queue *cq_copy_critical;
|
struct command_queue *cq_copy_critical;
|
||||||
struct command_queue *cq_copy_background;
|
struct command_queue *cq_copy_background;
|
||||||
|
|
||||||
/* Swapchain */
|
/* Swapchain */
|
||||||
HWND swapchain_hwnd;
|
struct swapchain swapchain;
|
||||||
struct v2i32 swapchain_resolution;
|
|
||||||
u32 swapchain_frame_index;
|
|
||||||
IDXGISwapChain3 *swapchain;
|
|
||||||
struct dx12_resource *swapchain_resources[DX12_SWAPCHAIN_BUFFER_COUNT];
|
|
||||||
} G = ZI, DEBUG_ALIAS(G, G_gp_dx12);
|
} G = ZI, DEBUG_ALIAS(G, G_gp_dx12);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -378,10 +382,7 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gp_shutdown)
|
|||||||
__prof;
|
__prof;
|
||||||
#if DX12_DEBUG
|
#if DX12_DEBUG
|
||||||
/* Release objects to make live object reporting less noisy */
|
/* Release objects to make live object reporting less noisy */
|
||||||
for (u64 i = 0; i < ARRAY_COUNT(G.swapchain_resources); ++i) {
|
//IDXGISwapChain3_Release(G.swapchain);
|
||||||
dx12_resource_release(G.swapchain_resources[i]);
|
|
||||||
}
|
|
||||||
IDXGISwapChain3_Release(G.swapchain);
|
|
||||||
command_queue_release(G.cq_copy_background);
|
command_queue_release(G.cq_copy_background);
|
||||||
command_queue_release(G.cq_copy_critical);
|
command_queue_release(G.cq_copy_critical);
|
||||||
command_queue_release(G.cq_compute);
|
command_queue_release(G.cq_compute);
|
||||||
@ -441,20 +442,27 @@ INTERNAL struct handle_entry *handle_get_entry(struct gp_handle handle, struct s
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void *handle_get_data(struct gp_handle handle, enum handle_kind kind)
|
INTERNAL void *handle_get_data_locked(struct gp_handle handle, enum handle_kind kind, struct sys_lock *lock)
|
||||||
{
|
{
|
||||||
(UNUSED)kind;
|
sys_assert_locked_e_or_s(lock, G.handle_entries_mutex);
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
if (handle.gen) {
|
if (handle.gen) {
|
||||||
struct sys_lock lock = sys_mutex_lock_s(G.handle_entries_mutex);
|
struct handle_entry *entry = handle_get_entry(handle, lock);
|
||||||
{
|
|
||||||
struct handle_entry *entry = handle_get_entry(handle, &lock);
|
|
||||||
data = entry->data;
|
data = entry->data;
|
||||||
#if RTC
|
#if RTC
|
||||||
/* Handle should match expected kind */
|
/* Handle should match expected kind */
|
||||||
ASSERT(entry->kind == kind);
|
ASSERT(entry->kind == kind);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL void *handle_get_data(struct gp_handle handle, enum handle_kind kind)
|
||||||
|
{
|
||||||
|
void *data = NULL;
|
||||||
|
if (handle.gen) {
|
||||||
|
struct sys_lock lock = sys_mutex_lock_e(G.handle_entries_mutex);
|
||||||
|
data = handle_get_data_locked(handle, kind, &lock);
|
||||||
sys_mutex_unlock(&lock);
|
sys_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
@ -670,7 +678,8 @@ INTERNAL void dx12_init_objects(void)
|
|||||||
G.rtv_heap = cpu_descriptor_heap_alloc(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
G.rtv_heap = cpu_descriptor_heap_alloc(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||||
|
|
||||||
/* Create command queues */
|
/* Create command queues */
|
||||||
G.global_command_list_mutex = sys_mutex_alloc();
|
G.global_command_list_record_mutex = sys_mutex_alloc();
|
||||||
|
G.global_command_list_submit_mutex = sys_mutex_alloc();
|
||||||
G.cq_direct = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, LIT("Direct queue"));
|
G.cq_direct = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, LIT("Direct queue"));
|
||||||
G.cq_compute = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, LIT("Compute queue"));
|
G.cq_compute = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, LIT("Compute queue"));
|
||||||
G.cq_copy_critical = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_COPY, D3D12_COMMAND_QUEUE_PRIORITY_HIGH, LIT("High priority copy queue"));
|
G.cq_copy_critical = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_COPY, D3D12_COMMAND_QUEUE_PRIORITY_HIGH, LIT("High priority copy queue"));
|
||||||
@ -1402,6 +1411,17 @@ INTERNAL struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh)
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL void descriptor_release(struct descriptor *descriptor)
|
||||||
|
{
|
||||||
|
struct cpu_descriptor_heap *dh = descriptor->heap;
|
||||||
|
struct sys_lock lock = sys_mutex_lock_e(dh->mutex);
|
||||||
|
{
|
||||||
|
descriptor->next_free = dh->first_free_descriptor;
|
||||||
|
dh->first_free_descriptor = descriptor;
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&lock);
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* CPU descriptor heap
|
* CPU descriptor heap
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -1456,16 +1476,42 @@ INTERNAL void cpu_descriptor_heap_release(struct cpu_descriptor_heap *dh)
|
|||||||
struct flow {
|
struct flow {
|
||||||
struct arena *arena;
|
struct arena *arena;
|
||||||
|
|
||||||
/* Below fields are reset each dispatch */
|
/* Material instances */
|
||||||
struct sprite_scope *sprite_scope;
|
u32 num_material_instance_descs;
|
||||||
struct arena *material_instances_arena;
|
struct arena *material_instance_descs_arena;
|
||||||
struct arena *material_grids_arena;
|
|
||||||
|
/* Grids */
|
||||||
|
u32 num_material_grid_descs;
|
||||||
|
struct arena *material_grid_descs_arena;
|
||||||
|
|
||||||
|
/* Shapes */
|
||||||
struct arena *shape_verts_arena;
|
struct arena *shape_verts_arena;
|
||||||
struct arena *shape_indices_arena;
|
struct arena *shape_indices_arena;
|
||||||
|
|
||||||
struct flow *next_free;
|
struct flow *next_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct material_instance_desc {
|
||||||
|
struct xform xf;
|
||||||
|
struct sprite_tag sprite;
|
||||||
|
struct gp_handle texture;
|
||||||
|
struct clip_rect clip;
|
||||||
|
u32 tint;
|
||||||
|
f32 emittance;
|
||||||
|
i32 grid_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct material_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;
|
||||||
|
};
|
||||||
|
|
||||||
INTERNAL struct flow *flow_alloc(void)
|
INTERNAL struct flow *flow_alloc(void)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
@ -1476,9 +1522,8 @@ INTERNAL struct flow *flow_alloc(void)
|
|||||||
flow->arena = arena;
|
flow->arena = arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
flow->sprite_scope = sprite_scope_begin();
|
flow->material_instance_descs_arena = arena_alloc(GIGABYTE(1));
|
||||||
flow->material_instances_arena = arena_alloc(GIGABYTE(1));
|
flow->material_grid_descs_arena = arena_alloc(GIGABYTE(1));
|
||||||
flow->material_grids_arena = arena_alloc(GIGABYTE(1));
|
|
||||||
flow->shape_verts_arena = arena_alloc(GIGABYTE(1));
|
flow->shape_verts_arena = arena_alloc(GIGABYTE(1));
|
||||||
flow->shape_indices_arena = arena_alloc(GIGABYTE(1));
|
flow->shape_indices_arena = arena_alloc(GIGABYTE(1));
|
||||||
|
|
||||||
@ -1488,90 +1533,81 @@ INTERNAL struct flow *flow_alloc(void)
|
|||||||
INTERNAL void flow_reset(struct flow *flow)
|
INTERNAL void flow_reset(struct flow *flow)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
sprite_scope_end(flow->sprite_scope);
|
|
||||||
flow->sprite_scope = sprite_scope_begin();
|
/* Reset material instances */
|
||||||
arena_reset(flow->material_instances_arena);
|
flow->num_material_instance_descs = 0;
|
||||||
arena_reset(flow->material_grids_arena);
|
arena_reset(flow->material_instance_descs_arena);
|
||||||
|
|
||||||
|
/* Reset grids */
|
||||||
|
flow->num_material_grid_descs = 0;
|
||||||
|
arena_reset(flow->material_grid_descs_arena);
|
||||||
|
|
||||||
|
/* Reset shapes */
|
||||||
arena_reset(flow->shape_verts_arena);
|
arena_reset(flow->shape_verts_arena);
|
||||||
arena_reset(flow->shape_indices_arena);
|
arena_reset(flow->shape_indices_arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gp_handle gp_flow_alloc(void)
|
struct gp_flow *gp_flow_alloc(void)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct flow *flow = flow_alloc();
|
struct flow *flow = flow_alloc();
|
||||||
return handle_alloc(DX12_HANDLE_KIND_FLOW, flow);
|
return (struct gp_flow *)flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc desc)
|
i32 gp_push_cmd(struct gp_flow *gp_flow, struct gp_cmd_desc *cmd_desc)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct flow *flow = handle_get_data(gp_flow, DX12_HANDLE_KIND_FLOW);
|
i32 ret = 0;
|
||||||
|
struct flow *flow = (struct flow *)gp_flow;
|
||||||
if (flow) {
|
if (flow) {
|
||||||
switch (desc.kind) {
|
switch (cmd_desc->kind) {
|
||||||
default: break;
|
default: break;
|
||||||
|
|
||||||
case GP_CMD_KIND_DRAW_MATERIAL:
|
case GP_CMD_KIND_DRAW_MATERIAL:
|
||||||
{
|
{
|
||||||
i32 texture_id = -1;
|
struct material_instance_desc *instance_desc = arena_push(flow->material_instance_descs_arena, struct material_instance_desc);
|
||||||
{
|
instance_desc->xf = cmd_desc->material.xf;
|
||||||
struct dx12_resource *texture = NULL;
|
instance_desc->sprite = cmd_desc->material.sprite;
|
||||||
if (desc.material.texture.gen != 0) {
|
instance_desc->texture = cmd_desc->material.texture;
|
||||||
texture = handle_get_data(desc.material.texture, DX12_HANDLE_KIND_RESOURCE);
|
instance_desc->clip = cmd_desc->material.clip;
|
||||||
} else if (desc.material.sprite.hash != 0) {
|
instance_desc->tint = cmd_desc->material.tint;
|
||||||
struct sprite_texture *st = sprite_texture_from_tag_async(flow->sprite_scope, desc.material.sprite);
|
instance_desc->emittance = cmd_desc->material.emittance;
|
||||||
texture = handle_get_data(st->texture, DX12_HANDLE_KIND_RESOURCE);
|
instance_desc->grid_id = cmd_desc->material.grid_cmd_id - 1;
|
||||||
}
|
ret = ++flow->num_material_instance_descs;
|
||||||
if (texture) {
|
|
||||||
texture_id = texture->srv_descriptor->index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 grid_id = -1;
|
|
||||||
if (desc.material.grid) {
|
|
||||||
struct gp_grid_desc *grid_desc = desc.material.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);
|
|
||||||
instance->flags = sh_uint_from_u32(SH_MATERIAL_FLAG_NONE);
|
|
||||||
instance->tex_nurid = sh_int_from_i32(texture_id);
|
|
||||||
instance->grid_id = sh_int_from_i32(grid_id);
|
|
||||||
instance->xf = sh_float2x3_from_xform(desc.material.xf);
|
|
||||||
instance->uv0 = sh_float2_from_v2(desc.material.clip.p0);
|
|
||||||
instance->uv1 = sh_float2_from_v2(desc.material.clip.p1);
|
|
||||||
instance->tint_srgb = sh_uint_from_u32(desc.material.tint);
|
|
||||||
instance->emittance = sh_float_from_f32(desc.material.emittance);
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case GP_CMD_KIND_DRAW_SHAPE:
|
case GP_CMD_KIND_DRAW_SHAPE:
|
||||||
{
|
{
|
||||||
u32 color = desc.shape.color;
|
u32 color = cmd_desc->shape.color;
|
||||||
u32 vert_offset = flow->shape_verts_arena->pos / sizeof(struct sh_shape_vert);
|
struct sh_shape_vert *verts = arena_push_array_no_zero(flow->shape_verts_arena, struct sh_shape_vert, cmd_desc->shape.vertices.count);
|
||||||
struct sh_shape_vert *verts = arena_push_array_no_zero(flow->shape_verts_arena, struct sh_shape_vert, desc.shape.vertices.count);
|
u32 *indices = arena_push_array_no_zero(flow->shape_indices_arena, u32, cmd_desc->shape.indices.count);
|
||||||
u32 *indices = arena_push_array_no_zero(flow->shape_indices_arena, u32, desc.shape.indices.count);
|
for (u32 i = 0; i < cmd_desc->shape.vertices.count; ++i) {
|
||||||
for (u32 i = 0; i < desc.shape.vertices.count; ++i) {
|
|
||||||
struct sh_shape_vert *v = &verts[i];
|
struct sh_shape_vert *v = &verts[i];
|
||||||
v->pos = sh_float2_from_v2(desc.shape.vertices.points[i]);
|
v->pos = sh_float2_from_v2(cmd_desc->shape.vertices.points[i]);
|
||||||
v->color_srgb = sh_uint_from_u32(color);
|
v->color_srgb = sh_uint_from_u32(color);
|
||||||
}
|
}
|
||||||
for (u32 i = 0; i < desc.shape.indices.count; ++i) {
|
u32 vert_offset = verts - (struct sh_shape_vert *)arena_base(flow->shape_verts_arena);
|
||||||
indices[i] = desc.shape.indices.indices[i] + vert_offset;
|
for (u32 i = 0; i < cmd_desc->shape.indices.count; ++i) {
|
||||||
|
indices[i] = cmd_desc->shape.indices.indices[i] + vert_offset;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case GP_CMD_KIND_PUSH_GRID:
|
||||||
|
{
|
||||||
|
struct material_grid_desc *grid_desc = arena_push(flow->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;
|
||||||
|
grid_desc->bg0_color = cmd_desc->grid.bg0_color;
|
||||||
|
grid_desc->bg1_color = cmd_desc->grid.bg1_color;
|
||||||
|
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;
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -1641,43 +1677,10 @@ INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_pr
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12Resource *buff, struct v2i32 texture_size)
|
|
||||||
{
|
|
||||||
__prof;
|
|
||||||
struct dx12_resource *r = NULL;
|
|
||||||
{
|
|
||||||
struct sys_lock lock = sys_mutex_lock_e(G.resources_mutex);
|
|
||||||
if (G.first_free_resource) {
|
|
||||||
r = G.first_free_resource;
|
|
||||||
G.first_free_resource = r->next_free;
|
|
||||||
} else {
|
|
||||||
r = arena_push_no_zero(G.resources_arena, struct dx12_resource);
|
|
||||||
}
|
|
||||||
sys_mutex_unlock(&lock);
|
|
||||||
}
|
|
||||||
MEMZERO_STRUCT(r);
|
|
||||||
|
|
||||||
/* FIXME: Initialize dx12 resource struct here */
|
|
||||||
|
|
||||||
r->resource = buff;
|
|
||||||
r->rtv_descriptor = descriptor_alloc(G.rtv_heap);
|
|
||||||
r->texture_size = texture_size;
|
|
||||||
r->state = D3D12_RESOURCE_STATE_PRESENT; /* FIXME */
|
|
||||||
|
|
||||||
ID3D12Device_CreateRenderTargetView(G.device, r->resource, NULL, r->rtv_descriptor->handle);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL void dx12_resource_release(struct dx12_resource *t)
|
INTERNAL void dx12_resource_release(struct dx12_resource *t)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
(UNUSED)t;
|
/* TODO */
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL void dx12_resource_release_now(struct dx12_resource *t)
|
|
||||||
{
|
|
||||||
__prof;
|
|
||||||
(UNUSED)t;
|
(UNUSED)t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1717,8 +1720,9 @@ INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE
|
|||||||
cq = arena_push(arena, struct command_queue);
|
cq = arena_push(arena, struct command_queue);
|
||||||
cq->arena = arena;
|
cq->arena = arena;
|
||||||
}
|
}
|
||||||
cq->mutex = sys_mutex_alloc();
|
|
||||||
cq->type = type;
|
cq->type = type;
|
||||||
|
cq->submitted_command_lists_mutex = sys_mutex_alloc();
|
||||||
|
cq->submit_fence_mutex = sys_mutex_alloc();
|
||||||
|
|
||||||
D3D12_COMMAND_QUEUE_DESC desc = ZI;
|
D3D12_COMMAND_QUEUE_DESC desc = ZI;
|
||||||
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||||
@ -1729,7 +1733,7 @@ INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE
|
|||||||
sys_panic(LIT("Failed to create command queue"));
|
sys_panic(LIT("Failed to create command queue"));
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = ID3D12Device_CreateFence(G.device, 0, 0, &IID_ID3D12Fence, (void **)&cq->fence);
|
hr = ID3D12Device_CreateFence(G.device, 0, 0, &IID_ID3D12Fence, (void **)&cq->submit_fence);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
sys_panic(LIT("Failed to create command queue fence"));
|
sys_panic(LIT("Failed to create command queue fence"));
|
||||||
}
|
}
|
||||||
@ -1755,16 +1759,16 @@ INTERNAL void command_queue_release(struct command_queue *cq)
|
|||||||
INTERNAL struct command_list *command_list_open(struct command_queue *cq)
|
INTERNAL struct command_list *command_list_open(struct command_queue *cq)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
u64 queue_fence_value = ID3D12Fence_GetCompletedValue(cq->fence);
|
u64 completed_fence_value = ID3D12Fence_GetCompletedValue(cq->submit_fence);
|
||||||
|
|
||||||
struct command_list *cl = NULL;
|
struct command_list *cl = NULL;
|
||||||
struct ID3D12GraphicsCommandList *old_cl = NULL;
|
struct ID3D12GraphicsCommandList *old_cl = NULL;
|
||||||
struct ID3D12CommandAllocator *old_ca = NULL;
|
struct ID3D12CommandAllocator *old_ca = NULL;
|
||||||
{
|
{
|
||||||
struct sys_lock lock = sys_mutex_lock_e(cq->mutex);
|
struct sys_lock lock = sys_mutex_lock_e(cq->submitted_command_lists_mutex);
|
||||||
/* Find first command list ready for reuse */
|
/* Find first command list ready for reuse */
|
||||||
for (struct command_list *tmp = cq->first_submitted_command_list; tmp; tmp = tmp->next_submitted) {
|
for (struct command_list *tmp = cq->first_submitted_command_list; tmp; tmp = tmp->next_submitted) {
|
||||||
if (queue_fence_value >= tmp->submitted_fence_target) {
|
if (completed_fence_value >= tmp->submitted_fence_target) {
|
||||||
cl = tmp;
|
cl = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1792,7 +1796,7 @@ INTERNAL struct command_list *command_list_open(struct command_queue *cq)
|
|||||||
}
|
}
|
||||||
MEMZERO_STRUCT(cl);
|
MEMZERO_STRUCT(cl);
|
||||||
cl->cq = cq;
|
cl->cq = cq;
|
||||||
cl->global_lock = sys_mutex_lock_s(G.global_command_list_mutex);
|
cl->global_record_lock = sys_mutex_lock_s(G.global_command_list_record_mutex);
|
||||||
|
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
/* FIXME: Determine command list type from command queue */
|
/* FIXME: Determine command list type from command queue */
|
||||||
@ -1816,7 +1820,7 @@ INTERNAL struct command_list *command_list_open(struct command_queue *cq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close */
|
/* Reset */
|
||||||
hr = ID3D12CommandAllocator_Reset(cl->ca);
|
hr = ID3D12CommandAllocator_Reset(cl->ca);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
sys_panic(LIT("Failed to reset command allocator"));
|
sys_panic(LIT("Failed to reset command allocator"));
|
||||||
@ -1836,24 +1840,37 @@ INTERNAL u64 command_list_close(struct command_list *cl)
|
|||||||
__prof;
|
__prof;
|
||||||
struct command_queue *cq = cl->cq;
|
struct command_queue *cq = cl->cq;
|
||||||
|
|
||||||
/* Close & execute */
|
/* Close */
|
||||||
|
{
|
||||||
|
__profscope(Close DX12 command list);
|
||||||
HRESULT hr = ID3D12GraphicsCommandList_Close(cl->cl);
|
HRESULT hr = ID3D12GraphicsCommandList_Close(cl->cl);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
|
/* TODO: Don't panic */
|
||||||
sys_panic(LIT("Failed to close command list before execution"));
|
sys_panic(LIT("Failed to close command list before execution"));
|
||||||
}
|
}
|
||||||
ID3D12CommandQueue_ExecuteCommandLists(cq->cq, 1, (ID3D12CommandList **)&cl->cl);
|
}
|
||||||
|
|
||||||
/* Queue fence signal */
|
/* Submit */
|
||||||
/* FIXME: Wrap execute & signal in mutex */
|
u64 submit_fence_target = 0;
|
||||||
u64 target_fence_value = atomic_u64_eval_add_u64(&cq->fence_target, 1) + 1;
|
{
|
||||||
ID3D12CommandQueue_Signal(cq->cq, cq->fence, target_fence_value);
|
__profscope(Execute);
|
||||||
|
struct sys_lock global_lock = sys_mutex_lock_s(G.global_command_list_submit_mutex);
|
||||||
|
struct sys_lock fence_lock = sys_mutex_lock_e(cq->submit_fence_mutex);
|
||||||
|
{
|
||||||
|
submit_fence_target = ++cq->submit_fence_target;
|
||||||
|
ID3D12CommandQueue_ExecuteCommandLists(cq->cq, 1, (ID3D12CommandList **)&cl->cl);
|
||||||
|
ID3D12CommandQueue_Signal(cq->cq, cq->submit_fence, submit_fence_target);
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&fence_lock);
|
||||||
|
sys_mutex_unlock(&global_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add descriptor heaps to submitted list */
|
/* Add descriptor heaps to submitted list */
|
||||||
{
|
{
|
||||||
struct sys_lock lock = sys_mutex_lock_e(G.command_descriptor_heaps_mutex);
|
struct sys_lock lock = sys_mutex_lock_e(G.command_descriptor_heaps_mutex);
|
||||||
for (struct command_descriptor_heap *cdh = cl->first_command_descriptor_heap; cdh; cdh = cdh->next_in_command_list) {
|
for (struct command_descriptor_heap *cdh = cl->first_command_descriptor_heap; cdh; cdh = cdh->next_in_command_list) {
|
||||||
cdh->submitted_cq = cq;
|
cdh->submitted_cq = cq;
|
||||||
cdh->submitted_fence_target = target_fence_value;
|
cdh->submitted_fence_target = submit_fence_target;
|
||||||
if (G.last_submitted_command_descriptor_heap) {
|
if (G.last_submitted_command_descriptor_heap) {
|
||||||
G.last_submitted_command_descriptor_heap->next_submitted = cdh;
|
G.last_submitted_command_descriptor_heap->next_submitted = cdh;
|
||||||
} else {
|
} else {
|
||||||
@ -1870,7 +1887,7 @@ INTERNAL u64 command_list_close(struct command_list *cl)
|
|||||||
for (struct command_buffer *cb = cl->first_command_buffer; cb; cb = cb->next_in_command_list) {
|
for (struct command_buffer *cb = cl->first_command_buffer; cb; cb = cb->next_in_command_list) {
|
||||||
struct command_buffer_group *group = cb->group;
|
struct command_buffer_group *group = cb->group;
|
||||||
cb->submitted_cq = cq;
|
cb->submitted_cq = cq;
|
||||||
cb->submitted_fence_target = target_fence_value;
|
cb->submitted_fence_target = submit_fence_target;
|
||||||
if (group->last_submitted) {
|
if (group->last_submitted) {
|
||||||
group->last_submitted->next_submitted = cb;
|
group->last_submitted->next_submitted = cb;
|
||||||
} else {
|
} else {
|
||||||
@ -1882,10 +1899,10 @@ INTERNAL u64 command_list_close(struct command_list *cl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add command list to submitted list */
|
/* Add command list to submitted list */
|
||||||
sys_mutex_unlock(&cl->global_lock);
|
sys_mutex_unlock(&cl->global_record_lock);
|
||||||
cl->submitted_fence_target = target_fence_value;
|
cl->submitted_fence_target = submit_fence_target;
|
||||||
{
|
{
|
||||||
struct sys_lock lock = sys_mutex_lock_e(cq->mutex);
|
struct sys_lock lock = sys_mutex_lock_e(cq->submitted_command_lists_mutex);
|
||||||
if (cq->last_submitted_command_list) {
|
if (cq->last_submitted_command_list) {
|
||||||
cq->last_submitted_command_list->next_submitted = cl;
|
cq->last_submitted_command_list->next_submitted = cl;
|
||||||
} else {
|
} else {
|
||||||
@ -1895,7 +1912,7 @@ INTERNAL u64 command_list_close(struct command_list *cl)
|
|||||||
sys_mutex_unlock(&lock);
|
sys_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return target_fence_value;
|
return submit_fence_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -1917,8 +1934,8 @@ INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struc
|
|||||||
/* Find first heap ready for reuse */
|
/* Find first heap ready for reuse */
|
||||||
for (struct command_descriptor_heap *tmp = G.first_submitted_command_descriptor_heap; tmp; tmp = tmp->next_submitted) {
|
for (struct command_descriptor_heap *tmp = G.first_submitted_command_descriptor_heap; tmp; tmp = tmp->next_submitted) {
|
||||||
/* TODO: Cache completed fence values */
|
/* TODO: Cache completed fence values */
|
||||||
u64 queue_fence_value = ID3D12Fence_GetCompletedValue(tmp->submitted_cq->fence);
|
u64 completed_fence_value = ID3D12Fence_GetCompletedValue(tmp->submitted_cq->submit_fence);
|
||||||
if (queue_fence_value >= tmp->submitted_fence_target) {
|
if (completed_fence_value >= tmp->submitted_fence_target) {
|
||||||
cdh = tmp;
|
cdh = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2032,8 +2049,8 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl
|
|||||||
/* Find first command buffer ready for reuse */
|
/* Find first command buffer ready for reuse */
|
||||||
for (struct command_buffer *tmp = cb_group->first_submitted; tmp; tmp = tmp->next_submitted) {
|
for (struct command_buffer *tmp = cb_group->first_submitted; tmp; tmp = tmp->next_submitted) {
|
||||||
/* TODO: Cache completed fence values */
|
/* TODO: Cache completed fence values */
|
||||||
u64 queue_fence_value = ID3D12Fence_GetCompletedValue(tmp->submitted_cq->fence);
|
u64 completed_fence_value = ID3D12Fence_GetCompletedValue(tmp->submitted_cq->submit_fence);
|
||||||
if (queue_fence_value >= tmp->submitted_fence_target) {
|
if (completed_fence_value >= tmp->submitted_fence_target) {
|
||||||
cb = tmp;
|
cb = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2319,11 +2336,14 @@ struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, stru
|
|||||||
|
|
||||||
/* Wait */
|
/* Wait */
|
||||||
/* TODO: Return async waitable to caller */
|
/* TODO: Return async waitable to caller */
|
||||||
|
{
|
||||||
|
__profscope(Wait for upload);
|
||||||
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
ID3D12Fence_SetEventOnCompletion(cq->fence, fence_target, event);
|
ID3D12Fence_SetEventOnCompletion(cq->submit_fence, fence_target, event);
|
||||||
WaitForSingleObject(event, INFINITE);
|
WaitForSingleObject(event, INFINITE);
|
||||||
CloseHandle(event);
|
CloseHandle(event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return handle_alloc(DX12_HANDLE_KIND_RESOURCE, r);
|
return handle_alloc(DX12_HANDLE_KIND_RESOURCE, r);
|
||||||
}
|
}
|
||||||
@ -2353,9 +2373,10 @@ INLINE struct mat4x4 calculate_vp(struct xform view, f32 viewport_width, f32 vie
|
|||||||
void gp_dispatch(struct gp_dispatch_params params)
|
void gp_dispatch(struct gp_dispatch_params params)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
|
struct flow *flow = (struct flow *)params.flow;
|
||||||
|
|
||||||
struct flow *flow = handle_get_data(params.flow, DX12_HANDLE_KIND_FLOW);
|
struct sprite_scope *sprite_scope = sprite_scope_begin();
|
||||||
|
|
||||||
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
||||||
struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, LIT("material"));
|
struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, LIT("material"));
|
||||||
struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, LIT("shape"));
|
struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, LIT("shape"));
|
||||||
@ -2372,9 +2393,64 @@ 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 *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));
|
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);
|
||||||
|
{
|
||||||
|
__profscope(Process flow data);
|
||||||
|
|
||||||
|
/* Process material instances */
|
||||||
|
{
|
||||||
|
__profscope(Process material instances);
|
||||||
|
struct sys_lock handles_lock = sys_mutex_lock_s(G.handle_entries_mutex);
|
||||||
|
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];
|
||||||
|
struct sh_material_instance *instance = &material_instances[i];
|
||||||
|
i32 texture_id = -1;
|
||||||
|
{
|
||||||
|
struct dx12_resource *texture = NULL;
|
||||||
|
if (desc->texture.gen != 0) {
|
||||||
|
texture = handle_get_data_locked(desc->texture, DX12_HANDLE_KIND_RESOURCE, &handles_lock);
|
||||||
|
} else if (desc->sprite.hash != 0) {
|
||||||
|
struct sprite_texture *st = sprite_texture_from_tag_async(sprite_scope, desc->sprite);
|
||||||
|
texture = handle_get_data_locked(st->texture, DX12_HANDLE_KIND_RESOURCE, &handles_lock);
|
||||||
|
}
|
||||||
|
if (texture) {
|
||||||
|
texture_id = texture->srv_descriptor->index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instance->tex_nurid = sh_int_from_i32(texture_id);
|
||||||
|
instance->grid_id = sh_int_from_i32(desc->grid_id);
|
||||||
|
instance->xf = sh_float2x3_from_xform(desc->xf);
|
||||||
|
instance->uv0 = sh_float2_from_v2(desc->clip.p0);
|
||||||
|
instance->uv1 = sh_float2_from_v2(desc->clip.p1);
|
||||||
|
instance->tint_srgb = sh_uint_from_u32(desc->tint);
|
||||||
|
instance->emittance = sh_float_from_f32(desc->emittance);
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&handles_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process grids */
|
||||||
|
{
|
||||||
|
__profscope(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];
|
||||||
|
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);
|
||||||
|
grid->offset = sh_float2_from_v2(desc->offset);
|
||||||
|
grid->bg0_srgb = sh_uint_from_u32(desc->bg0_color);
|
||||||
|
grid->bg1_srgb = sh_uint_from_u32(desc->bg1_color);
|
||||||
|
grid->line_srgb = sh_uint_from_u32(desc->line_color);
|
||||||
|
grid->x_srgb = sh_uint_from_u32(desc->x_color);
|
||||||
|
grid->y_srgb = sh_uint_from_u32(desc->y_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Upload buffers */
|
/* Upload buffers */
|
||||||
struct command_buffer *material_instance_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_instances_arena));
|
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 *material_grid_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_grids_arena));
|
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_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 *shape_indices_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->shape_indices_arena));
|
||||||
|
|
||||||
@ -2409,7 +2485,7 @@ void gp_dispatch(struct gp_dispatch_params params)
|
|||||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, material_instance_buffer->resource->gpu_address);
|
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, material_instance_buffer->resource->gpu_address);
|
||||||
|
|
||||||
/* Set grid buffer */
|
/* Set grid buffer */
|
||||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, material_grid_buffer->resource->gpu_address);
|
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, grid_buffer->resource->gpu_address);
|
||||||
|
|
||||||
/* Set descriptor heap */
|
/* Set descriptor heap */
|
||||||
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
||||||
@ -2469,7 +2545,10 @@ 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);
|
||||||
|
sprite_scope_end(sprite_scope);
|
||||||
|
|
||||||
flow_reset(flow);
|
flow_reset(flow);
|
||||||
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -2505,36 +2584,60 @@ struct gp_memory_info gp_query_memory_info(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Present
|
* Swapchain
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL struct dx12_resource *update_swapchain(struct sys_window *window, struct v2i32 resolution)
|
INTERNAL struct swapchain_buffer *update_swapchain(struct swapchain *swapchain, struct sys_window *window, struct v2i32 resolution)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
|
resolution.x = max_i32(resolution.x, 1);
|
||||||
b32 should_rebuild = !v2i32_eq(G.swapchain_resolution, resolution);
|
resolution.y = max_i32(resolution.y, 1);
|
||||||
|
b32 should_rebuild = !v2i32_eq(swapchain->resolution, resolution);
|
||||||
if (should_rebuild) {
|
if (should_rebuild) {
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
|
struct command_queue *cq = G.cq_direct;
|
||||||
|
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
|
||||||
|
if (swapchain->swapchain) {
|
||||||
|
ASSERT(hwnd == swapchain->hwnd);
|
||||||
|
|
||||||
if (G.swapchain) {
|
/* Lock direct queue submissions (in case any write to backbuffer) */
|
||||||
ASSERT(hwnd == G.swapchain_hwnd);
|
/* TODO: Less overkill approach - Only flush present_blit since we know it's the only operation targeting backbuffer */
|
||||||
/* Resize existing swapchain */
|
//struct sys_lock lock = sys_mutex_lock_e(cq->submit_fence_mutex);
|
||||||
/* FIXME: Fence */
|
DEBUGBREAKABLE;
|
||||||
|
struct sys_lock lock = sys_mutex_lock_e(G.global_command_list_record_mutex);
|
||||||
|
{
|
||||||
|
/* Flush direct queue */
|
||||||
|
//ID3D12CommandQueue_Signal(cq->cq, cq->submit_fence, ++cq->submit_fence_target);
|
||||||
|
{
|
||||||
|
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
ID3D12Fence_SetEventOnCompletion(cq->submit_fence, cq->submit_fence_target, event);
|
||||||
|
WaitForSingleObject(event, INFINITE);
|
||||||
|
CloseHandle(event);
|
||||||
|
}
|
||||||
|
|
||||||
/* Release resources */
|
/* Release buffers */
|
||||||
for (u32 i = 0; i < ARRAY_COUNT(G.swapchain_resources); ++i) {
|
for (u32 i = 0; i < ARRAY_COUNT(swapchain->buffers); ++i) {
|
||||||
struct dx12_resource *resource = G.swapchain_resources[i];
|
struct swapchain_buffer *sb = &swapchain->buffers[i];
|
||||||
dx12_resource_release_now(resource);
|
descriptor_release(sb->rtv_descriptor);
|
||||||
|
ID3D12Resource_Release(sb->resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resize buffers */
|
/* Resize buffers */
|
||||||
IDXGISwapChain_ResizeBuffers(G.swapchain, 0, resolution.x, resolution.y, DXGI_FORMAT_UNKNOWN, DX12_SWAPCHAIN_FLAGS);
|
hr = IDXGISwapChain_ResizeBuffers(swapchain->swapchain, 0, resolution.x, resolution.y, DXGI_FORMAT_UNKNOWN, DX12_SWAPCHAIN_FLAGS);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
/* TODO: Don't panic */
|
||||||
|
sys_panic(LIT("Failed to resize swapchain"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&lock);
|
||||||
} else {
|
} else {
|
||||||
/* Create swapchain1 */
|
/* Create swapchain1 */
|
||||||
IDXGISwapChain1 *swapchain1 = NULL;
|
IDXGISwapChain1 *swapchain1 = NULL;
|
||||||
{
|
{
|
||||||
DXGI_SWAP_CHAIN_DESC1 desc = ZI;
|
DXGI_SWAP_CHAIN_DESC1 desc = ZI;
|
||||||
desc.Format = DX12_SWAPCHAIN_FORMAT;
|
desc.Format = DX12_SWAPCHAIN_FORMAT;
|
||||||
|
desc.Width = resolution.x;
|
||||||
|
desc.Height = resolution.y;
|
||||||
desc.SampleDesc.Count = 1;
|
desc.SampleDesc.Count = 1;
|
||||||
desc.SampleDesc.Quality = 0;
|
desc.SampleDesc.Quality = 0;
|
||||||
desc.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
desc.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
@ -2543,44 +2646,54 @@ INTERNAL struct dx12_resource *update_swapchain(struct sys_window *window, struc
|
|||||||
desc.Flags = DX12_SWAPCHAIN_FLAGS;
|
desc.Flags = DX12_SWAPCHAIN_FLAGS;
|
||||||
desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
hr = IDXGIFactory2_CreateSwapChainForHwnd(G.factory, (IUnknown *)G.cq_direct->cq, hwnd, &desc, NULL, NULL, &swapchain1);
|
hr = IDXGIFactory2_CreateSwapChainForHwnd(G.factory, (IUnknown *)cq->cq, hwnd, &desc, NULL, NULL, &swapchain1);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dx12_init_error(LIT("Failed to create IDXGISwapChain1"));
|
sys_panic(LIT("Failed to create IDXGISwapChain1"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Upgrade to swapchain3 */
|
/* Upgrade to swapchain3 */
|
||||||
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&G.swapchain);
|
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain->swapchain);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dx12_init_error(LIT("Failed to create IDXGISwapChain3"));
|
sys_panic(LIT("Failed to create IDXGISwapChain3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable Alt+Enter changing monitor resolution to match window size */
|
/* Disable Alt+Enter changing monitor resolution to match window size */
|
||||||
IDXGIFactory_MakeWindowAssociation(G.factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
IDXGIFactory_MakeWindowAssociation(G.factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
|
||||||
IDXGISwapChain1_Release(swapchain1);
|
IDXGISwapChain1_Release(swapchain1);
|
||||||
G.swapchain_hwnd = hwnd;
|
swapchain->hwnd = hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate swapchain resources */
|
/* Allocate swapchain resources */
|
||||||
for (u32 i = 0; i < ARRAY_COUNT(G.swapchain_resources); ++i) {
|
for (u32 i = 0; i < ARRAY_COUNT(swapchain->buffers); ++i) {
|
||||||
ID3D12Resource *resource = NULL;
|
ID3D12Resource *resource = NULL;
|
||||||
hr = IDXGISwapChain3_GetBuffer(G.swapchain, i, &IID_ID3D12Resource, (void **)&resource);
|
hr = IDXGISwapChain3_GetBuffer(swapchain->swapchain, i, &IID_ID3D12Resource, (void **)&resource);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
/* TODO: Don't panic */
|
/* TODO: Don't panic */
|
||||||
dx12_init_error(LIT("Failed to get swapchain buffer"));
|
sys_panic(LIT("Failed to get swapchain buffer"));
|
||||||
}
|
}
|
||||||
G.swapchain_resources[i] = dx12_resource_alloc_from_swapchain_buffer(resource, resolution);
|
struct swapchain_buffer *sb = &swapchain->buffers[i];
|
||||||
|
MEMZERO_STRUCT(sb);
|
||||||
|
sb->swapchain = swapchain;
|
||||||
|
sb->resource = resource;
|
||||||
|
sb->rtv_descriptor = descriptor_alloc(G.rtv_heap);
|
||||||
|
sb->state = D3D12_RESOURCE_STATE_COMMON;
|
||||||
|
ID3D12Device_CreateRenderTargetView(G.device, sb->resource, NULL, sb->rtv_descriptor->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
G.swapchain_resolution = resolution;
|
swapchain->resolution = resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
G.swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(G.swapchain);
|
u32 backbuffer_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain->swapchain);
|
||||||
return G.swapchain_resources[G.swapchain_frame_index];
|
return &swapchain->buffers[backbuffer_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src, struct xform src_xf)
|
/* ========================== *
|
||||||
|
* Present
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *src, struct xform src_xf)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
||||||
@ -2589,6 +2702,7 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src,
|
|||||||
struct command_list *cl = command_list_open(G.cq_direct);
|
struct command_list *cl = command_list_open(G.cq_direct);
|
||||||
{
|
{
|
||||||
__profscope_dx12(cl->cq->prof, cl->cl, Blit, RGB32_F(0.5, 0.2, 0.2));
|
__profscope_dx12(cl->cq->prof, cl->cl, Blit, RGB32_F(0.5, 0.2, 0.2));
|
||||||
|
struct swapchain *swapchain = dst->swapchain;
|
||||||
|
|
||||||
/* Upload dummmy vert & index buffer */
|
/* Upload dummmy vert & index buffer */
|
||||||
/* TODO: Make these static */
|
/* TODO: Make these static */
|
||||||
@ -2600,13 +2714,25 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src,
|
|||||||
/* 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);
|
||||||
|
|
||||||
struct rect viewport_rect = RECT_FROM_V2(V2(0, 0), V2(dst->texture_size.x, dst->texture_size.y));
|
struct rect viewport_rect = RECT_FROM_V2(V2(0, 0), V2(swapchain->resolution.x, swapchain->resolution.y));
|
||||||
D3D12_VIEWPORT viewport = viewport_from_rect(viewport_rect);
|
D3D12_VIEWPORT viewport = viewport_from_rect(viewport_rect);
|
||||||
D3D12_RECT scissor = scissor_from_rect(viewport_rect);
|
D3D12_RECT scissor = scissor_from_rect(viewport_rect);
|
||||||
struct mat4x4 vp_matrix = calculate_vp(src_xf, viewport.Width, viewport.Height);
|
struct mat4x4 vp_matrix = calculate_vp(src_xf, viewport.Width, viewport.Height);
|
||||||
|
|
||||||
/* Transition dst to render target */
|
/* Transition dst to render target */
|
||||||
dx12_resource_barrier(cl->cl, dst, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
{
|
||||||
|
struct D3D12_RESOURCE_TRANSITION_BARRIER rtb = ZI;
|
||||||
|
rtb.pResource = dst->resource;
|
||||||
|
rtb.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
rtb.StateBefore = dst->state;
|
||||||
|
rtb.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||||
|
struct D3D12_RESOURCE_BARRIER rb = ZI;
|
||||||
|
rb.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||||
|
rb.Flags = 0;
|
||||||
|
rb.Transition = rtb;
|
||||||
|
ID3D12GraphicsCommandList_ResourceBarrier(cl->cl, 1, &rb);
|
||||||
|
dst->state = rtb.StateAfter;
|
||||||
|
}
|
||||||
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &dst->rtv_descriptor->handle, false, NULL);
|
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &dst->rtv_descriptor->handle, false, NULL);
|
||||||
|
|
||||||
/* Clear */
|
/* Clear */
|
||||||
@ -2641,24 +2767,38 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src,
|
|||||||
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
|
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
|
||||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, 1, 0, 0, 0);
|
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, 1, 0, 0, 0);
|
||||||
|
|
||||||
/* Set dst to presentable */
|
/* Transition dst to presentable */
|
||||||
dx12_resource_barrier(cl->cl, dst, D3D12_RESOURCE_STATE_PRESENT);
|
{
|
||||||
|
struct D3D12_RESOURCE_TRANSITION_BARRIER rtb = ZI;
|
||||||
|
rtb.pResource = dst->resource;
|
||||||
|
rtb.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
rtb.StateBefore = dst->state;
|
||||||
|
rtb.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||||
|
struct D3D12_RESOURCE_BARRIER rb = ZI;
|
||||||
|
rb.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||||
|
rb.Flags = 0;
|
||||||
|
rb.Transition = rtb;
|
||||||
|
ID3D12GraphicsCommandList_ResourceBarrier(cl->cl, 1, &rb);
|
||||||
|
dst->state = rtb.StateAfter;
|
||||||
|
}
|
||||||
|
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &dst->rtv_descriptor->handle, false, NULL);
|
||||||
}
|
}
|
||||||
command_list_close(cl);
|
command_list_close(cl);
|
||||||
}
|
}
|
||||||
pipeline_scope_end(pipeline_scope);
|
pipeline_scope_end(pipeline_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)
|
void gp_present(struct sys_window *window, struct v2i32 backresolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
//sys_sleep(0.1);
|
//sys_sleep(0.1);
|
||||||
|
|
||||||
struct dx12_resource *backbuffer_resource = update_swapchain(window, backbuffer_resolution);
|
struct swapchain *swapchain = &G.swapchain;
|
||||||
|
struct swapchain_buffer *swapchain_buffer = update_swapchain(swapchain, window, backresolution);
|
||||||
struct dx12_resource *texture_resource = handle_get_data(texture, DX12_HANDLE_KIND_RESOURCE);
|
struct dx12_resource *texture_resource = handle_get_data(texture, DX12_HANDLE_KIND_RESOURCE);
|
||||||
|
|
||||||
/* Blit */
|
/* Blit */
|
||||||
present_blit(backbuffer_resource, texture_resource, texture_xf);
|
present_blit(swapchain_buffer, texture_resource, texture_xf);
|
||||||
|
|
||||||
//sys_sleep(0.1);
|
//sys_sleep(0.1);
|
||||||
|
|
||||||
@ -2666,7 +2806,7 @@ void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, s
|
|||||||
/* FIXME: Resource barrier */
|
/* FIXME: Resource barrier */
|
||||||
{
|
{
|
||||||
__profscope(Present);
|
__profscope(Present);
|
||||||
HRESULT hr = IDXGISwapChain3_Present(G.swapchain, 0, 0);
|
HRESULT hr = IDXGISwapChain3_Present(swapchain->swapchain, 0, 0);
|
||||||
if (!SUCCEEDED(hr)) {
|
if (!SUCCEEDED(hr)) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
@ -2675,8 +2815,9 @@ void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, s
|
|||||||
|
|
||||||
#if PROFILING
|
#if PROFILING
|
||||||
{
|
{
|
||||||
/* Lock because command shouldn't be recording during a frame mark */
|
__profscope(Mark queue frames);
|
||||||
struct sys_lock lock = sys_mutex_lock_e(G.global_command_list_mutex);
|
/* Lock because frame marks shouldn't occur while command lists are recording */
|
||||||
|
struct sys_lock lock = sys_mutex_lock_e(G.global_command_list_record_mutex);
|
||||||
__prof_dx12_new_frame(G.cq_direct->prof);
|
__prof_dx12_new_frame(G.cq_direct->prof);
|
||||||
__prof_dx12_new_frame(G.cq_compute->prof);
|
__prof_dx12_new_frame(G.cq_compute->prof);
|
||||||
__prof_dx12_new_frame(G.cq_copy_critical->prof);
|
__prof_dx12_new_frame(G.cq_copy_critical->prof);
|
||||||
@ -2684,6 +2825,7 @@ void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, s
|
|||||||
sys_mutex_unlock(&lock);
|
sys_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
__profscope(Collect queues);
|
||||||
__prof_dx12_collect(G.cq_direct->prof);
|
__prof_dx12_collect(G.cq_direct->prof);
|
||||||
__prof_dx12_collect(G.cq_compute->prof);
|
__prof_dx12_collect(G.cq_compute->prof);
|
||||||
__prof_dx12_collect(G.cq_copy_critical->prof);
|
__prof_dx12_collect(G.cq_copy_critical->prof);
|
||||||
@ -2692,7 +2834,7 @@ void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, s
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
(UNUSED)backbuffer_resolution;
|
(UNUSED)backresolution;
|
||||||
(UNUSED)texture;
|
(UNUSED)texture;
|
||||||
(UNUSED)texture_xf;
|
(UNUSED)texture_xf;
|
||||||
(UNUSED)vsync;
|
(UNUSED)vsync;
|
||||||
|
|||||||
@ -898,8 +898,6 @@ INTERNAL struct sprite_scope_cache_ref *cache_lookup(struct sprite_scope *scope,
|
|||||||
|
|
||||||
INTERNAL struct sprite_scope_cache_ref *cache_entry_from_tag(struct sprite_scope *scope, struct sprite_tag tag, enum cache_entry_kind kind, b32 force_new)
|
INTERNAL struct sprite_scope_cache_ref *cache_entry_from_tag(struct sprite_scope *scope, struct sprite_tag tag, enum cache_entry_kind kind, b32 force_new)
|
||||||
{
|
{
|
||||||
__prof;
|
|
||||||
|
|
||||||
struct cache_entry_hash hash = cache_entry_hash_from_tag_hash(tag.hash, kind);
|
struct cache_entry_hash hash = cache_entry_hash_from_tag_hash(tag.hash, kind);
|
||||||
u64 bin_index = hash.v % CACHE_BINS_COUNT;
|
u64 bin_index = hash.v % CACHE_BINS_COUNT;
|
||||||
struct sprite_scope_cache_ref *scope_ref = NULL;
|
struct sprite_scope_cache_ref *scope_ref = NULL;
|
||||||
|
|||||||
@ -73,8 +73,8 @@ GLOBAL struct {
|
|||||||
/* Gpu handles */
|
/* Gpu handles */
|
||||||
struct gp_handle user_texture;
|
struct gp_handle user_texture;
|
||||||
|
|
||||||
struct gp_handle world_gp_flow;
|
struct gp_flow *world_gp_flow;
|
||||||
struct gp_handle ui_gp_flow;
|
struct gp_flow *ui_gp_flow;
|
||||||
|
|
||||||
struct xform world_to_user_xf;
|
struct xform world_to_user_xf;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user