diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 19b5cb471..fe1cf17f5 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -168,7 +168,7 @@ void EditorComponent::ResizeBuffers() desc.Width = wiRenderer::GetInternalResolution().x; desc.Height = wiRenderer::GetInternalResolution().y; - desc.Format = wiRenderer::GetDevice()->GetBackBufferFormat(); // todo: smaller format, but then somehow need to specify custom rt format for wiImage PSO! + desc.Format = FORMAT_R8_UNORM; desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE; if (renderPath->getMSAASampleCount() > 1) { diff --git a/Editor/Translator.cpp b/Editor/Translator.cpp index 936ff0a49..6c00d5b5b 100644 --- a/Editor/Translator.cpp +++ b/Editor/Translator.cpp @@ -32,8 +32,6 @@ void Translator::LoadShaders() desc.rs = wiRenderer::GetRasterizerState(RSTYPE_DOUBLESIDED); desc.bs = wiRenderer::GetBlendState(BSTYPE_ADDITIVE); desc.pt = TRIANGLELIST; - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::GetDevice()->GetBackBufferFormat(); device->CreatePipelineState(&desc, &pso_solidpart); } @@ -48,8 +46,6 @@ void Translator::LoadShaders() desc.rs = wiRenderer::GetRasterizerState(RSTYPE_WIRE_DOUBLESIDED_SMOOTH); desc.bs = wiRenderer::GetBlendState(BSTYPE_TRANSPARENT); desc.pt = LINELIST; - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::GetDevice()->GetBackBufferFormat(); device->CreatePipelineState(&desc, &pso_wirepart); } diff --git a/WickedEngine/RenderPath3D.cpp b/WickedEngine/RenderPath3D.cpp index dbcc274f1..2bc65991a 100644 --- a/WickedEngine/RenderPath3D.cpp +++ b/WickedEngine/RenderPath3D.cpp @@ -226,7 +226,7 @@ void RenderPath3D::ResizeBuffers() { TextureDesc desc; desc.BindFlags = BIND_DEPTH_STENCIL; - desc.Format = wiRenderer::DSFormat_full; + desc.Format = wiRenderer::DSFormat_small; desc.Width = wiRenderer::GetInternalResolution().x / 4; desc.Height = wiRenderer::GetInternalResolution().y / 4; desc.layout = IMAGE_LAYOUT_DEPTHSTENCIL; @@ -580,10 +580,6 @@ void RenderPath3D::RenderTransparents(const RenderPass& renderpass_transparent, wiImageParams fx; fx.enableFullScreen(); - fx.enableHDR(); - - // Note set a stencilmode that always passes, because pipeline state with depthbuffer will be used in this render pass (shuts up warnings): - fx.stencilComp = STENCILMODE_ALWAYS; if (getVolumeLightsEnabled()) { @@ -668,7 +664,6 @@ void RenderPath3D::RenderBloom(const RenderPass& renderpass_bloom, CommandList c device->BindViewports(1, &vp, cmd); wiImageParams fx; - fx.enableHDR(); fx.enableFullScreen(); fx.blendFlag = BLENDMODE_ADDITIVE; diff --git a/WickedEngine/ShaderInterop_FFTGenerator.h b/WickedEngine/ShaderInterop_FFTGenerator.h index 883be945f..89a62e06b 100644 --- a/WickedEngine/ShaderInterop_FFTGenerator.h +++ b/WickedEngine/ShaderInterop_FFTGenerator.h @@ -2,6 +2,8 @@ #define WI_SHADERINTEROP_FFTGENERATOR_H #include "ShaderInterop.h" +#define COHERENCY_GRANULARITY 128 + CBUFFER(FFTGeneratorCB, CBSLOT_OTHER_FFTGENERATOR) { uint thread_count; diff --git a/WickedEngine/fft_512x512_c2c_CS.hlsl b/WickedEngine/fft_512x512_c2c_CS.hlsl index 338bb5de4..c873620a5 100644 --- a/WickedEngine/fft_512x512_c2c_CS.hlsl +++ b/WickedEngine/fft_512x512_c2c_CS.hlsl @@ -3,9 +3,6 @@ #define COS_PI_4_16 0.70710678118654752440084436210485f #define TWIDDLE_1_8 COS_PI_4_16, -COS_PI_4_16 #define TWIDDLE_3_8 -COS_PI_4_16, -COS_PI_4_16 - -#define COHERENCY_GRANULARITY 128 - void FT2(inout float2 a, inout float2 b) { diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index e3322e0ab..0ec30eb58 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -648,9 +648,6 @@ void wiEmittedParticle::LoadShaders() desc.bs = &blendStates[i]; desc.rs = &rasterizerState; desc.dss = &depthStencilState; - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::RTFormat_hdr; - desc.DSFormat = wiRenderer::DSFormat_full; desc.ps = pixelShader[SOFT]; device->CreatePipelineState(&desc, &PSO[i][SOFT]); @@ -667,9 +664,6 @@ void wiEmittedParticle::LoadShaders() desc.bs = &blendStates[BLENDMODE_ALPHA]; desc.rs = &wireFrameRS; desc.dss = &depthStencilState; - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::RTFormat_hdr; - desc.DSFormat = wiRenderer::DSFormat_full; device->CreatePipelineState(&desc, &PSO_wire); } diff --git a/WickedEngine/wiFFTGenerator.cpp b/WickedEngine/wiFFTGenerator.cpp index 787e522f6..153d09d50 100644 --- a/WickedEngine/wiFFTGenerator.cpp +++ b/WickedEngine/wiFFTGenerator.cpp @@ -9,192 +9,203 @@ using namespace wiGraphics; -static const ComputeShader* pRadix008A_CS = nullptr; -static const ComputeShader* pRadix008A_CS2 = nullptr; - -void radix008A( - const CSFFT512x512_Plan& fft_plan, - const GPUResource& pUAV_Dst, - const GPUResource& pSRV_Src, - UINT thread_count, - UINT istride, - CommandList cmd) +namespace wiFFTGenerator { - // Setup execution configuration - UINT grid = thread_count / COHERENCY_GRANULARITY; - GraphicsDevice* device = wiRenderer::GetDevice(); + static const ComputeShader* pRadix008A_CS = nullptr; + static const ComputeShader* pRadix008A_CS2 = nullptr; - // Buffers - const GPUResource* srvs[1] = { &pSRV_Src }; - device->BindResources(CS, srvs, TEXSLOT_ONDEMAND0, 1, cmd); +#define TWO_PI 6.283185307179586476925286766559 - const GPUResource* uavs[1] = { &pUAV_Dst }; - device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), cmd); +#define FFT_DIMENSIONS 3U +#define FFT_PLAN_SIZE_LIMIT (1U << 27) - // Shader - if (istride > 1) +#define FFT_FORWARD -1 +#define FFT_INVERSE 1 + + void radix008A( + const CSFFT512x512_Plan& fft_plan, + const GPUResource& pUAV_Dst, + const GPUResource& pSRV_Src, + UINT thread_count, + UINT istride, + CommandList cmd) { - device->BindComputeShader(pRadix008A_CS, cmd); - } - else - { - device->BindComputeShader(pRadix008A_CS2, cmd); + // Setup execution configuration + UINT grid = thread_count / COHERENCY_GRANULARITY; + + GraphicsDevice* device = wiRenderer::GetDevice(); + + // Buffers + const GPUResource* srvs[1] = { &pSRV_Src }; + device->BindResources(CS, srvs, TEXSLOT_ONDEMAND0, 1, cmd); + + const GPUResource* uavs[1] = { &pUAV_Dst }; + device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), cmd); + + // Shader + if (istride > 1) + { + device->BindComputeShader(pRadix008A_CS, cmd); + } + else + { + device->BindComputeShader(pRadix008A_CS2, cmd); + } + + // Execute + device->Dispatch(grid, 1, 1, cmd); + device->Barrier(&GPUBarrier::Memory(), 1, cmd); + + // Unbind resource + device->UnbindResources(TEXSLOT_ONDEMAND0, 1, cmd); + device->UnbindUAVs(0, 1, cmd); } - // Execute - device->Dispatch(grid, 1, 1, cmd); - device->Barrier(&GPUBarrier::Memory(), 1, cmd); + void fft_512x512_c2c( + const CSFFT512x512_Plan& fft_plan, + const GPUResource& pUAV_Dst, + const GPUResource& pSRV_Dst, + const GPUResource& pSRV_Src, + CommandList cmd) + { + const UINT thread_count = fft_plan.slices * (512 * 512) / 8; + GraphicsDevice* device = wiRenderer::GetDevice(); + const GPUBuffer* cs_cbs; + + UINT istride = 512 * 512 / 8; + cs_cbs = &fft_plan.pRadix008A_CB[0]; + device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); + radix008A(fft_plan, fft_plan.pBuffer_Tmp, pSRV_Src, thread_count, istride, cmd); + + istride /= 8; + cs_cbs = &fft_plan.pRadix008A_CB[1]; + device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); + radix008A(fft_plan, pUAV_Dst, fft_plan.pBuffer_Tmp, thread_count, istride, cmd); + + istride /= 8; + cs_cbs = &fft_plan.pRadix008A_CB[2]; + device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); + radix008A(fft_plan, fft_plan.pBuffer_Tmp, pSRV_Dst, thread_count, istride, cmd); + + istride /= 8; + cs_cbs = &fft_plan.pRadix008A_CB[3]; + device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); + radix008A(fft_plan, pUAV_Dst, fft_plan.pBuffer_Tmp, thread_count, istride, cmd); + + istride /= 8; + cs_cbs = &fft_plan.pRadix008A_CB[4]; + device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); + radix008A(fft_plan, fft_plan.pBuffer_Tmp, pSRV_Dst, thread_count, istride, cmd); + + istride /= 8; + cs_cbs = &fft_plan.pRadix008A_CB[5]; + device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); + radix008A(fft_plan, pUAV_Dst, fft_plan.pBuffer_Tmp, thread_count, istride, cmd); + } + + void create_cbuffers_512x512(CSFFT512x512_Plan& plan, GraphicsDevice* device, UINT slices) + { + // Create 6 cbuffers for 512x512 transform. + + GPUBufferDesc cb_desc; + cb_desc.Usage = USAGE_IMMUTABLE; + cb_desc.BindFlags = BIND_CONSTANT_BUFFER; + cb_desc.CPUAccessFlags = 0; + cb_desc.MiscFlags = 0; + cb_desc.ByteWidth = sizeof(FFTGeneratorCB); + cb_desc.StructureByteStride = 0; + + SubresourceData cb_data; + cb_data.SysMemPitch = 0; + cb_data.SysMemSlicePitch = 0; + + // Buffer 0 + const UINT thread_count = slices * (512 * 512) / 8; + UINT ostride = 512 * 512 / 8; + UINT istride = ostride; + double phase_base = -TWO_PI / (512.0 * 512.0); + + FFTGeneratorCB cb_data_buf0 = { thread_count, ostride, istride, 512, (float)phase_base }; + cb_data.pSysMem = &cb_data_buf0; + + device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[0]); + + // Buffer 1 + istride /= 8; + phase_base *= 8.0; + + FFTGeneratorCB cb_data_buf1 = { thread_count, ostride, istride, 512, (float)phase_base }; + cb_data.pSysMem = &cb_data_buf1; + + device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[1]); + + // Buffer 2 + istride /= 8; + phase_base *= 8.0; + + FFTGeneratorCB cb_data_buf2 = { thread_count, ostride, istride, 512, (float)phase_base }; + cb_data.pSysMem = &cb_data_buf2; + + device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[2]); + + // Buffer 3 + istride /= 8; + phase_base *= 8.0; + ostride /= 512; + + FFTGeneratorCB cb_data_buf3 = { thread_count, ostride, istride, 1, (float)phase_base }; + cb_data.pSysMem = &cb_data_buf3; + + device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[3]); + + // Buffer 4 + istride /= 8; + phase_base *= 8.0; + + FFTGeneratorCB cb_data_buf4 = { thread_count, ostride, istride, 1, (float)phase_base }; + cb_data.pSysMem = &cb_data_buf4; + + device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[4]); + + // Buffer 5 + istride /= 8; + phase_base *= 8.0; + + FFTGeneratorCB cb_data_buf5 = { thread_count, ostride, istride, 1, (float)phase_base }; + cb_data.pSysMem = &cb_data_buf5; + + device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[5]); + } + + void fft512x512_create_plan(CSFFT512x512_Plan& plan, UINT slices) + { + GraphicsDevice* device = wiRenderer::GetDevice(); + + plan.slices = slices; + + // Constants + // Create 6 cbuffers for 512x512 transform + create_cbuffers_512x512(plan, device, slices); + + // Temp buffer + GPUBufferDesc buf_desc; + buf_desc.ByteWidth = sizeof(float) * 2 * (512 * slices) * 512; + buf_desc.Usage = USAGE_DEFAULT; + buf_desc.BindFlags = BIND_UNORDERED_ACCESS | BIND_SHADER_RESOURCE; + buf_desc.CPUAccessFlags = 0; + buf_desc.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED; + buf_desc.StructureByteStride = sizeof(float) * 2; + + device->CreateBuffer(&buf_desc, nullptr, &plan.pBuffer_Tmp); + } + + void LoadShaders() + { + std::string path = wiRenderer::GetShaderPath(); + + pRadix008A_CS = static_cast(wiResourceManager::GetShaderManager().add(path + "fft_512x512_c2c_CS.cso", wiResourceManager::COMPUTESHADER)); + pRadix008A_CS2 = static_cast(wiResourceManager::GetShaderManager().add(path + "fft_512x512_c2c_v2_CS.cso", wiResourceManager::COMPUTESHADER)); + } - // Unbind resource - device->UnbindResources(TEXSLOT_ONDEMAND0, 1, cmd); - device->UnbindUAVs(0, 1, cmd); -} - -void fft_512x512_c2c( - const CSFFT512x512_Plan& fft_plan, - const GPUResource& pUAV_Dst, - const GPUResource& pSRV_Dst, - const GPUResource& pSRV_Src, - CommandList cmd) -{ - const UINT thread_count = fft_plan.slices * (512 * 512) / 8; - GraphicsDevice* device = wiRenderer::GetDevice(); - const GPUBuffer* cs_cbs; - - UINT istride = 512 * 512 / 8; - cs_cbs = &fft_plan.pRadix008A_CB[0]; - device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); - radix008A(fft_plan, fft_plan.pBuffer_Tmp, pSRV_Src, thread_count, istride, cmd); - - istride /= 8; - cs_cbs = &fft_plan.pRadix008A_CB[1]; - device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); - radix008A(fft_plan, pUAV_Dst, fft_plan.pBuffer_Tmp, thread_count, istride, cmd); - - istride /= 8; - cs_cbs = &fft_plan.pRadix008A_CB[2]; - device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); - radix008A(fft_plan, fft_plan.pBuffer_Tmp, pSRV_Dst, thread_count, istride, cmd); - - istride /= 8; - cs_cbs = &fft_plan.pRadix008A_CB[3]; - device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); - radix008A(fft_plan, pUAV_Dst, fft_plan.pBuffer_Tmp, thread_count, istride, cmd); - - istride /= 8; - cs_cbs = &fft_plan.pRadix008A_CB[4]; - device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); - radix008A(fft_plan, fft_plan.pBuffer_Tmp, pSRV_Dst, thread_count, istride, cmd); - - istride /= 8; - cs_cbs = &fft_plan.pRadix008A_CB[5]; - device->BindConstantBuffer(CS, cs_cbs, CB_GETBINDSLOT(FFTGeneratorCB), cmd); - radix008A(fft_plan, pUAV_Dst, fft_plan.pBuffer_Tmp, thread_count, istride, cmd); -} - -void create_cbuffers_512x512(CSFFT512x512_Plan& plan, GraphicsDevice* device, UINT slices) -{ - // Create 6 cbuffers for 512x512 transform. - - GPUBufferDesc cb_desc; - cb_desc.Usage = USAGE_IMMUTABLE; - cb_desc.BindFlags = BIND_CONSTANT_BUFFER; - cb_desc.CPUAccessFlags = 0; - cb_desc.MiscFlags = 0; - cb_desc.ByteWidth = sizeof(FFTGeneratorCB); - cb_desc.StructureByteStride = 0; - - SubresourceData cb_data; - cb_data.SysMemPitch = 0; - cb_data.SysMemSlicePitch = 0; - - // Buffer 0 - const UINT thread_count = slices * (512 * 512) / 8; - UINT ostride = 512 * 512 / 8; - UINT istride = ostride; - double phase_base = -TWO_PI / (512.0 * 512.0); - - FFTGeneratorCB cb_data_buf0 = { thread_count, ostride, istride, 512, (float)phase_base }; - cb_data.pSysMem = &cb_data_buf0; - - device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[0]); - - // Buffer 1 - istride /= 8; - phase_base *= 8.0; - - FFTGeneratorCB cb_data_buf1 = { thread_count, ostride, istride, 512, (float)phase_base }; - cb_data.pSysMem = &cb_data_buf1; - - device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[1]); - - // Buffer 2 - istride /= 8; - phase_base *= 8.0; - - FFTGeneratorCB cb_data_buf2 = { thread_count, ostride, istride, 512, (float)phase_base }; - cb_data.pSysMem = &cb_data_buf2; - - device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[2]); - - // Buffer 3 - istride /= 8; - phase_base *= 8.0; - ostride /= 512; - - FFTGeneratorCB cb_data_buf3 = { thread_count, ostride, istride, 1, (float)phase_base }; - cb_data.pSysMem = &cb_data_buf3; - - device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[3]); - - // Buffer 4 - istride /= 8; - phase_base *= 8.0; - - FFTGeneratorCB cb_data_buf4 = { thread_count, ostride, istride, 1, (float)phase_base }; - cb_data.pSysMem = &cb_data_buf4; - - device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[4]); - - // Buffer 5 - istride /= 8; - phase_base *= 8.0; - - FFTGeneratorCB cb_data_buf5 = { thread_count, ostride, istride, 1, (float)phase_base }; - cb_data.pSysMem = &cb_data_buf5; - - device->CreateBuffer(&cb_desc, &cb_data, &plan.pRadix008A_CB[5]); -} - -void fft512x512_create_plan(CSFFT512x512_Plan& plan, UINT slices) -{ - GraphicsDevice* device = wiRenderer::GetDevice(); - - plan.slices = slices; - - // Constants - // Create 6 cbuffers for 512x512 transform - create_cbuffers_512x512(plan, device, slices); - - // Temp buffer - GPUBufferDesc buf_desc; - buf_desc.ByteWidth = sizeof(float) * 2 * (512 * slices) * 512; - buf_desc.Usage = USAGE_DEFAULT; - buf_desc.BindFlags = BIND_UNORDERED_ACCESS | BIND_SHADER_RESOURCE; - buf_desc.CPUAccessFlags = 0; - buf_desc.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED; - buf_desc.StructureByteStride = sizeof(float) * 2; - - device->CreateBuffer(&buf_desc, nullptr, &plan.pBuffer_Tmp); -} - - - -void CSFFT_512x512_Data_t::LoadShaders() -{ - std::string path = wiRenderer::GetShaderPath(); - - pRadix008A_CS = static_cast(wiResourceManager::GetShaderManager().add(path+ "fft_512x512_c2c_CS.cso", wiResourceManager::COMPUTESHADER)); - pRadix008A_CS2 = static_cast(wiResourceManager::GetShaderManager().add(path + "fft_512x512_c2c_v2_CS.cso", wiResourceManager::COMPUTESHADER)); } diff --git a/WickedEngine/wiFFTGenerator.h b/WickedEngine/wiFFTGenerator.h index 0192d9855..6401d563e 100644 --- a/WickedEngine/wiFFTGenerator.h +++ b/WickedEngine/wiFFTGenerator.h @@ -2,46 +2,29 @@ #include "CommonInclude.h" #include "wiGraphicsDevice.h" - -//Memory access coherency (in threads) -#define COHERENCY_GRANULARITY 128 - - -/////////////////////////////////////////////////////////////////////////////// -// Common types -/////////////////////////////////////////////////////////////////////////////// - -typedef struct CSFFT_512x512_Data_t +namespace wiFFTGenerator { - // More than one array can be transformed at same time - UINT slices; - // For 512x512 config, we need 6 constant buffers - wiGraphics::GPUBuffer pRadix008A_CB[6]; + struct CSFFT512x512_Plan + { + // More than one array can be transformed at same time + UINT slices; - wiGraphics::GPUBuffer pBuffer_Tmp; + // For 512x512 config, we need 6 constant buffers + wiGraphics::GPUBuffer pRadix008A_CB[6]; - static void LoadShaders(); -} CSFFT512x512_Plan; - -//////////////////////////////////////////////////////////////////////////////// -// Common constants -//////////////////////////////////////////////////////////////////////////////// -#define TWO_PI 6.283185307179586476925286766559 - -#define FFT_DIMENSIONS 3U -#define FFT_PLAN_SIZE_LIMIT (1U << 27) - -#define FFT_FORWARD -1 -#define FFT_INVERSE 1 + wiGraphics::GPUBuffer pBuffer_Tmp; + }; -void fft512x512_create_plan(CSFFT512x512_Plan& plan, UINT slices); + void fft512x512_create_plan(CSFFT512x512_Plan& plan, UINT slices); -void fft_512x512_c2c( - const CSFFT512x512_Plan& fft_plan, - const wiGraphics::GPUResource& pUAV_Dst, - const wiGraphics::GPUResource& pSRV_Dst, - const wiGraphics::GPUResource& pSRV_Src, - wiGraphics::CommandList cmd); + void fft_512x512_c2c( + const CSFFT512x512_Plan& fft_plan, + const wiGraphics::GPUResource& pUAV_Dst, + const wiGraphics::GPUResource& pSRV_Dst, + const wiGraphics::GPUResource& pSRV_Src, + wiGraphics::CommandList cmd); + void LoadShaders(); +} diff --git a/WickedEngine/wiFont.cpp b/WickedEngine/wiFont.cpp index 31935df95..12eadf463 100644 --- a/WickedEngine/wiFont.cpp +++ b/WickedEngine/wiFont.cpp @@ -34,7 +34,6 @@ namespace wiFont_Internal GPUBuffer constantBuffer; BlendState blendState; RasterizerState rasterizerState; - DepthStencilState depthStencilState; Sampler sampler; VertexLayout vertexLayout; @@ -252,11 +251,6 @@ void wiFont::Initialize() rs.AntialiasedLineEnable = false; device->CreateRasterizerState(&rs, &rasterizerState); - DepthStencilStateDesc dsd; - dsd.DepthEnable = false; - dsd.StencilEnable = false; - device->CreateDepthStencilState(&dsd, &depthStencilState); - BlendStateDesc bd; bd.RenderTarget[0].BlendEnable = true; bd.RenderTarget[0].SrcBlend = BLEND_ONE; @@ -322,9 +316,6 @@ void wiFont::LoadShaders() desc.il = &vertexLayout; desc.bs = &blendState; desc.rs = &rasterizerState; - desc.dss = &depthStencilState; - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::GetDevice()->GetBackBufferFormat(); wiRenderer::GetDevice()->CreatePipelineState(&desc, &PSO); } diff --git a/WickedEngine/wiGraphicsDescriptors.h b/WickedEngine/wiGraphicsDescriptors.h index 5b49b18cf..a9b45eaa0 100644 --- a/WickedEngine/wiGraphicsDescriptors.h +++ b/WickedEngine/wiGraphicsDescriptors.h @@ -471,10 +471,6 @@ namespace wiGraphics const DepthStencilState* dss = nullptr; const VertexLayout* il = nullptr; PRIMITIVETOPOLOGY pt = TRIANGLELIST; - UINT numRTs = 0; - FORMAT RTFormats[8] = {}; - FORMAT DSFormat = FORMAT_UNKNOWN; - SampleDesc sampleDesc; UINT sampleMask = 0xFFFFFFFF; }; struct GPUBarrier diff --git a/WickedEngine/wiGraphicsDevice.h b/WickedEngine/wiGraphicsDevice.h index 145d5cb35..361256738 100644 --- a/WickedEngine/wiGraphicsDevice.h +++ b/WickedEngine/wiGraphicsDevice.h @@ -81,6 +81,7 @@ namespace wiGraphics virtual CommandList BeginCommandList() = 0; virtual void WaitForGPU() = 0; + virtual void ClearPipelineStateCache() {}; inline bool GetVSyncEnabled() const { return VSYNC; } inline void SetVSyncEnabled(bool value) { VSYNC = value; } diff --git a/WickedEngine/wiGraphicsDevice_DX12.cpp b/WickedEngine/wiGraphicsDevice_DX12.cpp index 9113078be..62cc59662 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.cpp +++ b/WickedEngine/wiGraphicsDevice_DX12.cpp @@ -2206,6 +2206,7 @@ namespace wiGraphics DestroyInputLayout(pInputLayout); pInputLayout->Register(this); + pInputLayout->desc.clear(); pInputLayout->desc.reserve((size_t)NumElements); for (UINT i = 0; i < NumElements; ++i) { @@ -2358,6 +2359,19 @@ namespace wiGraphics pso->desc = *pDesc; + pso->hash = 0; + wiHelper::hash_combine(pso->hash, pDesc->vs); + wiHelper::hash_combine(pso->hash, pDesc->ps); + wiHelper::hash_combine(pso->hash, pDesc->hs); + wiHelper::hash_combine(pso->hash, pDesc->ds); + wiHelper::hash_combine(pso->hash, pDesc->gs); + wiHelper::hash_combine(pso->hash, pDesc->il); + wiHelper::hash_combine(pso->hash, pDesc->rs); + wiHelper::hash_combine(pso->hash, pDesc->bs); + wiHelper::hash_combine(pso->hash, pDesc->dss); + wiHelper::hash_combine(pso->hash, pDesc->pt); + wiHelper::hash_combine(pso->hash, pDesc->sampleMask); + return S_OK; } HRESULT GraphicsDevice_DX12::CreateRenderPass(const RenderPassDesc* pDesc, RenderPass* renderpass) @@ -2367,6 +2381,15 @@ namespace wiGraphics renderpass->desc = *pDesc; + renderpass->hash = 0; + wiHelper::hash_combine(renderpass->hash, pDesc->numAttachments); + for (UINT i = 0; i < pDesc->numAttachments; ++i) + { + wiHelper::hash_combine(renderpass->hash, pDesc->attachments[i].texture->desc.Format); + wiHelper::hash_combine(renderpass->hash, pDesc->attachments[i].texture->desc.SampleDesc.Count); + wiHelper::hash_combine(renderpass->hash, pDesc->attachments[i].texture->desc.SampleDesc.Quality); + } + return S_OK; } @@ -2858,11 +2881,7 @@ namespace wiGraphics } void GraphicsDevice_DX12::DestroyPipelineState(PipelineState* pso) { - if (pso->pipeline != WI_NULL_HANDLE) - { - DeferredDestroy({ DestroyItem::PIPELINE, FRAMECOUNT, pso->pipeline }); - pso->pipeline = WI_NULL_HANDLE; - } + pso->hash = 0; } void GraphicsDevice_DX12::DestroyRenderPass(RenderPass* renderpass) { @@ -2970,6 +2989,19 @@ namespace wiGraphics counter++; free_commandlists.push_back(cmd); + + for (auto& x : pipelines_worker[cmd]) + { + if (pipelines_global.count(x.first) == 0) + { + pipelines_global[x.first] = x.second; + } + else + { + DeferredDestroy({ DestroyItem::PIPELINE, FRAMECOUNT, (wiCPUHandle)x.second }); + } + } + pipelines_worker[cmd].clear(); } directQueue->ExecuteCommandLists(counter, cmdLists); @@ -3095,11 +3127,6 @@ namespace wiGraphics } GetDirectCommandList((CommandList)cmd)->RSSetScissorRects(8, pRects); - for (auto& x : pipelines_worker[cmd]) - { - pipelines_global[x.first] = x.second; - } - pipelines_worker[cmd].clear(); prev_pipeline_hash[cmd] = 0; active_renderpass[cmd] = nullptr; @@ -3115,7 +3142,23 @@ namespace wiGraphics WaitForSingleObject(frameFenceEvent, INFINITE); } } + void GraphicsDevice_DX12::ClearPipelineStateCache() + { + for (auto& x : pipelines_global) + { + DeferredDestroy({ DestroyItem::PIPELINE, FRAMECOUNT, (wiCPUHandle)x.second }); + } + pipelines_global.clear(); + for (int i = 0; i < ARRAYSIZE(pipelines_worker); ++i) + { + for (auto& x : pipelines_worker[i]) + { + DeferredDestroy({ DestroyItem::PIPELINE, FRAMECOUNT, (wiCPUHandle)x.second }); + } + pipelines_worker[i].clear(); + } + } void GraphicsDevice_DX12::RenderPassBegin(const RenderPass* renderpass, CommandList cmd) { @@ -3464,8 +3507,11 @@ namespace wiGraphics void GraphicsDevice_DX12::BindPipelineState(const PipelineState* pso, CommandList cmd) { size_t pipeline_hash = 0; - wiHelper::hash_combine(pipeline_hash, size_t(pso)); - wiHelper::hash_combine(pipeline_hash, size_t(active_renderpass[cmd])); + wiHelper::hash_combine(pipeline_hash, pso->hash); + if (active_renderpass[cmd] != nullptr) + { + wiHelper::hash_combine(pipeline_hash, active_renderpass[cmd]->hash); + } if (prev_pipeline_hash[cmd] == pipeline_hash) { return; @@ -3581,15 +3627,73 @@ namespace wiGraphics } desc.InputLayout.pInputElementDescs = elements; - desc.NumRenderTargets = pso->desc.numRTs; - for (UINT i = 0; i < desc.NumRenderTargets; ++i) + desc.NumRenderTargets = 0; + desc.DSVFormat = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + if (active_renderpass[cmd] == nullptr) { - desc.RTVFormats[i] = _ConvertFormat(pso->desc.RTFormats[i]); + desc.NumRenderTargets = 1; + desc.RTVFormats[0] = _ConvertFormat(BACKBUFFER_FORMAT); } - desc.DSVFormat = _ConvertFormat(pso->desc.DSFormat); + else + { + for (UINT i = 0; i < active_renderpass[cmd]->desc.numAttachments; ++i) + { + const RenderPassAttachment& attachment = active_renderpass[cmd]->desc.attachments[i]; - desc.SampleDesc.Count = pso->desc.sampleDesc.Count; - desc.SampleDesc.Quality = pso->desc.sampleDesc.Quality; + switch (attachment.type) + { + case RenderPassAttachment::RENDERTARGET: + switch (attachment.texture->desc.Format) + { + case FORMAT_R16_TYPELESS: + desc.RTVFormats[desc.NumRenderTargets] = DXGI_FORMAT_R16_UNORM; + break; + case FORMAT_R32_TYPELESS: + desc.RTVFormats[desc.NumRenderTargets] = DXGI_FORMAT_R32_FLOAT; + break; + case FORMAT_R24G8_TYPELESS: + desc.RTVFormats[desc.NumRenderTargets] = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + break; + case FORMAT_R32G8X24_TYPELESS: + desc.RTVFormats[desc.NumRenderTargets] = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + break; + default: + desc.RTVFormats[desc.NumRenderTargets] = _ConvertFormat(attachment.texture->desc.Format); + break; + } + desc.NumRenderTargets++; + break; + case RenderPassAttachment::DEPTH_STENCIL: + switch (attachment.texture->desc.Format) + { + case FORMAT_R16_TYPELESS: + desc.DSVFormat = DXGI_FORMAT_D16_UNORM; + break; + case FORMAT_R32_TYPELESS: + desc.DSVFormat = DXGI_FORMAT_D32_FLOAT; + break; + case FORMAT_R24G8_TYPELESS: + desc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; + break; + case FORMAT_R32G8X24_TYPELESS: + desc.DSVFormat = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + break; + default: + desc.DSVFormat = _ConvertFormat(attachment.texture->desc.Format); + break; + } + break; + default: + assert(0); + break; + } + + desc.SampleDesc.Count = attachment.texture->desc.SampleDesc.Count; + desc.SampleDesc.Quality = attachment.texture->desc.SampleDesc.Quality; + } + } desc.SampleMask = pso->desc.sampleMask; switch (pso->desc.pt) diff --git a/WickedEngine/wiGraphicsDevice_DX12.h b/WickedEngine/wiGraphicsDevice_DX12.h index 0b6f64759..d30aef1ae 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.h +++ b/WickedEngine/wiGraphicsDevice_DX12.h @@ -268,6 +268,7 @@ namespace wiGraphics virtual CommandList BeginCommandList() override; void WaitForGPU() override; + void ClearPipelineStateCache() override; void SetResolution(int width, int height) override; diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index d470cfddc..e76074d64 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -2709,6 +2709,7 @@ namespace wiGraphics DestroyInputLayout(pInputLayout); pInputLayout->Register(this); + pInputLayout->desc.clear(); pInputLayout->desc.reserve((size_t)NumElements); for (UINT i = 0; i < NumElements; ++i) { @@ -3038,499 +3039,20 @@ namespace wiGraphics pso->desc = *pDesc; - VkResult res; - - std::vector attachments; - std::vector colorAttachmentRefs; - - attachments.reserve(pDesc->numRTs); - colorAttachmentRefs.reserve(pDesc->numRTs); - - // This will be a dummy render pass used for PSO validation: - VkRenderPass renderPass = VK_NULL_HANDLE; - { - uint32_t psoAttachmentCount = pDesc->numRTs + (pDesc->DSFormat == FORMAT_UNKNOWN ? 0 : 1); - - VkAttachmentDescription attachmentDescriptions[9]; - VkAttachmentReference colorAttachmentRefs[9]; - - for (UINT i = 0; i < pDesc->numRTs; ++i) - { - VkAttachmentDescription attachment = {}; - attachment.format = _ConvertFormat(pDesc->RTFormats[i]); - attachment.samples = VK_SAMPLE_COUNT_1_BIT; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; - attachmentDescriptions[i] = attachment; - - VkAttachmentReference ref = {}; - ref.attachment = i; - ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - colorAttachmentRefs[i] = ref; - } - - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = pDesc->numRTs; - subpass.pColorAttachments = colorAttachmentRefs; - - VkAttachmentDescription depthAttachment = {}; - VkAttachmentReference depthAttachmentRef = {}; - if (pDesc->DSFormat != FORMAT_UNKNOWN) - { - depthAttachment.format = _ConvertFormat(pDesc->DSFormat); - depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; - depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - depthAttachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; - attachmentDescriptions[pDesc->numRTs] = depthAttachment; - - depthAttachmentRef.attachment = pDesc->numRTs; - depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - subpass.pDepthStencilAttachment = &depthAttachmentRef; - } - - VkRenderPassCreateInfo renderPassInfo = {}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassInfo.attachmentCount = psoAttachmentCount; - renderPassInfo.pAttachments = attachmentDescriptions; - renderPassInfo.subpassCount = 1; - renderPassInfo.pSubpasses = &subpass; - - res = vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass); - assert(res == VK_SUCCESS); - } - - - - VkGraphicsPipelineCreateInfo pipelineInfo = {}; - pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipelineInfo.layout = defaultPipelineLayout_Graphics; - pipelineInfo.renderPass = renderPass; - pipelineInfo.subpass = 0; - pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; - - - // Shaders: - - std::vector shaderStages; - - if (pDesc->vs != nullptr) - { - VkShaderModuleCreateInfo moduleInfo = {}; - moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleInfo.codeSize = pDesc->vs->code.size; - moduleInfo.pCode = reinterpret_cast(pDesc->vs->code.data); - VkShaderModule shaderModule; - res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); - assert(res == VK_SUCCESS); - - VkPipelineShaderStageCreateInfo stageInfo = {}; - stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; - stageInfo.module = shaderModule; - stageInfo.pName = "main"; - - shaderStages.push_back(stageInfo); - } - - if (pDesc->hs != nullptr) - { - VkShaderModuleCreateInfo moduleInfo = {}; - moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleInfo.codeSize = pDesc->hs->code.size; - moduleInfo.pCode = reinterpret_cast(pDesc->hs->code.data); - VkShaderModule shaderModule; - res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); - assert(res == VK_SUCCESS); - - VkPipelineShaderStageCreateInfo stageInfo = {}; - stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stageInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; - stageInfo.module = shaderModule; - stageInfo.pName = "main"; - - shaderStages.push_back(stageInfo); - } - - if (pDesc->ds != nullptr) - { - VkShaderModuleCreateInfo moduleInfo = {}; - moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleInfo.codeSize = pDesc->ds->code.size; - moduleInfo.pCode = reinterpret_cast(pDesc->ds->code.data); - VkShaderModule shaderModule; - res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); - assert(res == VK_SUCCESS); - - VkPipelineShaderStageCreateInfo stageInfo = {}; - stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stageInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; - stageInfo.module = shaderModule; - stageInfo.pName = "main"; - - shaderStages.push_back(stageInfo); - } - - if (pDesc->gs != nullptr) - { - VkShaderModuleCreateInfo moduleInfo = {}; - moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleInfo.codeSize = pDesc->gs->code.size; - moduleInfo.pCode = reinterpret_cast(pDesc->gs->code.data); - VkShaderModule shaderModule; - res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); - assert(res == VK_SUCCESS); - - VkPipelineShaderStageCreateInfo stageInfo = {}; - stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stageInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - stageInfo.module = shaderModule; - stageInfo.pName = "main"; - - shaderStages.push_back(stageInfo); - } - - if (pDesc->ps != nullptr) - { - VkShaderModuleCreateInfo moduleInfo = {}; - moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleInfo.codeSize = pDesc->ps->code.size; - moduleInfo.pCode = reinterpret_cast(pDesc->ps->code.data); - VkShaderModule shaderModule; - res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); - assert(res == VK_SUCCESS); - - VkPipelineShaderStageCreateInfo stageInfo = {}; - stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - stageInfo.module = shaderModule; - stageInfo.pName = "main"; - - shaderStages.push_back(stageInfo); - } - - pipelineInfo.stageCount = static_cast(shaderStages.size()); - pipelineInfo.pStages = shaderStages.data(); - - - // Fixed function states: - - // Input layout: - VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; - vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - std::vector bindings; - std::vector attributes; - if (pDesc->il != nullptr) - { - uint32_t lastBinding = 0xFFFFFFFF; - for (auto& x : pDesc->il->desc) - { - VkVertexInputBindingDescription bind = {}; - bind.binding = x.InputSlot; - bind.inputRate = x.InputSlotClass == INPUT_PER_VERTEX_DATA ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE; - bind.stride = x.AlignedByteOffset; - if (bind.stride == VertexLayoutDesc::APPEND_ALIGNED_ELEMENT) - { - // need to manually resolve this from the format spec. - bind.stride = GetFormatStride(x.Format); - } - - if (lastBinding != bind.binding) - { - bindings.push_back(bind); - lastBinding = bind.binding; - } - else - { - bindings.back().stride += bind.stride; - } - } - - uint32_t offset = 0; - uint32_t i = 0; - lastBinding = 0xFFFFFFFF; - for (auto& x : pDesc->il->desc) - { - VkVertexInputAttributeDescription attr = {}; - attr.binding = x.InputSlot; - if (attr.binding != lastBinding) - { - lastBinding = attr.binding; - offset = 0; - } - attr.format = _ConvertFormat(x.Format); - attr.location = i; - attr.offset = x.AlignedByteOffset; - if (attr.offset == VertexLayoutDesc::APPEND_ALIGNED_ELEMENT) - { - // need to manually resolve this from the format spec. - attr.offset = offset; - offset += GetFormatStride(x.Format); - } - - attributes.push_back(attr); - - i++; - } - - vertexInputInfo.vertexBindingDescriptionCount = static_cast(bindings.size()); - vertexInputInfo.pVertexBindingDescriptions = bindings.data(); - vertexInputInfo.vertexAttributeDescriptionCount = static_cast(attributes.size()); - vertexInputInfo.pVertexAttributeDescriptions = attributes.data(); - } - pipelineInfo.pVertexInputState = &vertexInputInfo; - - // Primitive type: - VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; - inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - switch (pDesc->pt) - { - case POINTLIST: - inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; - break; - case LINELIST: - inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; - break; - case TRIANGLESTRIP: - inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - break; - case TRIANGLELIST: - inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - break; - case PATCHLIST: - inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; - break; - default: - break; - } - inputAssembly.primitiveRestartEnable = VK_FALSE; - - pipelineInfo.pInputAssemblyState = &inputAssembly; - - - // Rasterizer: - VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizer.depthClampEnable = VK_TRUE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - rasterizer.lineWidth = 1.0f; - rasterizer.cullMode = VK_CULL_MODE_NONE; - rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0.0f; - rasterizer.depthBiasClamp = 0.0f; - rasterizer.depthBiasSlopeFactor = 0.0f; - - // depth clip will be enabled via Vulkan 1.1 extension VK_EXT_depth_clip_enable: - VkPipelineRasterizationDepthClipStateCreateInfoEXT depthclip = {}; - depthclip.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT; - depthclip.depthClipEnable = VK_TRUE; - rasterizer.pNext = &depthclip; - - if (pDesc->rs != nullptr) - { - const RasterizerStateDesc& desc = pDesc->rs->desc; - - switch (desc.FillMode) - { - case FILL_WIREFRAME: - rasterizer.polygonMode = VK_POLYGON_MODE_LINE; - break; - case FILL_SOLID: - default: - rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - break; - } - - switch (desc.CullMode) - { - case CULL_BACK: - rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; - break; - case CULL_FRONT: - rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT; - break; - case CULL_NONE: - default: - rasterizer.cullMode = VK_CULL_MODE_NONE; - break; - } - - rasterizer.frontFace = desc.FrontCounterClockwise ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE; - rasterizer.depthBiasEnable = desc.DepthBias != 0; - rasterizer.depthBiasConstantFactor = static_cast(desc.DepthBias); - rasterizer.depthBiasClamp = desc.DepthBiasClamp; - rasterizer.depthBiasSlopeFactor = desc.SlopeScaledDepthBias; - - // depth clip is extension in Vulkan 1.1: - depthclip.depthClipEnable = desc.DepthClipEnable ? VK_TRUE : VK_FALSE; - } - - pipelineInfo.pRasterizationState = &rasterizer; - - - // Viewport, Scissor: - VkViewport viewport = {}; - viewport.x = 0; - viewport.y = 0; - viewport.width = 65535; - viewport.height = 65535; - viewport.minDepth = 0; - viewport.maxDepth = 1; - - VkRect2D scissor = {}; - scissor.extent.width = 65535; - scissor.extent.height = 65535; - - VkPipelineViewportStateCreateInfo viewportState = {}; - viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewportState.viewportCount = 1; - viewportState.pViewports = &viewport; - viewportState.scissorCount = 1; - viewportState.pScissors = &scissor; - - pipelineInfo.pViewportState = &viewportState; - - - // Depth-Stencil: - VkPipelineDepthStencilStateCreateInfo depthstencil = {}; - depthstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - if (pDesc->dss != nullptr) - { - depthstencil.depthTestEnable = pDesc->dss->desc.DepthEnable ? VK_TRUE : VK_FALSE; - depthstencil.depthWriteEnable = pDesc->dss->desc.DepthWriteMask == DEPTH_WRITE_MASK_ZERO ? VK_FALSE : VK_TRUE; - depthstencil.depthCompareOp = _ConvertComparisonFunc(pDesc->dss->desc.DepthFunc); - - depthstencil.stencilTestEnable = pDesc->dss->desc.StencilEnable ? VK_TRUE : VK_FALSE; - - depthstencil.front.compareMask = pDesc->dss->desc.StencilReadMask; - depthstencil.front.writeMask = pDesc->dss->desc.StencilWriteMask; - depthstencil.front.reference = 0; // runtime supplied - depthstencil.front.compareOp = _ConvertComparisonFunc(pDesc->dss->desc.FrontFace.StencilFunc); - depthstencil.front.passOp = _ConvertStencilOp(pDesc->dss->desc.FrontFace.StencilPassOp); - depthstencil.front.failOp = _ConvertStencilOp(pDesc->dss->desc.FrontFace.StencilFailOp); - depthstencil.front.depthFailOp = _ConvertStencilOp(pDesc->dss->desc.FrontFace.StencilDepthFailOp); - - depthstencil.back.compareMask = pDesc->dss->desc.StencilReadMask; - depthstencil.back.writeMask = pDesc->dss->desc.StencilWriteMask; - depthstencil.back.reference = 0; // runtime supplied - depthstencil.back.compareOp = _ConvertComparisonFunc(pDesc->dss->desc.BackFace.StencilFunc); - depthstencil.back.passOp = _ConvertStencilOp(pDesc->dss->desc.BackFace.StencilPassOp); - depthstencil.back.failOp = _ConvertStencilOp(pDesc->dss->desc.BackFace.StencilFailOp); - depthstencil.back.depthFailOp = _ConvertStencilOp(pDesc->dss->desc.BackFace.StencilDepthFailOp); - - depthstencil.depthBoundsTestEnable = VK_FALSE; - } - - pipelineInfo.pDepthStencilState = &depthstencil; - - - // MSAA: - VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.sampleShadingEnable = VK_FALSE; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampling.minSampleShading = 1.0f; - multisampling.pSampleMask = nullptr; - multisampling.alphaToCoverageEnable = VK_FALSE; - multisampling.alphaToOneEnable = VK_FALSE; - - pipelineInfo.pMultisampleState = &multisampling; - - - // Blending: - std::vector colorBlendAttachments(pDesc->numRTs); - for (size_t i = 0; i < colorBlendAttachments.size(); ++i) - { - RenderTargetBlendStateDesc desc = pDesc->bs != nullptr ? pDesc->bs->desc.RenderTarget[i] : RenderTargetBlendStateDesc(); - - colorBlendAttachments[i].blendEnable = desc.BlendEnable ? VK_TRUE : VK_FALSE; - - colorBlendAttachments[i].colorWriteMask = 0; - if (desc.RenderTargetWriteMask & COLOR_WRITE_ENABLE_RED) - { - colorBlendAttachments[i].colorWriteMask |= VK_COLOR_COMPONENT_R_BIT; - } - if (desc.RenderTargetWriteMask & COLOR_WRITE_ENABLE_GREEN) - { - colorBlendAttachments[i].colorWriteMask |= VK_COLOR_COMPONENT_G_BIT; - } - if (desc.RenderTargetWriteMask & COLOR_WRITE_ENABLE_BLUE) - { - colorBlendAttachments[i].colorWriteMask |= VK_COLOR_COMPONENT_B_BIT; - } - if (desc.RenderTargetWriteMask & COLOR_WRITE_ENABLE_ALPHA) - { - colorBlendAttachments[i].colorWriteMask |= VK_COLOR_COMPONENT_A_BIT; - } - - colorBlendAttachments[i].srcColorBlendFactor = _ConvertBlend(desc.SrcBlend); - colorBlendAttachments[i].dstColorBlendFactor = _ConvertBlend(desc.DestBlend); - colorBlendAttachments[i].colorBlendOp = _ConvertBlendOp(desc.BlendOp); - colorBlendAttachments[i].srcAlphaBlendFactor = _ConvertBlend(desc.SrcBlendAlpha); - colorBlendAttachments[i].dstAlphaBlendFactor = _ConvertBlend(desc.DestBlendAlpha); - colorBlendAttachments[i].alphaBlendOp = _ConvertBlendOp(desc.BlendOpAlpha); - } - - VkPipelineColorBlendStateCreateInfo colorBlending = {}; - colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - colorBlending.logicOpEnable = VK_FALSE; - colorBlending.logicOp = VK_LOGIC_OP_COPY; - colorBlending.attachmentCount = static_cast(colorBlendAttachments.size()); - colorBlending.pAttachments = colorBlendAttachments.data(); - colorBlending.blendConstants[0] = 1.0f; - colorBlending.blendConstants[1] = 1.0f; - colorBlending.blendConstants[2] = 1.0f; - colorBlending.blendConstants[3] = 1.0f; - - pipelineInfo.pColorBlendState = &colorBlending; - - - // Tessellation: - VkPipelineTessellationStateCreateInfo tessellationInfo = {}; - tessellationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; - tessellationInfo.patchControlPoints = 3; - - pipelineInfo.pTessellationState = &tessellationInfo; - - - - - // Dynamic state will be specified at runtime: - VkDynamicState dynamicStates[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_BLEND_CONSTANTS - }; - - VkPipelineDynamicStateCreateInfo dynamicState = {}; - dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicState.dynamicStateCount = ARRAYSIZE(dynamicStates); - dynamicState.pDynamicStates = dynamicStates; - - pipelineInfo.pDynamicState = &dynamicState; - - - res = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, reinterpret_cast(&pso->pipeline)); - assert(res == VK_SUCCESS); - - - // Dummy render pass no longer needed: - vkDestroyRenderPass(device, renderPass, nullptr); - - return res == VK_SUCCESS ? S_OK : E_FAIL; + pso->hash = 0; + wiHelper::hash_combine(pso->hash, pDesc->vs); + wiHelper::hash_combine(pso->hash, pDesc->ps); + wiHelper::hash_combine(pso->hash, pDesc->hs); + wiHelper::hash_combine(pso->hash, pDesc->ds); + wiHelper::hash_combine(pso->hash, pDesc->gs); + wiHelper::hash_combine(pso->hash, pDesc->il); + wiHelper::hash_combine(pso->hash, pDesc->rs); + wiHelper::hash_combine(pso->hash, pDesc->bs); + wiHelper::hash_combine(pso->hash, pDesc->dss); + wiHelper::hash_combine(pso->hash, pDesc->pt); + wiHelper::hash_combine(pso->hash, pDesc->sampleMask); + + return S_OK; } HRESULT GraphicsDevice_Vulkan::CreateRenderPass(const RenderPassDesc* pDesc, RenderPass* renderpass) { @@ -3539,6 +3061,14 @@ namespace wiGraphics renderpass->desc = *pDesc; + renderpass->hash = 0; + wiHelper::hash_combine(renderpass->hash, pDesc->numAttachments); + for (UINT i = 0; i < pDesc->numAttachments; ++i) + { + wiHelper::hash_combine(renderpass->hash, pDesc->attachments[i].texture->desc.Format); + wiHelper::hash_combine(renderpass->hash, pDesc->attachments[i].texture->desc.SampleDesc.Count); + } + VkResult res; VkImageView attachments[9] = {}; @@ -4090,8 +3620,7 @@ namespace wiGraphics } void GraphicsDevice_Vulkan::DestroyPipelineState(PipelineState* pso) { - DeferredDestroy({ DestroyItem::PIPELINE, pso->pipeline }); - pso->pipeline = WI_NULL_HANDLE; + pso->hash = 0; } void GraphicsDevice_Vulkan::DestroyRenderPass(RenderPass* renderpass) { @@ -4218,7 +3747,7 @@ namespace wiGraphics submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &frame.transitionCommandBuffer; - res = vkQueueSubmit(graphicsQueue, 1, &submitInfo, nullptr); + res = vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); assert(res == VK_SUCCESS); } } @@ -4244,6 +3773,19 @@ namespace wiGraphics counter++; free_commandlists.push_back(cmd); + + for (auto& x : pipelines_worker[cmd]) + { + if (pipelines_global.count(x.first) == 0) + { + pipelines_global[x.first] = x.second; + } + else + { + DeferredDestroy({ DestroyItem::PIPELINE, FRAMECOUNT, (wiCPUHandle)x.second }); + } + } + pipelines_worker[cmd].clear(); } VkSubmitInfo submitInfo = {}; @@ -4443,6 +3985,9 @@ namespace wiGraphics // reset immediate resource allocators: GetFrameResources().resourceBuffer[cmd]->clear(); + prev_pipeline_hash[cmd] = 0; + active_renderpass[cmd] = VK_NULL_HANDLE; + active_commandlists.push_back(cmd); return cmd; } @@ -4451,10 +3996,29 @@ namespace wiGraphics { vkQueueWaitIdle(graphicsQueue); } + void GraphicsDevice_Vulkan::ClearPipelineStateCache() + { + for (auto& x : pipelines_global) + { + DeferredDestroy({ DestroyItem::PIPELINE, FRAMECOUNT, (wiCPUHandle)x.second }); + } + pipelines_global.clear(); + + for (int i = 0; i < ARRAYSIZE(pipelines_worker); ++i) + { + for (auto& x : pipelines_worker[i]) + { + DeferredDestroy({ DestroyItem::PIPELINE, FRAMECOUNT, (wiCPUHandle)x.second }); + } + pipelines_worker[i].clear(); + } + } void GraphicsDevice_Vulkan::RenderPassBegin(const RenderPass* renderpass, CommandList cmd) { + active_renderpass[cmd] = renderpass; + VkRenderPassBeginInfo renderPassInfo = {}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.renderPass = (VkRenderPass)renderpass->renderpass; @@ -4500,6 +4064,8 @@ namespace wiGraphics void GraphicsDevice_Vulkan::RenderPassEnd(CommandList cmd) { vkCmdEndRenderPass(GetDirectCommandList(cmd)); + + active_renderpass[cmd] = VK_NULL_HANDLE; } void GraphicsDevice_Vulkan::BindScissorRects(UINT numRects, const Rect* rects, CommandList cmd) { assert(rects != nullptr); @@ -4630,7 +4196,464 @@ namespace wiGraphics } void GraphicsDevice_Vulkan::BindPipelineState(const PipelineState* pso, CommandList cmd) { - vkCmdBindPipeline(GetDirectCommandList(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, (VkPipeline)pso->pipeline); + size_t pipeline_hash = 0; + wiHelper::hash_combine(pipeline_hash, pso->hash); + if (active_renderpass[cmd] != nullptr) + { + wiHelper::hash_combine(pipeline_hash, active_renderpass[cmd]->hash); + } + if (prev_pipeline_hash[cmd] == pipeline_hash) + { + return; + } + prev_pipeline_hash[cmd] = pipeline_hash; + + VkPipeline pipeline = VK_NULL_HANDLE; + auto it = pipelines_global.find(pipeline_hash); + if (it == pipelines_global.end()) + { + for (auto& x : pipelines_worker[cmd]) + { + if (pipeline_hash == x.first) + { + pipeline = x.second; + break; + } + } + + if (pipeline == VK_NULL_HANDLE) + { + VkResult res; + + VkGraphicsPipelineCreateInfo pipelineInfo = {}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineInfo.layout = defaultPipelineLayout_Graphics; + pipelineInfo.renderPass = active_renderpass[cmd] == nullptr ? defaultRenderPass : (VkRenderPass)active_renderpass[cmd]->renderpass; + pipelineInfo.subpass = 0; + pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; + + // Shaders: + + std::vector shaderStages; + + if (pso->desc.vs != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pso->desc.vs->code.size; + moduleInfo.pCode = reinterpret_cast(pso->desc.vs->code.data); + VkShaderModule shaderModule; + res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); + assert(res == VK_SUCCESS); + + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; + + shaderStages.push_back(stageInfo); + } + + if (pso->desc.hs != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pso->desc.hs->code.size; + moduleInfo.pCode = reinterpret_cast(pso->desc.hs->code.data); + VkShaderModule shaderModule; + res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); + assert(res == VK_SUCCESS); + + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; + + shaderStages.push_back(stageInfo); + } + + if (pso->desc.ds != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pso->desc.ds->code.size; + moduleInfo.pCode = reinterpret_cast(pso->desc.ds->code.data); + VkShaderModule shaderModule; + res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); + assert(res == VK_SUCCESS); + + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; + + shaderStages.push_back(stageInfo); + } + + if (pso->desc.gs != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pso->desc.gs->code.size; + moduleInfo.pCode = reinterpret_cast(pso->desc.gs->code.data); + VkShaderModule shaderModule; + res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); + assert(res == VK_SUCCESS); + + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; + + shaderStages.push_back(stageInfo); + } + + if (pso->desc.ps != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pso->desc.ps->code.size; + moduleInfo.pCode = reinterpret_cast(pso->desc.ps->code.data); + VkShaderModule shaderModule; + res = vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule); + assert(res == VK_SUCCESS); + + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; + + shaderStages.push_back(stageInfo); + } + + pipelineInfo.stageCount = static_cast(shaderStages.size()); + pipelineInfo.pStages = shaderStages.data(); + + + // Fixed function states: + + // Input layout: + VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; + vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + std::vector bindings; + std::vector attributes; + if (pso->desc.il != nullptr) + { + uint32_t lastBinding = 0xFFFFFFFF; + for (auto& x : pso->desc.il->desc) + { + VkVertexInputBindingDescription bind = {}; + bind.binding = x.InputSlot; + bind.inputRate = x.InputSlotClass == INPUT_PER_VERTEX_DATA ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE; + bind.stride = x.AlignedByteOffset; + if (bind.stride == VertexLayoutDesc::APPEND_ALIGNED_ELEMENT) + { + // need to manually resolve this from the format spec. + bind.stride = GetFormatStride(x.Format); + } + + if (lastBinding != bind.binding) + { + bindings.push_back(bind); + lastBinding = bind.binding; + } + else + { + bindings.back().stride += bind.stride; + } + } + + uint32_t offset = 0; + uint32_t i = 0; + lastBinding = 0xFFFFFFFF; + for (auto& x : pso->desc.il->desc) + { + VkVertexInputAttributeDescription attr = {}; + attr.binding = x.InputSlot; + if (attr.binding != lastBinding) + { + lastBinding = attr.binding; + offset = 0; + } + attr.format = _ConvertFormat(x.Format); + attr.location = i; + attr.offset = x.AlignedByteOffset; + if (attr.offset == VertexLayoutDesc::APPEND_ALIGNED_ELEMENT) + { + // need to manually resolve this from the format spec. + attr.offset = offset; + offset += GetFormatStride(x.Format); + } + + attributes.push_back(attr); + + i++; + } + + vertexInputInfo.vertexBindingDescriptionCount = static_cast(bindings.size()); + vertexInputInfo.pVertexBindingDescriptions = bindings.data(); + vertexInputInfo.vertexAttributeDescriptionCount = static_cast(attributes.size()); + vertexInputInfo.pVertexAttributeDescriptions = attributes.data(); + } + pipelineInfo.pVertexInputState = &vertexInputInfo; + + // Primitive type: + VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; + inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + switch (pso->desc.pt) + { + case POINTLIST: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + break; + case LINELIST: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + break; + case TRIANGLESTRIP: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + break; + case TRIANGLELIST: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + break; + case PATCHLIST: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; + break; + default: + break; + } + inputAssembly.primitiveRestartEnable = VK_FALSE; + + pipelineInfo.pInputAssemblyState = &inputAssembly; + + + // Rasterizer: + VkPipelineRasterizationStateCreateInfo rasterizer = {}; + rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterizer.depthClampEnable = VK_TRUE; + rasterizer.rasterizerDiscardEnable = VK_FALSE; + rasterizer.polygonMode = VK_POLYGON_MODE_FILL; + rasterizer.lineWidth = 1.0f; + rasterizer.cullMode = VK_CULL_MODE_NONE; + rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizer.depthBiasEnable = VK_FALSE; + rasterizer.depthBiasConstantFactor = 0.0f; + rasterizer.depthBiasClamp = 0.0f; + rasterizer.depthBiasSlopeFactor = 0.0f; + + // depth clip will be enabled via Vulkan 1.1 extension VK_EXT_depth_clip_enable: + VkPipelineRasterizationDepthClipStateCreateInfoEXT depthclip = {}; + depthclip.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT; + depthclip.depthClipEnable = VK_TRUE; + rasterizer.pNext = &depthclip; + + if (pso->desc.rs != nullptr) + { + const RasterizerStateDesc& desc = pso->desc.rs->desc; + + switch (desc.FillMode) + { + case FILL_WIREFRAME: + rasterizer.polygonMode = VK_POLYGON_MODE_LINE; + break; + case FILL_SOLID: + default: + rasterizer.polygonMode = VK_POLYGON_MODE_FILL; + break; + } + + switch (desc.CullMode) + { + case CULL_BACK: + rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; + break; + case CULL_FRONT: + rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT; + break; + case CULL_NONE: + default: + rasterizer.cullMode = VK_CULL_MODE_NONE; + break; + } + + rasterizer.frontFace = desc.FrontCounterClockwise ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE; + rasterizer.depthBiasEnable = desc.DepthBias != 0; + rasterizer.depthBiasConstantFactor = static_cast(desc.DepthBias); + rasterizer.depthBiasClamp = desc.DepthBiasClamp; + rasterizer.depthBiasSlopeFactor = desc.SlopeScaledDepthBias; + + // depth clip is extension in Vulkan 1.1: + depthclip.depthClipEnable = desc.DepthClipEnable ? VK_TRUE : VK_FALSE; + } + + pipelineInfo.pRasterizationState = &rasterizer; + + + // Viewport, Scissor: + VkViewport viewport = {}; + viewport.x = 0; + viewport.y = 0; + viewport.width = 65535; + viewport.height = 65535; + viewport.minDepth = 0; + viewport.maxDepth = 1; + + VkRect2D scissor = {}; + scissor.extent.width = 65535; + scissor.extent.height = 65535; + + VkPipelineViewportStateCreateInfo viewportState = {}; + viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewportState.viewportCount = 1; + viewportState.pViewports = &viewport; + viewportState.scissorCount = 1; + viewportState.pScissors = &scissor; + + pipelineInfo.pViewportState = &viewportState; + + + // Depth-Stencil: + VkPipelineDepthStencilStateCreateInfo depthstencil = {}; + depthstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + if (pso->desc.dss != nullptr) + { + depthstencil.depthTestEnable = pso->desc.dss->desc.DepthEnable ? VK_TRUE : VK_FALSE; + depthstencil.depthWriteEnable = pso->desc.dss->desc.DepthWriteMask == DEPTH_WRITE_MASK_ZERO ? VK_FALSE : VK_TRUE; + depthstencil.depthCompareOp = _ConvertComparisonFunc(pso->desc.dss->desc.DepthFunc); + + depthstencil.stencilTestEnable = pso->desc.dss->desc.StencilEnable ? VK_TRUE : VK_FALSE; + + depthstencil.front.compareMask = pso->desc.dss->desc.StencilReadMask; + depthstencil.front.writeMask = pso->desc.dss->desc.StencilWriteMask; + depthstencil.front.reference = 0; // runtime supplied + depthstencil.front.compareOp = _ConvertComparisonFunc(pso->desc.dss->desc.FrontFace.StencilFunc); + depthstencil.front.passOp = _ConvertStencilOp(pso->desc.dss->desc.FrontFace.StencilPassOp); + depthstencil.front.failOp = _ConvertStencilOp(pso->desc.dss->desc.FrontFace.StencilFailOp); + depthstencil.front.depthFailOp = _ConvertStencilOp(pso->desc.dss->desc.FrontFace.StencilDepthFailOp); + + depthstencil.back.compareMask = pso->desc.dss->desc.StencilReadMask; + depthstencil.back.writeMask = pso->desc.dss->desc.StencilWriteMask; + depthstencil.back.reference = 0; // runtime supplied + depthstencil.back.compareOp = _ConvertComparisonFunc(pso->desc.dss->desc.BackFace.StencilFunc); + depthstencil.back.passOp = _ConvertStencilOp(pso->desc.dss->desc.BackFace.StencilPassOp); + depthstencil.back.failOp = _ConvertStencilOp(pso->desc.dss->desc.BackFace.StencilFailOp); + depthstencil.back.depthFailOp = _ConvertStencilOp(pso->desc.dss->desc.BackFace.StencilDepthFailOp); + + depthstencil.depthBoundsTestEnable = VK_FALSE; + } + + pipelineInfo.pDepthStencilState = &depthstencil; + + + // MSAA: + VkPipelineMultisampleStateCreateInfo multisampling = {}; + multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampling.sampleShadingEnable = VK_FALSE; + multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + multisampling.minSampleShading = 1.0f; + multisampling.pSampleMask = nullptr; + multisampling.alphaToCoverageEnable = VK_FALSE; + multisampling.alphaToOneEnable = VK_FALSE; + + pipelineInfo.pMultisampleState = &multisampling; + + + // Blending: + uint32_t numBlendAttachments = 0; + VkPipelineColorBlendAttachmentState colorBlendAttachments[8]; + const UINT blend_loopCount = active_renderpass[cmd] == nullptr ? 1 : active_renderpass[cmd]->desc.numAttachments; + for (UINT i = 0; i < blend_loopCount; ++i) + { + if (active_renderpass[cmd] != nullptr && active_renderpass[cmd]->desc.attachments[i].type != RenderPassAttachment::RENDERTARGET) + { + continue; + } + + RenderTargetBlendStateDesc desc = pso->desc.bs->desc.RenderTarget[numBlendAttachments++]; + + colorBlendAttachments[i].blendEnable = desc.BlendEnable ? VK_TRUE : VK_FALSE; + + colorBlendAttachments[i].colorWriteMask = 0; + if (desc.RenderTargetWriteMask & COLOR_WRITE_ENABLE_RED) + { + colorBlendAttachments[i].colorWriteMask |= VK_COLOR_COMPONENT_R_BIT; + } + if (desc.RenderTargetWriteMask & COLOR_WRITE_ENABLE_GREEN) + { + colorBlendAttachments[i].colorWriteMask |= VK_COLOR_COMPONENT_G_BIT; + } + if (desc.RenderTargetWriteMask & COLOR_WRITE_ENABLE_BLUE) + { + colorBlendAttachments[i].colorWriteMask |= VK_COLOR_COMPONENT_B_BIT; + } + if (desc.RenderTargetWriteMask & COLOR_WRITE_ENABLE_ALPHA) + { + colorBlendAttachments[i].colorWriteMask |= VK_COLOR_COMPONENT_A_BIT; + } + + colorBlendAttachments[i].srcColorBlendFactor = _ConvertBlend(desc.SrcBlend); + colorBlendAttachments[i].dstColorBlendFactor = _ConvertBlend(desc.DestBlend); + colorBlendAttachments[i].colorBlendOp = _ConvertBlendOp(desc.BlendOp); + colorBlendAttachments[i].srcAlphaBlendFactor = _ConvertBlend(desc.SrcBlendAlpha); + colorBlendAttachments[i].dstAlphaBlendFactor = _ConvertBlend(desc.DestBlendAlpha); + colorBlendAttachments[i].alphaBlendOp = _ConvertBlendOp(desc.BlendOpAlpha); + } + + VkPipelineColorBlendStateCreateInfo colorBlending = {}; + colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlending.logicOpEnable = VK_FALSE; + colorBlending.logicOp = VK_LOGIC_OP_COPY; + colorBlending.attachmentCount = numBlendAttachments; + colorBlending.pAttachments = colorBlendAttachments; + colorBlending.blendConstants[0] = 1.0f; + colorBlending.blendConstants[1] = 1.0f; + colorBlending.blendConstants[2] = 1.0f; + colorBlending.blendConstants[3] = 1.0f; + + pipelineInfo.pColorBlendState = &colorBlending; + + + // Tessellation: + VkPipelineTessellationStateCreateInfo tessellationInfo = {}; + tessellationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; + tessellationInfo.patchControlPoints = 3; + + pipelineInfo.pTessellationState = &tessellationInfo; + + + + + // Dynamic state will be specified at runtime: + VkDynamicState dynamicStates[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_BLEND_CONSTANTS + }; + + VkPipelineDynamicStateCreateInfo dynamicState = {}; + dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicState.dynamicStateCount = ARRAYSIZE(dynamicStates); + dynamicState.pDynamicStates = dynamicStates; + + pipelineInfo.pDynamicState = &dynamicState; + + res = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline); + assert(res == VK_SUCCESS); + + pipelines_worker[cmd].push_back(std::make_pair(pipeline_hash, pipeline)); + } + } + else + { + pipeline = it->second; + } + assert(pipeline != VK_NULL_HANDLE); + + vkCmdBindPipeline(GetDirectCommandList(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); } void GraphicsDevice_Vulkan::BindComputeShader(const ComputeShader* cs, CommandList cmd) { diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.h b/WickedEngine/wiGraphicsDevice_Vulkan.h index a129a5eaa..6b03e330f 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.h +++ b/WickedEngine/wiGraphicsDevice_Vulkan.h @@ -204,6 +204,11 @@ namespace wiGraphics UploadBuffer* bufferUploader; UploadBuffer* textureUploader; + std::unordered_map pipelines_global; + std::vector> pipelines_worker[COMMANDLIST_COUNT]; + size_t prev_pipeline_hash[COMMANDLIST_COUNT] = {}; + const RenderPass* active_renderpass[COMMANDLIST_COUNT] = {}; + std::atomic commandlist_count{ 0 }; wiContainers::ThreadSafeRingBuffer free_commandlists; wiContainers::ThreadSafeRingBuffer active_commandlists; @@ -289,6 +294,7 @@ namespace wiGraphics virtual CommandList BeginCommandList() override; void WaitForGPU() override; + void ClearPipelineStateCache() override; void SetResolution(int width, int height) override; diff --git a/WickedEngine/wiGraphicsResource.h b/WickedEngine/wiGraphicsResource.h index 6e021332d..32db0c719 100644 --- a/WickedEngine/wiGraphicsResource.h +++ b/WickedEngine/wiGraphicsResource.h @@ -196,7 +196,7 @@ namespace wiGraphics struct PipelineState : public GraphicsDeviceChild { - wiCPUHandle pipeline = WI_NULL_HANDLE; + size_t hash = 0; PipelineStateDesc desc; const PipelineStateDesc& GetDesc() const { return desc; } @@ -207,6 +207,7 @@ namespace wiGraphics struct RenderPass : public GraphicsDeviceChild { + size_t hash = 0; wiCPUHandle framebuffer = WI_NULL_HANDLE; wiCPUHandle renderpass = WI_NULL_HANDLE; RenderPassDesc desc; diff --git a/WickedEngine/wiHairParticle.cpp b/WickedEngine/wiHairParticle.cpp index 3cf67c348..ee557f10d 100644 --- a/WickedEngine/wiHairParticle.cpp +++ b/WickedEngine/wiHairParticle.cpp @@ -245,8 +245,6 @@ void wiHairParticle::LoadShaders() desc.rs = &ncrs; desc.dss = &dss_default; - desc.DSFormat = wiRenderer::DSFormat_full; - switch (i) { case RENDERPASS_DEPTHONLY: @@ -259,6 +257,7 @@ void wiHairParticle::LoadShaders() if (j == 0) { desc.ps = ps_forward; + desc.dss = &dss_equal; } else { @@ -269,6 +268,7 @@ void wiHairParticle::LoadShaders() if (j == 0) { desc.ps = ps_tiledforward; + desc.dss = &dss_equal; } else { @@ -277,28 +277,9 @@ void wiHairParticle::LoadShaders() break; } - switch (i) - { - case RENDERPASS_FORWARD: - case RENDERPASS_TILEDFORWARD: - desc.numRTs = 2; - desc.RTFormats[0] = wiRenderer::RTFormat_hdr; - desc.RTFormats[1] = wiRenderer::RTFormat_gbuffer_1; - desc.dss = &dss_equal; // opaque - break; - case RENDERPASS_DEFERRED: - desc.numRTs = 5; - desc.RTFormats[0] = wiRenderer::RTFormat_gbuffer_0; - desc.RTFormats[1] = wiRenderer::RTFormat_gbuffer_1; - desc.RTFormats[2] = wiRenderer::RTFormat_gbuffer_2; - desc.RTFormats[3] = wiRenderer::RTFormat_deferred_lightbuffer; - desc.RTFormats[4] = wiRenderer::RTFormat_deferred_lightbuffer; - } - if (j == 1) { desc.dss = &dss_rejectopaque_keeptransparent; // transparent - desc.numRTs = 1; } device->CreatePipelineState(&desc, &PSO[i][j]); @@ -315,9 +296,6 @@ void wiHairParticle::LoadShaders() desc.bs = &bs[0]; desc.rs = &wirers; desc.dss = &dss_default; - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::RTFormat_hdr; - desc.DSFormat = wiRenderer::DSFormat_full; device->CreatePipelineState(&desc, &PSO_wire); } diff --git a/WickedEngine/wiHelper.h b/WickedEngine/wiHelper.h index d1c80ec0c..f3eaa9322 100644 --- a/WickedEngine/wiHelper.h +++ b/WickedEngine/wiHelper.h @@ -8,7 +8,7 @@ namespace wiHelper { template - inline void hash_combine(std::size_t& seed, const T& v) + constexpr void hash_combine(std::size_t& seed, const T& v) { std::hash hasher; seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); diff --git a/WickedEngine/wiImage.cpp b/WickedEngine/wiImage.cpp index 4b422fe32..4dd5a2f6d 100644 --- a/WickedEngine/wiImage.cpp +++ b/WickedEngine/wiImage.cpp @@ -24,12 +24,6 @@ namespace wiImage IMAGE_SHADER_FULLSCREEN, IMAGE_SHADER_COUNT }; - enum IMAGE_HDR - { - IMAGE_HDR_DISABLED, - IMAGE_HDR_ENABLED, - IMAGE_HDR_COUNT - }; enum IMAGE_SAMPLING { IMAGE_SAMPLING_SIMPLE, @@ -44,7 +38,7 @@ namespace wiImage BlendState blendStates[BLENDMODE_COUNT]; RasterizerState rasterizerState; DepthStencilState depthStencilStates[STENCILMODE_COUNT][STENCILREFMODE_COUNT]; - PipelineState imagePSO[IMAGE_SHADER_COUNT][BLENDMODE_COUNT][STENCILMODE_COUNT][STENCILREFMODE_COUNT][IMAGE_HDR_COUNT][IMAGE_SAMPLING_COUNT]; + PipelineState imagePSO[IMAGE_SHADER_COUNT][BLENDMODE_COUNT][STENCILMODE_COUNT][STENCILREFMODE_COUNT][IMAGE_SAMPLING_COUNT]; std::atomic_bool initialized{ false }; @@ -112,7 +106,7 @@ namespace wiImage if (params.isFullScreenEnabled()) { - device->BindPipelineState(&imagePSO[IMAGE_SHADER_FULLSCREEN][params.blendFlag][params.stencilComp][params.stencilRefMode][params.isHDREnabled()][sampling_type], cmd); + device->BindPipelineState(&imagePSO[IMAGE_SHADER_FULLSCREEN][params.blendFlag][params.stencilComp][params.stencilRefMode][sampling_type], cmd); device->UpdateBuffer(&constantBuffer, &cb, cmd); device->BindConstantBuffer(PS, &constantBuffer, CB_GETBINDSLOT(ImageCB), cmd); device->Draw(3, 0, cmd); @@ -225,7 +219,7 @@ namespace wiImage } } - device->BindPipelineState(&imagePSO[targetShader][params.blendFlag][params.stencilComp][params.stencilRefMode][params.isHDREnabled()][sampling_type], cmd); + device->BindPipelineState(&imagePSO[targetShader][params.blendFlag][params.stencilComp][params.stencilRefMode][sampling_type], cmd); device->BindConstantBuffer(VS, &constantBuffer, CB_GETBINDSLOT(ImageCB), cmd); device->BindConstantBuffer(PS, &constantBuffer, CB_GETBINDSLOT(ImageCB), cmd); @@ -282,22 +276,7 @@ namespace wiImage { desc.dss = &depthStencilStates[k][m]; - if (k == STENCILMODE_DISABLED) - { - desc.DSFormat = FORMAT_UNKNOWN; - } - else - { - desc.DSFormat = wiRenderer::DSFormat_full; - } - - desc.numRTs = 1; - - desc.RTFormats[0] = device->GetBackBufferFormat(); - device->CreatePipelineState(&desc, &imagePSO[i][j][k][m][0][l]); - - desc.RTFormats[0] = wiRenderer::RTFormat_hdr; - device->CreatePipelineState(&desc, &imagePSO[i][j][k][m][1][l]); + device->CreatePipelineState(&desc, &imagePSO[i][j][k][m][l]); } } diff --git a/WickedEngine/wiImage.h b/WickedEngine/wiImage.h index 8d84594ca..50a0e4a38 100644 --- a/WickedEngine/wiImage.h +++ b/WickedEngine/wiImage.h @@ -63,8 +63,7 @@ struct wiImageParams DRAWRECT2 = 1 << 1, MIRROR = 1 << 2, EXTRACT_NORMALMAP = 1 << 3, - HDR = 1 << 4, - FULLSCREEN = 1 << 5, + FULLSCREEN = 1 << 4, }; uint32_t _flags = EMPTY; @@ -130,7 +129,6 @@ struct wiImageParams constexpr bool isDrawRect2Enabled() const { return _flags & DRAWRECT2; } constexpr bool isMirrorEnabled() const { return _flags & MIRROR; } constexpr bool isExtractNormalMapEnabled() const { return _flags & EXTRACT_NORMALMAP; } - constexpr bool isHDREnabled() const { return _flags & HDR; } constexpr bool isFullScreenEnabled() const { return _flags & FULLSCREEN; } // enables draw rectangle for base texture (cutout texture outside draw rectangle) @@ -141,8 +139,6 @@ struct wiImageParams void enableMirror() { _flags |= MIRROR; } // enable normal map extraction shader that will perform texcolor * 2 - 1 (preferably onto a signed render target) void enableExtractNormalMap() { _flags |= EXTRACT_NORMALMAP; } - // enable HDR blending to float render target - void enableHDR() { _flags |= HDR; } // enable full screen override. It just draws texture onto the full screen, disabling any other setup except sampler and stencil) void enableFullScreen() { _flags |= FULLSCREEN; } @@ -154,8 +150,6 @@ struct wiImageParams void disableMirror() { _flags &= ~MIRROR; } // disable normal map extraction shader void disableExtractNormalMap() { _flags &= ~EXTRACT_NORMALMAP; } - // if you want to render onto normalized render target - void disableHDR() { _flags &= ~HDR; } // disable full screen override void disableFullScreen() { _flags &= ~FULLSCREEN; } diff --git a/WickedEngine/wiOcean.cpp b/WickedEngine/wiOcean.cpp index 2bbe84569..44f7aeac9 100644 --- a/WickedEngine/wiOcean.cpp +++ b/WickedEngine/wiOcean.cpp @@ -28,7 +28,7 @@ namespace wiOcean_Internal PipelineState PSO, PSO_wire; - CSFFT512x512_Plan m_fft_plan; + wiFFTGenerator::CSFFT512x512_Plan m_fft_plan; } using namespace wiOcean_Internal; @@ -393,9 +393,6 @@ void wiOcean::LoadShaders() desc.bs = &blendState; desc.rs = &rasterizerState; desc.dss = &depthStencilState; - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::RTFormat_hdr; - desc.DSFormat = wiRenderer::DSFormat_full; device->CreatePipelineState(&desc, &PSO); desc.ps = g_pWireframePS; @@ -459,7 +456,7 @@ void wiOcean::Initialize() LoadShaders(); - CSFFT_512x512_Data_t::LoadShaders(); + wiFFTGenerator::LoadShaders(); fft512x512_create_plan(m_fft_plan, 3); wiBackLog::post("wiOcean Initialized"); diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 1981f77d9..eeafa9ff0 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -457,7 +457,7 @@ void ReloadShaders(const std::string& path) GetShaderPath() = path; } - GetDevice()->WaitForGPU(); + GetDevice()->ClearPipelineStateCache(); wiResourceManager::GetShaderManager().Clear(); LoadShaders(); @@ -466,7 +466,7 @@ void ReloadShaders(const std::string& path) wiFont::LoadShaders(); wiImage::LoadShaders(); wiOcean::LoadShaders(); - CSFFT_512x512_Data_t::LoadShaders(); + wiFFTGenerator::LoadShaders(); wiWidget::LoadShaders(); wiGPUSortLib::LoadShaders(); wiGPUBVH::LoadShaders(); @@ -2306,78 +2306,6 @@ void LoadShaders() break; } - switch (renderPass) - { - case RENDERPASS_TEXTURE: - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - break; - case RENDERPASS_DEFERRED: - desc.numRTs = 5; - desc.RTFormats[0] = RTFormat_gbuffer_0; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.RTFormats[2] = RTFormat_gbuffer_2; - desc.RTFormats[3] = RTFormat_deferred_lightbuffer; - desc.RTFormats[4] = RTFormat_deferred_lightbuffer; - desc.DSFormat = DSFormat_full; - break; - case RENDERPASS_FORWARD: - if (transparency) - { - desc.numRTs = 1; - } - else - { - desc.numRTs = 2; - } - desc.RTFormats[0] = RTFormat_hdr; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.DSFormat = DSFormat_full; - break; - case RENDERPASS_TILEDFORWARD: - if (transparency) - { - desc.numRTs = 1; - } - else - { - desc.numRTs = 2; - } - desc.RTFormats[0] = RTFormat_hdr; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.DSFormat = DSFormat_full; - break; - case RENDERPASS_DEPTHONLY: - desc.numRTs = 0; - desc.DSFormat = DSFormat_full; - break; - case RENDERPASS_ENVMAPCAPTURE: - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_envprobe; - desc.DSFormat = DSFormat_small; - break; - case RENDERPASS_SHADOW: - if (transparency) - { - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_ldr; - } - else - { - desc.numRTs = 0; - } - desc.DSFormat = DSFormat_small; - break; - case RENDERPASS_SHADOWCUBE: - desc.numRTs = 0; - desc.DSFormat = DSFormat_small; - break; - case RENDERPASS_VOXELIZE: - desc.numRTs = 0; - break; - } - if (tessellation) { desc.pt = PATCHLIST; @@ -2416,10 +2344,6 @@ void LoadShaders() desc.dss = &depthStencils[DSSTYPE_DEPTHREAD]; desc.pt = TRIANGLELIST; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - device->CreatePipelineState(&desc, &PSO_object_hologram); CustomShader customShader; @@ -2438,10 +2362,6 @@ void LoadShaders() desc.dss = &depthStencils[DSSTYPE_DEFAULT]; desc.il = &vertexLayouts[VLTYPE_OBJECT_POS_TEX]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - desc.ps = pixelShaders[PSTYPE_OBJECT_FORWARD_WATER]; device->CreatePipelineState(&desc, &PSO_object_water[RENDERPASS_FORWARD]); @@ -2465,10 +2385,6 @@ void LoadShaders() desc.dss = &depthStencils[DSSTYPE_DEFAULT]; desc.il = &vertexLayouts[VLTYPE_OBJECT_POS_TEX]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - device->CreatePipelineState(&desc, &PSO_object_wire); }); wiJobSystem::Execute(ctx, [device] { @@ -2480,10 +2396,6 @@ void LoadShaders() desc.dss = &depthStencils[DSSTYPE_DEFERREDLIGHT]; desc.pt = TRIANGLESTRIP; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_gbuffer_0; - //desc.RTFormats[1] = RTFormat_gbuffer_1; - device->CreatePipelineState(&desc, &PSO_decal); }); wiJobSystem::Execute(ctx, [device] { @@ -2494,8 +2406,6 @@ void LoadShaders() desc.dss = &depthStencils[DSSTYPE_DEPTHREAD]; desc.pt = TRIANGLESTRIP; - desc.DSFormat = DSFormat_small; - device->CreatePipelineState(&desc, &PSO_occlusionquery); }); wiJobSystem::Dispatch(ctx, RENDERPASS_COUNT, 1, [device](wiJobDispatchArgs args) { @@ -2520,24 +2430,14 @@ void LoadShaders() case RENDERPASS_DEFERRED: desc.vs = vertexShaders[VSTYPE_IMPOSTOR]; desc.ps = pixelShaders[PSTYPE_IMPOSTOR_DEFERRED]; - desc.numRTs = 3; - desc.RTFormats[0] = RTFormat_gbuffer_0; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.RTFormats[2] = RTFormat_gbuffer_2; break; case RENDERPASS_FORWARD: desc.vs = vertexShaders[VSTYPE_IMPOSTOR]; desc.ps = pixelShaders[PSTYPE_IMPOSTOR_FORWARD]; - desc.numRTs = 2; - desc.RTFormats[0] = RTFormat_hdr; - desc.RTFormats[1] = RTFormat_gbuffer_1; break; case RENDERPASS_TILEDFORWARD: desc.vs = vertexShaders[VSTYPE_IMPOSTOR]; desc.ps = pixelShaders[PSTYPE_IMPOSTOR_TILEDFORWARD]; - desc.numRTs = 2; - desc.RTFormats[0] = RTFormat_hdr; - desc.RTFormats[1] = RTFormat_gbuffer_1; break; case RENDERPASS_DEPTHONLY: desc.vs = vertexShaders[VSTYPE_IMPOSTOR]; @@ -2546,11 +2446,8 @@ void LoadShaders() default: desc.vs = vertexShaders[VSTYPE_IMPOSTOR]; desc.ps = pixelShaders[PSTYPE_IMPOSTOR_SIMPLE]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; break; } - desc.DSFormat = DSFormat_full; device->CreatePipelineState(&desc, &PSO_impostor[args.jobIndex]); }); @@ -2563,10 +2460,6 @@ void LoadShaders() desc.dss = &depthStencils[DSSTYPE_DEFAULT]; desc.il = nullptr; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - device->CreatePipelineState(&desc, &PSO_impostor_wire); }); wiJobSystem::Execute(ctx, [device] { @@ -2577,10 +2470,6 @@ void LoadShaders() desc.dss = &depthStencils[DSSTYPE_CAPTUREIMPOSTOR]; desc.il = &vertexLayouts[VLTYPE_OBJECT_ALL]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_impostor; - desc.DSFormat = DSFormat_small; - desc.ps = pixelShaders[PSTYPE_CAPTUREIMPOSTOR_ALBEDO]; device->CreatePipelineState(&desc, &PSO_captureimpostor_albedo); @@ -2633,11 +2522,6 @@ void LoadShaders() break; } - desc.numRTs = 2; - desc.RTFormats[0] = RTFormat_deferred_lightbuffer; - desc.RTFormats[1] = RTFormat_deferred_lightbuffer; - desc.DSFormat = DSFormat_full; - device->CreatePipelineState(&desc, &PSO_deferredlight[args.jobIndex]); @@ -2683,10 +2567,6 @@ void LoadShaders() break; } - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - device->CreatePipelineState(&desc, &PSO_lightvisualizer[args.jobIndex]); } @@ -2714,10 +2594,6 @@ void LoadShaders() break; } - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = FORMAT_UNKNOWN; - device->CreatePipelineState(&desc, &PSO_volumetriclight[args.jobIndex]); } @@ -2731,11 +2607,6 @@ void LoadShaders() desc.bs = &blendStates[BSTYPE_ENVIRONMENTALLIGHT]; desc.dss = &depthStencils[DSSTYPE_DEFERREDLIGHT]; - desc.numRTs = 2; - desc.RTFormats[0] = RTFormat_deferred_lightbuffer; - desc.RTFormats[1] = RTFormat_deferred_lightbuffer; - desc.DSFormat = DSFormat_full; - device->CreatePipelineState(&desc, &PSO_enviromentallight); }); wiJobSystem::Execute(ctx, [device] { @@ -2747,10 +2618,6 @@ void LoadShaders() desc.bs = &blendStates[BSTYPE_TRANSPARENT]; desc.dss = &depthStencils[DSSTYPE_XRAY]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_lightmap_object; - desc.DSFormat = FORMAT_UNKNOWN; - device->CreatePipelineState(&desc, &PSO_renderlightmap); }); wiJobSystem::Execute(ctx, [device] { @@ -2761,8 +2628,6 @@ void LoadShaders() desc.bs = &blendStates[BSTYPE_OPAQUE]; desc.dss = &depthStencils[DSSTYPE_WRITEONLY]; - desc.DSFormat = DSFormat_small; - device->CreatePipelineState(&desc, &PSO_downsampledepthbuffer); }); wiJobSystem::Execute(ctx, [device] { @@ -2773,10 +2638,6 @@ void LoadShaders() desc.bs = &blendStates[BSTYPE_OPAQUE]; desc.dss = &depthStencils[DSSTYPE_DEFERREDCOMPOSITION]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - device->CreatePipelineState(&desc, &PSO_deferredcomposition); }); wiJobSystem::Execute(ctx, [device] { @@ -2787,10 +2648,6 @@ void LoadShaders() desc.bs = &blendStates[BSTYPE_OPAQUE]; desc.dss = &depthStencils[DSSTYPE_SSS]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_deferred_lightbuffer; - desc.DSFormat = DSFormat_full; - device->CreatePipelineState(&desc, &PSO_sss); }); wiJobSystem::Execute(ctx, [device] { @@ -2802,8 +2659,6 @@ void LoadShaders() desc.rs = &rasterizers[RSTYPE_DOUBLESIDED]; desc.dss = &depthStencils[DSSTYPE_XRAY]; desc.pt = POINTLIST; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; device->CreatePipelineState(&desc, &PSO_lensflare); }); @@ -2818,45 +2673,28 @@ void LoadShaders() desc.bs = &blendStates[BSTYPE_OPAQUE]; desc.vs = vertexShaders[VSTYPE_SKY]; desc.ps = pixelShaders[PSTYPE_SKY_STATIC]; - desc.numRTs = 2; - desc.RTFormats[0] = RTFormat_hdr; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.DSFormat = DSFormat_full; break; case SKYRENDERING_DYNAMIC: desc.bs = &blendStates[BSTYPE_OPAQUE]; desc.vs = vertexShaders[VSTYPE_SKY]; desc.ps = pixelShaders[PSTYPE_SKY_DYNAMIC]; - desc.numRTs = 2; - desc.RTFormats[0] = RTFormat_hdr; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.DSFormat = DSFormat_full; break; case SKYRENDERING_SUN: desc.bs = &blendStates[BSTYPE_ADDITIVE]; desc.vs = vertexShaders[VSTYPE_SKY]; desc.ps = pixelShaders[PSTYPE_SUN]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; break; case SKYRENDERING_ENVMAPCAPTURE_STATIC: desc.bs = &blendStates[BSTYPE_OPAQUE]; desc.vs = vertexShaders[VSTYPE_ENVMAP_SKY]; desc.ps = pixelShaders[PSTYPE_ENVMAP_SKY_STATIC]; desc.gs = geometryShaders[GSTYPE_ENVMAP_SKY]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_small; break; case SKYRENDERING_ENVMAPCAPTURE_DYNAMIC: desc.bs = &blendStates[BSTYPE_OPAQUE]; desc.vs = vertexShaders[VSTYPE_ENVMAP_SKY]; desc.ps = pixelShaders[PSTYPE_ENVMAP_SKY_DYNAMIC]; desc.gs = geometryShaders[GSTYPE_ENVMAP_SKY]; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_small; break; } @@ -2865,10 +2703,6 @@ void LoadShaders() wiJobSystem::Dispatch(ctx, DEBUGRENDERING_COUNT, 1, [device](wiJobDispatchArgs args) { PipelineStateDesc desc; - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - switch (args.jobIndex) { case DEBUGRENDERING_ENVPROBE: @@ -2947,8 +2781,6 @@ void LoadShaders() desc.rs = &rasterizers[RSTYPE_DOUBLESIDED]; desc.bs = &blendStates[BSTYPE_TRANSPARENT]; desc.pt = TRIANGLELIST; - desc.DSFormat = FORMAT_UNKNOWN; - desc.RTFormats[0] = FORMAT_R32G32B32A32_FLOAT; break; } @@ -5867,7 +5699,7 @@ void DrawDebugWorld(const CameraComponent& camera, CommandList cmd) } - if (debugEnvProbes) + if (debugEnvProbes && textures[TEXTYPE_CUBEARRAY_ENVMAPARRAY] != nullptr) { device->EventBegin("Debug EnvProbes", cmd); // Envmap spheres: @@ -6265,6 +6097,10 @@ void DrawDeferredDecals( } static const UINT envmapCount = 16; +static const UINT envmapRes = 128; +static const UINT envmapMIPs = 8; +static Texture2D envrenderingDepthBuffer; +static std::vector renderpasses_envmap; vector probesToRefresh(envmapCount); void ManageEnvProbes() { @@ -6320,23 +6156,12 @@ void ManageEnvProbes() probesToRefresh.push_back((uint32_t)probeIndex); } -} -void RefreshEnvProbes(CommandList cmd) -{ - const Scene& scene = GetScene(); - GraphicsDevice* device = GetDevice(); - device->EventBegin("EnvironmentProbe Refresh", cmd); - - static const UINT envmapRes = 128; - static const UINT envmapMIPs = 8; - static Texture2D envrenderingDepthBuffer; - static std::vector renderpasses_envmap; - - if (textures[TEXTYPE_CUBEARRAY_ENVMAPARRAY] == nullptr) + if (!probesToRefresh.empty() && textures[TEXTYPE_CUBEARRAY_ENVMAPARRAY] == nullptr) { - TextureDesc desc; + GraphicsDevice* device = GetDevice(); + TextureDesc desc; desc.ArraySize = 6; desc.BindFlags = BIND_DEPTH_STENCIL; desc.CPUAccessFlags = 0; @@ -6395,6 +6220,18 @@ void RefreshEnvProbes(CommandList cmd) assert(subresource_index == textures[TEXTYPE_CUBEARRAY_ENVMAPARRAY]->GetDesc().MipLevels + i); } } +} +void RefreshEnvProbes(CommandList cmd) +{ + if (probesToRefresh.empty()) + { + return; + } + + const Scene& scene = GetScene(); + + GraphicsDevice* device = GetDevice(); + device->EventBegin("EnvironmentProbe Refresh", cmd); ViewPort VP; VP.Height = envmapRes; @@ -6408,7 +6245,6 @@ void RefreshEnvProbes(CommandList cmd) const float zNearP = GetCamera().zNearP; const float zFarP = GetCamera().zFarP; - for (uint32_t probeIndex : probesToRefresh) { const EnvironmentProbeComponent& probe = scene.probes[probeIndex]; @@ -6550,6 +6386,10 @@ void RefreshEnvProbes(CommandList cmd) } static const UINT maxImpostorCount = 8; +static const UINT impostorTextureArraySize = maxImpostorCount * impostorCaptureAngles * 3; +static const UINT impostorTextureDim = 128; +static Texture2D impostorDepthStencil; +static std::vector renderpasses_impostor; vector impostorsToRefresh(maxImpostorCount); void ManageImpostors() { @@ -6568,191 +6408,190 @@ void ManageImpostors() impostorsToRefresh.push_back((uint32_t)impostorIndex); } + + if (!impostorsToRefresh.empty() && textures[TEXTYPE_2D_IMPOSTORARRAY] == nullptr) + { + GraphicsDevice* device = GetDevice(); + + TextureDesc desc; + desc.Width = impostorTextureDim; + desc.Height = impostorTextureDim; + + desc.BindFlags = BIND_DEPTH_STENCIL; + desc.ArraySize = 1; + desc.Format = DSFormat_small; + HRESULT hr = device->CreateTexture2D(&desc, nullptr, &impostorDepthStencil); + assert(SUCCEEDED(hr)); + device->SetName(&impostorDepthStencil, "impostorDepthStencil"); + + desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS; + desc.ArraySize = impostorTextureArraySize; + desc.Format = RTFormat_impostor; + + textures[TEXTYPE_2D_IMPOSTORARRAY] = new Texture2D; + hr = device->CreateTexture2D(&desc, nullptr, (Texture2D*)textures[TEXTYPE_2D_IMPOSTORARRAY]); + assert(SUCCEEDED(hr)); + device->SetName(textures[TEXTYPE_2D_IMPOSTORARRAY], "ImpostorTarget"); + + renderpasses_impostor.resize(desc.ArraySize); + + for (UINT i = 0; i < desc.ArraySize; ++i) + { + int subresource_index; + subresource_index = device->CreateSubresource(textures[TEXTYPE_2D_IMPOSTORARRAY], RTV, i, 1, 0, 1); + assert(subresource_index == i); + + RenderPassDesc renderpassdesc; + renderpassdesc.numAttachments = 2; + renderpassdesc.attachments[0] = { RenderPassAttachment::RENDERTARGET,RenderPassAttachment::LOADOP_CLEAR,(Texture2D*)textures[TEXTYPE_2D_IMPOSTORARRAY], subresource_index }; + renderpassdesc.attachments[1] = { RenderPassAttachment::DEPTH_STENCIL,RenderPassAttachment::LOADOP_CLEAR,&impostorDepthStencil, subresource_index }; + hr = device->CreateRenderPass(&renderpassdesc, &renderpasses_impostor[subresource_index]); + } + } } void RefreshImpostors(CommandList cmd) { + if (impostorsToRefresh.empty()) + { + return; + } + const Scene& scene = GetScene(); - if (!impostorsToRefresh.empty()) + GraphicsDevice* device = GetDevice(); + device->EventBegin("Impostor Refresh", cmd); + + BindConstantBuffers(VS, cmd); + BindConstantBuffers(PS, cmd); + + struct InstBuf { - GraphicsDevice* device = GetDevice(); - device->EventBegin("Impostor Refresh", cmd); + Instance instance; + InstancePrev instancePrev; + InstanceAtlas instanceAtlas; + }; + GraphicsDevice::GPUAllocation mem = device->AllocateGPU(sizeof(InstBuf), cmd); + volatile InstBuf* buff = (volatile InstBuf*)mem.data; + buff->instance.Create(IDENTITYMATRIX); + buff->instancePrev.Create(IDENTITYMATRIX); + buff->instanceAtlas.Create(XMFLOAT4(1, 1, 0, 0)); - BindConstantBuffers(VS, cmd); - BindConstantBuffers(PS, cmd); + for (uint32_t impostorIndex : impostorsToRefresh) + { + const ImpostorComponent& impostor = scene.impostors[impostorIndex]; - static const UINT textureArraySize = maxImpostorCount * impostorCaptureAngles * 3; - static const UINT textureDim = 128; - static Texture2D depthStencil; - static std::vector renderpasses_impostor; + Entity entity = scene.impostors.GetEntity(impostorIndex); + const MeshComponent& mesh = *scene.meshes.GetComponent(entity); - if (textures[TEXTYPE_2D_IMPOSTORARRAY] == nullptr) - { - TextureDesc desc; - desc.Width = textureDim; - desc.Height = textureDim; + const AABB& bbox = mesh.aabb; + const XMFLOAT3 extents = bbox.getHalfWidth(); - desc.BindFlags = BIND_DEPTH_STENCIL; - desc.ArraySize = 1; - desc.Format = DSFormat_small; - HRESULT hr = device->CreateTexture2D(&desc, nullptr, &depthStencil); - assert(SUCCEEDED(hr)); - device->SetName(&depthStencil, "ImpostorDepthTarget"); - - desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS; - desc.ArraySize = textureArraySize; - desc.Format = RTFormat_impostor; - - textures[TEXTYPE_2D_IMPOSTORARRAY] = new Texture2D; - hr = device->CreateTexture2D(&desc, nullptr, (Texture2D*)textures[TEXTYPE_2D_IMPOSTORARRAY]); - assert(SUCCEEDED(hr)); - device->SetName(textures[TEXTYPE_2D_IMPOSTORARRAY], "ImpostorTarget"); - - renderpasses_impostor.resize(desc.ArraySize); - - for (UINT i = 0; i < desc.ArraySize; ++i) - { - int subresource_index; - subresource_index = device->CreateSubresource(textures[TEXTYPE_2D_IMPOSTORARRAY], RTV, i, 1, 0, 1); - assert(subresource_index == i); - - RenderPassDesc renderpassdesc; - renderpassdesc.numAttachments = 2; - renderpassdesc.attachments[0] = { RenderPassAttachment::RENDERTARGET,RenderPassAttachment::LOADOP_CLEAR,(Texture2D*)textures[TEXTYPE_2D_IMPOSTORARRAY], subresource_index }; - renderpassdesc.attachments[1] = { RenderPassAttachment::DEPTH_STENCIL,RenderPassAttachment::LOADOP_CLEAR,&depthStencil, subresource_index }; - hr = device->CreateRenderPass(&renderpassdesc, &renderpasses_impostor[subresource_index]); - } - } - - struct InstBuf - { - Instance instance; - InstancePrev instancePrev; - InstanceAtlas instanceAtlas; + const GPUBuffer* vbs[] = { + mesh.IsSkinned() ? mesh.streamoutBuffer_POS.get() : mesh.vertexBuffer_POS.get(), + mesh.vertexBuffer_UV0.get(), + mesh.vertexBuffer_UV1.get(), + mesh.vertexBuffer_ATL.get(), + mesh.vertexBuffer_COL.get(), + mesh.IsSkinned() ? mesh.streamoutBuffer_POS.get() : mesh.vertexBuffer_POS.get(), + mem.buffer }; - GraphicsDevice::GPUAllocation mem = device->AllocateGPU(sizeof(InstBuf), cmd); - volatile InstBuf* buff = (volatile InstBuf*)mem.data; - buff->instance.Create(IDENTITYMATRIX); - buff->instancePrev.Create(IDENTITYMATRIX); - buff->instanceAtlas.Create(XMFLOAT4(1, 1, 0, 0)); + UINT strides[] = { + sizeof(MeshComponent::Vertex_POS), + sizeof(MeshComponent::Vertex_TEX), + sizeof(MeshComponent::Vertex_TEX), + sizeof(MeshComponent::Vertex_TEX), + sizeof(MeshComponent::Vertex_COL), + sizeof(MeshComponent::Vertex_POS), + sizeof(InstBuf) + }; + UINT offsets[] = { + 0, + 0, + 0, + 0, + 0, + 0, + mem.offset + }; + device->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, offsets, cmd); - for (uint32_t impostorIndex : impostorsToRefresh) + device->BindIndexBuffer(mesh.indexBuffer.get(), mesh.GetIndexFormat(), 0, cmd); + + for (int prop = 0; prop < 3; ++prop) { - const ImpostorComponent& impostor = scene.impostors[impostorIndex]; - - Entity entity = scene.impostors.GetEntity(impostorIndex); - const MeshComponent& mesh = *scene.meshes.GetComponent(entity); - - const AABB& bbox = mesh.aabb; - const XMFLOAT3 extents = bbox.getHalfWidth(); - - const GPUBuffer* vbs[] = { - mesh.IsSkinned() ? mesh.streamoutBuffer_POS.get() : mesh.vertexBuffer_POS.get(), - mesh.vertexBuffer_UV0.get(), - mesh.vertexBuffer_UV1.get(), - mesh.vertexBuffer_ATL.get(), - mesh.vertexBuffer_COL.get(), - mesh.IsSkinned() ? mesh.streamoutBuffer_POS.get() : mesh.vertexBuffer_POS.get(), - mem.buffer - }; - UINT strides[] = { - sizeof(MeshComponent::Vertex_POS), - sizeof(MeshComponent::Vertex_TEX), - sizeof(MeshComponent::Vertex_TEX), - sizeof(MeshComponent::Vertex_TEX), - sizeof(MeshComponent::Vertex_COL), - sizeof(MeshComponent::Vertex_POS), - sizeof(InstBuf) - }; - UINT offsets[] = { - 0, - 0, - 0, - 0, - 0, - 0, - mem.offset - }; - device->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, offsets, cmd); - - device->BindIndexBuffer(mesh.indexBuffer.get(), mesh.GetIndexFormat(), 0, cmd); - - for (int prop = 0; prop < 3; ++prop) + switch (prop) { - switch (prop) - { - case 0: - device->BindPipelineState(&PSO_captureimpostor_albedo, cmd); - break; - case 1: - device->BindPipelineState(&PSO_captureimpostor_normal, cmd); - break; - case 2: - device->BindPipelineState(&PSO_captureimpostor_surface, cmd); - break; - } - - for (size_t i = 0; i < impostorCaptureAngles; ++i) - { - int textureIndex = (int)(impostorIndex * impostorCaptureAngles * 3 + prop * impostorCaptureAngles + i); - device->RenderPassBegin(&renderpasses_impostor[textureIndex], cmd); - - ViewPort viewPort; - viewPort.Height = (float)textureDim; - viewPort.Width = (float)textureDim; - viewPort.TopLeftX = 0; - viewPort.TopLeftY = 0; - viewPort.MinDepth = 0; - viewPort.MaxDepth = 1; - device->BindViewports(1, &viewPort, cmd); - - - CameraComponent impostorcamera; - TransformComponent camera_transform; - - camera_transform.ClearTransform(); - camera_transform.Translate(bbox.getCenter()); - - XMMATRIX P = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.y, extents.y, -extents.z, extents.z); - XMStoreFloat4x4(&impostorcamera.Projection, P); - camera_transform.RotateRollPitchYaw(XMFLOAT3(0, XM_2PI * (float)i / (float)impostorCaptureAngles, 0)); - - camera_transform.UpdateTransform(); - impostorcamera.TransformCamera(camera_transform); - impostorcamera.UpdateCamera(); - UpdateCameraCB(impostorcamera, cmd); - - for (auto& subset : mesh.subsets) - { - if (subset.indexCount == 0) - { - continue; - } - const MaterialComponent& material = *scene.materials.GetComponent(subset.materialID); - - device->BindConstantBuffer(VS, material.constantBuffer.get(), CB_GETBINDSLOT(MaterialCB), cmd); - device->BindConstantBuffer(PS, material.constantBuffer.get(), CB_GETBINDSLOT(MaterialCB), cmd); - - const GPUResource* res[] = { - material.GetBaseColorMap(), - material.GetNormalMap(), - material.GetSurfaceMap(), - }; - device->BindResources(PS, res, TEXSLOT_ONDEMAND0, ARRAYSIZE(res), cmd); - - device->DrawIndexedInstanced(subset.indexCount, 1, subset.indexOffset, 0, 0, cmd); - } - - device->RenderPassEnd(cmd); - } + case 0: + device->BindPipelineState(&PSO_captureimpostor_albedo, cmd); + break; + case 1: + device->BindPipelineState(&PSO_captureimpostor_normal, cmd); + break; + case 2: + device->BindPipelineState(&PSO_captureimpostor_surface, cmd); + break; } + for (size_t i = 0; i < impostorCaptureAngles; ++i) + { + int textureIndex = (int)(impostorIndex * impostorCaptureAngles * 3 + prop * impostorCaptureAngles + i); + device->RenderPassBegin(&renderpasses_impostor[textureIndex], cmd); + + ViewPort viewPort; + viewPort.Height = (float)impostorTextureDim; + viewPort.Width = (float)impostorTextureDim; + viewPort.TopLeftX = 0; + viewPort.TopLeftY = 0; + viewPort.MinDepth = 0; + viewPort.MaxDepth = 1; + device->BindViewports(1, &viewPort, cmd); + + + CameraComponent impostorcamera; + TransformComponent camera_transform; + + camera_transform.ClearTransform(); + camera_transform.Translate(bbox.getCenter()); + + XMMATRIX P = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.y, extents.y, -extents.z, extents.z); + XMStoreFloat4x4(&impostorcamera.Projection, P); + camera_transform.RotateRollPitchYaw(XMFLOAT3(0, XM_2PI * (float)i / (float)impostorCaptureAngles, 0)); + + camera_transform.UpdateTransform(); + impostorcamera.TransformCamera(camera_transform); + impostorcamera.UpdateCamera(); + UpdateCameraCB(impostorcamera, cmd); + + for (auto& subset : mesh.subsets) + { + if (subset.indexCount == 0) + { + continue; + } + const MaterialComponent& material = *scene.materials.GetComponent(subset.materialID); + + device->BindConstantBuffer(VS, material.constantBuffer.get(), CB_GETBINDSLOT(MaterialCB), cmd); + device->BindConstantBuffer(PS, material.constantBuffer.get(), CB_GETBINDSLOT(MaterialCB), cmd); + + const GPUResource* res[] = { + material.GetBaseColorMap(), + material.GetNormalMap(), + material.GetSurfaceMap(), + }; + device->BindResources(PS, res, TEXSLOT_ONDEMAND0, ARRAYSIZE(res), cmd); + + device->DrawIndexedInstanced(subset.indexCount, 1, subset.indexOffset, 0, 0, cmd); + } + + device->RenderPassEnd(cmd); + } } - UpdateCameraCB(GetCamera(), cmd); - - device->EventEnd(cmd); } + + UpdateCameraCB(GetCamera(), cmd); + + device->EventEnd(cmd); } void VoxelRadiance(CommandList cmd) diff --git a/WickedEngine/wiWidget.cpp b/WickedEngine/wiWidget.cpp index 3eeb54d7c..ac3dd8a53 100644 --- a/WickedEngine/wiWidget.cpp +++ b/WickedEngine/wiWidget.cpp @@ -241,8 +241,6 @@ void wiWidget::LoadShaders() desc.dss = wiRenderer::GetDepthStencilState(DSSTYPE_XRAY); desc.bs = wiRenderer::GetBlendState(BSTYPE_TRANSPARENT); desc.rs = wiRenderer::GetRasterizerState(RSTYPE_DOUBLESIDED); - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::GetDevice()->GetBackBufferFormat(); desc.pt = TRIANGLESTRIP; HRESULT hr = wiRenderer::GetDevice()->CreatePipelineState(&desc, &PSO_colorpicker); assert(SUCCEEDED(hr));