DX12: pipelines creation (WIP).

This commit is contained in:
Artem Kharytoniuk 2017-12-09 01:48:21 +01:00
parent d148127fca
commit 7f597965fb
2 changed files with 190 additions and 4 deletions

View File

@ -1,5 +1,6 @@
#include "tr_local.h"
#include <chrono>
#include <functional>
#include "D3d12.h"
@ -200,9 +201,9 @@ void dx_initialize() {
D3D12_STATIC_SAMPLER_DESC sampler = {};
sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler.MipLODBias = 0;
sampler.MaxAnisotropy = 0;
sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
@ -446,8 +447,188 @@ void dx_upload_image_data(ID3D12Resource* texture, int width, int height, bool m
});
}
static ID3D12PipelineState* create_pipeline(const Vk_Pipeline_Def& def) {
ComPtr<ID3DBlob> vertexShader;
ComPtr<ID3DBlob> pixelShader;
DX_CHECK(D3DCompileFromFile(L"d:/Quake-III-Arena-Kenny-Edition/src/engine/renderer/shaders/shaders.hlsl", nullptr, nullptr, "VSMain", "vs_5_0", 0, 0, &vertexShader, nullptr));
DX_CHECK(D3DCompileFromFile(L"d:/Quake-III-Arena-Kenny-Edition/src/engine/renderer/shaders/shaders.hlsl", nullptr, nullptr, "PSMain", "ps_5_0", 0, 0, &pixelShader, nullptr));
// Define the vertex input layout.
D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 2, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
};
// Describe and create the graphics pipeline state object (PSO).
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeline_desc = {};
pipeline_desc.InputLayout = { inputElementDescs, _countof(inputElementDescs) };
pipeline_desc.pRootSignature = dx.root_signature;
pipeline_desc.VS = CD3DX12_SHADER_BYTECODE(vertexShader.Get());
pipeline_desc.PS = CD3DX12_SHADER_BYTECODE(pixelShader.Get());
pipeline_desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
pipeline_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
//
// Blend.
//
auto& blend_state = pipeline_desc.BlendState;
blend_state.AlphaToCoverageEnable = FALSE;
blend_state.IndependentBlendEnable = FALSE;
auto& rt_blend_desc = blend_state.RenderTarget[0];
rt_blend_desc.BlendEnable = (def.state_bits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS)) ? TRUE : FALSE;
rt_blend_desc.LogicOpEnable = FALSE;
if (rt_blend_desc.BlendEnable) {
switch (def.state_bits & GLS_SRCBLEND_BITS) {
case GLS_SRCBLEND_ZERO:
rt_blend_desc.SrcBlend = D3D12_BLEND_ZERO;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_ZERO;
break;
case GLS_SRCBLEND_ONE:
rt_blend_desc.SrcBlend = D3D12_BLEND_ONE;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_ONE;
break;
case GLS_SRCBLEND_DST_COLOR:
rt_blend_desc.SrcBlend = D3D12_BLEND_DEST_COLOR;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_DEST_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
rt_blend_desc.SrcBlend = D3D12_BLEND_INV_DEST_COLOR;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_INV_DEST_ALPHA;
break;
case GLS_SRCBLEND_SRC_ALPHA:
rt_blend_desc.SrcBlend = D3D12_BLEND_SRC_ALPHA;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
rt_blend_desc.SrcBlend = D3D12_BLEND_INV_SRC_ALPHA;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
break;
case GLS_SRCBLEND_DST_ALPHA:
rt_blend_desc.SrcBlend = D3D12_BLEND_DEST_ALPHA;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_DEST_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
rt_blend_desc.SrcBlend = D3D12_BLEND_INV_DEST_ALPHA;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_INV_DEST_ALPHA;
break;
case GLS_SRCBLEND_ALPHA_SATURATE:
rt_blend_desc.SrcBlend = D3D12_BLEND_SRC_ALPHA_SAT;
rt_blend_desc.SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA_SAT;
break;
default:
ri.Error( ERR_DROP, "create_pipeline: invalid src blend state bits\n" );
break;
}
switch (def.state_bits & GLS_DSTBLEND_BITS) {
case GLS_DSTBLEND_ZERO:
rt_blend_desc.DestBlend = D3D12_BLEND_ZERO;
rt_blend_desc.DestBlendAlpha = D3D12_BLEND_ZERO;
break;
case GLS_DSTBLEND_ONE:
rt_blend_desc.DestBlend = D3D12_BLEND_ONE;
rt_blend_desc.DestBlendAlpha = D3D12_BLEND_ONE;
break;
case GLS_DSTBLEND_SRC_COLOR:
rt_blend_desc.DestBlend = D3D12_BLEND_SRC_COLOR;
rt_blend_desc.DestBlendAlpha = D3D12_BLEND_SRC_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
rt_blend_desc.DestBlend = D3D12_BLEND_INV_SRC_COLOR;
rt_blend_desc.DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
break;
case GLS_DSTBLEND_SRC_ALPHA:
rt_blend_desc.DestBlend = D3D12_BLEND_SRC_ALPHA;
rt_blend_desc.DestBlendAlpha = D3D12_BLEND_SRC_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
rt_blend_desc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
rt_blend_desc.DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
break;
case GLS_DSTBLEND_DST_ALPHA:
rt_blend_desc.DestBlend = D3D12_BLEND_DEST_ALPHA;
rt_blend_desc.DestBlendAlpha = D3D12_BLEND_DEST_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
rt_blend_desc.DestBlend = D3D12_BLEND_INV_DEST_ALPHA;
rt_blend_desc.DestBlendAlpha = D3D12_BLEND_INV_DEST_ALPHA;
break;
default:
ri.Error( ERR_DROP, "create_pipeline: invalid dst blend state bits\n" );
break;
}
}
rt_blend_desc.BlendOp = D3D12_BLEND_OP_ADD;
rt_blend_desc.BlendOpAlpha = D3D12_BLEND_OP_ADD;
rt_blend_desc.LogicOp = D3D12_LOGIC_OP_COPY;
rt_blend_desc.RenderTargetWriteMask = (def.shadow_phase == Vk_Shadow_Phase::shadow_edges_rendering) ? 0 : D3D12_COLOR_WRITE_ENABLE_ALL;
//
// Depth/stencil.
//
auto& depth_stencil_state = pipeline_desc.DepthStencilState;
depth_stencil_state.DepthEnable = (def.state_bits & GLS_DEPTHTEST_DISABLE) ? FALSE : TRUE;
depth_stencil_state.DepthWriteMask = (def.state_bits & GLS_DEPTHMASK_TRUE) ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
depth_stencil_state.DepthFunc = (def.state_bits & GLS_DEPTHFUNC_EQUAL) ? D3D12_COMPARISON_FUNC_EQUAL : D3D12_COMPARISON_FUNC_LESS_EQUAL;
depth_stencil_state.StencilEnable = (def.shadow_phase != Vk_Shadow_Phase::disabled) ? TRUE : FALSE;
pipeline_desc.SampleMask = UINT_MAX;
pipeline_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
pipeline_desc.NumRenderTargets = 1;
pipeline_desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
pipeline_desc.SampleDesc.Count = 1;
ID3D12PipelineState* pipeline_state;
DX_CHECK(dx.device->CreateGraphicsPipelineState(&pipeline_desc, IID_PPV_ARGS(&pipeline_state)));
return pipeline_state;
}
struct Timer {
using Clock = std::chrono::high_resolution_clock;
using Second = std::chrono::duration<double, std::ratio<1>>;
Clock::time_point start = Clock::now();
double elapsed_seconds() const {
const auto duration = Clock::now() - start;
double seconds = std::chrono::duration_cast<Second>(duration).count();
return seconds;
}
};
ID3D12PipelineState* dx_find_pipeline(const Vk_Pipeline_Def& def) {
return dx.pipeline_state;
for (int i = 0; i < dx_world.num_pipelines; i++) {
const auto& cur_def = dx_world.pipeline_defs[i];
if (cur_def.shader_type == def.shader_type &&
cur_def.state_bits == def.state_bits &&
cur_def.face_culling == def.face_culling &&
cur_def.polygon_offset == def.polygon_offset &&
cur_def.clipping_plane == def.clipping_plane &&
cur_def.mirror == def.mirror &&
cur_def.line_primitives == def.line_primitives &&
cur_def.shadow_phase == def.shadow_phase)
{
return dx_world.pipelines[i];
}
}
if (dx_world.num_pipelines >= MAX_VK_PIPELINES) {
ri.Error(ERR_DROP, "dx_find_pipeline: MAX_VK_PIPELINES hit\n");
}
Timer t;
ID3D12PipelineState* pipeline_state = create_pipeline(def);
dx_world.pipeline_create_time += t.elapsed_seconds();
dx_world.pipeline_defs[dx_world.num_pipelines] = def;
dx_world.pipelines[dx_world.num_pipelines] = pipeline_state;
dx_world.num_pipelines++;
return pipeline_state;
}
static void get_mvp_transform(float* mvp) {

View File

@ -84,6 +84,11 @@ struct Dx_World {
//
// Resources.
//
int num_pipelines = 0;
Vk_Pipeline_Def pipeline_defs[MAX_VK_PIPELINES];
ID3D12PipelineState* pipelines[MAX_VK_PIPELINES];
float pipeline_create_time;
Dx_Image images[MAX_VK_IMAGES];
//