srgb aware rendering

This commit is contained in:
jacob 2025-05-23 00:40:51 -05:00
parent b0ffb143f2
commit 7c1eae3b8c
10 changed files with 159 additions and 130 deletions

View File

@ -1,25 +1,25 @@
struct vs_input { struct vs_input {
float4 pos : POSITION; float4 pos : POSITION;
float4 color_bg0 : COLOR_BG_A;
float4 color_bg1 : COLOR_BG_B;
float4 color_line : COLOR_LINE;
float4 color_x : COLOR_X;
float4 color_y : COLOR_Y;
float line_thickness : THICKNESS; float line_thickness : THICKNESS;
float line_spacing : SPACING; float line_spacing : SPACING;
float2 offset : OFFSET; float2 offset : OFFSET;
float4 bg0_srgb : COLOR0;
float4 bg1_srgb : COLOR1;
float4 line_srgb : COLOR2;
float4 x_srgb : COLOR3;
float4 y_srgb : COLOR4;
}; };
struct ps_input { struct ps_input {
float4 screen_pos : SV_POSITION; float4 screen_pos : SV_POSITION;
float4 color_bg0 : COLOR_BG_A;
float4 color_bg1 : COLOR_BG_B;
float4 color_line : COLOR_LINE;
float4 color_x : COLOR_X;
float4 color_y : COLOR_Y;
float line_thickness : THICKNESS; float line_thickness : THICKNESS;
float line_spacing : SPACING; float line_spacing : SPACING;
float2 offset : OFFSET; float2 offset : OFFSET;
float4 bg0_lin : COLOR0;
float4 bg1_lin : COLOR1;
float4 line_lin : COLOR2;
float4 x_lin : COLOR3;
float4 y_lin : COLOR4;
}; };
cbuffer vs_constants : register(b0) cbuffer vs_constants : register(b0)
@ -27,19 +27,24 @@ cbuffer vs_constants : register(b0)
float4x4 projection; float4x4 projection;
}; };
float4 linear_from_srgb(float4 srgb)
{
return float4(pow(srgb.rgb, 2.2), srgb.a);
}
ps_input vs_main(vs_input input) ps_input vs_main(vs_input input)
{ {
ps_input output; ps_input output;
output.screen_pos = mul(projection, float4(input.pos.xy, 0.f, 1.f)); output.screen_pos = mul(projection, float4(input.pos.xy, 0.f, 1.f));
output.color_bg0 = input.color_bg0;
output.color_bg1 = input.color_bg1;
output.color_line = input.color_line;
output.color_x = input.color_x;
output.color_y = input.color_y;
output.line_thickness = input.line_thickness; output.line_thickness = input.line_thickness;
output.line_spacing = input.line_spacing; output.line_spacing = input.line_spacing;
output.offset = input.offset; output.offset = input.offset;
output.bg0_lin = linear_from_srgb(input.bg0_srgb);
output.bg1_lin = linear_from_srgb(input.bg1_srgb);
output.line_lin = linear_from_srgb(input.line_srgb);
output.x_lin = linear_from_srgb(input.x_srgb);
output.y_lin = linear_from_srgb(input.y_srgb);
return output; return output;
} }
@ -49,17 +54,18 @@ float4 ps_main(ps_input input) : SV_TARGET
float2 grid_pos = input.screen_pos.xy + input.offset; float2 grid_pos = input.screen_pos.xy + input.offset;
float half_thickness = input.line_thickness / 2; float half_thickness = input.line_thickness / 2;
float spacing = input.line_spacing; float spacing = input.line_spacing;
float4 color = input.color_bg0;
float4 color = input.bg0_lin;
float2 v = abs(round(grid_pos / spacing) * spacing - grid_pos); float2 v = abs(round(grid_pos / spacing) * spacing - grid_pos);
float dist = min(v.x, v.y); float dist = min(v.x, v.y);
if (grid_pos.y <= half_thickness && grid_pos.y >= -half_thickness) { if (grid_pos.y <= half_thickness && grid_pos.y >= -half_thickness) {
color = input.color_x; color = input.x_lin;
} else if (grid_pos.x <= half_thickness && grid_pos.x >= -half_thickness) { } else if (grid_pos.x <= half_thickness && grid_pos.x >= -half_thickness) {
color = input.color_y; color = input.y_lin;
} else if (dist < half_thickness) { } else if (dist < half_thickness) {
color = input.color_line; color = input.line_lin;
} else { } else {
bool checker = false; bool checker = false;
uint cell_x = (uint)(abs(grid_pos.x) / spacing) + (grid_pos.x < 0); uint cell_x = (uint)(abs(grid_pos.x) / spacing) + (grid_pos.x < 0);
@ -70,7 +76,7 @@ float4 ps_main(ps_input input) : SV_TARGET
checker = cell_y % 2 == 1; checker = cell_y % 2 == 1;
} }
if (checker) { if (checker) {
color = input.color_bg1; color = input.bg1_lin;
} }
} }

View File

@ -11,27 +11,32 @@ cbuffer constants : register(b0)
struct vs_input { struct vs_input {
float4 pos : POSITION; float4 pos : POSITION;
float2 uv : TEXCOORD; float2 uv : TEXCOORD;
float4 col : COLOR; float4 tint_srgb : COLOR;
}; };
struct ps_input { struct ps_input {
float4 pos : SV_POSITION; float4 pos : SV_POSITION;
float2 uv : TEXCOORD; float2 uv : TEXCOORD;
float4 col : COLOR; float4 tint_lin : COLOR;
}; };
float4 linear_from_srgb(float4 srgb)
{
return float4(pow(srgb.rgb, 2.2), srgb.a);
}
ps_input vs_main(vs_input input) ps_input vs_main(vs_input input)
{ {
ps_input output; ps_input output;
output.pos = mul(projection, float4(input.pos.xy, 0.f, 1.f)); output.pos = mul(projection, float4(input.pos.xy, 0.f, 1.f));
output.uv = input.uv; output.uv = input.uv;
output.col = input.col; output.tint_lin = linear_from_srgb(input.tint_srgb);
return output; return output;
} }
float4 ps_main(ps_input input) : SV_TARGET float4 ps_main(ps_input input) : SV_TARGET
{ {
return globals.texture0.Sample(globals.sampler0, input.uv) * input.col; return globals.texture0.Sample(globals.sampler0, input.uv) * input.tint_lin;
} }

View File

@ -705,6 +705,14 @@ struct ase_decode_image_result ase_decode_image(struct arena *arena, struct stri
} }
} break; } break;
case CHUNK_TYPE_COLOR_PROFILE: {
u16 type = br_read_ubits(&br, 16);
if (type == 1) {
res.srgb = true;
}
br_seek_to_byte(&br, chunk_end_pos);
} break;
default: { default: {
br_seek_to_byte(&br, chunk_end_pos); br_seek_to_byte(&br, chunk_end_pos);
} break; } break;

View File

@ -48,6 +48,7 @@ struct ase_frame {
struct ase_decode_image_result { struct ase_decode_image_result {
struct image_rgba image; struct image_rgba image;
struct ase_error_list errors; struct ase_error_list errors;
b32 srgb;
}; };
struct ase_decode_sheet_result { struct ase_decode_sheet_result {

View File

@ -290,25 +290,15 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
#define ALPHA_F(color, a) ((color) & 0x00FFFFFF) | (_RGB_U8_FROM_F((a)) << 24) #define ALPHA_F(color, a) ((color) & 0x00FFFFFF) | (_RGB_U8_FROM_F((a)) << 24)
/* Palette color defines */ /* Color defines */
#define COLOR_WHITE RGB(0xE6, 0xE8, 0xE6) #define COLOR_WHITE RGB(0xFF, 0xFF, 0xFF)
#define COLOR_BLACK RGB(0x4C, 0x2E, 0x05) #define COLOR_BLACK RGB(0x00, 0x00, 0x00)
#define COLOR_RED RGB(0x6F, 0x1D, 0x1B) #define COLOR_RED RGB(0xFF, 0x00, 0x00)
#define COLOR_GREEN RGB(0x26, 0xA9, 0x6C) #define COLOR_GREEN RGB(0x00, 0xFF, 0x00)
#define COLOR_BLUE RGB(0x25, 0x8E, 0xA6) #define COLOR_BLUE RGB(0x00, 0x00, 0xFF)
#define COLOR_YELLOW RGB(0xFC, 0xF6, 0xB1) #define COLOR_YELLOW RGB(0xFF, 0xFF, 0x00)
#define COLOR_ORANGE RGB(0xFF, 0x7F, 0x51) #define COLOR_ORANGE RGB(0xFF, 0xA5, 0x00)
#define COLOR_PURPLE RGB(0xFF, 0x57, 0xBB) #define COLOR_PURPLE RGB(0xFF, 0x00, 0XFF)
/* True color defines */
#define COLOR_TRUE_WHITE RGB(0xFF, 0xFF, 0xFF)
#define COLOR_TRUE_BLACK RGB(0x00, 0x00, 0x00)
#define COLOR_TRUE_RED RGB(0xFF, 0x00, 0x00)
#define COLOR_TRUE_GREEN RGB(0x00, 0xFF, 0x00)
#define COLOR_TRUE_BLUE RGB(0x00, 0x00, 0xFF)
#define COLOR_TRUE_YELLOW RGB(0xFF, 0xFF, 0x00)
#define COLOR_TRUE_ORANGE RGB(0xFF, 0xA5, 0x00)
#define COLOR_TRUE_PURPLE RGB(0xFF, 0x00, 0XFF)
/* Barrier */ /* Barrier */
#if COMPILER_MSVC #if COMPILER_MSVC

View File

@ -28,7 +28,7 @@ struct draw_startup_receipt draw_startup(struct renderer_startup_receipt *render
* Texture * Texture
* ========================== */ * ========================== */
void draw_quad_texture_ex(struct renderer_cmd_buffer *cmdbuff, struct renderer_texture texture, struct sprite_tag sprite, struct clip_rect clip, u32 tint0, u32 tint1, struct quad quad) void draw_quad_texture_ex(struct renderer_cmd_buffer *cmdbuff, struct renderer_texture texture, struct sprite_tag sprite, struct clip_rect clip, u32 tint0_srgb, u32 tint1_srgb, struct quad quad)
{ {
struct renderer_cmd_parameters cmd_params = ZI; struct renderer_cmd_parameters cmd_params = ZI;
cmd_params.kind = SHADER_TRIANGLE; cmd_params.kind = SHADER_TRIANGLE;
@ -44,25 +44,25 @@ void draw_quad_texture_ex(struct renderer_cmd_buffer *cmdbuff, struct renderer_t
vertices[0] = (struct triangle_shader_vertex) { vertices[0] = (struct triangle_shader_vertex) {
.pos = quad.p0, .pos = quad.p0,
.uv = { clip.p0.x, clip.p0.y }, .uv = { clip.p0.x, clip.p0.y },
.color = tint0 .tint_srgb = tint0_srgb
}; };
/* Top right */ /* Top right */
vertices[1] = (struct triangle_shader_vertex) { vertices[1] = (struct triangle_shader_vertex) {
.pos = quad.p1, .pos = quad.p1,
.uv = { clip.p1.x, clip.p0.y }, .uv = { clip.p1.x, clip.p0.y },
.color = tint0 .tint_srgb = tint0_srgb
}; };
/* Bottom right */ /* Bottom right */
vertices[2] = (struct triangle_shader_vertex) { vertices[2] = (struct triangle_shader_vertex) {
.pos = quad.p2, .pos = quad.p2,
.uv = { clip.p1.x, clip.p1.y }, .uv = { clip.p1.x, clip.p1.y },
.color = tint1 .tint_srgb = tint1_srgb
}; };
/* Bottom left */ /* Bottom left */
vertices[3] = (struct triangle_shader_vertex) { vertices[3] = (struct triangle_shader_vertex) {
.pos = quad.p3, .pos = quad.p3,
.uv = { clip.p0.x, clip.p1.y }, .uv = { clip.p0.x, clip.p1.y },
.color = tint1 .tint_srgb = tint1_srgb
}; };
/* Top / right triangle */ /* Top / right triangle */
@ -85,7 +85,7 @@ void draw_quad_texture(struct renderer_cmd_buffer *cmdbuff, struct draw_texture_
* Solid fill shapes * Solid fill shapes
* ========================== */ * ========================== */
void draw_poly(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, u32 color) void draw_poly(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, u32 srgb)
{ {
if (array.count < 3) { if (array.count < 3) {
return; return;
@ -107,7 +107,7 @@ void draw_poly(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, u32 c
for (u32 i = 0; i < array.count; ++i) { for (u32 i = 0; i < array.count; ++i) {
vertices[i] = (struct triangle_shader_vertex) { vertices[i] = (struct triangle_shader_vertex) {
.pos = array.points[i], .pos = array.points[i],
.color = color .tint_srgb = srgb
}; };
} }
@ -120,7 +120,7 @@ void draw_poly(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, u32 c
} }
} }
void draw_circle(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius, u32 color, u32 detail) void draw_circle(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius, u32 srgb, u32 detail)
{ {
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
@ -137,39 +137,39 @@ void draw_circle(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius,
.points = points, .points = points,
.count = detail .count = detail
}; };
draw_poly(cmdbuff, a, color); draw_poly(cmdbuff, a, srgb);
scratch_end(scratch); scratch_end(scratch);
} }
void draw_quad(struct renderer_cmd_buffer *cmdbuff, struct quad quad, u32 color) void draw_quad(struct renderer_cmd_buffer *cmdbuff, struct quad quad, u32 srgb)
{ {
draw_quad_texture_ex(cmdbuff, G.solid_white, sprite_tag_nil(), CLIP_ALL, color, color, quad); draw_quad_texture_ex(cmdbuff, G.solid_white, sprite_tag_nil(), CLIP_ALL, srgb, srgb, quad);
} }
/* ========================== * /* ========================== *
* Solid line shapes * Solid line shapes
* ========================== */ * ========================== */
void draw_gradient_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, u32 color_start, u32 color_end) void draw_gradient_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, u32 start_srgb, u32 end_srgb)
{ {
struct quad quad = quad_from_line(start, end, thickness); struct quad quad = quad_from_line(start, end, thickness);
draw_quad_texture_ex(cmdbuff, G.solid_white, sprite_tag_nil(), CLIP_ALL, color_start, color_end, quad); draw_quad_texture_ex(cmdbuff, G.solid_white, sprite_tag_nil(), CLIP_ALL, start_srgb, end_srgb, quad);
} }
void draw_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, u32 color) void draw_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, u32 srgb)
{ {
struct quad quad = quad_from_line(start, end, thickness); struct quad quad = quad_from_line(start, end, thickness);
draw_quad(cmdbuff, quad, color); draw_quad(cmdbuff, quad, srgb);
} }
void draw_ray(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, struct v2 rel, f32 thickness, u32 color) void draw_ray(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, struct v2 rel, f32 thickness, u32 srgb)
{ {
struct quad quad = quad_from_ray(pos, rel, thickness); struct quad quad = quad_from_ray(pos, rel, thickness);
draw_quad(cmdbuff, quad, color); draw_quad(cmdbuff, quad, srgb);
} }
void draw_poly_line(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, b32 loop, f32 thickness, u32 color) void draw_poly_line(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, b32 loop, f32 thickness, u32 srgb)
{ {
if (array.count < 2) { if (array.count < 2) {
return; return;
@ -179,17 +179,17 @@ void draw_poly_line(struct renderer_cmd_buffer *cmdbuff, struct v2_array array,
struct v2 p1 = array.points[i - 1]; struct v2 p1 = array.points[i - 1];
struct v2 p2 = array.points[i]; struct v2 p2 = array.points[i];
struct quad q = quad_from_line(p1, p2, thickness); struct quad q = quad_from_line(p1, p2, thickness);
draw_quad(cmdbuff, q, color); draw_quad(cmdbuff, q, srgb);
} }
if (loop && array.count > 2) { if (loop && array.count > 2) {
struct v2 p1 = array.points[array.count - 1]; struct v2 p1 = array.points[array.count - 1];
struct v2 p2 = array.points[0]; struct v2 p2 = array.points[0];
struct quad q = quad_from_line(p1, p2, thickness); struct quad q = quad_from_line(p1, p2, thickness);
draw_quad(cmdbuff, q, color); draw_quad(cmdbuff, q, srgb);
} }
} }
void draw_circle_line(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail) void draw_circle_line(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius, f32 thickness, u32 srgb, u32 detail)
{ {
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
@ -206,19 +206,19 @@ void draw_circle_line(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 ra
.points = points, .points = points,
.count = detail .count = detail
}; };
draw_poly_line(cmdbuff, a, true, thickness, color); draw_poly_line(cmdbuff, a, true, thickness, srgb);
scratch_end(scratch); scratch_end(scratch);
} }
void draw_quad_line(struct renderer_cmd_buffer *cmdbuff, struct quad quad, f32 thickness, u32 color) void draw_quad_line(struct renderer_cmd_buffer *cmdbuff, struct quad quad, f32 thickness, u32 srgb)
{ {
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(cmdbuff, a, true, thickness, color); draw_poly_line(cmdbuff, a, true, thickness, srgb);
} }
void draw_arrow_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color) void draw_arrow_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 srgb)
{ {
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 */
@ -242,19 +242,19 @@ void draw_arrow_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struc
.points = head_points, .points = head_points,
.count = ARRAY_COUNT(head_points) .count = ARRAY_COUNT(head_points)
}; };
draw_poly(cmdbuff, head_points_v2_array, color); draw_poly(cmdbuff, head_points_v2_array, srgb);
struct quad line_quad = quad_from_line(start, head_start, thickness); struct quad line_quad = quad_from_line(start, head_start, thickness);
draw_quad(cmdbuff, line_quad, color); draw_quad(cmdbuff, line_quad, srgb);
} }
void draw_arrow_ray(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color) void draw_arrow_ray(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 srgb)
{ {
struct v2 end = v2_add(pos, rel); struct v2 end = v2_add(pos, rel);
draw_arrow_line(cmdbuff, pos, end, thickness, arrowhead_height, color); draw_arrow_line(cmdbuff, pos, end, thickness, arrowhead_height, srgb);
} }
void draw_collider_line(struct renderer_cmd_buffer *cmdbuff, struct xform draw_xf, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail) void draw_collider_line(struct renderer_cmd_buffer *cmdbuff, struct xform draw_xf, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 srgb, u32 detail)
{ {
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
@ -269,12 +269,12 @@ void draw_collider_line(struct renderer_cmd_buffer *cmdbuff, struct xform draw_x
#if 1 #if 1
struct v2_array poly = { .points = points, .count = detail }; struct v2_array poly = { .points = points, .count = detail };
draw_poly_line(cmdbuff, poly, true, thickness, color); draw_poly_line(cmdbuff, poly, true, thickness, srgb);
#else #else
for (u64 i = 0; i < detail; ++i) { for (u64 i = 0; i < detail; ++i) {
struct v2 point = points[i]; struct v2 point = points[i];
(UNUSED)thickness; (UNUSED)thickness;
draw_circle(cmdbuff, point, 3, color, 10); draw_circle(cmdbuff, point, 3, srgb, 10);
} }
#endif #endif
@ -285,7 +285,7 @@ void draw_collider_line(struct renderer_cmd_buffer *cmdbuff, struct xform draw_x
* Grid * Grid
* ========================== */ * ========================== */
void draw_grid(struct renderer_cmd_buffer *cmdbuff, struct rect rect, u32 color_bg0, u32 color_bg1, u32 color_line, u32 color_x, u32 color_y, f32 thickness, f32 spacing, struct v2 offset) void draw_grid(struct renderer_cmd_buffer *cmdbuff, struct rect rect, u32 bg0_srgb, u32 bg1_srgb, u32 line_srgb, u32 x_srgb, u32 y_srgb, f32 thickness, f32 spacing, struct v2 offset)
{ {
struct renderer_cmd_parameters cmd_params = ZI; struct renderer_cmd_parameters cmd_params = ZI;
cmd_params.kind = SHADER_GRID; cmd_params.kind = SHADER_GRID;
@ -298,11 +298,11 @@ void draw_grid(struct renderer_cmd_buffer *cmdbuff, struct rect rect, u32 color_
struct quad quad = quad_from_rect(rect); struct quad quad = quad_from_rect(rect);
struct grid_shader_vertex attributes = ZI; struct grid_shader_vertex attributes = ZI;
attributes.color_bg0 = color_bg0; attributes.bg0_srgb = bg0_srgb;
attributes.color_bg1 = color_bg1; attributes.bg1_srgb = bg1_srgb;
attributes.color_line = color_line; attributes.line_srgb = line_srgb;
attributes.color_x= color_x; attributes.x_srgb = x_srgb;
attributes.color_y = color_y; attributes.y_srgb = y_srgb;
attributes.line_thickness = thickness; attributes.line_thickness = thickness;
attributes.line_spacing = spacing; attributes.line_spacing = spacing;
attributes.offset = offset; attributes.offset = offset;

View File

@ -28,21 +28,21 @@ struct draw_startup_receipt draw_startup(struct renderer_startup_receipt *render
void draw_quad_texture_ex(struct renderer_cmd_buffer *cmdbuff, struct renderer_texture texture, struct sprite_tag sprite, struct clip_rect clip, u32 tint0, u32 tint1, struct quad quad); void draw_quad_texture_ex(struct renderer_cmd_buffer *cmdbuff, struct renderer_texture texture, struct sprite_tag sprite, struct clip_rect clip, u32 tint0, u32 tint1, struct quad quad);
void draw_quad_texture(struct renderer_cmd_buffer *cmdbuff, struct draw_texture_params params, struct quad quad); void draw_quad_texture(struct renderer_cmd_buffer *cmdbuff, struct draw_texture_params params, struct quad quad);
void draw_poly(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, u32 color); void draw_poly(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, u32 srgb);
void draw_circle(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius, u32 color, u32 detail); void draw_circle(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius, u32 srgb, u32 detail);
void draw_quad(struct renderer_cmd_buffer *cmdbuff, struct quad quad, u32 color); void draw_quad(struct renderer_cmd_buffer *cmdbuff, struct quad quad, u32 srgb);
void draw_gradient_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, u32 color_start, u32 color_end); void draw_gradient_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, u32 start_srgb, u32 end_srgb);
void draw_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, u32 color); void draw_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, u32 srgb);
void draw_ray(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 ray, f32 thickness, u32 color); void draw_ray(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 ray, f32 thickness, u32 srgb);
void draw_poly_line(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, b32 loop, f32 thickness, u32 color); void draw_poly_line(struct renderer_cmd_buffer *cmdbuff, struct v2_array array, b32 loop, f32 thickness, u32 srgb);
void draw_circle_line(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail); void draw_circle_line(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 radius, f32 thickness, u32 srgb, u32 detail);
void draw_quad_line(struct renderer_cmd_buffer *cmdbuff, struct quad quad, f32 thickness, u32 color); void draw_quad_line(struct renderer_cmd_buffer *cmdbuff, struct quad quad, f32 thickness, u32 srgb);
void draw_arrow_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color); void draw_arrow_line(struct renderer_cmd_buffer *cmdbuff, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 srgb);
void draw_arrow_ray(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color); void draw_arrow_ray(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 srgb);
void draw_collider_line(struct renderer_cmd_buffer *cmdbuff, struct xform draw_xf, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail); void draw_collider_line(struct renderer_cmd_buffer *cmdbuff, struct xform draw_xf, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 srgb, u32 detail);
void draw_grid(struct renderer_cmd_buffer *cmdbuff, struct rect rect, u32 color_bg0, u32 color_bg1, u32 color_line, u32 color_x, u32 color_y, f32 thickness, f32 spacing, struct v2 offset); void draw_grid(struct renderer_cmd_buffer *cmdbuff, struct rect rect, u32 bg0_srgb, u32 bg1_srgb, u32 line_srgb, u32 x_srgb, u32 y_srgb, f32 thickness, f32 spacing, struct v2 offset);
void draw_text(struct renderer_cmd_buffer *cmdbuff, struct font *font, struct v2 pos, struct string str); void draw_text(struct renderer_cmd_buffer *cmdbuff, struct font *font, struct v2 pos, struct string str);
void draw_text_ex(struct renderer_cmd_buffer *cmdbuff, struct font *font, struct v2 pos, f32 scale, struct string str); void draw_text_ex(struct renderer_cmd_buffer *cmdbuff, struct font *font, struct v2 pos, f32 scale, struct string str);

View File

@ -39,19 +39,19 @@ struct renderer_cmd_parameters {
PACK(struct triangle_shader_vertex { PACK(struct triangle_shader_vertex {
struct v2 pos; struct v2 pos;
struct v2 uv; struct v2 uv;
u32 color; u32 tint_srgb;
}); });
PACK(struct grid_shader_vertex { PACK(struct grid_shader_vertex {
struct v2 pos; struct v2 pos;
u32 color_bg0;
u32 color_bg1;
u32 color_line;
u32 color_x;
u32 color_y;
f32 line_thickness; f32 line_thickness;
f32 line_spacing; f32 line_spacing;
struct v2 offset; struct v2 offset;
u32 bg0_srgb;
u32 bg1_srgb;
u32 line_srgb;
u32 x_srgb;
u32 y_srgb;
}); });
/* ========================== * /* ========================== *
@ -69,6 +69,7 @@ enum renderer_texture_format {
RENDERER_TEXTURE_FORMAT_NONE, RENDERER_TEXTURE_FORMAT_NONE,
RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM,
RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB,
NUM_RENDERER_TEXTURE_FORMATS NUM_RENDERER_TEXTURE_FORMATS
}; };

View File

@ -30,13 +30,19 @@
#define SHADER_INFO_LOOKUP_BINS 64 #define SHADER_INFO_LOOKUP_BINS 64
/* FIXME: Enable this and resolve unreleased references */ /* FIXME: Enable this and resolve unreleased references */
//#define D3D11_DEBUG RTC #if RTC
#define D3D11_DEBUG 0 # define D3D11_DEBUG 0
#else
# define D3D11_DEBUG 0
#endif
#define D3D11_SHADER_DEBUG RTC #define D3D11_SHADER_DEBUG RTC
#define D3D11_SWAPCHAIN_FLAGS (DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) #define D3D11_SWAPCHAIN_FLAGS (DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING)
#define D3D11_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM)
#define D3D11_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
struct dx11_shader { struct dx11_shader {
enum shader_kind kind; enum shader_kind kind;
b32 valid; /* Is this shader allocated */ b32 valid; /* Is this shader allocated */
@ -230,14 +236,14 @@ INTERNAL void init_shader_table(void)
.vertex_size = sizeof(struct grid_shader_vertex), .vertex_size = sizeof(struct grid_shader_vertex),
.input_layout_desc = { .input_layout_desc = {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR_BG_A", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR_BG_B", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR_LINE", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR_X", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR_Y", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "THICKNESS", 0, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "THICKNESS", 0, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "SPACING", 0, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "SPACING", 0, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "OFFSET", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } { "OFFSET", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 2, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 3, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 4, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
} }
}; };
@ -445,7 +451,7 @@ struct renderer_startup_receipt renderer_startup(struct sys_window *window)
} }
#if D3D11_DEBUG #if D3D11_DEBUG
/* Enable debug break on API errors */ /* D3D11 Debug break */
{ {
ID3D11InfoQueue *info; ID3D11InfoQueue *info;
ID3D11Device_QueryInterface(device, &IID_ID3D11InfoQueue, (void **)&info); ID3D11Device_QueryInterface(device, &IID_ID3D11InfoQueue, (void **)&info);
@ -454,7 +460,7 @@ struct renderer_startup_receipt renderer_startup(struct sys_window *window)
ID3D11InfoQueue_Release(info); ID3D11InfoQueue_Release(info);
} }
/* Enable debug break for DXGI too */ /* DXGI Debug break */
{ {
IDXGIInfoQueue *dxgiInfo; IDXGIInfoQueue *dxgiInfo;
hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgiInfo); hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgiInfo);
@ -485,19 +491,13 @@ struct renderer_startup_receipt renderer_startup(struct sys_window *window)
ASSERT(SUCCEEDED(hr)); ASSERT(SUCCEEDED(hr));
DXGI_SWAP_CHAIN_DESC1 desc = { DXGI_SWAP_CHAIN_DESC1 desc = {
.Format = DXGI_FORMAT_R8G8B8A8_UNORM, .Format = D3D11_SWAPCHAIN_FORMAT,
.SampleDesc = { 1, 0 }, .SampleDesc = { 1, 0 },
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, .BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.BufferCount = 2, .BufferCount = 2,
.Scaling = DXGI_SCALING_NONE, .Scaling = DXGI_SCALING_NONE,
.Flags = D3D11_SWAPCHAIN_FLAGS, .Flags = D3D11_SWAPCHAIN_FLAGS,
.AlphaMode = DXGI_ALPHA_MODE_IGNORE, .AlphaMode = DXGI_ALPHA_MODE_IGNORE,
/* More efficient FLIP presentation model.
* Windows 10 allows to use DXGI_SWAP_EFFECT_FLIP_DISCARD
* For Windows 8 compatibility use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
* For Windows 7 compatibility use DXGI_SWAP_EFFECT_DISCARD
*/
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD, .SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
}; };
@ -520,6 +520,7 @@ struct renderer_startup_receipt renderer_startup(struct sys_window *window)
G.dev = device; G.dev = device;
G.devcon = context; G.devcon = context;
G.swapchain = swapchain; G.swapchain = swapchain;
G.backbuffer_texture.is_backbuffer = true;
struct string prof_ctx_name = LIT("D3d11 Context"); struct string prof_ctx_name = LIT("D3d11 Context");
(UNUSED)prof_ctx_name; (UNUSED)prof_ctx_name;
@ -706,10 +707,10 @@ INTERNAL void dx11_render(ID3D11RenderTargetView *target, struct renderer_cmd_bu
if (texture) { if (texture) {
/* Bind texture */ /* Bind texture */
D3D11_TEXTURE2D_DESC texture_desc = ZI;
ID3D11Texture2D_GetDesc(texture, &texture_desc);
/* Create SRV */ /* Create SRV */
D3D11_TEXTURE2D_DESC texture_desc = ZI;
ID3D11Texture2D_GetDesc(texture, &texture_desc);
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = { .Format = texture_desc.Format, .ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D, .Texture2D.MipLevels = texture_desc.MipLevels, .Texture2D.MostDetailedMip = 0 }; D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = { .Format = texture_desc.Format, .ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D, .Texture2D.MipLevels = texture_desc.MipLevels, .Texture2D.MostDetailedMip = 0 };
ID3D11ShaderResourceView *texture_srv = NULL; ID3D11ShaderResourceView *texture_srv = NULL;
ID3D11Device_CreateShaderResourceView(G.dev, (ID3D11Resource *)texture, &srv_desc, &texture_srv); ID3D11Device_CreateShaderResourceView(G.dev, (ID3D11Resource *)texture, &srv_desc, &texture_srv);
@ -771,6 +772,10 @@ INTERNAL struct dx11_format dx11_format_from_renderer_format(enum renderer_textu
[RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM] = { [RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM] = {
.format = DXGI_FORMAT_R8G8B8A8_UNORM, .format = DXGI_FORMAT_R8G8B8A8_UNORM,
.pixel_size = 4 .pixel_size = 4
},
[RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = {
.format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
.pixel_size = 4
} }
}; };
struct dx11_format res = ZI; struct dx11_format res = ZI;
@ -806,7 +811,7 @@ INTERNAL struct dx11_texture *dx11_texture_alloc(enum renderer_texture_format fo
if (dx11_format.format == DXGI_FORMAT_UNKNOWN) { if (dx11_format.format == DXGI_FORMAT_UNKNOWN) {
/* Unknown format */ /* Unknown format */
ASSERT(false); ASSERT(false);
dx11_format = (struct dx11_format) { .format = DXGI_FORMAT_R8G8B8A8_UNORM, .pixel_size = 4 }; sys_panic(LIT("Unknown dx11 texture format during texture allocation"));
} }
u32 bind_flags = D3D11_BIND_SHADER_RESOURCE; u32 bind_flags = D3D11_BIND_SHADER_RESOURCE;
@ -911,8 +916,16 @@ void renderer_texture_render(struct renderer_texture texture, struct renderer_cm
struct dx11_texture *t = (struct dx11_texture *)texture.handle; struct dx11_texture *t = (struct dx11_texture *)texture.handle;
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = ZI;
D3D11_RENDER_TARGET_VIEW_DESC *rtv_desc_param = NULL;
if (t->is_backbuffer) {
rtv_desc.Format = D3D11_SWAPCHAIN_RTV_FORMAT;
rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtv_desc_param = &rtv_desc;
}
ID3D11RenderTargetView *target_view = NULL; ID3D11RenderTargetView *target_view = NULL;
ID3D11Device_CreateRenderTargetView(G.dev, (ID3D11Resource *)t->texture, NULL, &target_view); ID3D11Device_CreateRenderTargetView(G.dev, (ID3D11Resource *)t->texture, rtv_desc_param, &target_view);
if (target_view) { if (target_view) {
dx11_render(target_view, cmdbuff, view, viewport); dx11_render(target_view, cmdbuff, view, viewport);
} }

View File

@ -368,11 +368,16 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t
decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs)); decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs));
resource_close(&texture_rs); resource_close(&texture_rs);
enum renderer_texture_format format = RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM;
if (decoded.srgb) {
format = RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB;
}
/* Initialize */ /* Initialize */
e->texture = arena_push(&e->arena, struct sprite_texture); e->texture = arena_push(&e->arena, struct sprite_texture);
e->texture->width = decoded.image.width; e->texture->width = decoded.image.width;
e->texture->height = decoded.image.height; e->texture->height = decoded.image.height;
e->texture->texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels); e->texture->texture = renderer_texture_alloc(format, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels);
e->texture->valid = true; e->texture->valid = true;
e->texture->loaded = true; e->texture->loaded = true;
/* TODO: Query renderer for more accurate texture size in VRAM */ /* TODO: Query renderer for more accurate texture size in VRAM */