From 4653835914ebff168ba8be719158c62deb234eb4 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Fri, 17 Mar 2017 01:13:13 +0100 Subject: [PATCH] Implemented custom filtered mipchain generator, extended graphicsdevice, updated voxel radiance --- WickedEngine/SamplerMapping.h | 6 +- WickedEngine/WickedEngine_SHADERS.vcxproj | 20 + .../WickedEngine_SHADERS.vcxproj.filters | 6 + .../generateMIPChain3D_SimpleFilterCS.hlsl | 18 + WickedEngine/voxelConeTracingHF.hlsli | 2 +- WickedEngine/voxelSceneCopyClearCS.hlsl | 3 +- ...voxelSceneCopyClear_TemporalSmoothing.hlsl | 3 + WickedEngine/wiEnums.h | 2 + WickedEngine/wiGraphicsDevice.h | 22 +- WickedEngine/wiGraphicsDevice_DX11.cpp | 406 +++++++++++++----- WickedEngine/wiGraphicsDevice_DX11.h | 22 +- WickedEngine/wiGraphicsResource.cpp | 40 +- WickedEngine/wiGraphicsResource.h | 25 +- WickedEngine/wiRenderer.cpp | 77 +++- WickedEngine/wiRenderer.h | 10 + WickedEngine/wiVersion.cpp | 2 +- 16 files changed, 493 insertions(+), 171 deletions(-) create mode 100644 WickedEngine/generateMIPChain3D_SimpleFilterCS.hlsl create mode 100644 WickedEngine/voxelSceneCopyClear_TemporalSmoothing.hlsl diff --git a/WickedEngine/SamplerMapping.h b/WickedEngine/SamplerMapping.h index 5cae6801d..9fd4f2383 100644 --- a/WickedEngine/SamplerMapping.h +++ b/WickedEngine/SamplerMapping.h @@ -39,9 +39,7 @@ // Automatically binds samplers on the shader side: // Needs macro expansion -#define SAMPLERSTATE_X(name, slot) SamplerState name : register(s ## slot); -#define SAMPLERSTATE(name, slot) SAMPLERSTATE_X(name, slot) -#define SAMPLERCOMPARISONSTATE_X(name, slot) SamplerComparisonState name : register(s ## slot); -#define SAMPLERCOMPARISONSTATE(name, slot) SAMPLERCOMPARISONSTATE_X(name, slot) +#define SAMPLERSTATE(name, slot) SamplerState name : register(s ## slot); +#define SAMPLERCOMPARISONSTATE(name, slot) SamplerComparisonState name : register(s ## slot); #endif // _SAMPLER_MAPPING_H_ diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj b/WickedEngine/WickedEngine_SHADERS.vcxproj index 5166a4789..414c7597f 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj @@ -237,6 +237,16 @@ Pixel Pixel + + Compute + 4.0 + Compute + 4.0 + Compute + 5.0 + Compute + 4.0 + Geometry 4.0 @@ -909,6 +919,16 @@ Compute 4.0 + + Compute + 4.0 + Compute + 4.0 + Compute + 5.0 + Compute + 4.0 + Vertex Vertex diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters index fdec66a00..0aca4ba01 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters @@ -543,6 +543,12 @@ CS + + CS + + + CS + diff --git a/WickedEngine/generateMIPChain3D_SimpleFilterCS.hlsl b/WickedEngine/generateMIPChain3D_SimpleFilterCS.hlsl new file mode 100644 index 000000000..5c01cae7e --- /dev/null +++ b/WickedEngine/generateMIPChain3D_SimpleFilterCS.hlsl @@ -0,0 +1,18 @@ +#include "globals.hlsli" + +TEXTURE3D(input, float4, 0); +RWTEXTURE3D(output, float4, 0); + +SAMPLERSTATE(samplerstate, SSLOT_ONDEMAND0); + +[numthreads(8, 8, 8)] +void main( uint3 DTid : SV_DispatchThreadID ) +{ + uint3 dim; + output.GetDimensions(dim.x, dim.y, dim.z); + + if (DTid.x < dim.x && DTid.y < dim.y && DTid.z < dim.z) + { + output[DTid] = input.SampleLevel(samplerstate, ((float3)DTid + 0.5f) / (float3)dim, 0); + } +} \ No newline at end of file diff --git a/WickedEngine/voxelConeTracingHF.hlsli b/WickedEngine/voxelConeTracingHF.hlsli index b6f9c2346..8d1d72b8d 100644 --- a/WickedEngine/voxelConeTracingHF.hlsli +++ b/WickedEngine/voxelConeTracingHF.hlsli @@ -85,7 +85,7 @@ inline float4 ConeTraceReflection(in Texture3D voxels, in float3 uvw, in tc += coneVec * (1 + mip); - float4 sam = voxels.SampleLevel(sampler_point_clamp, tc, mip); + float4 sam = voxels.SampleLevel(sampler_linear_clamp, tc, mip); accumulation.a += sam.a; accumulation.rgb += sam.rgb * sam.a; diff --git a/WickedEngine/voxelSceneCopyClearCS.hlsl b/WickedEngine/voxelSceneCopyClearCS.hlsl index c06fb96e3..b5874d959 100644 --- a/WickedEngine/voxelSceneCopyClearCS.hlsl +++ b/WickedEngine/voxelSceneCopyClearCS.hlsl @@ -1,8 +1,6 @@ #include "globals.hlsli" #include "voxelHF.hlsli" -#define TEMPORAL_SMOOTHING - RWSTRUCTUREDBUFFER(input_output, VoxelType, 0); RWTEXTURE3D(output_emission, float4, 1); @@ -29,6 +27,7 @@ void main( uint3 DTid : SV_DispatchThreadID ) } else { + // This operation requires Feature: Typed UAV additional format loads! output_emission[writecoord] = lerp(output_emission[writecoord], float4(color.rgb, 1), 0.2f); } #else diff --git a/WickedEngine/voxelSceneCopyClear_TemporalSmoothing.hlsl b/WickedEngine/voxelSceneCopyClear_TemporalSmoothing.hlsl new file mode 100644 index 000000000..7e6589a17 --- /dev/null +++ b/WickedEngine/voxelSceneCopyClear_TemporalSmoothing.hlsl @@ -0,0 +1,3 @@ +#define TEMPORAL_SMOOTHING + +#include "voxelSceneCopyClearCS.hlsl" diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index 7fa0b5741..8144a6dd0 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -227,8 +227,10 @@ enum CSTYPES CSTYPE_TILEDLIGHTCULLING_DEBUG, CSTYPE_RESOLVEMSAADEPTHSTENCIL, CSTYPE_VOXELSCENECOPYCLEAR, + CSTYPE_VOXELSCENECOPYCLEAR_TEMPORALSMOOTHING, CSTYPE_VOXELRADIANCESECONDARYBOUNCE, CSTYPE_VOXELCLEARONLYNORMAL, + CSTYPE_GENERATEMIPCHAIN3D_SIMPLEFILTER, CSTYPE_LAST }; diff --git a/WickedEngine/wiGraphicsDevice.h b/WickedEngine/wiGraphicsDevice.h index 8adff8e32..27f1466f8 100644 --- a/WickedEngine/wiGraphicsDevice.h +++ b/WickedEngine/wiGraphicsDevice.h @@ -87,17 +87,17 @@ namespace wiGraphicsTypes virtual void BindViewports(UINT NumViewports, const ViewPort *pViewports, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; virtual void BindRenderTargetsUAVs(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GPUUnorderedResource* const *ppUAVs, int slotUAV, int countUAV, - GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, UINT arrayIndex = 0) = 0; - virtual void BindRenderTargets(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, UINT arrayIndex = 0) = 0; - virtual void ClearRenderTarget(Texture* pTexture, const FLOAT ColorRGBA[4], GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, UINT arrayIndex = 0) = 0; - virtual void ClearDepthStencil(Texture2D* pTexture, UINT ClearFlags, FLOAT Depth, UINT8 Stencil, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, UINT arrayIndex = 0) = 0; - virtual void BindResourcePS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; - virtual void BindResourceVS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; - virtual void BindResourceGS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; - virtual void BindResourceDS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; - virtual void BindResourceHS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; - virtual void BindResourceCS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; - virtual void BindUnorderedAccessResourceCS(const GPUUnorderedResource* buffer, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; + GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void BindRenderTargets(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void ClearRenderTarget(Texture* pTexture, const FLOAT ColorRGBA[4], GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void ClearDepthStencil(Texture2D* pTexture, UINT ClearFlags, FLOAT Depth, UINT8 Stencil, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void BindResourcePS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void BindResourceVS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void BindResourceGS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void BindResourceDS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void BindResourceHS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void BindResourceCS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; + virtual void BindUnorderedAccessResourceCS(const GPUUnorderedResource* buffer, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) = 0; virtual void UnBindResources(int slot, int num, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; virtual void UnBindUnorderedAccessResources(int slot, int num, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; virtual void BindSamplerPS(const Sampler* sampler, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) = 0; diff --git a/WickedEngine/wiGraphicsDevice_DX11.cpp b/WickedEngine/wiGraphicsDevice_DX11.cpp index 54296044d..a827ad86d 100644 --- a/WickedEngine/wiGraphicsDevice_DX11.cpp +++ b/WickedEngine/wiGraphicsDevice_DX11.cpp @@ -1614,7 +1614,7 @@ HRESULT GraphicsDevice_DX11::CreateBuffer(const GPUBufferDesc *pDesc, const Subr srv_desc.BufferEx.NumElements = desc.ByteWidth / desc.StructureByteStride; } - hr = device->CreateShaderResourceView(ppBuffer->resource_DX11, &srv_desc, &ppBuffer->shaderResourceView_DX11); + hr = device->CreateShaderResourceView(ppBuffer->resource_DX11, &srv_desc, &ppBuffer->SRV_DX11); assert(SUCCEEDED(hr) && "ShaderResourceView of the GPUBuffer could not be created!"); } @@ -1641,7 +1641,7 @@ HRESULT GraphicsDevice_DX11::CreateBuffer(const GPUBufferDesc *pDesc, const Subr uav_desc.Buffer.NumElements = desc.ByteWidth / desc.StructureByteStride; } - hr = device->CreateUnorderedAccessView(ppBuffer->resource_DX11, &uav_desc, &ppBuffer->unorderedAccessView_DX11); + hr = device->CreateUnorderedAccessView(ppBuffer->resource_DX11, &uav_desc, &ppBuffer->UAV_DX11); assert(SUCCEEDED(hr) && "UnorderedAccessView of the GPUBuffer could not be created!"); } @@ -1667,6 +1667,11 @@ HRESULT GraphicsDevice_DX11::CreateTexture1D(const Texture1DDesc* pDesc, const S if (FAILED(hr)) return hr; + if ((*ppTexture1D)->desc.MipLevels == 0) + { + (*ppTexture1D)->desc.MipLevels = (UINT)log2((*ppTexture1D)->desc.Width); + } + CreateShaderResourceView(*ppTexture1D); if (desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) @@ -1678,7 +1683,7 @@ HRESULT GraphicsDevice_DX11::CreateTexture1D(const Texture1DDesc* pDesc, const S uav_desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D; uav_desc.Texture2D.MipSlice = 0; - hr = device->CreateUnorderedAccessView((*ppTexture1D)->texture1D_DX11, &uav_desc, &(*ppTexture1D)->unorderedAccessView_DX11); + hr = device->CreateUnorderedAccessView((*ppTexture1D)->texture1D_DX11, &uav_desc, &(*ppTexture1D)->UAV_DX11); assert(SUCCEEDED(hr) && "UnorderedAccessView of the Texture1D could not be created!"); } @@ -1715,6 +1720,11 @@ HRESULT GraphicsDevice_DX11::CreateTexture2D(const Texture2DDesc* pDesc, const S if (FAILED(hr)) return hr; + if ((*ppTexture2D)->desc.MipLevels == 0) + { + (*ppTexture2D)->desc.MipLevels = (UINT)log2(max((*ppTexture2D)->desc.Width, (*ppTexture2D)->desc.Height)); + } + CreateRenderTargetView(*ppTexture2D); CreateShaderResourceView(*ppTexture2D); CreateDepthStencilView(*ppTexture2D); @@ -1729,7 +1739,7 @@ HRESULT GraphicsDevice_DX11::CreateTexture2D(const Texture2DDesc* pDesc, const S uav_desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; uav_desc.Texture2D.MipSlice = 0; - hr = device->CreateUnorderedAccessView((*ppTexture2D)->texture2D_DX11, &uav_desc, &(*ppTexture2D)->unorderedAccessView_DX11); + hr = device->CreateUnorderedAccessView((*ppTexture2D)->texture2D_DX11, &uav_desc, &(*ppTexture2D)->UAV_DX11); assert(SUCCEEDED(hr) && "UnorderedAccessView of the Texture2D could not be created!"); } @@ -1754,6 +1764,11 @@ HRESULT GraphicsDevice_DX11::CreateTexture3D(const Texture3DDesc* pDesc, const S if (FAILED(hr)) return hr; + if ((*ppTexture3D)->desc.MipLevels == 0) + { + (*ppTexture3D)->desc.MipLevels = (UINT)log2(max((*ppTexture3D)->desc.Width, max((*ppTexture3D)->desc.Height, (*ppTexture3D)->desc.Depth))); + } + CreateShaderResourceView(*ppTexture3D); CreateRenderTargetView(*ppTexture3D); @@ -1763,20 +1778,39 @@ HRESULT GraphicsDevice_DX11::CreateTexture3D(const Texture3DDesc* pDesc, const S D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc; ZeroMemory(&uav_desc, sizeof(uav_desc)); uav_desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; - uav_desc.Texture3D.MipSlice = 0; uav_desc.Texture3D.FirstWSlice = 0; - uav_desc.Texture3D.WSize = desc.Depth; - hr = device->CreateUnorderedAccessView((*ppTexture3D)->texture3D_DX11, &uav_desc, &(*ppTexture3D)->unorderedAccessView_DX11); + if ((*ppTexture3D)->independentUAVMIPs) + { + // Create subresource UAVs: + UINT miplevels = (*ppTexture3D)->desc.MipLevels; + uav_desc.Texture3D.WSize = desc.Depth; + for (UINT i = 0; i < miplevels; ++i) + { + uav_desc.Texture3D.MipSlice = i; - assert(SUCCEEDED(hr) && "UnorderedAccessView of the Texture2D could not be created!"); + (*ppTexture3D)->additionalUAVs_DX11.push_back(nullptr); + hr = device->CreateUnorderedAccessView((*ppTexture3D)->texture3D_DX11, &uav_desc, &(*ppTexture3D)->additionalUAVs_DX11[i]); + assert(SUCCEEDED(hr) && "UnorderedAccessView of the Texture3D could not be created!"); + + uav_desc.Texture3D.WSize /= 2; + } + } + + { + // Create full-resource UAV + uav_desc.Texture3D.MipSlice = 0; + uav_desc.Texture3D.WSize = desc.Depth; + hr = device->CreateUnorderedAccessView((*ppTexture3D)->texture3D_DX11, &uav_desc, &(*ppTexture3D)->UAV_DX11); + assert(SUCCEEDED(hr) && "UnorderedAccessView of the Texture3D could not be created!"); + } } return hr; } HRESULT GraphicsDevice_DX11::CreateShaderResourceView(Texture1D* pTexture) { - if (pTexture->shaderResourceView_DX11 != nullptr) + if (pTexture->SRV_DX11 != nullptr) { return E_FAIL; } @@ -1805,7 +1839,7 @@ HRESULT GraphicsDevice_DX11::CreateShaderResourceView(Texture1D* pTexture) shaderResourceViewDesc.Texture1D.MipLevels = -1; //...to least detailed } - hr = device->CreateShaderResourceView(pTexture->texture1D_DX11, &shaderResourceViewDesc, &pTexture->shaderResourceView_DX11); + hr = device->CreateShaderResourceView(pTexture->texture1D_DX11, &shaderResourceViewDesc, &pTexture->SRV_DX11); assert(SUCCEEDED(hr) && "ShaderResourceView Creation failed!"); } @@ -1814,7 +1848,7 @@ HRESULT GraphicsDevice_DX11::CreateShaderResourceView(Texture1D* pTexture) } HRESULT GraphicsDevice_DX11::CreateShaderResourceView(Texture2D* pTexture) { - if (pTexture->shaderResourceView_DX11 != nullptr) + if (pTexture->SRV_DX11 != nullptr) { return E_FAIL; } @@ -1896,7 +1930,7 @@ HRESULT GraphicsDevice_DX11::CreateShaderResourceView(Texture2D* pTexture) } } - hr = device->CreateShaderResourceView(pTexture->texture2D_DX11, &shaderResourceViewDesc, &pTexture->shaderResourceView_DX11); + hr = device->CreateShaderResourceView(pTexture->texture2D_DX11, &shaderResourceViewDesc, &pTexture->SRV_DX11); assert(SUCCEEDED(hr) && "ShaderResourceView Creation failed!"); } @@ -1905,7 +1939,7 @@ HRESULT GraphicsDevice_DX11::CreateShaderResourceView(Texture2D* pTexture) } HRESULT GraphicsDevice_DX11::CreateShaderResourceView(Texture3D* pTexture) { - if (pTexture->shaderResourceView_DX11 != nullptr) + if (pTexture->SRV_DX11 != nullptr) { return E_FAIL; } @@ -1918,19 +1952,38 @@ HRESULT GraphicsDevice_DX11::CreateShaderResourceView(Texture3D* pTexture) ZeroMemory(&shaderResourceViewDesc, sizeof(shaderResourceViewDesc)); shaderResourceViewDesc.Format = _ConvertFormat(pTexture->desc.Format); shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - shaderResourceViewDesc.Texture3D.MostDetailedMip = 0; //from most detailed... - shaderResourceViewDesc.Texture3D.MipLevels = -1; //...to least detailed - hr = device->CreateShaderResourceView(pTexture->texture3D_DX11, &shaderResourceViewDesc, &pTexture->shaderResourceView_DX11); + if (pTexture->independentSRVMIPs) + { + // Create subresource SRVs: + UINT miplevels = pTexture->desc.MipLevels; + for (UINT i = 0; i < miplevels; ++i) + { + shaderResourceViewDesc.Texture3D.MostDetailedMip = i; + shaderResourceViewDesc.Texture3D.MipLevels = 1; + + pTexture->additionalSRVs_DX11.push_back(nullptr); + hr = device->CreateShaderResourceView(pTexture->texture3D_DX11, &shaderResourceViewDesc, &pTexture->additionalSRVs_DX11[i]); + assert(SUCCEEDED(hr) && "ShaderResourceView Creation failed!"); + } + } + + { + // Create full-resource SRV: + shaderResourceViewDesc.Texture3D.MostDetailedMip = 0; //from most detailed... + shaderResourceViewDesc.Texture3D.MipLevels = -1; //...to least detailed + + hr = device->CreateShaderResourceView(pTexture->texture3D_DX11, &shaderResourceViewDesc, &pTexture->SRV_DX11); + assert(SUCCEEDED(hr) && "ShaderResourceView Creation failed!"); + } - assert(SUCCEEDED(hr) && "ShaderResourceView Creation failed!"); } return hr; } HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture2D* pTexture) { - if (!pTexture->renderTargetViews_DX11.empty()) + if (!pTexture->additionalRTVs_DX11.empty()) { return E_FAIL; } @@ -1963,34 +2016,32 @@ HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture2D* pTexture) renderTargetViewDesc.Texture2DArray.FirstArraySlice = i; renderTargetViewDesc.Texture2DArray.ArraySize = 1; - pTexture->renderTargetViews_DX11.push_back(nullptr); - hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->renderTargetViews_DX11[i]); + pTexture->additionalRTVs_DX11.push_back(nullptr); + hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->additionalRTVs_DX11[i]); + assert(SUCCEEDED(hr) && "RenderTargetView Creation failed!"); } } - else + else if (pTexture->independentRTVArraySlices) { - - if (pTexture->independentRTVArraySlices) + // independent slices + for (UINT i = 0; i < slices; ++i) { - // independent slices - for (UINT i = 0; i < slices; ++i) - { - renderTargetViewDesc.Texture2DArray.FirstArraySlice = i * 6; - renderTargetViewDesc.Texture2DArray.ArraySize = 6; + renderTargetViewDesc.Texture2DArray.FirstArraySlice = i * 6; + renderTargetViewDesc.Texture2DArray.ArraySize = 6; - pTexture->renderTargetViews_DX11.push_back(nullptr); - hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->renderTargetViews_DX11[i]); - } + pTexture->additionalRTVs_DX11.push_back(nullptr); + hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->additionalRTVs_DX11[i]); + assert(SUCCEEDED(hr) && "RenderTargetView Creation failed!"); } - else - { - // everything in one - renderTargetViewDesc.Texture2DArray.FirstArraySlice = 0; - renderTargetViewDesc.Texture2DArray.ArraySize = arraySize; + } - pTexture->renderTargetViews_DX11.push_back(nullptr); - hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->renderTargetViews_DX11[0]); - } + { + // Create full-resource RTVs: + renderTargetViewDesc.Texture2DArray.FirstArraySlice = 0; + renderTargetViewDesc.Texture2DArray.ArraySize = arraySize; + + hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->RTV_DX11); + assert(SUCCEEDED(hr) && "RenderTargetView Creation failed!"); } } else @@ -1998,6 +2049,7 @@ HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture2D* pTexture) // Texture2D, Texture2DArray... if (arraySize > 1 && pTexture->independentRTVArraySlices) { + // Create subresource RTVs: for (UINT i = 0; i < arraySize; ++i) { if (multisampled) @@ -2014,12 +2066,14 @@ HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture2D* pTexture) renderTargetViewDesc.Texture2DArray.MipSlice = 0; } - pTexture->renderTargetViews_DX11.push_back(nullptr); - hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->renderTargetViews_DX11[i]); + pTexture->additionalRTVs_DX11.push_back(nullptr); + hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->additionalRTVs_DX11[i]); + assert(SUCCEEDED(hr) && "RenderTargetView Creation failed!"); } } - else + { + // Create the full-resource RTV: if (arraySize > 1) { if (multisampled) @@ -2049,19 +2103,17 @@ HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture2D* pTexture) } } - pTexture->renderTargetViews_DX11.push_back(nullptr); - hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->renderTargetViews_DX11[0]); + hr = device->CreateRenderTargetView(pTexture->texture2D_DX11, &renderTargetViewDesc, &pTexture->RTV_DX11); + assert(SUCCEEDED(hr) && "RenderTargetView Creation failed!"); } } - - assert(SUCCEEDED(hr) && "RenderTargetView Creation failed!"); } return hr; } HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture3D* pTexture) { - if (!pTexture->renderTargetViews_DX11.empty()) + if (!pTexture->additionalRTVs_DX11.empty()) { return E_FAIL; } @@ -2076,6 +2128,7 @@ HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture3D* pTexture) if (pTexture->independentRTVArraySlices) { + // Create Subresource RTVs: for (UINT i = 0; i < pTexture->GetDesc().Depth; ++i) { renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; @@ -2083,19 +2136,20 @@ HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture3D* pTexture) renderTargetViewDesc.Texture3D.FirstWSlice = i; renderTargetViewDesc.Texture3D.WSize = 1; - pTexture->renderTargetViews_DX11.push_back(nullptr); - hr = device->CreateRenderTargetView(pTexture->texture3D_DX11, &renderTargetViewDesc, &pTexture->renderTargetViews_DX11[i]); + pTexture->additionalRTVs_DX11.push_back(nullptr); + hr = device->CreateRenderTargetView(pTexture->texture3D_DX11, &renderTargetViewDesc, &pTexture->additionalRTVs_DX11[i]); } } - else + { + // Create full-resource RTV: renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; renderTargetViewDesc.Texture3D.MipSlice = 0; renderTargetViewDesc.Texture3D.FirstWSlice = 0; renderTargetViewDesc.Texture3D.WSize = -1; - pTexture->renderTargetViews_DX11.push_back(nullptr); - hr = device->CreateRenderTargetView(pTexture->texture3D_DX11, &renderTargetViewDesc, &pTexture->renderTargetViews_DX11[0]); + pTexture->additionalRTVs_DX11.push_back(nullptr); + hr = device->CreateRenderTargetView(pTexture->texture3D_DX11, &renderTargetViewDesc, &pTexture->additionalRTVs_DX11[0]); } assert(SUCCEEDED(hr) && "RenderTargetView Creation failed!"); @@ -2105,7 +2159,7 @@ HRESULT GraphicsDevice_DX11::CreateRenderTargetView(Texture3D* pTexture) } HRESULT GraphicsDevice_DX11::CreateDepthStencilView(Texture2D* pTexture) { - if (!pTexture->depthStencilViews_DX11.empty()) + if (!pTexture->additionalDSVs_DX11.empty()) { return E_FAIL; } @@ -2155,34 +2209,29 @@ HRESULT GraphicsDevice_DX11::CreateDepthStencilView(Texture2D* pTexture) depthStencilViewDesc.Texture2DArray.FirstArraySlice = i; depthStencilViewDesc.Texture2DArray.ArraySize = 1; - pTexture->depthStencilViews_DX11.push_back(nullptr); - hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->depthStencilViews_DX11[i]); + pTexture->additionalDSVs_DX11.push_back(nullptr); + hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->additionalDSVs_DX11[i]); } } - else + else if (pTexture->independentRTVArraySlices) { - - if (pTexture->independentRTVArraySlices) + // independent slices + for (UINT i = 0; i < slices; ++i) { - // independent slices - for (UINT i = 0; i < slices; ++i) - { - depthStencilViewDesc.Texture2DArray.FirstArraySlice = i * 6; - depthStencilViewDesc.Texture2DArray.ArraySize = 6; + depthStencilViewDesc.Texture2DArray.FirstArraySlice = i * 6; + depthStencilViewDesc.Texture2DArray.ArraySize = 6; - pTexture->depthStencilViews_DX11.push_back(nullptr); - hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->depthStencilViews_DX11[i]); - } + pTexture->additionalDSVs_DX11.push_back(nullptr); + hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->additionalDSVs_DX11[i]); } - else - { - // everything in one - depthStencilViewDesc.Texture2DArray.FirstArraySlice = 0; - depthStencilViewDesc.Texture2DArray.ArraySize = arraySize; + } - pTexture->depthStencilViews_DX11.push_back(nullptr); - hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->depthStencilViews_DX11[0]); - } + { + // Create full-resource DSV: + depthStencilViewDesc.Texture2DArray.FirstArraySlice = 0; + depthStencilViewDesc.Texture2DArray.ArraySize = arraySize; + + hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->DSV_DX11); } } else @@ -2190,6 +2239,7 @@ HRESULT GraphicsDevice_DX11::CreateDepthStencilView(Texture2D* pTexture) // Texture2D, Texture2DArray... if (arraySize > 1 && pTexture->independentRTVArraySlices) { + // Create subresource DSVs: for (UINT i = 0; i < arraySize; ++i) { if (multisampled) @@ -2206,12 +2256,13 @@ HRESULT GraphicsDevice_DX11::CreateDepthStencilView(Texture2D* pTexture) depthStencilViewDesc.Texture2DArray.ArraySize = 1; } - pTexture->depthStencilViews_DX11.push_back(nullptr); - hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->depthStencilViews_DX11[i]); + pTexture->additionalDSVs_DX11.push_back(nullptr); + hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->additionalDSVs_DX11[i]); } } else { + // Create full-resource DSV: if (arraySize > 1) { if (multisampled) @@ -2241,8 +2292,7 @@ HRESULT GraphicsDevice_DX11::CreateDepthStencilView(Texture2D* pTexture) } } - pTexture->depthStencilViews_DX11.push_back(nullptr); - hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->depthStencilViews_DX11[0]); + hr = device->CreateDepthStencilView(pTexture->texture2D_DX11, &depthStencilViewDesc, &pTexture->DSV_DX11); } } @@ -2565,87 +2615,219 @@ void GraphicsDevice_DX11::BindViewports(UINT NumViewports, const ViewPort *pView SAFE_DELETE_ARRAY(pd3dViewPorts); } void GraphicsDevice_DX11::BindRenderTargetsUAVs(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GPUUnorderedResource* const *ppUAVs, int slotUAV, int countUAV, - GRAPHICSTHREAD threadID, UINT arrayIndex) + GRAPHICSTHREAD threadID, int arrayIndex) { + // RTVs: ID3D11RenderTargetView* renderTargetViews[8]; ZeroMemory(renderTargetViews, sizeof(renderTargetViews)); for (UINT i = 0; i < min(NumViews, 8); ++i) { - assert(ppRenderTargets[i]->renderTargetViews_DX11.size() > arrayIndex && "Invalid rendertarget arrayIndex!"); - renderTargetViews[i] = ppRenderTargets[i]->renderTargetViews_DX11[arrayIndex]; + if (arrayIndex < 0) + { + renderTargetViews[i] = ppRenderTargets[i]->RTV_DX11; + } + else + { + assert(ppRenderTargets[i]->additionalRTVs_DX11.size() > arrayIndex && "Invalid rendertarget arrayIndex!"); + renderTargetViews[i] = ppRenderTargets[i]->additionalRTVs_DX11[arrayIndex]; + } } - assert(depthStencilTexture == nullptr || depthStencilTexture->depthStencilViews_DX11.size() > arrayIndex && "Invalid depthstencil arrayIndex!"); - ID3D11DepthStencilView* depthStencilView = (depthStencilTexture == nullptr ? nullptr : depthStencilTexture->depthStencilViews_DX11[arrayIndex]); + + // DSVs: + ID3D11DepthStencilView* depthStencilView = nullptr; + if (depthStencilTexture != nullptr) + { + if (arrayIndex < 0) + { + depthStencilView = depthStencilTexture->DSV_DX11; + } + else + { + assert(depthStencilTexture->additionalDSVs_DX11.size() > arrayIndex && "Invalid depthstencil arrayIndex!"); + depthStencilView = depthStencilTexture->additionalDSVs_DX11[arrayIndex]; + } + } + + // UAVs: ID3D11UnorderedAccessView* UAVs[8]; ZeroMemory(UAVs, sizeof(UAVs)); for (int i = 0; i < min(countUAV, 8); ++i) { - UAVs[i] = ppUAVs[i]->unorderedAccessView_DX11; + UAVs[i] = ppUAVs[i]->UAV_DX11; } + + deviceContexts[threadID]->OMSetRenderTargetsAndUnorderedAccessViews(NumViews, renderTargetViews, depthStencilView, slotUAV, countUAV, UAVs, nullptr); } -void GraphicsDevice_DX11::BindRenderTargets(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GRAPHICSTHREAD threadID, UINT arrayIndex) +void GraphicsDevice_DX11::BindRenderTargets(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GRAPHICSTHREAD threadID, int arrayIndex) { + // RTVs: ID3D11RenderTargetView* renderTargetViews[8]; ZeroMemory(renderTargetViews, sizeof(renderTargetViews)); for (UINT i = 0; i < min(NumViews, 8); ++i) { - assert(ppRenderTargets[i]->renderTargetViews_DX11.size() > arrayIndex && "Invalid rendertarget arrayIndex!"); - renderTargetViews[i] = ppRenderTargets[i]->renderTargetViews_DX11[arrayIndex]; + if (arrayIndex < 0) + { + renderTargetViews[i] = ppRenderTargets[i]->RTV_DX11; + } + else + { + assert(ppRenderTargets[i]->additionalRTVs_DX11.size() > arrayIndex && "Invalid rendertarget arrayIndex!"); + renderTargetViews[i] = ppRenderTargets[i]->additionalRTVs_DX11[arrayIndex]; + } } - assert(depthStencilTexture == nullptr || depthStencilTexture->depthStencilViews_DX11.size() > arrayIndex && "Invalid depthstencil arrayIndex!"); - ID3D11DepthStencilView* depthStencilView = (depthStencilTexture == nullptr ? nullptr : depthStencilTexture->depthStencilViews_DX11[arrayIndex]); + + // DSVs: + ID3D11DepthStencilView* depthStencilView = nullptr; + if (depthStencilTexture != nullptr) + { + if (arrayIndex < 0) + { + depthStencilView = depthStencilTexture->DSV_DX11; + } + else + { + assert(depthStencilTexture->additionalDSVs_DX11.size() > arrayIndex && "Invalid depthstencil arrayIndex!"); + depthStencilView = depthStencilTexture->additionalDSVs_DX11[arrayIndex]; + } + } + deviceContexts[threadID]->OMSetRenderTargets(NumViews, renderTargetViews, depthStencilView); } -void GraphicsDevice_DX11::ClearRenderTarget(Texture* pTexture, const FLOAT ColorRGBA[4], GRAPHICSTHREAD threadID, UINT arrayIndex) +void GraphicsDevice_DX11::ClearRenderTarget(Texture* pTexture, const FLOAT ColorRGBA[4], GRAPHICSTHREAD threadID, int arrayIndex) { - assert(pTexture->renderTargetViews_DX11.size() > arrayIndex && "Invalid rendertarget arrayIndex!"); - deviceContexts[threadID]->ClearRenderTargetView(pTexture->renderTargetViews_DX11[arrayIndex], ColorRGBA); + if (arrayIndex < 0) + { + deviceContexts[threadID]->ClearRenderTargetView(pTexture->RTV_DX11, ColorRGBA); + } + else + { + assert(pTexture->additionalRTVs_DX11.size() > arrayIndex && "Invalid rendertarget arrayIndex!"); + deviceContexts[threadID]->ClearRenderTargetView(pTexture->additionalRTVs_DX11[arrayIndex], ColorRGBA); + } } -void GraphicsDevice_DX11::ClearDepthStencil(Texture2D* pTexture, UINT ClearFlags, FLOAT Depth, UINT8 Stencil, GRAPHICSTHREAD threadID, UINT arrayIndex) +void GraphicsDevice_DX11::ClearDepthStencil(Texture2D* pTexture, UINT ClearFlags, FLOAT Depth, UINT8 Stencil, GRAPHICSTHREAD threadID, int arrayIndex) { - assert(pTexture->depthStencilViews_DX11.size() > arrayIndex && "Invalid depthstencil arrayIndex!"); UINT _flags = 0; if (ClearFlags & CLEAR_DEPTH) _flags |= D3D11_CLEAR_DEPTH; if (ClearFlags & CLEAR_STENCIL) _flags |= D3D11_CLEAR_STENCIL; - deviceContexts[threadID]->ClearDepthStencilView(pTexture->depthStencilViews_DX11[arrayIndex], _flags, Depth, Stencil); + + if (arrayIndex < 0) + { + deviceContexts[threadID]->ClearDepthStencilView(pTexture->DSV_DX11, _flags, Depth, Stencil); + } + else + { + assert(pTexture->additionalDSVs_DX11.size() > arrayIndex && "Invalid depthstencil arrayIndex!"); + deviceContexts[threadID]->ClearDepthStencilView(pTexture->additionalDSVs_DX11[arrayIndex], _flags, Depth, Stencil); + } } -void GraphicsDevice_DX11::BindResourcePS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID) +void GraphicsDevice_DX11::BindResourcePS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID, int arrayIndex) { if (resource != nullptr) - deviceContexts[threadID]->PSSetShaderResources(slot, 1, &resource->shaderResourceView_DX11); + { + if (arrayIndex < 0) + { + deviceContexts[threadID]->PSSetShaderResources(slot, 1, &resource->SRV_DX11); + } + else + { + assert(resource->additionalSRVs_DX11.size() > arrayIndex && "Invalid arrayIndex!"); + deviceContexts[threadID]->PSSetShaderResources(slot, 1, &resource->additionalSRVs_DX11[arrayIndex]); + } + } } -void GraphicsDevice_DX11::BindResourceVS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID) +void GraphicsDevice_DX11::BindResourceVS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID, int arrayIndex) { if (resource != nullptr) - deviceContexts[threadID]->VSSetShaderResources(slot, 1, &resource->shaderResourceView_DX11); + { + if (arrayIndex < 0) + { + deviceContexts[threadID]->VSSetShaderResources(slot, 1, &resource->SRV_DX11); + } + else + { + assert(resource->additionalSRVs_DX11.size() > arrayIndex && "Invalid arrayIndex!"); + deviceContexts[threadID]->VSSetShaderResources(slot, 1, &resource->additionalSRVs_DX11[arrayIndex]); + } + } } -void GraphicsDevice_DX11::BindResourceGS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID) +void GraphicsDevice_DX11::BindResourceGS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID, int arrayIndex) { if (resource != nullptr) - deviceContexts[threadID]->GSSetShaderResources(slot, 1, &resource->shaderResourceView_DX11); + { + if (arrayIndex < 0) + { + deviceContexts[threadID]->GSSetShaderResources(slot, 1, &resource->SRV_DX11); + } + else + { + assert(resource->additionalSRVs_DX11.size() > arrayIndex && "Invalid arrayIndex!"); + deviceContexts[threadID]->GSSetShaderResources(slot, 1, &resource->additionalSRVs_DX11[arrayIndex]); + } + } } -void GraphicsDevice_DX11::BindResourceDS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID) +void GraphicsDevice_DX11::BindResourceDS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID, int arrayIndex) { if (resource != nullptr) - deviceContexts[threadID]->DSSetShaderResources(slot, 1, &resource->shaderResourceView_DX11); + { + if (arrayIndex < 0) + { + deviceContexts[threadID]->DSSetShaderResources(slot, 1, &resource->SRV_DX11); + } + else + { + assert(resource->additionalSRVs_DX11.size() > arrayIndex && "Invalid arrayIndex!"); + deviceContexts[threadID]->DSSetShaderResources(slot, 1, &resource->additionalSRVs_DX11[arrayIndex]); + } + } } -void GraphicsDevice_DX11::BindResourceHS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID) +void GraphicsDevice_DX11::BindResourceHS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID, int arrayIndex) { if (resource != nullptr) - deviceContexts[threadID]->HSSetShaderResources(slot, 1, &resource->shaderResourceView_DX11); + { + if (arrayIndex < 0) + { + deviceContexts[threadID]->HSSetShaderResources(slot, 1, &resource->SRV_DX11); + } + else + { + assert(resource->additionalSRVs_DX11.size() > arrayIndex && "Invalid arrayIndex!"); + deviceContexts[threadID]->HSSetShaderResources(slot, 1, &resource->additionalSRVs_DX11[arrayIndex]); + } + } } -void GraphicsDevice_DX11::BindResourceCS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID) +void GraphicsDevice_DX11::BindResourceCS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID, int arrayIndex) { if (resource != nullptr) - deviceContexts[threadID]->CSSetShaderResources(slot, 1, &resource->shaderResourceView_DX11); + { + if (arrayIndex < 0) + { + deviceContexts[threadID]->CSSetShaderResources(slot, 1, &resource->SRV_DX11); + } + else + { + assert(resource->additionalSRVs_DX11.size() > arrayIndex && "Invalid arrayIndex!"); + deviceContexts[threadID]->CSSetShaderResources(slot, 1, &resource->additionalSRVs_DX11[arrayIndex]); + } + } } -void GraphicsDevice_DX11::BindUnorderedAccessResourceCS(const GPUUnorderedResource* resource, int slot, GRAPHICSTHREAD threadID) +void GraphicsDevice_DX11::BindUnorderedAccessResourceCS(const GPUUnorderedResource* resource, int slot, GRAPHICSTHREAD threadID, int arrayIndex) { if (resource != nullptr) - deviceContexts[threadID]->CSSetUnorderedAccessViews(slot, 1, &resource->unorderedAccessView_DX11, nullptr); + { + if (arrayIndex < 0) + { + deviceContexts[threadID]->CSSetUnorderedAccessViews(slot, 1, &resource->UAV_DX11, nullptr); + } + else + { + assert(resource->additionalUAVs_DX11.size() > arrayIndex && "Invalid arrayIndex!"); + deviceContexts[threadID]->CSSetUnorderedAccessViews(slot, 1, &resource->additionalUAVs_DX11[arrayIndex], nullptr); + } + } } void GraphicsDevice_DX11::UnBindResources(int slot, int num, GRAPHICSTHREAD threadID) { @@ -2834,7 +3016,7 @@ void GraphicsDevice_DX11::Dispatch(UINT threadGroupCountX, UINT threadGroupCount } void GraphicsDevice_DX11::GenerateMips(Texture* texture, GRAPHICSTHREAD threadID) { - deviceContexts[threadID]->GenerateMips(texture->shaderResourceView_DX11); + deviceContexts[threadID]->GenerateMips(texture->SRV_DX11); } void GraphicsDevice_DX11::CopyTexture2D(Texture2D* pDst, const Texture2D* pSrc, GRAPHICSTHREAD threadID) { @@ -3006,14 +3188,14 @@ HRESULT GraphicsDevice_DX11::CreateTextureFromFile(const string& fileName, Textu if (!fileName.substr(fileName.length() - 4).compare(string(".dds"))) { // Load dds - hr = CreateDDSTextureFromFile(device, wstring(fileName.begin(),fileName.end()).c_str(), (ID3D11Resource**)&(*ppTexture)->texture2D_DX11, &(*ppTexture)->shaderResourceView_DX11); + hr = CreateDDSTextureFromFile(device, wstring(fileName.begin(),fileName.end()).c_str(), (ID3D11Resource**)&(*ppTexture)->texture2D_DX11, &(*ppTexture)->SRV_DX11); } else { // Load WIC if (mipMaps && threadID == GRAPHICSTHREAD_IMMEDIATE) LOCK(); - hr = CreateWICTextureFromFile(mipMaps, device, deviceContexts[threadID], wstring(fileName.begin(), fileName.end()).c_str(), (ID3D11Resource**)&(*ppTexture)->texture2D_DX11, &(*ppTexture)->shaderResourceView_DX11); + hr = CreateWICTextureFromFile(mipMaps, device, deviceContexts[threadID], wstring(fileName.begin(), fileName.end()).c_str(), (ID3D11Resource**)&(*ppTexture)->texture2D_DX11, &(*ppTexture)->SRV_DX11); if (mipMaps && threadID == GRAPHICSTHREAD_IMMEDIATE) UNLOCK(); } diff --git a/WickedEngine/wiGraphicsDevice_DX11.h b/WickedEngine/wiGraphicsDevice_DX11.h index 0028d6fb1..861766dea 100644 --- a/WickedEngine/wiGraphicsDevice_DX11.h +++ b/WickedEngine/wiGraphicsDevice_DX11.h @@ -69,17 +69,17 @@ namespace wiGraphicsTypes virtual void BindViewports(UINT NumViewports, const ViewPort *pViewports, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; virtual void BindRenderTargetsUAVs(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GPUUnorderedResource* const *ppUAVs, int slotUAV, int countUAV, - GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, UINT arrayIndex = 0) override; - virtual void BindRenderTargets(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, UINT arrayIndex = 0) override; - virtual void ClearRenderTarget(Texture* pTexture, const FLOAT ColorRGBA[4], GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, UINT arrayIndex = 0) override; - virtual void ClearDepthStencil(Texture2D* pTexture, UINT ClearFlags, FLOAT Depth, UINT8 Stencil, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, UINT arrayIndex = 0) override; - virtual void BindResourcePS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; - virtual void BindResourceVS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; - virtual void BindResourceGS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; - virtual void BindResourceDS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; - virtual void BindResourceHS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; - virtual void BindResourceCS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; - virtual void BindUnorderedAccessResourceCS(const GPUUnorderedResource* buffer, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; + GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void BindRenderTargets(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void ClearRenderTarget(Texture* pTexture, const FLOAT ColorRGBA[4], GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void ClearDepthStencil(Texture2D* pTexture, UINT ClearFlags, FLOAT Depth, UINT8 Stencil, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void BindResourcePS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void BindResourceVS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void BindResourceGS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void BindResourceDS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void BindResourceHS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void BindResourceCS(const GPUResource* resource, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; + virtual void BindUnorderedAccessResourceCS(const GPUUnorderedResource* buffer, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE, int arrayIndex = -1) override; virtual void UnBindResources(int slot, int num, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; virtual void UnBindUnorderedAccessResources(int slot, int num, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; virtual void BindSamplerPS(const Sampler* sampler, int slot, GRAPHICSTHREAD threadID = GRAPHICSTHREAD_IMMEDIATE) override; diff --git a/WickedEngine/wiGraphicsResource.cpp b/WickedEngine/wiGraphicsResource.cpp index c02c26f50..18671fe3c 100644 --- a/WickedEngine/wiGraphicsResource.cpp +++ b/WickedEngine/wiGraphicsResource.cpp @@ -68,20 +68,28 @@ namespace wiGraphicsTypes GPUResource::GPUResource() { - SAFE_INIT(shaderResourceView_DX11); + SAFE_INIT(SRV_DX11); } GPUResource::~GPUResource() { - SAFE_RELEASE(shaderResourceView_DX11); + SAFE_RELEASE(SRV_DX11); + for (auto& x : additionalSRVs_DX11) + { + SAFE_RELEASE(x); + } } GPUUnorderedResource::GPUUnorderedResource() { - SAFE_INIT(unorderedAccessView_DX11); + SAFE_INIT(UAV_DX11); } GPUUnorderedResource::~GPUUnorderedResource() { - SAFE_RELEASE(unorderedAccessView_DX11); + SAFE_RELEASE(UAV_DX11); + for (auto& x : additionalUAVs_DX11) + { + SAFE_RELEASE(x); + } } GPUBuffer::GPUBuffer() : GPUResource(), GPUUnorderedResource() @@ -149,12 +157,16 @@ namespace wiGraphicsTypes SAFE_DELETE(vertexLayout); } - Texture::Texture() : GPUResource(), GPUUnorderedResource(), independentRTVArraySlices(false), independentRTVCubemapFaces(false) + Texture::Texture() : GPUResource(), GPUUnorderedResource() + , independentRTVArraySlices(false), independentRTVCubemapFaces(false) + , independentSRVMIPs(false), independentUAVMIPs(false) { + SAFE_INIT(RTV_DX11); } Texture::~Texture() { - for (auto& x : renderTargetViews_DX11) + SAFE_RELEASE(RTV_DX11); + for (auto& x : additionalRTVs_DX11) { SAFE_RELEASE(x); } @@ -163,17 +175,17 @@ namespace wiGraphicsTypes { independentRTVArraySlices = value; } - bool Texture::IsIndepententRenderTargetArraySlices() - { - return independentRTVArraySlices; - } void Texture::RequestIndepententRenderTargetCubemapFaces(bool value) { independentRTVCubemapFaces = value; } - bool Texture::IsIndepententRenderTargetCubemapFaces() + void Texture::RequestIndepententShaderResourcesForMIPs(bool value) { - return independentRTVCubemapFaces; + independentSRVMIPs = value; + } + void Texture::RequestIndepententUnorderedAccessResourcesForMIPs(bool value) + { + independentUAVMIPs = value; } Texture1D::Texture1D() :Texture() @@ -188,11 +200,13 @@ namespace wiGraphicsTypes Texture2D::Texture2D() :Texture() { SAFE_INIT(texture2D_DX11); + SAFE_INIT(DSV_DX11); } Texture2D::~Texture2D() { SAFE_RELEASE(texture2D_DX11); - for (auto& x : depthStencilViews_DX11) + SAFE_RELEASE(DSV_DX11); + for (auto& x : additionalDSVs_DX11) { SAFE_RELEASE(x); } diff --git a/WickedEngine/wiGraphicsResource.h b/WickedEngine/wiGraphicsResource.h index 399feef90..6c9b45aee 100644 --- a/WickedEngine/wiGraphicsResource.h +++ b/WickedEngine/wiGraphicsResource.h @@ -122,7 +122,8 @@ namespace wiGraphicsTypes { friend class GraphicsDevice_DX11; private: - ID3D11ShaderResourceView* shaderResourceView_DX11; + ID3D11ShaderResourceView* SRV_DX11; // main resource SRV + vector additionalSRVs_DX11; // can be used for sub-resources if requested protected: GPUResource(); @@ -133,7 +134,8 @@ namespace wiGraphicsTypes { friend class GraphicsDevice_DX11; private: - ID3D11UnorderedAccessView* unorderedAccessView_DX11; + ID3D11UnorderedAccessView* UAV_DX11; // main resource UAV + vector additionalUAVs_DX11; // can be used for sub-resources if requested protected: GPUUnorderedResource(); @@ -232,19 +234,25 @@ namespace wiGraphicsTypes { friend class GraphicsDevice_DX11; private: - vector renderTargetViews_DX11; + ID3D11RenderTargetView* RTV_DX11; + vector additionalRTVs_DX11; bool independentRTVArraySlices; bool independentRTVCubemapFaces; + bool independentSRVMIPs; + bool independentUAVMIPs; public: Texture(); virtual ~Texture(); + // if true, then each array slice will get a unique rendertarget void RequestIndepententRenderTargetArraySlices(bool value); - bool IsIndepententRenderTargetArraySlices(); // if true, then each face of the cubemap will get a unique rendertarget void RequestIndepententRenderTargetCubemapFaces(bool value); - bool IsIndepententRenderTargetCubemapFaces(); + // if true, then each miplevel will get unique shader resource + void RequestIndepententShaderResourcesForMIPs(bool value); + // if true, then each miplevel will get unique unordered access resource + void RequestIndepententUnorderedAccessResourcesForMIPs(bool value); }; class Texture1D : public Texture @@ -264,9 +272,10 @@ namespace wiGraphicsTypes { friend class GraphicsDevice_DX11; private: - vector depthStencilViews_DX11; - ID3D11Texture2D* texture2D_DX11; - Texture2DDesc desc; + ID3D11DepthStencilView* DSV_DX11; + vector additionalDSVs_DX11; + ID3D11Texture2D* texture2D_DX11; + Texture2DDesc desc; public: Texture2D(); virtual ~Texture2D(); diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 3e7652b48..e10bde9a8 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -782,8 +782,10 @@ void wiRenderer::LoadShaders() computeShaders[CSTYPE_TILEDLIGHTCULLING_DEBUG] = static_cast(wiResourceManager::GetShaderManager()->add(SHADERPATH + "lightCullingCS_DEBUG.cso", wiResourceManager::COMPUTESHADER)); computeShaders[CSTYPE_RESOLVEMSAADEPTHSTENCIL] = static_cast(wiResourceManager::GetShaderManager()->add(SHADERPATH + "resolveMSAADepthStencilCS.cso", wiResourceManager::COMPUTESHADER)); computeShaders[CSTYPE_VOXELSCENECOPYCLEAR] = static_cast(wiResourceManager::GetShaderManager()->add(SHADERPATH + "voxelSceneCopyClearCS.cso", wiResourceManager::COMPUTESHADER)); + computeShaders[CSTYPE_VOXELSCENECOPYCLEAR_TEMPORALSMOOTHING] = static_cast(wiResourceManager::GetShaderManager()->add(SHADERPATH + "voxelSceneCopyClear_TemporalSmoothing.cso", wiResourceManager::COMPUTESHADER)); computeShaders[CSTYPE_VOXELRADIANCESECONDARYBOUNCE] = static_cast(wiResourceManager::GetShaderManager()->add(SHADERPATH + "voxelRadianceSecondaryBounceCS.cso", wiResourceManager::COMPUTESHADER)); computeShaders[CSTYPE_VOXELCLEARONLYNORMAL] = static_cast(wiResourceManager::GetShaderManager()->add(SHADERPATH + "voxelClearOnlyNormalCS.cso", wiResourceManager::COMPUTESHADER)); + computeShaders[CSTYPE_GENERATEMIPCHAIN3D_SIMPLEFILTER] = static_cast(wiResourceManager::GetShaderManager()->add(SHADERPATH + "generateMIPChain3D_SimpleFilterCS.cso", wiResourceManager::COMPUTESHADER)); hullShaders[HSTYPE_OBJECT] = static_cast(wiResourceManager::GetShaderManager()->add(SHADERPATH + "objectHS.cso", wiResourceManager::HULLSHADER)); @@ -3999,22 +4001,23 @@ void wiRenderer::VoxelRadiance(GRAPHICSTHREAD threadID) desc.Depth = voxelSceneData.res; desc.MipLevels = 0; desc.Format = FORMAT_R16G16B16A16_FLOAT; - desc.BindFlags = BIND_RENDER_TARGET | BIND_UNORDERED_ACCESS | BIND_SHADER_RESOURCE; + desc.BindFlags = BIND_UNORDERED_ACCESS | BIND_SHADER_RESOURCE; desc.Usage = USAGE_DEFAULT; desc.CPUAccessFlags = 0; - desc.MiscFlags = RESOURCE_MISC_GENERATE_MIPS; + desc.MiscFlags = 0; textures[TEXTYPE_3D_VOXELRADIANCE] = new Texture3D; + textures[TEXTYPE_3D_VOXELRADIANCE]->RequestIndepententShaderResourcesForMIPs(true); + textures[TEXTYPE_3D_VOXELRADIANCE]->RequestIndepententUnorderedAccessResourcesForMIPs(true); HRESULT hr = GetDevice()->CreateTexture3D(&desc, nullptr, (Texture3D**)&textures[TEXTYPE_3D_VOXELRADIANCE]); assert(SUCCEEDED(hr)); - textures[TEXTYPE_3D_VOXELRADIANCE_HELPER] = new Texture3D; - hr = GetDevice()->CreateTexture3D(&desc, nullptr, (Texture3D**)&textures[TEXTYPE_3D_VOXELRADIANCE_HELPER]); - assert(SUCCEEDED(hr)); } if (voxelSceneData.secondaryBounceEnabled && textures[TEXTYPE_3D_VOXELRADIANCE_HELPER] == nullptr) { Texture3DDesc desc = ((Texture3D*)textures[TEXTYPE_3D_VOXELRADIANCE])->GetDesc(); textures[TEXTYPE_3D_VOXELRADIANCE_HELPER] = new Texture3D; + textures[TEXTYPE_3D_VOXELRADIANCE_HELPER]->RequestIndepententShaderResourcesForMIPs(true); + textures[TEXTYPE_3D_VOXELRADIANCE_HELPER]->RequestIndepententUnorderedAccessResourcesForMIPs(true); HRESULT hr = GetDevice()->CreateTexture3D(&desc, nullptr, (Texture3D**)&textures[TEXTYPE_3D_VOXELRADIANCE_HELPER]); assert(SUCCEEDED(hr)); } @@ -4085,7 +4088,14 @@ void wiRenderer::VoxelRadiance(GRAPHICSTHREAD threadID) GetDevice()->BindUnorderedAccessResourceCS(resourceBuffers[RBTYPE_VOXELSCENE], 0, threadID); GetDevice()->BindUnorderedAccessResourceCS(textures[TEXTYPE_3D_VOXELRADIANCE], 1, threadID); - GetDevice()->BindCS(computeShaders[CSTYPE_VOXELSCENECOPYCLEAR], threadID); + if (GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_UNORDEREDACCESSTEXTURE_LOAD_FORMAT_EXT)) + { + GetDevice()->BindCS(computeShaders[CSTYPE_VOXELSCENECOPYCLEAR_TEMPORALSMOOTHING], threadID); + } + else + { + GetDevice()->BindCS(computeShaders[CSTYPE_VOXELSCENECOPYCLEAR], threadID); + } GetDevice()->Dispatch((UINT)(voxelSceneData.res * voxelSceneData.res * voxelSceneData.res / 1024), 1, 1, threadID); GetDevice()->EventEnd(); @@ -4094,7 +4104,7 @@ void wiRenderer::VoxelRadiance(GRAPHICSTHREAD threadID) GetDevice()->EventBegin("Voxel Radiance Secondary Bounce", threadID); GetDevice()->UnBindUnorderedAccessResources(1, 1, threadID); // Pre-integrate the voxel texture by creating blurred mip levels: - GetDevice()->GenerateMips(textures[TEXTYPE_3D_VOXELRADIANCE], threadID); + GenerateMipChain((Texture3D*)textures[TEXTYPE_3D_VOXELRADIANCE], MIPGENFILTER_LINEAR, threadID); GetDevice()->BindUnorderedAccessResourceCS(textures[TEXTYPE_3D_VOXELRADIANCE_HELPER], 0, threadID); GetDevice()->BindResourceCS(textures[TEXTYPE_3D_VOXELRADIANCE], 0, threadID); GetDevice()->BindResourceCS(resourceBuffers[RBTYPE_VOXELSCENE], 1, threadID); @@ -4117,7 +4127,7 @@ void wiRenderer::VoxelRadiance(GRAPHICSTHREAD threadID) // Pre-integrate the voxel texture by creating blurred mip levels: - GetDevice()->GenerateMips(result, threadID); + GenerateMipChain(result, MIPGENFILTER_LINEAR, threadID); } if (voxelHelper) @@ -4324,6 +4334,57 @@ void wiRenderer::ResolveMSAADepthBuffer(Texture2D* dst, Texture2D* src, GRAPHICS GetDevice()->EventEnd(); } +void wiRenderer::GenerateMipChain(Texture1D* texture, MIPGENFILTER filter, GRAPHICSTHREAD threadID) +{ + assert(0 && "Not implemented!"); +} +void wiRenderer::GenerateMipChain(Texture2D* texture, MIPGENFILTER filter, GRAPHICSTHREAD threadID) +{ + assert(0 && "Not implemented!"); +} +void wiRenderer::GenerateMipChain(Texture3D* texture, MIPGENFILTER filter, GRAPHICSTHREAD threadID) +{ + Texture3DDesc desc = texture->GetDesc(); + + if (desc.MipLevels < 2) + { + assert(0); + return; + } + + GetDevice()->EventBegin("GenerateMipChain 3D", threadID); + + switch (filter) + { + case wiRenderer::MIPGENFILTER_POINT: + GetDevice()->BindCS(computeShaders[CSTYPE_GENERATEMIPCHAIN3D_SIMPLEFILTER], threadID); + GetDevice()->BindSamplerCS(samplers[SSLOT_POINT_CLAMP], SSLOT_ONDEMAND0, threadID); + break; + case wiRenderer::MIPGENFILTER_LINEAR: + GetDevice()->BindCS(computeShaders[CSTYPE_GENERATEMIPCHAIN3D_SIMPLEFILTER], threadID); + GetDevice()->BindSamplerCS(samplers[SSLOT_LINEAR_CLAMP], SSLOT_ONDEMAND0, threadID); + break; + case wiRenderer::MIPGENFILTER_GAUSSIAN: + assert(0 && "Not implemented!"); + break; + } + + for (UINT i = 0; i < desc.MipLevels - 1; ++i) + { + GetDevice()->BindUnorderedAccessResourceCS(texture, 0, threadID, i + 1); + GetDevice()->BindResourceCS(texture, 0, threadID, i); + desc.Width = max(1, desc.Width / 2); + desc.Height = max(1, desc.Height / 2); + desc.Depth = max(1, desc.Depth / 2); + GetDevice()->Dispatch(max(1, desc.Width / 8), max(1, desc.Height / 8), max(1, desc.Depth / 8), threadID); + } + + GetDevice()->UnBindResources(0, 1, threadID); + GetDevice()->UnBindUnorderedAccessResources(0, 1, threadID); + GetDevice()->BindCS(nullptr, threadID); + + GetDevice()->EventEnd(); +} void wiRenderer::ManageDecalAtlas(GRAPHICSTHREAD threadID) { diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index a7f84da17..a73d0b2fc 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -454,6 +454,16 @@ public: static void ComputeTiledLightCulling(GRAPHICSTHREAD threadID); static void ResolveMSAADepthBuffer(wiGraphicsTypes::Texture2D* dst, wiGraphicsTypes::Texture2D* src, GRAPHICSTHREAD threadID); + enum MIPGENFILTER + { + MIPGENFILTER_POINT, + MIPGENFILTER_LINEAR, + MIPGENFILTER_GAUSSIAN, + }; + static void GenerateMipChain(wiGraphicsTypes::Texture1D* texture, MIPGENFILTER filter, GRAPHICSTHREAD threadID); + static void GenerateMipChain(wiGraphicsTypes::Texture2D* texture, MIPGENFILTER filter, GRAPHICSTHREAD threadID); + static void GenerateMipChain(wiGraphicsTypes::Texture3D* texture, MIPGENFILTER filter, GRAPHICSTHREAD threadID); + static void ManageDecalAtlas(GRAPHICSTHREAD threadID); static XMVECTOR GetSunPosition(); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 965149a00..4767f619d 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -7,7 +7,7 @@ namespace wiVersion // minor features, major updates const int minor = 11; // minor bug fixes, alterations, refactors, updates - const int revision = 9; + const int revision = 10; long GetVersion()