jfa start
This commit is contained in:
parent
070fb5427a
commit
f58bcd52ee
33
res/sh/jfa.hlsl
Normal file
33
res/sh/jfa.hlsl
Normal file
@ -0,0 +1,33 @@
|
||||
#include "sh/common.hlsl"
|
||||
|
||||
/* ========================== *
|
||||
* Root signature
|
||||
* ========================== */
|
||||
|
||||
#define ROOTSIG \
|
||||
"RootConstants(num32BitConstants=16, b0), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
||||
"StaticSampler(s0, " \
|
||||
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"maxAnisotropy = 1)"
|
||||
|
||||
ConstantBuffer<struct sh_jfa_constants> g_constants : register(b0);
|
||||
Texture2D g_textures[] : register(t0);
|
||||
|
||||
SamplerState g_sampler : register(s0);
|
||||
|
||||
/* ========================== *
|
||||
* Compute shader
|
||||
* ========================== */
|
||||
|
||||
struct cs_input {
|
||||
DECLS(uint, SV_DispatchThreadID);
|
||||
};
|
||||
|
||||
[numthreads(32, 1, 1)]
|
||||
SH_ENTRY(ROOTSIG) void cs(struct cs_input input)
|
||||
{
|
||||
}
|
||||
@ -69,6 +69,14 @@ SH_STRUCT(sh_blit_constants {
|
||||
});
|
||||
SH_ASSERT_32BIT(struct sh_blit_constants, 18); /* Expected 32bit root constant size in shader */
|
||||
|
||||
/* ========================== *
|
||||
* JFA shader structures
|
||||
* ========================== */
|
||||
|
||||
SH_STRUCT(sh_jfa_constants {
|
||||
SH_DECL(float4x4, projection);
|
||||
});
|
||||
|
||||
/* ========================== *
|
||||
* Material shader structures
|
||||
* ========================== */
|
||||
|
||||
148
src/gp_dx12.c
148
src/gp_dx12.c
@ -49,7 +49,7 @@
|
||||
#define DX12_NUM_RTV_DESCRIPTORS (1024 * 1)
|
||||
#define DX12_COMMAND_BUFFER_MIN_SIZE (1024 * 64)
|
||||
|
||||
#define DX12_MULTI_QUEUE 1
|
||||
#define DX12_MULTI_QUEUE !PROFILING
|
||||
#if DX12_MULTI_QUEUE
|
||||
# define DX12_QUEUE_DIRECT 0
|
||||
# define DX12_QUEUE_COMPUTE 1
|
||||
@ -79,6 +79,7 @@ struct shader_desc {
|
||||
|
||||
struct pipeline_desc {
|
||||
struct string name;
|
||||
struct shader_desc cs;
|
||||
struct shader_desc vs;
|
||||
struct shader_desc ps;
|
||||
D3D12_INPUT_ELEMENT_DESC ia[8];
|
||||
@ -663,6 +664,14 @@ INTERNAL void dx12_init_pipelines(void)
|
||||
|
||||
/* Register pipeline descs */
|
||||
{
|
||||
/* JFA pipeline */
|
||||
{
|
||||
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
|
||||
desc->name = LIT("jfa");
|
||||
desc->cs.file = LIT("sh/jfa.hlsl");
|
||||
desc->cs.func = LIT("cs");
|
||||
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc);
|
||||
}
|
||||
/* Material pipeline */
|
||||
{
|
||||
struct pipeline_desc *desc = arena_push(G.pipelines_arena, struct pipeline_desc);
|
||||
@ -812,7 +821,8 @@ INTERNAL void dx12_include_handler_release(struct dx12_include_handler *handler)
|
||||
|
||||
enum shader_compile_job_kind {
|
||||
SHADER_COMPILE_TASK_KIND_VS,
|
||||
SHADER_COMPILE_TASK_KIND_PS
|
||||
SHADER_COMPILE_TASK_KIND_PS,
|
||||
SHADER_COMPILE_TASK_KIND_CS
|
||||
};
|
||||
|
||||
struct shader_compile_job_param {
|
||||
@ -881,6 +891,11 @@ INTERNAL SYS_JOB_DEF(shader_compile_job, job)
|
||||
{
|
||||
target = "ps_5_1";
|
||||
} break;
|
||||
|
||||
case SHADER_COMPILE_TASK_KIND_CS:
|
||||
{
|
||||
target = "cs_5_1";
|
||||
} break;
|
||||
}
|
||||
D3D_SHADER_MACRO defines[] = {
|
||||
{ "SH_CPU", "0" },
|
||||
@ -940,24 +955,55 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||
|
||||
struct string error_str = LIT("Unknown error");
|
||||
|
||||
b32 has_cs = desc->cs.file.len > 0;
|
||||
b32 ps_res_is_shared = string_eq(desc->vs.file, desc->ps.file);
|
||||
struct resource vs_res = resource_open(desc->vs.file);
|
||||
struct resource ps_res = vs_res;
|
||||
|
||||
struct resource cs_res = ZI;
|
||||
struct resource vs_res = ZI;
|
||||
struct resource ps_res = ZI;
|
||||
if (has_cs) {
|
||||
cs_res = resource_open(desc->cs.file);
|
||||
if (desc->vs.file.len > 0 || desc->ps.file.len > 0) {
|
||||
error_str = LIT("Pipeline desc contains both compute and vs/ps shader");
|
||||
success = 0;
|
||||
}
|
||||
} else {
|
||||
vs_res = resource_open(desc->vs.file);
|
||||
ps_res = vs_res;
|
||||
if (!ps_res_is_shared) {
|
||||
ps_res = resource_open(desc->ps.file);
|
||||
}
|
||||
dict_set(pipeline->arena, pipeline->dependencies, hash_fnv64(HASH_FNV64_BASIS, desc->vs.file), 1);
|
||||
dict_set(pipeline->arena, pipeline->dependencies, hash_fnv64(HASH_FNV64_BASIS, desc->ps.file), 1);
|
||||
if (desc->vs.file.len <= 0 || desc->ps.file.len <= 0) {
|
||||
error_str = LIT("Pipeline desc is missing shaders");
|
||||
success = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (has_cs) {
|
||||
dict_set(pipeline->arena, pipeline->dependencies, hash_fnv64(HASH_FNV64_BASIS, desc->cs.file), 1);
|
||||
} else {
|
||||
dict_set(pipeline->arena, pipeline->dependencies, hash_fnv64(HASH_FNV64_BASIS, desc->vs.file), 1);
|
||||
dict_set(pipeline->arena, pipeline->dependencies, hash_fnv64(HASH_FNV64_BASIS, desc->ps.file), 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (has_cs) {
|
||||
if (!resource_exists(&cs_res)) {
|
||||
error_str = string_format(scratch.arena, LIT("Compute shader source \"%F\" not found"), FMT_STR(desc->vs.file));
|
||||
success = 0;
|
||||
}
|
||||
} else {
|
||||
if (!resource_exists(&vs_res)) {
|
||||
error_str = string_format(scratch.arena, LIT("Shader source \"%F\" not found"), FMT_STR(desc->vs.file));
|
||||
error_str = string_format(scratch.arena, LIT("Vertex shader source \"%F\" not found"), FMT_STR(desc->vs.file));
|
||||
success = 0;
|
||||
} else if (!resource_exists(&ps_res)) {
|
||||
error_str = string_format(scratch.arena, LIT("Shader source \"%F\" not found"), FMT_STR(desc->ps.file));
|
||||
error_str = string_format(scratch.arena, LIT("Pixel shader source \"%F\" not found"), FMT_STR(desc->ps.file));
|
||||
success = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct shader_compile_job_param vs = ZI;
|
||||
vs.kind = SHADER_COMPILE_TASK_KIND_VS;
|
||||
@ -971,8 +1017,22 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||
ps.shader_desc = desc->ps;
|
||||
ps.shader_res = &ps_res;
|
||||
|
||||
struct shader_compile_job_param cs = ZI;
|
||||
cs.kind = SHADER_COMPILE_TASK_KIND_CS;
|
||||
cs.pipeline = pipeline;
|
||||
cs.shader_desc = desc->cs;
|
||||
cs.shader_res = &cs_res;
|
||||
|
||||
/* Compile shaders */
|
||||
if (success) {
|
||||
if (has_cs) {
|
||||
struct shader_compile_job_param *params[] = { &cs };
|
||||
struct shader_compile_job_sig comp_sig = { .params = params };
|
||||
struct snc_counter counter = ZI;
|
||||
sys_run(countof(params), shader_compile_job, &comp_sig, SYS_POOL_INHERIT, SYS_PRIORITY_INHERIT, &counter);
|
||||
snc_counter_wait(&counter);
|
||||
success = cs.success;
|
||||
} else {
|
||||
struct shader_compile_job_param *params[] = { &vs, &ps };
|
||||
struct shader_compile_job_sig comp_sig = { .params = params };
|
||||
struct snc_counter counter = ZI;
|
||||
@ -980,6 +1040,7 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||
snc_counter_wait(&counter);
|
||||
success = vs.success && ps.success;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get root signature blob
|
||||
* NOTE: This isn't necessary for creating the root signature (since it
|
||||
@ -988,6 +1049,20 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||
ID3D10Blob *rootsig_blob = 0;
|
||||
if (success) {
|
||||
__profn("Validate root signatures");
|
||||
if (has_cs) {
|
||||
u32 cs_rootsig_data_len = 0;
|
||||
ID3D10Blob *cs_rootsig_blob = 0;
|
||||
D3DGetBlobPart(ID3D10Blob_GetBufferPointer(cs.blob), ID3D10Blob_GetBufferSize(cs.blob), D3D_BLOB_ROOT_SIGNATURE, 0, &cs_rootsig_blob);
|
||||
if (cs_rootsig_blob) {
|
||||
cs_rootsig_data_len = ID3D10Blob_GetBufferSize(cs_rootsig_blob);
|
||||
}
|
||||
if (cs_rootsig_data_len == 0) {
|
||||
success = 0;
|
||||
error_str = LIT("Vertex shader is missing root signature");
|
||||
} else {
|
||||
rootsig_blob = cs_rootsig_blob;
|
||||
}
|
||||
} else {
|
||||
char *vs_rootsig_data = 0;
|
||||
char *ps_rootsig_data = 0;
|
||||
u32 vs_rootsig_data_len = 0;
|
||||
@ -1020,6 +1095,7 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||
ID3D10Blob_Release(ps_rootsig_blob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create root signature */
|
||||
ID3D12RootSignature *rootsig = 0;
|
||||
@ -1035,8 +1111,19 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||
/* Create PSO */
|
||||
ID3D12PipelineState *pso = 0;
|
||||
if (success) {
|
||||
if (has_cs) {
|
||||
__profn("Create compute PSO");
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC pso_desc = { 0 };
|
||||
pso_desc.pRootSignature = rootsig;
|
||||
if (cs.success) {
|
||||
pso_desc.CS.pShaderBytecode = ID3D10Blob_GetBufferPointer(cs.blob);
|
||||
pso_desc.CS.BytecodeLength = ID3D10Blob_GetBufferSize(cs.blob);
|
||||
}
|
||||
hr = ID3D12Device_CreateComputePipelineState(G.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
||||
} else {
|
||||
__profn("Create graphics PSO");
|
||||
|
||||
/* Default rasterizer state */
|
||||
__profn("Create PSO");
|
||||
D3D12_RASTERIZER_DESC raster_desc = {
|
||||
.FillMode = D3D12_FILL_MODE_SOLID,
|
||||
.CullMode = D3D12_CULL_MODE_NONE,
|
||||
@ -1106,6 +1193,7 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||
pso_desc.SampleDesc.Count = 1;
|
||||
pso_desc.SampleDesc.Quality = 0;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(G.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
||||
}
|
||||
if (FAILED(hr)) {
|
||||
error_str = LIT("Failed to create pipeline state object");
|
||||
success = 0;
|
||||
@ -1142,10 +1230,14 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||
pipeline->compilation_time_ns = sys_time_ns() - start_ns;
|
||||
pipeline->success = success;
|
||||
|
||||
if (has_cs) {
|
||||
resource_close(&cs_res);
|
||||
} else {
|
||||
resource_close(&vs_res);
|
||||
if (!ps_res_is_shared) {
|
||||
resource_close(&ps_res);
|
||||
}
|
||||
}
|
||||
if (rootsig_blob) {
|
||||
ID3D10Blob_Release(rootsig_blob);
|
||||
}
|
||||
@ -2449,6 +2541,7 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
|
||||
struct sprite_scope *sprite_scope = sprite_scope_begin();
|
||||
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
||||
//struct pipeline *jfa_pipeline = pipeline_from_name(pipeline_scope, LIT("jfa"));
|
||||
struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, LIT("material"));
|
||||
struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, LIT("shape"));
|
||||
struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT];
|
||||
@ -2533,6 +2626,43 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* JFA pass */
|
||||
if (jfa_pipeline->success) {
|
||||
__profn("JFA pass");
|
||||
__profnc_dx12(cl->cq->prof, cl->cl, "JFA pass", RGB32_F(0.5, 0.2, 0.2));
|
||||
|
||||
/* Bind pipeline */
|
||||
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, jfa_pipeline->pso);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, jfa_pipeline->rootsig);
|
||||
|
||||
/* Set constants */
|
||||
struct sh_material_constants constants = ZI;
|
||||
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
|
||||
command_list_set_root_constant(cl, &constants, sizeof(constants));
|
||||
|
||||
/* Set instance buffer */
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, material_instance_buffer->resource->gpu_address);
|
||||
|
||||
/* Set grid buffer */
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, grid_buffer->resource->gpu_address);
|
||||
|
||||
/* Set descriptor heap */
|
||||
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 3, descriptor_heap->gpu_handle);
|
||||
|
||||
/* Draw */
|
||||
u32 instance_count = material_instance_buffer->size / sizeof(struct sh_material_instance);
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0);
|
||||
D3D12_INDEX_BUFFER_VIEW ibv = ibv_from_command_buffer(quad_index_buffer, DXGI_FORMAT_R16_UINT);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv);
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv);
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Material pass */
|
||||
if (material_pipeline->success) {
|
||||
__profn("Material pass");
|
||||
|
||||
@ -204,7 +204,7 @@ INTERNAL void wasapi_update_end(struct wasapi_buffer *wspbuf, struct mixed_pcm_f
|
||||
flags = AUDCLNT_BUFFERFLAGS_SILENT;
|
||||
|
||||
/* This shouldn't occur, mixer should be generating samples equivilent
|
||||
* to value returned from `playback_update_begin`. */
|
||||
* to value returned from `wasapi_update_begin`. */
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
|
||||
32
src/sys.h
32
src/sys.h
@ -235,22 +235,9 @@ void sys_watch_wake(struct sys_watch *dw);
|
||||
struct sys_watch_info_list sys_watch_info_copy(struct arena *arena, struct sys_watch_info_list src);
|
||||
|
||||
/* ========================== *
|
||||
* Window event
|
||||
* Window
|
||||
* ========================== */
|
||||
|
||||
enum sys_window_event_kind {
|
||||
SYS_EVENT_KIND_NONE,
|
||||
|
||||
SYS_EVENT_KIND_BUTTON_DOWN,
|
||||
SYS_EVENT_KIND_BUTTON_UP,
|
||||
SYS_EVENT_KIND_CURSOR_MOVE,
|
||||
SYS_EVENT_KIND_MOUSE_MOVE,
|
||||
SYS_EVENT_KIND_TEXT,
|
||||
SYS_EVENT_KIND_QUIT,
|
||||
|
||||
SYS_EVENT_KIND_COUNT
|
||||
};
|
||||
|
||||
enum sys_btn {
|
||||
SYS_BTN_NONE,
|
||||
|
||||
@ -355,6 +342,19 @@ enum sys_btn {
|
||||
SYS_BTN_COUNT
|
||||
};
|
||||
|
||||
enum sys_window_event_kind {
|
||||
SYS_EVENT_KIND_NONE,
|
||||
|
||||
SYS_EVENT_KIND_BUTTON_DOWN,
|
||||
SYS_EVENT_KIND_BUTTON_UP,
|
||||
SYS_EVENT_KIND_CURSOR_MOVE,
|
||||
SYS_EVENT_KIND_MOUSE_MOVE,
|
||||
SYS_EVENT_KIND_TEXT,
|
||||
SYS_EVENT_KIND_QUIT,
|
||||
|
||||
SYS_EVENT_KIND_COUNT
|
||||
};
|
||||
|
||||
struct sys_window_event {
|
||||
enum sys_window_event_kind kind;
|
||||
|
||||
@ -378,10 +378,6 @@ struct sys_window_event_array {
|
||||
struct sys_window_event *events;
|
||||
};
|
||||
|
||||
/* ========================== *
|
||||
* Window
|
||||
* ========================== */
|
||||
|
||||
/* NOTE:
|
||||
* A window object can only be interacted with by the thread that created it.
|
||||
* This restriction is in place because of how Win32 works, IE you cannot
|
||||
|
||||
Loading…
Reference in New Issue
Block a user