diff --git a/src/engine/renderer/dx.cpp b/src/engine/renderer/dx.cpp index 6521195..b4036c5 100644 --- a/src/engine/renderer/dx.cpp +++ b/src/engine/renderer/dx.cpp @@ -109,6 +109,8 @@ static void record_and_run_commands(ID3D12CommandQueue* command_queue, std::func command_list->Release(); } +ID3D12PipelineState* create_pipeline(const Vk_Pipeline_Def& def); + void dx_initialize() { #if defined(_DEBUG) // Enable the D3D12 debug layer @@ -366,10 +368,58 @@ void dx_initialize() { assert(((size_t)dx.index_buffer_ptr & 0xffff) == 0); } + // + // Standard pipelines. + // + + // fog and dlights + { + Vk_Pipeline_Def def; + def.shader_type = Vk_Shader_Type::single_texture; + def.clipping_plane = false; + def.mirror = false; + + unsigned int fog_state_bits[2] = { + GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL, + GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA + }; + unsigned int dlight_state_bits[2] = { + GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL, + GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL + }; + bool polygon_offset[2] = {false, true}; + + for (int i = 0; i < 2; i++) { + unsigned fog_state = fog_state_bits[i]; + unsigned dlight_state = dlight_state_bits[i]; + + for (int j = 0; j < 3; j++) { + def.face_culling = j; // cullType_t value + + for (int k = 0; k < 2; k++) { + def.polygon_offset = polygon_offset[k]; + + def.state_bits = fog_state; + dx.fog_pipeline_states[i][j][k] = create_pipeline(def); + + def.state_bits = dlight_state; + dx.dlight_pipeline_states[i][j][k] = create_pipeline(def); + } + } + } + } + dx.active = true; } void dx_shutdown() { + for (int i = 0; i < 2; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 2; k++) { + dx.fog_pipeline_states[i][j][k]->Release(); + dx.dlight_pipeline_states[i][j][k]->Release(); + } + dx.swapchain.Reset(); dx.command_allocator->Release(); diff --git a/src/engine/renderer/dx.h b/src/engine/renderer/dx.h index 5c08805..76c649a 100644 --- a/src/engine/renderer/dx.h +++ b/src/engine/renderer/dx.h @@ -98,6 +98,34 @@ struct Dx_Instance { int index_buffer_offset = 0; ID3D12Resource* geometry_buffer = nullptr; + + // + // Standard pipelines. + // + ID3D12PipelineState* skybox_pipeline_state = nullptr; + + // dim 0: 0 - front side, 1 - back size + // dim 1: 0 - normal view, 1 - mirror view + ID3D12PipelineState* shadow_volume_pipeline_states[2][2]; + ID3D12PipelineState* shadow_finish_pipeline_state = nullptr; + + // dim 0 is based on fogPass_t: 0 - corresponds to FP_EQUAL, 1 - corresponds to FP_LE. + // dim 1 is directly a cullType_t enum value. + // dim 2 is a polygon offset value (0 - off, 1 - on). + ID3D12PipelineState* fog_pipeline_states[2][3][2]; + + // dim 0 is based on dlight additive flag: 0 - not additive, 1 - additive + // dim 1 is directly a cullType_t enum value. + // dim 2 is a polygon offset value (0 - off, 1 - on). + ID3D12PipelineState* dlight_pipeline_states[2][3][2]; + + // debug visualization pipelines + ID3D12PipelineState* tris_debug_pipeline_state = nullptr; + ID3D12PipelineState* tris_mirror_debug_pipeline_state = nullptr; + ID3D12PipelineState* normals_debug_pipeline_state = nullptr; + ID3D12PipelineState* surface_debug_pipeline_state_solid = nullptr; + ID3D12PipelineState* surface_debug_pipeline_state_outline = nullptr; + ID3D12PipelineState* images_debug_pipeline_state; }; struct Dx_World { diff --git a/src/engine/renderer/tr_shade.c b/src/engine/renderer/tr_shade.c index 845b981..9ce2c93 100644 --- a/src/engine/renderer/tr_shade.c +++ b/src/engine/renderer/tr_shade.c @@ -398,6 +398,12 @@ static void ProjectDlightTexture( void ) { VkPipeline pipeline = vk.dlight_pipelines[dl->additive > 0 ? 1 : 0][tess.shader->cullType][tess.shader->polygonOffset]; vk_shade_geometry(pipeline, false, Vk_Depth_Range::normal); } + + // DX12 + if (dx.active) { + auto pipeline_state = dx.dlight_pipeline_states[dl->additive > 0 ? 1 : 0][tess.shader->cullType][tess.shader->polygonOffset]; + dx_shade_geometry(pipeline_state, false, Vk_Depth_Range::normal); + } } } @@ -443,6 +449,13 @@ static void RB_FogPass( void ) { VkPipeline pipeline = vk.fog_pipelines[tess.shader->fogPass - 1][tess.shader->cullType][tess.shader->polygonOffset]; vk_shade_geometry(pipeline, false, Vk_Depth_Range::normal); } + + // DX12 + if (dx.active) { + assert(tess.shader->fogPass > 0); + auto pipeline_state = dx.fog_pipeline_states[tess.shader->fogPass - 1][tess.shader->cullType][tess.shader->polygonOffset]; + dx_shade_geometry(pipeline_state, false, Vk_Depth_Range::normal); + } } /*