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); } }
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(); }
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); }
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); } } }
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; } } }
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); } }
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)); } }
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); }