Example #1
0
        public void CreateShaderResources()
        {
            // Create the output resource. The dimensions and format should match the swap-chain
            ResourceDescription resDesc = new ResourceDescription();

            resDesc.DepthOrArraySize  = 1;
            resDesc.Dimension         = ResourceDimension.Texture2D;
            resDesc.Format            = Format.R8G8B8A8_UNorm; // The backbuffer is actually DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, but sRGB formats can't be used with UAVs. We will convert to sRGB ourselves in the shader
            resDesc.Flags             = ResourceFlags.AllowUnorderedAccess;
            resDesc.Height            = mSwapChainRect.Height;
            resDesc.Layout            = TextureLayout.Unknown;
            resDesc.MipLevels         = 1;
            resDesc.SampleDescription = new SampleDescription(1, 0);
            resDesc.Width             = mSwapChainRect.Width;
            mpOutputResource          = mpDevice.CreateCommittedResource(AccelerationStructures.kDefaultHeapProps, HeapFlags.None, resDesc, ResourceStates.CopySource, null); // Starting as copy-source to simplify onFrameRender()

            // Create an SRV/UAV/VertexSRV/IndexSRV descriptor heap. Need 5 entries - 1 SRV for the scene, 1 UAV for the output, 1 SRV for VertexBuffer, 1 SRV for IndexBuffer, 1 SceneContantBuffer, 1 primitiveConstantBuffer
            mpSrvUavHeap = this.context.CreateDescriptorHeap(mpDevice, 6, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, true);

            // Create the UAV. Based on the root signature we created it should be the first entry
            UnorderedAccessViewDescription uavDesc = new UnorderedAccessViewDescription();

            uavDesc.ViewDimension = UnorderedAccessViewDimension.Texture2D;
            mpDevice.CreateUnorderedAccessView(mpOutputResource, null, uavDesc, mpSrvUavHeap.GetCPUDescriptorHandleForHeapStart());

            // Create the TLAS SRV right after the UAV. Note that we are using a different SRV desc here
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription();

            srvDesc.ViewDimension                            = ShaderResourceViewDimension.RaytracingAccelerationStructure;
            srvDesc.Shader4ComponentMapping                  = D3D12DefaultShader4ComponentMapping;
            srvDesc.RaytracingAccelerationStructure          = new RaytracingAccelerationStructureShaderResourceView();
            srvDesc.RaytracingAccelerationStructure.Location = mpTopLevelAS.GPUVirtualAddress;
            CpuDescriptorHandle srvHandle = mpSrvUavHeap.GetCPUDescriptorHandleForHeapStart();

            srvHandle.Ptr += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            mpDevice.CreateShaderResourceView(null, srvDesc, srvHandle);

            // Index SRV
            var indexSRVDesc = new ShaderResourceViewDescription()
            {
                ViewDimension           = ShaderResourceViewDimension.Buffer,
                Shader4ComponentMapping = D3D12DefaultShader4ComponentMapping,
                Format = Format.R32_Typeless,
                Buffer =
                {
                    NumElements         = (int)(this.acs.IndexCount * 2 / 4),
                    Flags               = BufferShaderResourceViewFlags.Raw,
                    StructureByteStride =                                  0,
                }
            };

            srvHandle.Ptr += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            indexSRVHandle = srvHandle;
            mpDevice.CreateShaderResourceView(this.acs.IndexBuffer, indexSRVDesc, indexSRVHandle);

            // Vertex SRV
            var vertexSRVDesc = new ShaderResourceViewDescription()
            {
                ViewDimension           = ShaderResourceViewDimension.Buffer,
                Shader4ComponentMapping = D3D12DefaultShader4ComponentMapping,
                Format = Format.Unknown,
                Buffer =
                {
                    NumElements         = (int)this.acs.VertexCount,
                    Flags               = BufferShaderResourceViewFlags.None,
                    StructureByteStride = Unsafe.SizeOf <VertexPositionNormalTangentTexture>(),
                }
            };

            srvHandle.Ptr  += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            vertexSRVHandle = srvHandle;
            mpDevice.CreateShaderResourceView(this.acs.VertexBuffer, vertexSRVDesc, vertexSRVHandle);

            // CB Scene
            Vector3   cameraPosition = new Vector3(0, 1, -7);
            Matrix4x4 view           = Matrix4x4.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.UnitY);
            Matrix4x4 proj           = Matrix4x4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)mSwapChainRect.Width / mSwapChainRect.Height, 0.1f, 1000f);
            Matrix4x4 viewProj       = Matrix4x4.Multiply(view, proj);

            Matrix4x4.Invert(viewProj, out Matrix4x4 projectionToWorld);
            SceneConstantBuffer sceneConstantBuffer = new SceneConstantBuffer()
            {
                projectionToWorld = Matrix4x4.Transpose(projectionToWorld),
                cameraPosition    = cameraPosition,
                lightPosition     = new Vector3(0.0f, 1.0f, -2.0f),
                lightDiffuseColor = new Vector4(0.5f, 0.5f, 0.5f, 1.0f),
                lightAmbientColor = new Vector4(0.1f, 0.1f, 0.1f, 1.0f),
                backgroundColor   = new Vector4(0.4f, 0.6f, 0.2f, 1.0f),
                MaxRecursionDepth = 4,
            };

            sceneCB = this.acs.CreateBuffer(mpDevice, (uint)Unsafe.SizeOf <SceneConstantBuffer>(), ResourceFlags.None, ResourceStates.GenericRead, AccelerationStructures.kUploadHeapProps);
            IntPtr pData;

            pData = sceneCB.Map(0, null);
            Helpers.MemCpy(pData, sceneConstantBuffer, (uint)Unsafe.SizeOf <SceneConstantBuffer>());
            sceneCB.Unmap(0, null);

            var sceneCBV = new ConstantBufferViewDescription()
            {
                BufferLocation = sceneCB.GPUVirtualAddress,
                SizeInBytes    = (Unsafe.SizeOf <SceneConstantBuffer>() + 255) & ~255,
            };

            srvHandle.Ptr += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            sceneCBVHandle = srvHandle;
            mpDevice.CreateConstantBufferView(sceneCBV, sceneCBVHandle);

            // CB Primitive
            PrimitiveConstantBuffer primitiveConstantBuffer = new PrimitiveConstantBuffer()
            {
                diffuseColor     = new Vector4(0.8f, 0f, 0f, 1.0f),
                inShadowRadiance = 0.35f,
                diffuseCoef      = 0.1f,
                specularCoef     = 0.7f,
                specularPower    = 50,
                reflectanceCoef  = 0.7f,
            };

            ID3D12Resource primitiveCB = this.acs.CreateBuffer(mpDevice, (uint)Unsafe.SizeOf <PrimitiveConstantBuffer>(), ResourceFlags.None, ResourceStates.GenericRead, AccelerationStructures.kUploadHeapProps);
            IntPtr         pData2;

            pData2 = primitiveCB.Map(0, null);
            Helpers.MemCpy(pData2, primitiveConstantBuffer, (uint)Unsafe.SizeOf <PrimitiveConstantBuffer>());
            primitiveCB.Unmap(0, null);

            var primitiveCBV = new ConstantBufferViewDescription()
            {
                BufferLocation = primitiveCB.GPUVirtualAddress,
                SizeInBytes    = (Unsafe.SizeOf <PrimitiveConstantBuffer>() + 255) & ~255,
            };

            srvHandle.Ptr += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            var primitiveCBVHandle = srvHandle;

            mpDevice.CreateConstantBufferView(primitiveCBV, primitiveCBVHandle);
        }