private void SetUpShaderResPackages()
 {
     if (scaleDownShader != null)
     {
         scaleDownShaderResPkg = new ShaderResourcePackage();
         scaleDownShaderResPkg.SetValue((ResourceViewBinding)scaleDownShader.GetBindingByIdentifier("SourceTex"), preGlowTargetBufferSRV);
         scaleDownShaderResPkg.SetValue((TextureSamplerBinding)scaleDownShader.GetBindingByIdentifier("SourceSampler"), copySSO);
         scaleDownShaderResUnbindPkg = new ShaderResourcePackage();
         scaleDownShaderResUnbindPkg.SetValue((ResourceViewBinding)scaleDownShader.GetBindingByIdentifier("SourceTex"), null);
     }
     if (scaleUpShader != null)
     {
         scaleUpShaderResPkg = new ShaderResourcePackage();
         scaleUpShaderResPkg.SetValue((ResourceViewBinding)scaleUpShader.GetBindingByIdentifier("SourceTex"), glowDstBufferSRV);
         scaleUpShaderResPkg.SetValue((TextureSamplerBinding)scaleUpShader.GetBindingByIdentifier("SourceSampler"), copySSO);
         scaleUpShaderResUnbindPkg = new ShaderResourcePackage();
         scaleUpShaderResUnbindPkg.SetValue((ResourceViewBinding)scaleUpShader.GetBindingByIdentifier("SourceTex"), null);
     }
     if (glowShader != null)
     {
         glowShaderVResPkg = new ShaderResourcePackage();
         glowShaderVResPkg.SetValue((ResourceViewBinding)glowShader.GetBindingByIdentifier("GlowSrc"), glowSrcBufferSRV);
         glowShaderVResUnbindPkg = new ShaderResourcePackage();
         glowShaderVResUnbindPkg.SetValue((ResourceViewBinding)glowShader.GetBindingByIdentifier("GlowSrc"), null);
     }
 }
Пример #2
0
        public unsafe void TestShaderResourcePackage()
        {
            ConstantBuffer <Vector4> matColorBuffer = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            TextureSampler           textureSampler = new TextureSampler(TextureFilterType.Anisotropic, TextureWrapMode.Border, AnisotropicFilteringLevel.EightTimes);
            FragmentShader           testFS         = new FragmentShader(
                @"Tests\SimpleFS.cso",
                new ConstantBufferBinding(0U, "MaterialColor", matColorBuffer),
                new TextureSamplerBinding(0U, "DefaultSampler")
                );

            Material testMaterial = new Material("Test Material", testFS);

            testMaterial.SetMaterialConstantValue((ConstantBufferBinding)testFS.GetBindingByIdentifier("MaterialColor"), Vector4.ONE);
            testMaterial.SetMaterialResource((TextureSamplerBinding)testFS.GetBindingByIdentifier("DefaultSampler"), textureSampler);

            ShaderResourcePackage shaderResourcePackage = testMaterial.FragmentShaderResourcePackage;

            Assert.AreEqual(Vector4.ONE, *((Vector4 *)shaderResourcePackage.GetValue((ConstantBufferBinding)testFS.GetBindingByIdentifier("MaterialColor"))));
            Assert.AreEqual(textureSampler, shaderResourcePackage.GetValue((TextureSamplerBinding)testFS.GetBindingByIdentifier("DefaultSampler")));

            testFS.Dispose();
            matColorBuffer.Dispose();
            testMaterial.Dispose();
            textureSampler.Dispose();
        }
Пример #3
0
 protected static void QueueShaderResourceUpdate(Shader shader, ShaderResourcePackage resourcePackage)
 {
     Assure.NotNull(shader);
     Assure.False(shader.IsDisposed, "Shader was disposed.");
     Assure.NotNull(resourcePackage);
     shader.RCQUpdateResources(ThreadLocalRCQ, resourcePackage);
 }
Пример #4
0
 public ShaderResourcePackage(ShaderResourcePackage c) : this()
 {
     lock (instanceMutationLock) {
         foreach (var binding in c.bindings)
         {
             bindings.Add(binding.Key, binding.Value);
         }
         foreach (var binding in c.cbBindings)
         {
             cbBindings.Add(binding.Key, binding.Value);
         }
     }
 }
Пример #5
0
 public void CopyFrom(ShaderResourcePackage srp)
 {
     lock (instanceMutationLock) {
         foreach (var binding in srp.bindings)
         {
             bindings[binding.Key] = binding.Value;
         }
         foreach (var binding in srp.cbBindings)
         {
             cbBindings[binding.Key] = binding.Value;
         }
     }
 }
Пример #6
0
        internal unsafe GeometryInputLayout(
            InputLayoutHandle inputLayoutHandle,
            KeyValuePair <VertexInputBinding, IVertexBuffer>[] boundComponentBuffers,
            VertexShader associatedShader,
            GeometryCache associatedCache
            ) : base(inputLayoutHandle, ResourceUsage.Immutable, APPROX_INPUT_ELEMENT_DESC_SIZE_BYTES * boundComponentBuffers.Length)
        {
            BoundComponentBuffers = boundComponentBuffers;
            AssociatedShader      = associatedShader;
            AssociatedCache       = associatedCache;

            ResourcePackage = new ShaderResourcePackage();
            foreach (KeyValuePair <VertexInputBinding, IVertexBuffer> pair in boundComponentBuffers)
            {
                ResourcePackage.SetValue(pair.Key, pair.Value);
            }
        }
Пример #7
0
        internal virtual void RCQUpdateResources(RenderCommandQueue commandQueue, ShaderResourcePackage shaderResources)
        {
            for (int i = 0; i < ConstantBufferBindings.Length; i++)
            {
                commandQueue.QueueCommand(RenderCommand.DiscardWriteShaderConstantBuffer(
                                              ConstantBufferBindings[i], shaderResources.GetValue(ConstantBufferBindings[i])
                                              ));
            }

            if (TextureSamplerBindings.Length > 0)
            {
                if (texSamplerValueDict == null)
                {
                    texSamplerValueDict = new FastClearList <KVP <TextureSamplerBinding, TextureSampler> >();
                }
                texSamplerValueDict.Clear();
                for (int i = 0; i < TextureSamplerBindings.Length; ++i)
                {
                    var tsb = TextureSamplerBindings[i];
                    texSamplerValueDict.Add(new KVP <TextureSamplerBinding, TextureSampler>(tsb, shaderResources.GetValue(tsb)));
                }
                commandQueue.QueueCommand(RenderCommand.SetShaderTextureSamplers(this, texSamplerValueDict));
            }

            if (ResourceViewBindings.Length > 0)
            {
                if (resViewValueDict == null)
                {
                    resViewValueDict = new FastClearList <KVP <ResourceViewBinding, IResourceView> >();
                }
                resViewValueDict.Clear();
                for (int i = 0; i < ResourceViewBindings.Length; ++i)
                {
                    var rvb = ResourceViewBindings[i];
                    resViewValueDict.Add(new KVP <ResourceViewBinding, IResourceView>(rvb, shaderResources.GetValue(rvb)));
                    Assure.False(
                        ((BaseResourceView)shaderResources.GetValue(ResourceViewBindings[i])) != null &&
                        ((BaseResourceView)shaderResources.GetValue(ResourceViewBindings[i])).Resource.PermittedBindings == GPUBindings.None,
                        "Underlying resource has no permitted GPU bindings."
                        );
                }
                commandQueue.QueueCommand(RenderCommand.SetShaderResourceViews(this, resViewValueDict));
            }
        }
Пример #8
0
        internal override void RCQUpdateResources(RenderCommandQueue commandQueue, ShaderResourcePackage shaderResources)
        {
            base.RCQUpdateResources(commandQueue, shaderResources);

            // Set vertex buffers
            if (InputBindings.Length > 0)
            {
                if (vertexInputValueDict == null)
                {
                    vertexInputValueDict = new Dictionary <VertexInputBinding, IVertexBuffer>();
                }
                vertexInputValueDict.Clear();
                for (int i = 0; i < InputBindings.Length; ++i)
                {
                    vertexInputValueDict[InputBindings[i]] = shaderResources.GetValue(InputBindings[i]);
                }
                commandQueue.QueueCommand(RenderCommand.SetShaderVertexBuffers(this, vertexInputValueDict));
            }
        }
        private void RenderCache_IterateMaterial(int materialIndex)
        {
            // Set up context variables
            KeyValuePair <Material, ModelInstanceManager.MIDArray> currentKVP = currentInstanceData[materialIndex];
            Material currentMaterial = currentKVP.Key;

            ModelInstanceManager.MIDArray currentMID = currentKVP.Value;

            // Skip this material if it or its shader are disposed
            if (currentMaterial.IsDisposed || currentMaterial.Shader.IsDisposed)
            {
                return;
            }

            // Skip this material if we're not using it
            bool inUse = false;

            for (int i = 0; i < currentMID.Length; ++i)
            {
                if (currentMID.Data[i].InUse)
                {
                    inUse = true;
                    break;
                }
            }
            if (!inUse)
            {
                return;
            }

            // Prepare shader according to material params, and switch to it or update it
            if (lastSetFragmentShader != currentMaterial.Shader || lastFrameNum != frameNum)
            {
                lastSetFragmentShader = currentMaterial.Shader;
                lastFrameNum          = frameNum;
                QueueShaderSwitch(lastSetFragmentShader);
            }
            var queuedSRP = currentMaterial.FragmentShaderResourcePackage;

            if (lastSetFragmentShader == geomFSWithShadowSupport)
            {
                if (modifiedSRP == null)
                {
                    modifiedSRP = new ShaderResourcePackage();
                }
                modifiedSRP.CopyFrom(queuedSRP);
                modifiedSRP.SetValue((ResourceViewBinding)lastSetFragmentShader.GetBindingByIdentifier("ShadowMap"), previousShadowBufferSRV);
                queuedSRP = modifiedSRP;
            }
            QueueShaderResourceUpdate(lastSetFragmentShader, queuedSRP);

            // Filter & sort
            if (materialFilteringWorkspace == null || materialFilteringWorkspace.Length < currentCache.NumModels)
            {
                materialFilteringWorkspace = new FastClearList <Transform> [currentCache.NumModels];
                for (int i = 0; i < materialFilteringWorkspace.Length; ++i)
                {
                    materialFilteringWorkspace[i] = new FastClearList <Transform>();
                }
            }
            for (int i = 0; i < materialFilteringWorkspace.Length; ++i)
            {
                materialFilteringWorkspace[i].Clear();
            }

            SortByProximityToCamera(currentMID);
            uint numInstances = 0U;

            for (uint i = 0U; i < currentMID.Length; ++i)
            {
                ModelInstanceData curMID = sortedModelData[i];
                if (!curMID.InUse)
                {
                    continue;
                }
                SceneLayer layer = currentSceneLayers[curMID.SceneLayerIndex];
                if (layer == null || !layer.GetRenderingEnabled() || !addedSceneLayers.Contains(layer))
                {
                    continue;
                }

                if (curMID.ModelIndex == __VEGG_MH.ModelIndex && currentCache.ID == __VEGG_MH.GeoCacheID)
                {
                    int instanceIndex = 0;
                    for (int j = 0; j < currentMID.Length; ++j)
                    {
                        if (currentMID.Data[j].Transform == curMID.Transform)
                        {
                            instanceIndex = j;
                            break;
                        }
                    }
                    Quaternion rot = Quaternion.IDENTITY;
                    foreach (var kvp in __VEGG_MIH_ARR)
                    {
                        if (kvp.Key.InstanceIndex == instanceIndex)
                        {
                            rot = kvp.Value;
                            break;
                        }
                    }
                    materialFilteringWorkspace[curMID.ModelIndex].Add(curMID.Transform.RotateBy(rot));
                }
                else
                {
                    materialFilteringWorkspace[curMID.ModelIndex].Add(curMID.Transform);
                }
                ++numInstances;
            }

            // Concatenate & queue render commands
            if (instanceConcatWorkspace == null || instanceConcatWorkspace.Length < numInstances)
            {
                instanceConcatWorkspace = new Matrix[numInstances << 1];                 // x2 so we don't create loads of garbage if the count keeps increasing by 1
            }

            uint instanceStartOffset = RenderCache_IterateMaterial_ConcatReserve(numInstances);
            uint nextWorkspaceIndex = 0;
            uint outVBStartIndex, outIBStartIndex, outVBCount, outIBCount;

            for (uint mI = 0U; mI < materialFilteringWorkspace.Length; ++mI)
            {
                FastClearList <Transform> filteredTransformList = materialFilteringWorkspace[mI];
                int numFilteredTransforms = filteredTransformList.Count;
                if (numFilteredTransforms == 0)
                {
                    continue;
                }

                currentCache.GetModelBufferValues(mI, out outVBStartIndex, out outIBStartIndex, out outVBCount, out outIBCount);

                QueueRenderCommand(RenderCommand.DrawIndexedInstanced(
                                       (int)outVBStartIndex,
                                       outIBStartIndex,
                                       outIBCount,
                                       nextWorkspaceIndex + instanceStartOffset,
                                       (uint)numFilteredTransforms
                                       ));

                for (int iI = 0; iI < numFilteredTransforms; ++iI)
                {
                    if (mI == __EGGHACK_MH.ModelIndex && currentCache.ID == __EGGHACK_MH.GeoCacheID)
                    {
                        instanceConcatWorkspace[nextWorkspaceIndex++] = filteredTransformList[iI].RotateBy(__EGGHACK_ROT).AsMatrixTransposed;
                    }
                    else
                    {
                        instanceConcatWorkspace[nextWorkspaceIndex++] = filteredTransformList[iI].AsMatrixTransposed;
                    }
                }
            }

            RenderCache_IterateMaterial_Concat(instanceConcatWorkspace, instanceStartOffset, numInstances);
        }