shape shader start
This commit is contained in:
parent
5bdaba67e7
commit
5a9d9debba
5
imgui.ini
Normal file
5
imgui.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
@ -24,12 +24,12 @@ SamplerState g_sampler : register(s0);
|
||||
* ========================== */
|
||||
|
||||
struct vs_input {
|
||||
DECL(uint, SV_VertexID);
|
||||
DECLS(uint, SV_VertexID);
|
||||
};
|
||||
|
||||
struct vs_output {
|
||||
DECL(float4, SV_Position);
|
||||
DECL(float2, uv);
|
||||
DECLS(float4, SV_Position);
|
||||
DECLS(float2, uv);
|
||||
};
|
||||
|
||||
SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input)
|
||||
@ -58,13 +58,13 @@ struct ps_input {
|
||||
};
|
||||
|
||||
struct ps_output {
|
||||
DECL(float4, SV_Target);
|
||||
DECLS(float4, SV_Target);
|
||||
};
|
||||
|
||||
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
||||
{
|
||||
struct ps_output output;
|
||||
const float gamma = g_constants.gamma;
|
||||
output.SV_Target = pow(g_textures[g_constants.tex_urid].Sample(g_sampler, input.vs.uv), 1/gamma);
|
||||
output.SV_Target = pow(abs(g_textures[g_constants.tex_urid].Sample(g_sampler, input.vs.uv)), 1/gamma);
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#define PI 3.14159265359
|
||||
#define GOLDEN 1.61803398875
|
||||
|
||||
#define DECL(t, n) t n : n
|
||||
#define DECLS(t, n) t n : n
|
||||
#define NURID(i) NonUniformResourceIndex(i)
|
||||
|
||||
#if !SH_CPU
|
||||
|
||||
@ -28,17 +28,17 @@ SamplerState g_sampler : register(s0);
|
||||
* ========================== */
|
||||
|
||||
struct vs_input {
|
||||
DECL(uint, SV_InstanceID);
|
||||
DECL(uint, SV_VertexID);
|
||||
DECLS(uint, SV_InstanceID);
|
||||
DECLS(uint, SV_VertexID);
|
||||
};
|
||||
|
||||
struct vs_output {
|
||||
nointerpolation DECL(uint, flags);
|
||||
nointerpolation DECL(int, tex_nurid);
|
||||
nointerpolation DECL(int, grid_id);
|
||||
DECL(float2, uv);
|
||||
DECL(float4, tint_lin);
|
||||
DECL(float4, SV_Position);
|
||||
nointerpolation DECLS(uint, flags);
|
||||
nointerpolation DECLS(int, tex_nurid);
|
||||
nointerpolation DECLS(int, grid_id);
|
||||
DECLS(float2, uv);
|
||||
DECLS(float4, tint_lin);
|
||||
DECLS(float4, SV_Position);
|
||||
};
|
||||
|
||||
SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input)
|
||||
@ -73,13 +73,13 @@ struct ps_input {
|
||||
};
|
||||
|
||||
struct ps_output {
|
||||
DECL(float4, SV_Target);
|
||||
DECLS(float4, SV_Target);
|
||||
};
|
||||
|
||||
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
||||
{
|
||||
struct ps_output output;
|
||||
output.SV_Target = float4(1, 1, 1, 1);
|
||||
output.SV_Target = input.vs.tint_lin;
|
||||
|
||||
/* Texture */
|
||||
if (input.vs.tex_nurid >= 0) {
|
||||
@ -92,15 +92,15 @@ SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
||||
float2 grid_pos = input.vs.SV_Position.xy + grid.offset;
|
||||
float half_thickness = grid.line_thickness / 2;
|
||||
float spacing = grid.line_spacing;
|
||||
float4 color = linear_from_srgb32(grid.bg0_srgb);
|
||||
uint color_srgb = grid.bg0_srgb;
|
||||
float2 v = abs(round(grid_pos / spacing) * spacing - grid_pos);
|
||||
float dist = min(v.x, v.y);
|
||||
if (grid_pos.y <= half_thickness && grid_pos.y >= -half_thickness) {
|
||||
color = linear_from_srgb32(grid.x_srgb);
|
||||
color_srgb = grid.x_srgb;
|
||||
} else if (grid_pos.x <= half_thickness && grid_pos.x >= -half_thickness) {
|
||||
color = linear_from_srgb32(grid.y_srgb);
|
||||
color_srgb = grid.y_srgb;
|
||||
} else if (dist < half_thickness) {
|
||||
color = linear_from_srgb32(grid.line_srgb);
|
||||
color_srgb = grid.line_srgb;
|
||||
} else {
|
||||
bool checker = false;
|
||||
uint cell_x = (uint)(abs(grid_pos.x) / spacing) + (grid_pos.x < 0);
|
||||
@ -111,12 +111,11 @@ SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
||||
checker = cell_y % 2 == 1;
|
||||
}
|
||||
if (checker) {
|
||||
color = linear_from_srgb32(grid.bg1_srgb);
|
||||
color_srgb = grid.bg1_srgb;
|
||||
}
|
||||
}
|
||||
output.SV_Target *= color;
|
||||
output.SV_Target *= linear_from_srgb32(color_srgb);
|
||||
}
|
||||
|
||||
output.SV_Target *= input.vs.tint_lin;
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#define SH_STRUCT(s) PACK(struct s)
|
||||
#define SH_DECL(t, n) struct CAT(sh_, t) n
|
||||
#define SH_DECLS(t, n) SH_DECL(t, n)
|
||||
#define SH_ENTRY(rootsig) static
|
||||
#define SH_ASSERT_32BIT(s, n) CT_ASSERT((sizeof(s) / 4) == n)
|
||||
|
||||
@ -51,6 +52,7 @@ INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v)
|
||||
|
||||
#define SH_STRUCT(s) struct s
|
||||
#define SH_DECL(t, n) t n
|
||||
#define SH_DECLS(t, n) t n : n
|
||||
#define SH_ENTRY(rootsig) [RootSignature(rootsig)]
|
||||
#define SH_ASSERT_32BIT(s, n)
|
||||
|
||||
@ -99,3 +101,17 @@ SH_STRUCT(sh_material_grid {
|
||||
SH_DECL(uint, x_srgb);
|
||||
SH_DECL(uint, y_srgb);
|
||||
});
|
||||
|
||||
/* ========================== *
|
||||
* Shape shader structures
|
||||
* ========================== */
|
||||
|
||||
SH_STRUCT(sh_shape_constants {
|
||||
SH_DECL(float4x4, projection);
|
||||
});
|
||||
SH_ASSERT_32BIT(struct sh_shape_constants, 16); /* Expected 32bit root constant size in shader */
|
||||
|
||||
SH_STRUCT(sh_shape_vert {
|
||||
SH_DECLS(float2, pos);
|
||||
SH_DECLS(uint, color_srgb);
|
||||
});
|
||||
|
||||
60
res/sh/shape.hlsl
Normal file
60
res/sh/shape.hlsl
Normal file
@ -0,0 +1,60 @@
|
||||
#include "sh/common.hlsl"
|
||||
|
||||
/* ========================== *
|
||||
* Root signature
|
||||
* ========================== */
|
||||
|
||||
#define ROOTSIG \
|
||||
"RootConstants(num32BitConstants=16, b0), " \
|
||||
"SRV(t0), " \
|
||||
"SRV(t1), " \
|
||||
"DescriptorTable(SRV(t2, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
||||
"StaticSampler(s0, " \
|
||||
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"maxAnisotropy = 1)"
|
||||
|
||||
ConstantBuffer<struct sh_material_constants> g_constants : register(b0);
|
||||
StructuredBuffer<struct sh_material_instance> g_instances : register(t0);
|
||||
StructuredBuffer<struct sh_material_grid> g_grids : register(t1);
|
||||
Texture2D g_textures[] : register(t2);
|
||||
|
||||
SamplerState g_sampler : register(s0);
|
||||
|
||||
/* ========================== *
|
||||
* Vertex shader
|
||||
* ========================== */
|
||||
|
||||
struct vs_output {
|
||||
DECLS(float4, SV_Position);
|
||||
DECLS(float4, color_lin);
|
||||
};
|
||||
|
||||
SH_ENTRY(ROOTSIG) struct vs_output vs(struct sh_shape_vert input)
|
||||
{
|
||||
struct vs_output output;
|
||||
output.SV_Position = mul(g_constants.projection, float4(input.pos, 0, 1));
|
||||
output.color_lin = linear_from_srgb32(input.color_srgb);
|
||||
return output;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Pixel shader
|
||||
* ========================== */
|
||||
|
||||
struct ps_input {
|
||||
struct vs_output vs;
|
||||
};
|
||||
|
||||
struct ps_output {
|
||||
DECLS(float4, SV_Target);
|
||||
};
|
||||
|
||||
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
||||
{
|
||||
struct ps_output output;
|
||||
output.SV_Target = input.vs.color_lin;
|
||||
return output;
|
||||
}
|
||||
@ -634,7 +634,7 @@ INLINE f64 clamp_f64(f64 v, f64 min, f64 max) { return v < min ? min : v > max ?
|
||||
|
||||
#include STRINGIZE(TRACY_INCLUDE_PATH)
|
||||
|
||||
#define PROFILING_CAPTURE_FRAME_IMAGE 1
|
||||
#define PROFILING_CAPTURE_FRAME_IMAGE 0
|
||||
|
||||
/* Clang/GCC cleanup macros */
|
||||
#if COMPILER_MSVC
|
||||
|
||||
31
src/draw.c
31
src/draw.c
@ -31,13 +31,13 @@ struct draw_startup_receipt draw_startup(struct gp_startup_receipt *gp_sr,
|
||||
void draw_texture(struct gp_handle flow, struct draw_texture_params params)
|
||||
{
|
||||
struct gp_cmd_desc cmd = ZI;
|
||||
cmd.kind = GP_CMD_KIND_DRAW_TEXTURE;
|
||||
cmd.texture.xf = params.xf;
|
||||
cmd.texture.sprite = params.sprite;
|
||||
cmd.texture.texture = params.texture;
|
||||
cmd.texture.clip = params.clip;
|
||||
cmd.texture.tint = params.tint;
|
||||
cmd.texture.emittance = params.emittance;
|
||||
cmd.kind = GP_CMD_KIND_DRAW_MATERIAL;
|
||||
cmd.material.xf = params.xf;
|
||||
cmd.material.sprite = params.sprite;
|
||||
cmd.material.texture = params.texture;
|
||||
cmd.material.clip = params.clip;
|
||||
cmd.material.tint = params.tint;
|
||||
cmd.material.emittance = params.emittance;
|
||||
gp_push_cmd(flow, cmd);
|
||||
}
|
||||
|
||||
@ -48,10 +48,10 @@ void draw_texture(struct gp_handle flow, struct draw_texture_params params)
|
||||
void draw_poly_ex(struct gp_handle flow, struct v2_array vertices, struct gp_indices indices, u32 color)
|
||||
{
|
||||
struct gp_cmd_desc cmd = ZI;
|
||||
cmd.kind = GP_CMD_KIND_DRAW_MESH;
|
||||
cmd.mesh.vertices = vertices;
|
||||
cmd.mesh.indices = indices;
|
||||
cmd.mesh.color = color;
|
||||
cmd.kind = GP_CMD_KIND_DRAW_SHAPE;
|
||||
cmd.shape.vertices = vertices;
|
||||
cmd.shape.indices = indices;
|
||||
cmd.shape.color = color;
|
||||
gp_push_cmd(flow, cmd);
|
||||
}
|
||||
|
||||
@ -271,10 +271,10 @@ void draw_grid(struct gp_handle flow, struct xform xf, u32 bg0_color, u32 bg1_co
|
||||
grid.offset = offset;
|
||||
|
||||
struct gp_cmd_desc cmd = ZI;
|
||||
cmd.kind = GP_CMD_KIND_DRAW_TEXTURE;
|
||||
cmd.texture.xf = xf;
|
||||
cmd.texture.tint = COLOR_WHITE;
|
||||
cmd.texture.grid = &grid;
|
||||
cmd.kind = GP_CMD_KIND_DRAW_MATERIAL;
|
||||
cmd.material.xf = xf;
|
||||
cmd.material.tint = COLOR_WHITE;
|
||||
cmd.material.grid = &grid;
|
||||
gp_push_cmd(flow, cmd);
|
||||
}
|
||||
|
||||
@ -285,6 +285,7 @@ void draw_grid(struct gp_handle flow, struct xform xf, u32 bg0_color, u32 bg1_co
|
||||
/* Returns the rect of the text area */
|
||||
struct rect draw_text(struct gp_handle flow, struct draw_text_params params)
|
||||
{
|
||||
__prof;
|
||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||
|
||||
f32 inv_font_image_width = 1.0 / (f32)params.font->image_width;
|
||||
|
||||
18
src/gp.h
18
src/gp.h
@ -70,9 +70,8 @@ struct gp_indices {
|
||||
|
||||
enum gp_cmd_kind {
|
||||
GP_CMD_KIND_NONE,
|
||||
GP_CMD_KIND_DRAW_MESH,
|
||||
GP_CMD_KIND_DRAW_TEXTURE,
|
||||
GP_CMD_KIND_TEST,
|
||||
GP_CMD_KIND_DRAW_SHAPE,
|
||||
GP_CMD_KIND_DRAW_MATERIAL,
|
||||
|
||||
NUM_GP_CMD_KINDS
|
||||
};
|
||||
@ -91,11 +90,6 @@ struct gp_grid_desc {
|
||||
struct gp_cmd_desc {
|
||||
enum gp_cmd_kind kind;
|
||||
union {
|
||||
struct {
|
||||
struct v2_array vertices;
|
||||
struct gp_indices indices;
|
||||
u32 color;
|
||||
} mesh;
|
||||
struct {
|
||||
struct xform xf;
|
||||
struct sprite_tag sprite;
|
||||
@ -104,10 +98,12 @@ struct gp_cmd_desc {
|
||||
u32 tint;
|
||||
f32 emittance;
|
||||
struct gp_grid_desc *grid;
|
||||
} texture;
|
||||
} material;
|
||||
struct {
|
||||
struct xform xf;
|
||||
} test;
|
||||
struct v2_array vertices;
|
||||
struct gp_indices indices;
|
||||
u32 color;
|
||||
} shape;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
406
src/gp_dx11.c
406
src/gp_dx11.c
@ -128,6 +128,7 @@ struct dx11_cmd_buffers {
|
||||
|
||||
struct dx11_cmd {
|
||||
enum gp_cmd_kind kind;
|
||||
b32 is_grid;
|
||||
union {
|
||||
struct {
|
||||
struct xform xf;
|
||||
@ -285,7 +286,7 @@ INTERNAL struct dx11_buffer *dx11_buffer_alloc(struct D3D11_BUFFER_DESC desc, D3
|
||||
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(shader_resource_watch_callback, name);
|
||||
#endif
|
||||
|
||||
struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struct sys_window *window)
|
||||
struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr)
|
||||
{
|
||||
__prof;
|
||||
(UNUSED)work_sr;
|
||||
@ -314,7 +315,6 @@ struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struc
|
||||
HRESULT hr;
|
||||
ID3D11Device *device = NULL;
|
||||
ID3D11DeviceContext *context = NULL;
|
||||
IDXGISwapChain2 *swapchain = NULL;
|
||||
|
||||
/* Create D3D11 device & context */
|
||||
{
|
||||
@ -361,71 +361,13 @@ struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struc
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create swap chain */
|
||||
{
|
||||
__profscope(Create swapchain);
|
||||
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
|
||||
|
||||
/* Get DXGI device from D3D11 device */
|
||||
IDXGIDevice *dxgiDevice;
|
||||
hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgiDevice);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* Get DXGI adapter from DXGI device */
|
||||
IDXGIAdapter *dxgiAdapter;
|
||||
hr = IDXGIDevice_GetAdapter(dxgiDevice, &dxgiAdapter);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* Get DXGI factory from DXGI adapter */
|
||||
IDXGIFactory2 *factory;
|
||||
hr = IDXGIAdapter_GetParent(dxgiAdapter, &IID_IDXGIFactory2, (void **)&factory);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 desc = {
|
||||
.Format = DX11_SWAPCHAIN_FORMAT,
|
||||
.SampleDesc = { 1, 0 },
|
||||
.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||
.BufferCount = 3,
|
||||
.Scaling = DXGI_SCALING_NONE,
|
||||
.Flags = DX11_SWAPCHAIN_FLAGS,
|
||||
.AlphaMode = DXGI_ALPHA_MODE_IGNORE,
|
||||
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD
|
||||
};
|
||||
|
||||
IDXGISwapChain1 *swapchain1 = NULL;
|
||||
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)device, hwnd, &desc, NULL, NULL, &swapchain1);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain2, (void **)&swapchain);
|
||||
}
|
||||
|
||||
/* Disable Alt+Enter changing monitor resolution to match window size */
|
||||
IDXGIFactory_MakeWindowAssociation(factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
||||
IDXGISwapChain1_Release(swapchain1);
|
||||
IDXGIFactory2_Release(factory);
|
||||
IDXGIAdapter_Release(dxgiAdapter);
|
||||
IDXGIDevice_Release(dxgiDevice);
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(hr) || !device || !context || !swapchain) {
|
||||
if (!SUCCEEDED(hr) || !device || !context) {
|
||||
/* Gpu initialization failure */
|
||||
/* TODO: Better message */
|
||||
sys_panic(LIT("Failed to initialize DirectX 11"));
|
||||
}
|
||||
G.dev = device;
|
||||
G.devcon = context;
|
||||
G.swapchain = swapchain;
|
||||
|
||||
/* Create the swapchain waitable object */
|
||||
#if DX11_WAIT_FRAME_LATENCY
|
||||
if (G.swapchain != NULL) {
|
||||
IDXGISwapChain2_SetMaximumFrameLatency(G.swapchain, 1);
|
||||
G.swapchain_waitable = IDXGISwapChain2_GetFrameLatencyWaitableObject(G.swapchain);
|
||||
ASSERT(G.swapchain_waitable != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct string prof_ctx_name = LIT("D3d11 Context");
|
||||
(UNUSED)prof_ctx_name;
|
||||
@ -1137,21 +1079,6 @@ struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, stru
|
||||
return res;
|
||||
}
|
||||
|
||||
void gp_texture_clear(struct gp_handle target_texture, u32 clear_color)
|
||||
{
|
||||
__prof;
|
||||
struct dx11_texture *t = (struct dx11_texture *)target_texture.v;
|
||||
if (t->rtv) {
|
||||
__profscope_dx11(G.profiling_ctx, Clear, RGB32_F(0.5, 0.1, 0.1));
|
||||
f32 r = (f32)((clear_color >> 0) & 0xFF) / 255.0f;
|
||||
f32 g = (f32)((clear_color >> 8) & 0xFF) / 255.0f;
|
||||
f32 b = (f32)((clear_color >> 16) & 0xFF) / 255.0f;
|
||||
f32 a = (f32)((clear_color >> 24) & 0xFF) / 255.0f;
|
||||
f32 fill[4] = { r, g, b, a };
|
||||
ID3D11DeviceContext_ClearRenderTargetView(G.devcon, t->rtv, fill);
|
||||
}
|
||||
}
|
||||
|
||||
struct v2i32 gp_texture_get_size(struct gp_handle texture)
|
||||
{
|
||||
return ((struct dx11_texture *)texture.v)->size;
|
||||
@ -1384,7 +1311,7 @@ void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc params)
|
||||
ASSERT(false);
|
||||
} break;
|
||||
|
||||
case GP_CMD_KIND_DRAW_MESH:
|
||||
case GP_CMD_KIND_DRAW_SHAPE:
|
||||
{
|
||||
struct dx11_cmd *cmd = flow->cpu_last_cmd;
|
||||
if (cmd && cmd->kind != params.kind) {
|
||||
@ -1429,11 +1356,47 @@ void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc params)
|
||||
|
||||
case GP_CMD_KIND_DRAW_TEXTURE:
|
||||
{
|
||||
if (params.texture.grid) {
|
||||
struct dx11_cmd *cmd = flow->cpu_last_cmd;
|
||||
if (cmd && (cmd->kind != params.kind || !cmd->is_grid)) {
|
||||
/* Cannot batch */
|
||||
cmd = NULL;
|
||||
}
|
||||
|
||||
/* Start new cmd */
|
||||
if (!cmd) {
|
||||
/* TODO: Better count method */
|
||||
cmd = arena_push(flow->cpu_cmds_arena, struct dx11_cmd);
|
||||
cmd->kind = params.kind;
|
||||
cmd->is_grid = true;
|
||||
cmd->grid.instance_offset = (flow->cmd_buffers.grid.instance_buffer->cpu_buffer_arena->pos / sizeof(struct dx11_grid_instance));
|
||||
if (flow->cpu_last_cmd) {
|
||||
flow->cpu_last_cmd->next = cmd;
|
||||
} else {
|
||||
flow->cpu_first_cmd = cmd;
|
||||
}
|
||||
flow->cpu_last_cmd = cmd;
|
||||
}
|
||||
|
||||
/* Push instance data */
|
||||
++cmd->grid.instance_count;
|
||||
struct dx11_grid_instance *instance = dx11_buffer_push(flow->cmd_buffers.grid.instance_buffer, sizeof(struct dx11_grid_instance));
|
||||
instance->xf = params.texture.xf;
|
||||
instance->line_thickness = params.texture.grid->line_thickness;
|
||||
instance->line_spacing = params.texture.grid->line_spacing;
|
||||
instance->offset = params.texture.grid->offset;
|
||||
instance->bg0_srgb = params.texture.grid->bg0_color;
|
||||
instance->bg1_srgb = params.texture.grid->bg1_color;
|
||||
instance->line_srgb = params.texture.grid->line_color;
|
||||
instance->x_srgb = params.texture.grid->x_color;
|
||||
instance->y_srgb = params.texture.grid->y_color;
|
||||
} else {
|
||||
struct dx11_cmd *cmd = flow->cpu_last_cmd;
|
||||
if (cmd &&
|
||||
((cmd->kind != params.kind) ||
|
||||
(cmd->texture.sprite.hash != params.texture.sprite.hash) ||
|
||||
(cmd->texture.texture.v != params.texture.texture.v))) {
|
||||
(cmd->texture.texture.v != params.texture.texture.v) ||
|
||||
(cmd->is_grid))) {
|
||||
/* Cannot batch */
|
||||
cmd = NULL;
|
||||
}
|
||||
@ -1462,42 +1425,7 @@ void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc params)
|
||||
instance->uv1 = params.texture.clip.p1;
|
||||
instance->tint_srgb = params.texture.tint;
|
||||
instance->emittance = params.texture.emittance;
|
||||
} break;
|
||||
|
||||
case GP_CMD_KIND_DRAW_GRID:
|
||||
{
|
||||
struct dx11_cmd *cmd = flow->cpu_last_cmd;
|
||||
if (cmd && cmd->kind != params.kind) {
|
||||
/* Cannot batch */
|
||||
cmd = NULL;
|
||||
}
|
||||
|
||||
/* Start new cmd */
|
||||
if (!cmd) {
|
||||
/* TODO: Better count method */
|
||||
cmd = arena_push(flow->cpu_cmds_arena, struct dx11_cmd);
|
||||
cmd->kind = params.kind;
|
||||
cmd->grid.instance_offset = (flow->cmd_buffers.grid.instance_buffer->cpu_buffer_arena->pos / sizeof(struct dx11_grid_instance));
|
||||
if (flow->cpu_last_cmd) {
|
||||
flow->cpu_last_cmd->next = cmd;
|
||||
} else {
|
||||
flow->cpu_first_cmd = cmd;
|
||||
}
|
||||
flow->cpu_last_cmd = cmd;
|
||||
}
|
||||
|
||||
/* Push instance data */
|
||||
++cmd->grid.instance_count;
|
||||
struct dx11_grid_instance *instance = dx11_buffer_push(flow->cmd_buffers.grid.instance_buffer, sizeof(struct dx11_grid_instance));
|
||||
instance->xf = params.grid.xf;
|
||||
instance->line_thickness = params.grid.line_thickness;
|
||||
instance->line_spacing = params.grid.line_spacing;
|
||||
instance->offset = params.grid.offset;
|
||||
instance->bg0_srgb = params.grid.bg0_color;
|
||||
instance->bg1_srgb = params.grid.bg1_color;
|
||||
instance->line_srgb = params.grid.line_color;
|
||||
instance->x_srgb = params.grid.x_color;
|
||||
instance->y_srgb = params.grid.y_color;
|
||||
} break;
|
||||
|
||||
case GP_CMD_KIND_TEST:
|
||||
@ -1655,6 +1583,20 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
flow->constant_buffer = constant_buffer;
|
||||
}
|
||||
|
||||
/* Clear target */
|
||||
if (params.clear_target) {
|
||||
u32 clear_color = 0;
|
||||
if (final_tex->rtv) {
|
||||
__profscope_dx11(G.profiling_ctx, Clear, RGB32_F(0.5, 0.1, 0.1));
|
||||
f32 r = (f32)((clear_color >> 0) & 0xFF) / 255.0f;
|
||||
f32 g = (f32)((clear_color >> 8) & 0xFF) / 255.0f;
|
||||
f32 b = (f32)((clear_color >> 16) & 0xFF) / 255.0f;
|
||||
f32 a = (f32)((clear_color >> 24) & 0xFF) / 255.0f;
|
||||
f32 fill[4] = { r, g, b, a };
|
||||
ID3D11DeviceContext_ClearRenderTargetView(G.devcon, final_tex->rtv, fill);
|
||||
}
|
||||
}
|
||||
|
||||
/* Regular pass */
|
||||
struct mat4x4 vp_matrix = calculate_vp(params.draw_target_view, viewport.width, viewport.height);
|
||||
{
|
||||
@ -1670,7 +1612,7 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
ASSERT(false);
|
||||
} break;
|
||||
|
||||
case GP_CMD_KIND_DRAW_MESH:
|
||||
case GP_CMD_KIND_DRAW_SHAPE:
|
||||
{
|
||||
__profscope(Draw mesh);
|
||||
__profscope_dx11(G.profiling_ctx, Draw mesh, RGB32_F(0.5, 0.2, 0.2));
|
||||
@ -1718,6 +1660,51 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
|
||||
case GP_CMD_KIND_DRAW_TEXTURE:
|
||||
{
|
||||
if (cmd->is_grid) {
|
||||
__profscope(Draw grid);
|
||||
__profscope_dx11(G.profiling_ctx, Draw grid, RGB32_F(0.2, 0.2, 0.5));
|
||||
struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_GRID];
|
||||
if (shader->valid) {
|
||||
struct dx11_buffer *instance_buffer = flow->cmd_buffers.grid.instance_buffer;
|
||||
u32 instance_offset = cmd->grid.instance_offset;
|
||||
u32 instance_count = cmd->grid.instance_count;
|
||||
|
||||
/* Bind shader */
|
||||
ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0);
|
||||
ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0);
|
||||
|
||||
/* Fill & bind constant buffer */
|
||||
{
|
||||
struct dx11_grid_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_grid_uniform));
|
||||
uniform->vp = vp_matrix;
|
||||
uniform->instance_offset = instance_offset;
|
||||
dx11_buffer_submit(constant_buffer);
|
||||
}
|
||||
ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer);
|
||||
ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer);
|
||||
|
||||
/* Bind dummy vertex buffer */
|
||||
u32 zero = 0;
|
||||
ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &G.dummy_vertex_buffer->gpu_buffer, &zero, &zero);
|
||||
ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero);
|
||||
|
||||
/* Bind SRVs */
|
||||
ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv };
|
||||
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs);
|
||||
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs);
|
||||
|
||||
/* Bind RTVs */
|
||||
ID3D11RenderTargetView *rtvs[] = { final_tex->rtv };
|
||||
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL);
|
||||
|
||||
/* Draw */
|
||||
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
||||
|
||||
/* Unbind */
|
||||
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV);
|
||||
}
|
||||
} else {
|
||||
__profscope(Draw texture);
|
||||
__profscope_dx11(G.profiling_ctx, Draw texture, RGB32_F(0.2, 0.5, 0.2));
|
||||
struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEXTURE];
|
||||
@ -1775,52 +1762,6 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case GP_CMD_KIND_DRAW_GRID:
|
||||
{
|
||||
__profscope(Draw grid);
|
||||
__profscope_dx11(G.profiling_ctx, Draw grid, RGB32_F(0.2, 0.2, 0.5));
|
||||
struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_GRID];
|
||||
if (shader->valid) {
|
||||
struct dx11_buffer *instance_buffer = flow->cmd_buffers.grid.instance_buffer;
|
||||
u32 instance_offset = cmd->grid.instance_offset;
|
||||
u32 instance_count = cmd->grid.instance_count;
|
||||
|
||||
/* Bind shader */
|
||||
ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0);
|
||||
ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0);
|
||||
|
||||
/* Fill & bind constant buffer */
|
||||
{
|
||||
struct dx11_grid_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_grid_uniform));
|
||||
uniform->vp = vp_matrix;
|
||||
uniform->instance_offset = instance_offset;
|
||||
dx11_buffer_submit(constant_buffer);
|
||||
}
|
||||
ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer);
|
||||
ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer);
|
||||
|
||||
/* Bind dummy vertex buffer */
|
||||
u32 zero = 0;
|
||||
ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &G.dummy_vertex_buffer->gpu_buffer, &zero, &zero);
|
||||
ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero);
|
||||
|
||||
/* Bind SRVs */
|
||||
ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv };
|
||||
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs);
|
||||
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs);
|
||||
|
||||
/* Bind RTVs */
|
||||
ID3D11RenderTargetView *rtvs[] = { final_tex->rtv };
|
||||
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL);
|
||||
|
||||
/* Draw */
|
||||
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
||||
|
||||
/* Unbind */
|
||||
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -1878,47 +1819,20 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Backbuffer
|
||||
* Memory info
|
||||
* ========================== */
|
||||
|
||||
struct gp_memory_info gp_query_memory_info(void)
|
||||
{
|
||||
return (struct gp_memory_info) { 0 };
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Present
|
||||
* ========================== */
|
||||
|
||||
INTERNAL void capture_image_for_profiler(void);
|
||||
|
||||
#if GSTAT_ENABLED || PROFILING
|
||||
INTERNAL struct DXGI_QUERY_VIDEO_MEMORY_INFO get_memory_info(void)
|
||||
{
|
||||
__prof;
|
||||
|
||||
/* Get DXGI device from D3D11 device */
|
||||
IDXGIDevice *dxgiDevice;
|
||||
HRESULT hr = ID3D11Device_QueryInterface(G.dev, &IID_IDXGIDevice, (void **)&dxgiDevice);
|
||||
(UNUSED)hr;
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* Get DXGI adapter from DXGI device */
|
||||
IDXGIAdapter *dxgiAdapter;
|
||||
hr = IDXGIDevice_GetAdapter(dxgiDevice, &dxgiAdapter);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
IDXGIAdapter3 *dxgiAdapter3 = NULL;
|
||||
hr = IDXGIAdapter_QueryInterface(dxgiAdapter, &IID_IDXGIAdapter3, (void **)&dxgiAdapter3);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
struct DXGI_QUERY_VIDEO_MEMORY_INFO info = ZI;
|
||||
IDXGIAdapter3_QueryVideoMemoryInfo(
|
||||
dxgiAdapter3,
|
||||
0,
|
||||
DXGI_MEMORY_SEGMENT_GROUP_LOCAL,
|
||||
&info
|
||||
);
|
||||
|
||||
IDXGIAdapter_Release(dxgiAdapter3);
|
||||
IDXGIAdapter_Release(dxgiAdapter);
|
||||
IDXGIDevice_Release(dxgiDevice);
|
||||
|
||||
return info;
|
||||
}
|
||||
#endif
|
||||
|
||||
INTERNAL void present_resize(struct v2i32 size)
|
||||
{
|
||||
__prof;
|
||||
@ -1968,19 +1882,78 @@ INTERNAL void present_blit(struct dx11_texture *dst, struct dx11_texture *src, s
|
||||
draw_texture(G.present_blit_flow, params);
|
||||
}
|
||||
|
||||
/* Clear texture */
|
||||
gp_texture_clear(dst_texture_handle, RGBA32_F(0, 0, 0, 1));
|
||||
|
||||
/* Render to backbuffer texture */
|
||||
struct gp_dispatch_params params = ZI;
|
||||
params.flow = G.present_blit_flow;
|
||||
params.draw_target = dst_texture_handle;
|
||||
params.draw_target_viewport = RECT_FROM_V2(V2(0, 0), V2(dst->size.x, dst->size.y));
|
||||
params.draw_target_view = XFORM_IDENT;
|
||||
params.clear_target = true;
|
||||
gp_dispatch(params);
|
||||
}
|
||||
|
||||
void gp_present(struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)
|
||||
INTERNAL void present_init_swapchain(struct sys_window *window)
|
||||
{
|
||||
|
||||
/* Create swap chain */
|
||||
{
|
||||
__profscope(Create swapchain);
|
||||
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
|
||||
|
||||
/* Get DXGI device from D3D11 device */
|
||||
IDXGIDevice *dxgiDevice;
|
||||
HRESULT hr = ID3D11Device_QueryInterface(G.dev, &IID_IDXGIDevice, (void **)&dxgiDevice);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* Get DXGI adapter from DXGI device */
|
||||
IDXGIAdapter *dxgiAdapter;
|
||||
hr = IDXGIDevice_GetAdapter(dxgiDevice, &dxgiAdapter);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* Get DXGI factory from DXGI adapter */
|
||||
IDXGIFactory2 *factory;
|
||||
hr = IDXGIAdapter_GetParent(dxgiAdapter, &IID_IDXGIFactory2, (void **)&factory);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 desc = {
|
||||
.Format = DX11_SWAPCHAIN_FORMAT,
|
||||
.SampleDesc = { 1, 0 },
|
||||
.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||
.BufferCount = 3,
|
||||
.Scaling = DXGI_SCALING_NONE,
|
||||
.Flags = DX11_SWAPCHAIN_FLAGS,
|
||||
.AlphaMode = DXGI_ALPHA_MODE_IGNORE,
|
||||
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD
|
||||
};
|
||||
|
||||
IDXGISwapChain1 *swapchain1 = NULL;
|
||||
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)G.dev, hwnd, &desc, NULL, NULL, &swapchain1);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain2, (void **)&G.swapchain);
|
||||
}
|
||||
|
||||
/* Disable Alt+Enter changing monitor resolution to match window size */
|
||||
IDXGIFactory_MakeWindowAssociation(factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
||||
IDXGISwapChain1_Release(swapchain1);
|
||||
IDXGIFactory2_Release(factory);
|
||||
IDXGIAdapter_Release(dxgiAdapter);
|
||||
IDXGIDevice_Release(dxgiDevice);
|
||||
}
|
||||
|
||||
/* Create the swapchain waitable object */
|
||||
#if DX11_WAIT_FRAME_LATENCY
|
||||
if (G.swapchain != NULL) {
|
||||
IDXGISwapChain2_SetMaximumFrameLatency(G.swapchain, 1);
|
||||
G.swapchain_waitable = IDXGISwapChain2_GetFrameLatencyWaitableObject(G.swapchain);
|
||||
ASSERT(G.swapchain_waitable != NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)
|
||||
{
|
||||
__prof;
|
||||
|
||||
@ -1994,36 +1967,9 @@ void gp_present(struct v2i32 backbuffer_resolution, struct gp_handle texture, st
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Track vram usage */
|
||||
#if GSTAT_ENABLED || PROFILING
|
||||
{
|
||||
struct DXGI_QUERY_VIDEO_MEMORY_INFO info = get_memory_info();
|
||||
u64 vram = info.CurrentUsage;
|
||||
u64 budget = info.Budget;
|
||||
(UNUSED)vram;
|
||||
(UNUSED)budget;
|
||||
# if GSTAT_ENABLED
|
||||
{
|
||||
gstat_set(GSTAT_VRAM_USAGE, vram);
|
||||
gstat_set(GSTAT_VRAM_BUDGET, budget);
|
||||
if (!G.swapchain) {
|
||||
present_init_swapchain(window);
|
||||
}
|
||||
# endif
|
||||
# if PROFILING
|
||||
{
|
||||
LOCAL_PERSIST char *vram_plot_name = NULL;
|
||||
LOCAL_PERSIST u64 prev_vram = 0;
|
||||
if (!vram_plot_name) {
|
||||
vram_plot_name = "Video memory usage";
|
||||
__prof_plot_init(vram_plot_name, __prof_plot_type_memory, 1, 1, 0);
|
||||
}
|
||||
if (vram != prev_vram) {
|
||||
__prof_plot_i(vram_plot_name, vram);
|
||||
}
|
||||
prev_vram = vram;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wait */
|
||||
i32 flags = 0;
|
||||
|
||||
291
src/gp_dx12.c
291
src/gp_dx12.c
@ -36,6 +36,12 @@
|
||||
#pragma comment(lib, "dxguid")
|
||||
#pragma comment(lib, "d3dcompiler")
|
||||
|
||||
#if PROFILING
|
||||
/* For RegOpenKeyEx */
|
||||
# include <winreg.h>
|
||||
# pragma comment(lib, "advapi32")
|
||||
#endif
|
||||
|
||||
//#define DX12_WAIT_FRAME_LATENCY 1
|
||||
//#define DX12_SWAPCHAIN_FLAGS ((DX12_ALLOW_TEARING * DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) | (DX12_WAIT_FRAME_LATENCY * DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT))
|
||||
|
||||
@ -153,8 +159,10 @@ struct command_descriptor_heap {
|
||||
struct command_buffer {
|
||||
struct command_buffer_group *group;
|
||||
|
||||
struct dx12_resource *resource;
|
||||
u64 size;
|
||||
struct dx12_resource *resource;
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv;
|
||||
D3D12_INDEX_BUFFER_VIEW Ibv;
|
||||
|
||||
struct command_buffer *next_in_command_list;
|
||||
|
||||
@ -372,6 +380,8 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gp_shutdown)
|
||||
command_queue_release(G.cq_compute);
|
||||
command_queue_release(G.cq_direct);
|
||||
ID3D12Device_Release(G.device);
|
||||
#else
|
||||
(UNUSED)command_queue_release;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -426,6 +436,7 @@ INTERNAL struct handle_entry *handle_get_entry(struct gp_handle handle, struct s
|
||||
|
||||
INTERNAL void *handle_get_data(struct gp_handle handle, enum handle_kind kind)
|
||||
{
|
||||
(UNUSED)kind;
|
||||
void *data = NULL;
|
||||
if (handle.gen) {
|
||||
struct sys_lock lock = sys_mutex_lock_s(G.handle_entries_mutex);
|
||||
@ -593,6 +604,41 @@ INTERNAL void dx12_init_device(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PROFILING
|
||||
/* Enable stable power state */
|
||||
{
|
||||
b32 success = true;
|
||||
__profscope(Set stable power state);
|
||||
HKEY key = 0;
|
||||
success = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", 0, KEY_READ, &key) == ERROR_SUCCESS;
|
||||
if (success) {
|
||||
DWORD value = ZI;
|
||||
DWORD dword_size = sizeof(DWORD);
|
||||
success = RegQueryValueExW(key, L"AllowDevelopmentWithoutDevLicense", 0, NULL, (LPBYTE)&value, &dword_size) == ERROR_SUCCESS;
|
||||
RegCloseKey(key);
|
||||
if (success) {
|
||||
success = value != 0;
|
||||
}
|
||||
}
|
||||
logf_info("D3D12 profiling is enabled, attempting to set stable power state (this will increase GPU timing stability at the cost of performance)");
|
||||
if (success) {
|
||||
logf_info("Machine is in developer mode, calling ID3D12Device::SetStablePowerState");
|
||||
hr = ID3D12Device_SetStablePowerState(G.device, 1);
|
||||
if (SUCCEEDED(hr)) {
|
||||
logf_info("ID3D12Device::SetStablePowerState succeeded");
|
||||
} else {
|
||||
success = false;
|
||||
logf_error("ID3D12Device::SetStablePowerState failed");
|
||||
}
|
||||
} else {
|
||||
logf_warning("Machine is not in developer mode, cannot call ID3D12Device::SetStablePowerState");
|
||||
}
|
||||
if (!success) {
|
||||
logf_warning("Profiling is enabled, but ID3D12Device::SetStablePowerState could not be called. This means that GPU timing may be unreliable.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@ -648,6 +694,16 @@ INTERNAL void dx12_init_pipelines(void)
|
||||
desc->ps.func = LIT("ps");
|
||||
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
|
||||
}
|
||||
/* Shape pipeline */
|
||||
{
|
||||
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
|
||||
desc->name = LIT("shape");
|
||||
desc->vs.file = LIT("sh/shape.hlsl");
|
||||
desc->ps.file = LIT("sh/shape.hlsl");
|
||||
desc->vs.func = LIT("vs");
|
||||
desc->ps.func = LIT("ps");
|
||||
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
|
||||
}
|
||||
/* Blit pipeilne */
|
||||
{
|
||||
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
|
||||
@ -674,7 +730,8 @@ INTERNAL void dx12_init_pipelines(void)
|
||||
struct pipeline *pipeline = pipelines[i];
|
||||
if (!pipeline->success) {
|
||||
struct string error = pipeline->first_error ? pipeline->first_error->msg : LIT("Unknown error");
|
||||
struct string msg = string_format(scratch.arena, LIT("Error creating pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(error));
|
||||
struct string msg = string_format(scratch.arena, LIT("Error initializing pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(error));
|
||||
log_error(msg);
|
||||
sys_message_box(SYS_MESSAGE_BOX_KIND_WARNING, msg);
|
||||
}
|
||||
}
|
||||
@ -1142,6 +1199,7 @@ INTERNAL void pipeline_release(struct pipeline *pipeline)
|
||||
|
||||
INTERNAL struct pipeline_scope *pipeline_scope_begin(void)
|
||||
{
|
||||
__prof;
|
||||
struct pipeline_scope *scope = NULL;
|
||||
{
|
||||
struct sys_lock lock = sys_mutex_lock_e(G.pipelines_mutex);
|
||||
@ -1166,6 +1224,7 @@ INTERNAL struct pipeline_scope *pipeline_scope_begin(void)
|
||||
|
||||
INTERNAL void pipeline_scope_end(struct pipeline_scope *scope)
|
||||
{
|
||||
__prof;
|
||||
struct sys_lock lock = sys_mutex_lock_e(G.pipelines_mutex);
|
||||
{
|
||||
for (struct dict_entry *entry = scope->refs->first; entry; entry = entry->next) {
|
||||
@ -1183,6 +1242,7 @@ INTERNAL void pipeline_scope_end(struct pipeline_scope *scope)
|
||||
INTERNAL READONLY struct pipeline g_nil_pipeline = ZI;
|
||||
INTERNAL struct pipeline *pipeline_from_name(struct pipeline_scope *scope, struct string name)
|
||||
{
|
||||
__prof;
|
||||
struct pipeline *res = &g_nil_pipeline;
|
||||
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name);
|
||||
|
||||
@ -1209,6 +1269,7 @@ INTERNAL struct pipeline *pipeline_from_name(struct pipeline_scope *scope, struc
|
||||
|
||||
INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines)
|
||||
{
|
||||
__prof;
|
||||
struct sys_lock lock = sys_mutex_lock_e(G.pipelines_mutex);
|
||||
{
|
||||
for (u64 i = 0; i < num_pipelines; ++i) {
|
||||
@ -1240,6 +1301,7 @@ INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines)
|
||||
#if RESOURCE_RELOADING
|
||||
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name)
|
||||
{
|
||||
__prof;
|
||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||
|
||||
/* Find dirty pipelines */
|
||||
@ -1260,6 +1322,7 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name
|
||||
}
|
||||
|
||||
/* Recompile dirty pipelines */
|
||||
if (num_pipelines > 0) {
|
||||
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
||||
pipeline_alloc_from_desc(num_pipelines, pipeline_descs, pipelines);
|
||||
{
|
||||
@ -1269,12 +1332,13 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name
|
||||
if (pipeline->success) {
|
||||
logf_success("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SECONDS_FROM_NS(pipeline->compilation_time_ns)));
|
||||
} else {
|
||||
struct pipeline *old_pipeline = dict_get(G.top_successful_pipelines, pipeline->hash);
|
||||
if (old_pipeline) {
|
||||
{
|
||||
struct string error = pipeline->first_error ? pipeline->first_error->msg : LIT("Unknown error");
|
||||
struct string msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(error));
|
||||
log_error(msg);
|
||||
} else {
|
||||
}
|
||||
struct pipeline *old_pipeline = dict_get(G.top_successful_pipelines, pipeline->hash);
|
||||
if (!old_pipeline) {
|
||||
/* If no previously successful pipeline exists, then show a message box rather than logging since logs may not be visible to user */
|
||||
struct string error = pipeline->first_error ? pipeline->first_error->msg : LIT("Unknown error");
|
||||
struct string msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(error));
|
||||
@ -1286,6 +1350,7 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name
|
||||
sys_mutex_unlock(&lock);
|
||||
}
|
||||
pipeline_register(num_pipelines, pipelines);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
@ -1297,6 +1362,7 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name
|
||||
|
||||
INTERNAL struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh)
|
||||
{
|
||||
__prof;
|
||||
struct descriptor *d = NULL;
|
||||
u32 index = 0;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = ZI;
|
||||
@ -1331,6 +1397,7 @@ INTERNAL struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh)
|
||||
|
||||
INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type)
|
||||
{
|
||||
__prof;
|
||||
struct cpu_descriptor_heap *dh = NULL;
|
||||
{
|
||||
struct arena *arena = arena_alloc(MEGABYTE(64));
|
||||
@ -1382,12 +1449,15 @@ struct flow {
|
||||
struct sprite_scope *sprite_scope;
|
||||
struct arena *material_instances_arena;
|
||||
struct arena *material_grids_arena;
|
||||
struct arena *shape_verts_arena;
|
||||
struct arena *shape_indices_arena;
|
||||
|
||||
struct flow *next_free;
|
||||
};
|
||||
|
||||
INTERNAL struct flow *flow_alloc(void)
|
||||
{
|
||||
__prof;
|
||||
struct flow *flow = NULL;
|
||||
{
|
||||
struct arena *arena = arena_alloc(MEGABYTE(64));
|
||||
@ -1398,40 +1468,47 @@ INTERNAL struct flow *flow_alloc(void)
|
||||
flow->sprite_scope = sprite_scope_begin();
|
||||
flow->material_instances_arena = arena_alloc(GIGABYTE(1));
|
||||
flow->material_grids_arena = arena_alloc(GIGABYTE(1));
|
||||
flow->shape_verts_arena = arena_alloc(GIGABYTE(1));
|
||||
flow->shape_indices_arena = arena_alloc(GIGABYTE(1));
|
||||
|
||||
return flow;
|
||||
}
|
||||
|
||||
INTERNAL void flow_reset(struct flow *flow)
|
||||
{
|
||||
__prof;
|
||||
sprite_scope_end(flow->sprite_scope);
|
||||
flow->sprite_scope = sprite_scope_begin();
|
||||
arena_reset(flow->material_instances_arena);
|
||||
arena_reset(flow->material_grids_arena);
|
||||
arena_reset(flow->shape_verts_arena);
|
||||
arena_reset(flow->shape_indices_arena);
|
||||
}
|
||||
|
||||
struct gp_handle gp_flow_alloc(void)
|
||||
{
|
||||
__prof;
|
||||
struct flow *flow = flow_alloc();
|
||||
return handle_alloc(DX12_HANDLE_KIND_FLOW, flow);
|
||||
}
|
||||
|
||||
void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc desc)
|
||||
{
|
||||
__prof;
|
||||
struct flow *flow = handle_get_data(gp_flow, DX12_HANDLE_KIND_FLOW);
|
||||
if (flow) {
|
||||
switch (desc.kind) {
|
||||
default: break;
|
||||
|
||||
case GP_CMD_KIND_DRAW_TEXTURE:
|
||||
case GP_CMD_KIND_DRAW_MATERIAL:
|
||||
{
|
||||
i32 texture_id = -1;
|
||||
{
|
||||
struct dx12_resource *texture = NULL;
|
||||
if (desc.texture.texture.gen != 0) {
|
||||
texture = handle_get_data(desc.texture.texture, DX12_HANDLE_KIND_RESOURCE);
|
||||
} else if (desc.texture.sprite.hash != 0) {
|
||||
struct sprite_texture *st = sprite_texture_from_tag_async(flow->sprite_scope, desc.texture.sprite);
|
||||
if (desc.material.texture.gen != 0) {
|
||||
texture = handle_get_data(desc.material.texture, DX12_HANDLE_KIND_RESOURCE);
|
||||
} else if (desc.material.sprite.hash != 0) {
|
||||
struct sprite_texture *st = sprite_texture_from_tag_async(flow->sprite_scope, desc.material.sprite);
|
||||
texture = handle_get_data(st->texture, DX12_HANDLE_KIND_RESOURCE);
|
||||
}
|
||||
if (texture) {
|
||||
@ -1440,8 +1517,8 @@ void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc desc)
|
||||
}
|
||||
|
||||
i32 grid_id = -1;
|
||||
if (desc.texture.grid) {
|
||||
struct gp_grid_desc *grid_desc = desc.texture.grid;
|
||||
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);
|
||||
@ -1459,11 +1536,27 @@ void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_desc desc)
|
||||
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.texture.xf);
|
||||
instance->uv0 = sh_float2_from_v2(desc.texture.clip.p0);
|
||||
instance->uv1 = sh_float2_from_v2(desc.texture.clip.p1);
|
||||
instance->tint_srgb = sh_uint_from_u32(desc.texture.tint);
|
||||
instance->emittance = sh_float_from_f32(desc.texture.emittance);
|
||||
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;
|
||||
|
||||
case GP_CMD_KIND_DRAW_SHAPE:
|
||||
{
|
||||
u32 color = 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, desc.shape.vertices.count);
|
||||
u32 *indices = arena_push_array_no_zero(flow->shape_indices_arena, u32, desc.shape.indices.count);
|
||||
for (u32 i = 0; i < desc.shape.vertices.count; ++i) {
|
||||
struct sh_shape_vert *v = &verts[i];
|
||||
v->pos = sh_float2_from_v2(desc.shape.vertices.points[i]);
|
||||
v->color_srgb = sh_uint_from_u32(color);
|
||||
}
|
||||
for (u32 i = 0; i < desc.shape.indices.count; ++i) {
|
||||
indices[i] = desc.shape.indices.indices[i] + vert_offset;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
@ -1484,6 +1577,7 @@ enum dx12_resource_view_flags {
|
||||
|
||||
INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_props, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_DESC desc, D3D12_RESOURCE_STATES initial_state, enum dx12_resource_view_flags view_flags)
|
||||
{
|
||||
__prof;
|
||||
struct dx12_resource *r = NULL;
|
||||
{
|
||||
struct sys_lock lock = sys_mutex_lock_e(G.resources_mutex);
|
||||
@ -1538,6 +1632,7 @@ INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_pr
|
||||
|
||||
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);
|
||||
@ -1565,16 +1660,19 @@ INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12R
|
||||
|
||||
INTERNAL void dx12_resource_release(struct dx12_resource *t)
|
||||
{
|
||||
__prof;
|
||||
(UNUSED)t;
|
||||
}
|
||||
|
||||
INTERNAL void dx12_resource_release_now(struct dx12_resource *t)
|
||||
{
|
||||
__prof;
|
||||
(UNUSED)t;
|
||||
}
|
||||
|
||||
INTERNAL enum D3D12_RESOURCE_STATES dx12_resource_barrier(ID3D12GraphicsCommandList *cl, struct dx12_resource *resource, enum D3D12_RESOURCE_STATES state)
|
||||
{
|
||||
__prof;
|
||||
enum D3D12_RESOURCE_STATES old_state = resource->state;
|
||||
if (state != resource->state) {
|
||||
struct D3D12_RESOURCE_TRANSITION_BARRIER rtb = ZI;
|
||||
@ -1601,6 +1699,7 @@ INTERNAL enum D3D12_RESOURCE_STATES dx12_resource_barrier(ID3D12GraphicsCommandL
|
||||
|
||||
INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE type, enum D3D12_COMMAND_QUEUE_PRIORITY priority)
|
||||
{
|
||||
__prof;
|
||||
struct command_queue *cq = NULL;
|
||||
{
|
||||
struct arena *arena = arena_alloc(GIGABYTE(64));
|
||||
@ -1629,6 +1728,7 @@ INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE
|
||||
|
||||
INTERNAL void command_queue_release(struct command_queue *cq)
|
||||
{
|
||||
__prof;
|
||||
/* TODO */
|
||||
(UNUSED)cq;
|
||||
//ID3D12CommandQueue_Release(G.cq_copy_background->cq);
|
||||
@ -1640,6 +1740,7 @@ INTERNAL void command_queue_release(struct command_queue *cq)
|
||||
|
||||
INTERNAL struct command_list *command_list_open(struct command_queue *cq)
|
||||
{
|
||||
__prof;
|
||||
u64 queue_fence_value = ID3D12Fence_GetCompletedValue(cq->fence);
|
||||
|
||||
struct command_list *cl = NULL;
|
||||
@ -1717,6 +1818,7 @@ INTERNAL struct command_list *command_list_open(struct command_queue *cq)
|
||||
/* TODO: Allow multiple command list submissions */
|
||||
INTERNAL u64 command_list_close(struct command_list *cl)
|
||||
{
|
||||
__prof;
|
||||
struct command_queue *cq = cl->cq;
|
||||
|
||||
/* Close & execute */
|
||||
@ -1786,6 +1888,7 @@ INTERNAL u64 command_list_close(struct command_list *cl)
|
||||
|
||||
INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struct command_list *cl, struct cpu_descriptor_heap *dh_cpu)
|
||||
{
|
||||
__prof;
|
||||
ASSERT(dh_cpu->type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); /* Src heap must have expected type */
|
||||
|
||||
/* Allocate GPU heap */
|
||||
@ -1888,6 +1991,8 @@ INTERNAL u64 align_up_pow2(u64 v)
|
||||
|
||||
INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl, struct string data)
|
||||
{
|
||||
__prof;
|
||||
|
||||
/* Determine size */
|
||||
u64 size = max_u64(DX12_COMMAND_BUFFER_MIN_SIZE, align_up_pow2(data.len));
|
||||
|
||||
@ -1942,6 +2047,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl
|
||||
cb->group = cb_group;
|
||||
cb->size = data.len;
|
||||
|
||||
/* Create upload heap */
|
||||
if (resource) {
|
||||
cb->resource = resource;
|
||||
} else {
|
||||
@ -1995,6 +2101,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl
|
||||
|
||||
INTERNAL void command_list_set_root_constant(struct command_list *cl, void *src, u32 size)
|
||||
{
|
||||
__prof;
|
||||
if (size % 4 == 0) {
|
||||
u32 num32bit = size / 4;
|
||||
for (u32 i = 0; i < num32bit; ++i) {
|
||||
@ -2030,12 +2137,31 @@ INTERNAL D3D12_RECT scissor_from_rect(struct rect r)
|
||||
return scissor;
|
||||
}
|
||||
|
||||
INTERNAL D3D12_VERTEX_BUFFER_VIEW vbv_from_command_buffer(struct command_buffer *cb, u32 vertex_size)
|
||||
{
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv = ZI;
|
||||
vbv.BufferLocation = cb->resource->gpu_address;
|
||||
vbv.SizeInBytes = cb->size;
|
||||
vbv.StrideInBytes = vertex_size;
|
||||
return vbv;
|
||||
}
|
||||
|
||||
INTERNAL D3D12_INDEX_BUFFER_VIEW ibv_from_command_buffer(struct command_buffer *cb, DXGI_FORMAT format)
|
||||
{
|
||||
D3D12_INDEX_BUFFER_VIEW ibv = ZI;
|
||||
ibv.BufferLocation = cb->resource->gpu_address;
|
||||
ibv.Format = format;
|
||||
ibv.SizeInBytes = cb->size;
|
||||
return ibv;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Texture
|
||||
* ========================== */
|
||||
|
||||
struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data)
|
||||
{
|
||||
__prof;
|
||||
struct dxgi_format_info { DXGI_FORMAT format; u32 size; };
|
||||
LOCAL_PERSIST const struct dxgi_format_info formats[] = {
|
||||
[GP_TEXTURE_FORMAT_R8G8B8A8_UNORM] = { DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
|
||||
@ -2215,7 +2341,7 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
|
||||
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
||||
struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, LIT("material"));
|
||||
if (material_pipeline->success) {
|
||||
struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, LIT("shape"));
|
||||
struct command_list *cl = command_list_open(G.cq_direct);
|
||||
{
|
||||
struct dx12_resource *target = handle_get_data(params.draw_target, DX12_HANDLE_KIND_RESOURCE);
|
||||
@ -2226,16 +2352,13 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 };
|
||||
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));
|
||||
D3D12_VERTEX_BUFFER_VIEW dummy_vertex_buffer_view = ZI;
|
||||
dummy_vertex_buffer_view.BufferLocation = dummy_vertex_buffer->resource->gpu_address;
|
||||
D3D12_INDEX_BUFFER_VIEW quad_index_buffer_view = ZI;
|
||||
quad_index_buffer_view.BufferLocation = quad_index_buffer->resource->gpu_address;
|
||||
quad_index_buffer_view.Format = DXGI_FORMAT_R16_UINT;
|
||||
quad_index_buffer_view.SizeInBytes = sizeof(quad_indices);
|
||||
|
||||
/* Upload buffers */
|
||||
struct command_buffer *instance_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_instances_arena));
|
||||
struct command_buffer *grid_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_grids_arena));
|
||||
struct command_buffer *material_instance_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_instances_arena));
|
||||
struct command_buffer *material_grid_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_grids_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));
|
||||
|
||||
|
||||
/* Upload descriptor heap */
|
||||
struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap);
|
||||
@ -2257,8 +2380,9 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
}
|
||||
|
||||
/* Material pass */
|
||||
{
|
||||
u32 instance_count = instance_buffer->size / sizeof(struct sh_material_instance);
|
||||
if (material_pipeline->success) {
|
||||
__profscope(Material pass);
|
||||
u32 instance_count = material_instance_buffer->size / sizeof(struct sh_material_instance);
|
||||
|
||||
/* Bind pipeline */
|
||||
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, material_pipeline->pso);
|
||||
@ -2270,10 +2394,10 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
command_list_set_root_constant(cl, &constants, sizeof(constants));
|
||||
|
||||
/* Bind instance buffer */
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, instance_buffer->resource->gpu_address);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, material_instance_buffer->resource->gpu_address);
|
||||
|
||||
/* Bind grid buffer */
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, grid_buffer->resource->gpu_address);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, material_grid_buffer->resource->gpu_address);
|
||||
|
||||
/* Bind descriptor heap */
|
||||
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
||||
@ -2287,19 +2411,53 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
|
||||
|
||||
/* Draw */
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0);
|
||||
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(quad_index_buffer, DXGI_FORMAT_R16_UINT);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &dummy_vertex_buffer_view);
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &quad_index_buffer_view);
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv);
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Shape pass */
|
||||
if (shape_pipeline->success) {
|
||||
__profscope(Shape pass);
|
||||
|
||||
/* Bind pipeline */
|
||||
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, material_pipeline->pso);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, material_pipeline->rootsig);
|
||||
|
||||
/* Set root constants */
|
||||
struct sh_shape_constants constants = ZI;
|
||||
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
|
||||
command_list_set_root_constant(cl, &constants, sizeof(constants));
|
||||
|
||||
/* Bind descriptor heap */
|
||||
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 3, descriptor_heap->gp_handle);
|
||||
|
||||
/* Setup Rasterizer State */
|
||||
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
|
||||
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport);
|
||||
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
|
||||
|
||||
/* Draw */
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(shape_verts_buffer, sizeof(struct sh_shape_vert));
|
||||
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(shape_indices_buffer, DXGI_FORMAT_R32_UINT);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv);
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Reset render target */
|
||||
{
|
||||
dx12_resource_barrier(cl->cl, target, target_old_state);
|
||||
}
|
||||
}
|
||||
command_list_close(cl);
|
||||
}
|
||||
pipeline_scope_end(pipeline_scope);
|
||||
flow_reset(flow);
|
||||
}
|
||||
@ -2308,54 +2466,6 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
* Memory info
|
||||
* ========================== */
|
||||
|
||||
#if 0
|
||||
struct gp_memory_info gp_query_memory_info(void)
|
||||
{
|
||||
struct gp_memory_info res = ZI;
|
||||
|
||||
HRESULT hr = 0;
|
||||
IDXGIAdapter3 *dxgiAdapter3 = NULL;
|
||||
struct DXGI_QUERY_VIDEO_MEMORY_INFO info = ZI;
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = IDXGIAdapter_QueryInterface(G.adapter, &IID_IDXGIAdapter3, (void **)&dxgiAdapter3);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
if (SUCCEEDED(hr)) {
|
||||
IDXGIAdapter3_QueryVideoMemoryInfo(dxgiAdapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info);
|
||||
{
|
||||
u64 vram = info.CurrentUsage;
|
||||
u64 budget = info.Budget;
|
||||
(UNUSED)vram;
|
||||
(UNUSED)budget;
|
||||
#if GSTAT_ENABLED
|
||||
{
|
||||
gstat_set(GSTAT_VRAM_USAGE, vram);
|
||||
gstat_set(GSTAT_VRAM_BUDGET, budget);
|
||||
}
|
||||
#endif
|
||||
#if PROFILING
|
||||
{
|
||||
LOCAL_PERSIST char *vram_plot_name = NULL;
|
||||
LOCAL_PERSIST u64 prev_vram = 0;
|
||||
if (!vram_plot_name) {
|
||||
vram_plot_name = "Video memory usage";
|
||||
__prof_plot_init(vram_plot_name, __prof_plot_type_memory, 1, 1, 0);
|
||||
}
|
||||
if (vram != prev_vram) {
|
||||
__prof_plot_i(vram_plot_name, vram);
|
||||
}
|
||||
prev_vram = vram;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (dxgiAdapter3) {
|
||||
IDXGIAdapter_Release(dxgiAdapter3);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
struct gp_memory_info gp_query_memory_info(void)
|
||||
{
|
||||
struct gp_memory_info res = ZI;
|
||||
@ -2383,8 +2493,6 @@ struct gp_memory_info gp_query_memory_info(void)
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ========================== *
|
||||
* Present
|
||||
@ -2476,12 +2584,6 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src,
|
||||
LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 };
|
||||
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));
|
||||
D3D12_VERTEX_BUFFER_VIEW dummy_vertex_buffer_view = ZI;
|
||||
dummy_vertex_buffer_view.BufferLocation = dummy_vertex_buffer->resource->gpu_address;
|
||||
D3D12_INDEX_BUFFER_VIEW quad_index_buffer_view = ZI;
|
||||
quad_index_buffer_view.BufferLocation = quad_index_buffer->resource->gpu_address;
|
||||
quad_index_buffer_view.Format = DXGI_FORMAT_R16_UINT;
|
||||
quad_index_buffer_view.SizeInBytes = sizeof(quad_indices);
|
||||
|
||||
/* Upload descriptor heap */
|
||||
struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap);
|
||||
@ -2520,9 +2622,11 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src,
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
|
||||
|
||||
/* Draw */
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0);
|
||||
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(quad_index_buffer, DXGI_FORMAT_R16_UINT);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &dummy_vertex_buffer_view);
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &quad_index_buffer_view);
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv);
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, 1, 0, 0, 0);
|
||||
|
||||
/* Set dst to presentable */
|
||||
@ -2535,6 +2639,7 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src,
|
||||
|
||||
void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)
|
||||
{
|
||||
__prof;
|
||||
//sys_sleep(0.1);
|
||||
|
||||
struct dx12_resource *backbuffer_resource = update_swapchain(window, backbuffer_resolution);
|
||||
@ -2547,10 +2652,14 @@ void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, s
|
||||
|
||||
/* Present */
|
||||
/* FIXME: Resource barrier */
|
||||
{
|
||||
__profscope(Present);
|
||||
HRESULT hr = IDXGISwapChain3_Present(G.swapchain, 0, 0);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
ASSERT(false);
|
||||
}
|
||||
__profframe(0);
|
||||
}
|
||||
|
||||
(UNUSED)backbuffer_resolution;
|
||||
(UNUSED)texture;
|
||||
|
||||
@ -974,7 +974,6 @@ INTERNAL struct sprite_scope_cache_ref *cache_entry_from_tag(struct sprite_scope
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return scope_ref;
|
||||
}
|
||||
|
||||
|
||||
@ -1195,6 +1195,11 @@ INTERNAL void win32_update_window_from_settings(struct win32_window *window, str
|
||||
};
|
||||
SetWindowPlacement(hwnd, &wp);
|
||||
|
||||
/* Make window always on top when debugging */
|
||||
#if RTC
|
||||
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
#endif
|
||||
|
||||
{
|
||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||
wchar_t *title_wstr = wstr_from_string(scratch.arena, string_from_cstr_no_limit(settings->title));
|
||||
|
||||
13
src/user.c
13
src/user.c
@ -1053,19 +1053,6 @@ INTERNAL void user_update(void)
|
||||
draw_grid(G.world_gp_flow, xform_from_rect(RECT_FROM_V2(pos, size)), color0, color1, RGBA32(0x3f, 0x3f, 0x3f, 0xFF), COLOR_RED, COLOR_GREEN, thickness, spacing, offset);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Draw test
|
||||
* ========================== */
|
||||
|
||||
{
|
||||
struct v2 pos = xform_invert_mul_v2(G.world_to_user_xf, V2(0, 0));
|
||||
struct v2 size = xform_basis_invert_mul_v2(G.world_to_user_xf, G.user_size);
|
||||
struct gp_cmd_desc cmd = ZI;
|
||||
cmd.kind = GP_CMD_KIND_TEST;
|
||||
cmd.test.xf = xform_from_rect(RECT_FROM_V2(pos, size));
|
||||
gp_push_cmd(G.world_gp_flow, cmd);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* ========================== *
|
||||
* Alloc / release tile cache entries
|
||||
|
||||
@ -548,11 +548,12 @@ struct work_handle work_slate_end(struct work_slate *ws, enum work_priority prio
|
||||
struct work_handle work_slate_end_and_help(struct work_slate *ws, enum work_priority priority)
|
||||
{
|
||||
__prof;
|
||||
|
||||
struct work_handle handle = ZI;
|
||||
if (ws->num_tasks > 0) {
|
||||
struct sys_lock lock = sys_mutex_lock_e(G.mutex);
|
||||
struct work_handle handle = work_push_from_slate_locked(&lock, ws, true, priority);
|
||||
handle = work_push_from_slate_locked(&lock, ws, true, priority);
|
||||
sys_mutex_unlock(&lock);
|
||||
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
@ -566,7 +567,7 @@ INTERNAL struct work *work_from_handle_locked(struct sys_lock *lock, struct work
|
||||
(UNUSED)lock;
|
||||
|
||||
struct work *work = handle.work;
|
||||
if (work->gen != handle.gen) {
|
||||
if (work && work->gen != handle.gen) {
|
||||
work = NULL;
|
||||
}
|
||||
return work;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user