public unsafe void TestClearRenderTargetWithWindow() { Window renderTargetWindow = new Window("Test window"); RenderTargetViewHandle outRTV; DepthStencilViewHandle outDSV; renderTargetWindow.GetWindowRTVAndDSV(out outRTV, out outDSV); RenderCommand testCommand = RenderCommand.ClearRenderTarget(renderTargetWindow); Assert.AreEqual(RenderCommandInstruction.ClearRenderTarget, testCommand.Instruction); Assert.AreEqual( outRTV, UnsafeUtils.Reinterpret <IntPtr, RenderTargetViewHandle>(new IntPtr(UnsafeUtils.Reinterpret <RenderCommandArgument, long>(testCommand.Arg1, sizeof(long))), sizeof(RenderTargetViewHandle)) ); renderTargetWindow.Close(); LosgapSystem.InvokeOnMaster(() => { }); // Wait for the window to be closed testCommand = RenderCommand.ClearRenderTarget(renderTargetWindow); Assert.AreEqual(RenderCommandInstruction.NoOperation, testCommand.Instruction); #if !DEVELOPMENT && !RELEASE try { RenderCommand.ClearRenderTarget(null as Window); Assert.Fail(); } catch (AssuranceFailedException) { } #endif }
public void TestClearRenderTarget() { Texture2D <TexelFormat.RenderTarget> renderTarget = TextureFactory.NewTexture2D <TexelFormat.RenderTarget>() .WithWidth(800U) .WithHeight(600U) .WithDynamicDetail(false) .WithMipAllocation(false) .WithMipGenerationTarget(false) .WithMultisampling(false) .WithPermittedBindings(GPUBindings.RenderTarget) .WithUsage(ResourceUsage.Write); RenderTargetView rtv = renderTarget.CreateRenderTargetView(0U); RenderCommand testCommand = RenderCommand.ClearRenderTarget(rtv); Assert.AreEqual(RenderCommandInstruction.ClearRenderTarget, testCommand.Instruction); Assert.AreEqual((RenderCommandArgument)(IntPtr)(ResourceViewHandle)rtv.ResourceViewHandle, testCommand.Arg1); #if !DEVELOPMENT && !RELEASE try { RenderCommand.ClearRenderTarget(null as RenderTargetView); Assert.Fail(); } catch (AssuranceFailedException) { } #endif rtv.Dispose(); renderTarget.Dispose(); #if !DEVELOPMENT && !RELEASE try { RenderCommand.ClearRenderTarget(rtv); Assert.Fail(); } catch (AssuranceFailedException) { } #endif }
protected internal override void Execute(ParallelizationProvider pp) { // See if we need to resize the light plane and get the new GBuffer Camera input; SceneViewport output; Texture2D <TexelFormat.RGBA32Float>[] currentGBuffer; geometryPass.GetLightPassParameters(out currentGBuffer, out input, out output); Vector2 outputSizePixels = output.SizePixels; if (outputSizePixels.X <= 0f || outputSizePixels.Y <= 0f) { return; } RenderTargetViewHandle windowRTV; DepthStencilViewHandle windowDSV; bool windowStillOpen = output.TargetWindow.GetWindowRTVAndDSV(out windowRTV, out windowDSV); if (!windowStillOpen) { return; } CheckGeometryPassParameters(currentGBuffer, outputSizePixels); // Clear the bloom textures QueueRenderCommand(RenderCommand.ClearRenderTarget(preBloomBufferRTV)); QueueRenderCommand(RenderCommand.ClearRenderTarget(reducedBloomBufferRTV)); QueueRenderCommand(RenderCommand.ClearRenderTarget(bloomTargetBufferRTV)); QueueRenderCommand(RenderCommand.ClearRenderTarget(nonDepthOfFieldBackBufferRTV)); QueueRenderCommand(RenderCommand.ClearRenderTarget(reducedNonDepthOfFieldBackBufferRTV)); QueueRenderCommand(RenderCommand.ClearRenderTarget(depthOfFieldBackBufferRTV)); QueueRenderCommand(RenderCommand.ClearDepthStencil(bloomResizeCopyDSDSV)); QueueRenderCommand(RenderCommand.ClearDepthStencil(dsThrowawayBufferDSV)); // Set topology QueueRenderCommand(RenderCommand.SetPrimitiveTopology(RenderCommand.DEFAULT_PRIMITIVE_TOPOLOGY)); // Set input layout QueueRenderCommand(RenderCommand.SetInputLayout(lightPlaneInputLayout)); // Enqueue VS commands QueueShaderSwitch(dlLightVS); QueueShaderResourceUpdate(dlLightVS, vsResPackage); /* ======================================= * STAGE: DYNAMIC LIGHTING APPLICATION * ======================================= */ // Enqueue FS commands Vector4 cameraPos = input.Position; ((ConstantBufferBinding)dlLightFS.GetBindingByIdentifier("CameraProperties")).SetValue((byte *)(&cameraPos)); QueueShaderSwitch(dlLightFS); // Set rasterizer state QueueRenderCommand(RenderCommand.SetRasterizerState(rsState)); QueueRenderCommand(RenderCommand.SetViewport(output)); // Set depth stencil state QueueRenderCommand(RenderCommand.SetDepthStencilState(dsState)); // Set blend state QueueRenderCommand(RenderCommand.SetBlendState(blendState)); // Set up output merger QueueRenderCommand(RenderCommand.SetRenderTargets(dsThrowawayBufferDSV.ResourceViewHandle, nonDepthOfFieldBackBufferRTV.ResourceViewHandle, preBloomBufferRTV.ResourceViewHandle)); // Draw lights //input = new Camera(); //input.Position = Vector3.ZERO; //input.Orient(Vector3.FORWARD, Vector3.UP); var frustum = input.GetFrustum(output); int numLights = addedLights.Count; int numLightsInFrustum = 0; for (int i = 0; i < numLights; ++i) { if (!frustum.IsWithinFrustum(new Sphere(addedLights[i].Position, addedLights[i].Radius))) { continue; } lightPropsWorkspace[numLightsInFrustum++] = addedLights[i].Properties; } if (numLightsInFrustum > dynamicLightCap) { dynamicLightComparer.CameraPosition = input.Position; Array.Sort(lightPropsWorkspace, 0, numLightsInFrustum, dynamicLightComparer); numLightsInFrustum = dynamicLightCap; } Buffer <LightProperties> lightBuffer = (Buffer <LightProperties>)(((ResourceViewBinding)dlLightFS.GetBindingByIdentifier("LightBuffer")).GetBoundResource().Resource); var lightMetaCBuffer = (ConstantBufferBinding)dlLightFS.GetBindingByIdentifier("LightMeta"); QueueShaderResourceUpdate(dlLightFS, fsResPackage); Array.Clear(perTileLightPropCounts, 0, perTileLightPropCounts.Length); Vector3 upDir = input.UpDirection; Vector3 downDir = -input.UpDirection; Vector3 rightDir = upDir.Cross(input.Orientation); Vector3 leftDir = -rightDir; var worldToProjMat = (*((Matrix *)input.GetRecalculatedViewMatrix()) * *((Matrix *)output.GetRecalculatedProjectionMatrix(input))); for (int i = 0; i < numLightsInFrustum; ++i) { var lightProps = lightPropsWorkspace[i]; //lightProps = new LightProperties( // Vector3.LEFT + Vector3.BACKWARD, 3f, Vector3.ONE //); var lightCentre = lightProps.Position; var lightTop = new Vector4(lightCentre + upDir * lightProps.Radius, w: 1f); var lightBottom = new Vector4(lightCentre + downDir * lightProps.Radius, w: 1f); var lightLeftmost = new Vector4(lightCentre + leftDir * lightProps.Radius, w: 1f); var lightRightmost = new Vector4(lightCentre + rightDir * lightProps.Radius, w: 1f); var lightTopProjspace = lightTop * worldToProjMat; var lightBottomProjspace = lightBottom * worldToProjMat; var lightLeftmostProjspace = lightLeftmost * worldToProjMat; var lightRightmostProjspace = lightRightmost * worldToProjMat; var lightTopScreenSpace = lightTopProjspace / Math.Abs(lightTopProjspace.W); var lightBottomScreenSpace = lightBottomProjspace / Math.Abs(lightBottomProjspace.W); var lightLeftmostScreenSpace = lightLeftmostProjspace / Math.Abs(lightLeftmostProjspace.W); var lightRightmostScreenSpace = lightRightmostProjspace / Math.Abs(lightRightmostProjspace.W); var xMin = ((float)MathUtils.Clamp(lightLeftmostScreenSpace.X, -1f, 1f) + 1f) * 0.5f; var xMax = ((float)MathUtils.Clamp(lightRightmostScreenSpace.X, -1f, 1f) + 1f) * 0.5f; var yMin = ((float)MathUtils.Clamp(lightBottomScreenSpace.Y, -1f, 1f) + 1f) * 0.5f; var yMax = ((float)MathUtils.Clamp(lightTopScreenSpace.Y, -1f, 1f) + 1f) * 0.5f; for (int x = 0; x < LIGHTING_TILE_GRANULARITY; ++x) { for (int y = 0; y < LIGHTING_TILE_GRANULARITY; ++y) { var tileXMin = tileOffsetsX[x]; var tileXMax = tileOffsetsX[x + 1]; var tileYMin = tileOffsetsY[y]; var tileYMax = tileOffsetsY[y + 1]; if (xMax < tileXMin || xMin > tileXMax || yMax < tileYMin || yMin > tileYMax) { continue; } var bucketIndex = x * LIGHTING_TILE_GRANULARITY + y; perTileLightPropsWorkspace[bucketIndex][perTileLightPropCounts[bucketIndex]++] = lightProps; } } } for (int x = 0; x < LIGHTING_TILE_GRANULARITY; ++x) { for (int y = 0; y < LIGHTING_TILE_GRANULARITY; ++y) { var bucketIndex = x * LIGHTING_TILE_GRANULARITY + y; var numLightsOnThisTile = perTileLightPropCounts[bucketIndex]; if (numLightsOnThisTile == 0) { continue; } var scalars = new Vector4(tileOffsetsX[x], tileOffsetsX[x + 1], tileOffsetsY[y], tileOffsetsY[y + 1]); // 0f to 1f, from bottom left corner QueueRenderCommand(RenderCommand.DiscardWriteShaderConstantBuffer( lightBuffer, new ArraySlice <LightProperties>(perTileLightPropsWorkspace[bucketIndex], 0U, (uint)numLightsOnThisTile), (uint)sizeof(LightProperties) )); int *numLightsWithPadding = stackalloc int[4]; numLightsWithPadding[0] = numLightsOnThisTile; QueueRenderCommand(RenderCommand.DiscardWriteShaderConstantBuffer(lightMetaCBuffer, (IntPtr)(numLightsWithPadding))); QueueRenderCommand(RenderCommand.DiscardWriteShaderConstantBuffer(lightVSScalarsBufferBinding, (IntPtr)(&scalars))); QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); } } // Unbind gbuffer QueueShaderResourceUpdate(dlLightFS, fsUnbindResPackage); /* ======================================= * STAGE: ADD AMBIENT LIGHT (DL FINAL) * ======================================= */ // Switch to finalization shader var scalarsFinal = new Vector4(0f, 1f, 0f, 1f); QueueRenderCommand(RenderCommand.DiscardWriteShaderConstantBuffer(lightVSScalarsBufferBinding, (IntPtr)(&scalarsFinal))); QueueShaderSwitch(dlFinalFS); QueueShaderResourceUpdate(dlFinalFS, finalizationShaderResPackage); // Draw finalization triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(dlFinalFS, finalizationShaderUnbindResPackage); /* ======================================= * STAGE: OUTLINING * ======================================= */ // Switch to outlining shader QueueShaderSwitch(outliningShader); QueueShaderResourceUpdate(outliningShader, outliningShaderResPackage); // Set blend state QueueRenderCommand(RenderCommand.SetBlendState(outliningBlendState)); // Draw outlining triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(outliningShader, outliningShaderUnbindResPackage); /* ======================================= * STAGE: DOWNSCALE PRE-BLOOM BUFFER TEX * ======================================= */ // Set up output merger QueueRenderCommand(RenderCommand.SetRenderTargets(bloomResizeCopyDSDSV, reducedBloomBufferRTV)); // Switch to copy shader QueueShaderSwitch(copyShader); QueueShaderResourceUpdate(copyShader, copyShaderResPackage); // Set blend state QueueRenderCommand(RenderCommand.SetBlendState(blendState)); // Draw fullscreen triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(copyShader, copyShaderUnbindResPackage); /* ======================================= * STAGE: BLOOM RENDER TO BLOOM TARGET * ======================================= */ // Clear DSV QueueRenderCommand(RenderCommand.ClearDepthStencil(bloomResizeCopyDSDSV)); // Set up output merger QueueRenderCommand(RenderCommand.SetRenderTargets(bloomResizeCopyDSDSV, bloomTargetBufferRTV)); // Switch to bloom H shader QueueShaderSwitch(bloomHShader); QueueShaderResourceUpdate(bloomHShader, bloomHShaderResPackage); // Draw fullscreen triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(bloomHShader, bloomHShaderUnbindResPackage); // Switch to bloom V shader QueueShaderSwitch(bloomVShader); QueueShaderResourceUpdate(bloomVShader, bloomVShaderResPackage); // Draw fullscreen triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(bloomVShader, bloomVShaderUnbindResPackage); /* ======================================= * STAGE: COPY BLOOM RESULT ON TO NON-DoF BUFFER * ======================================= */ // Set up output merger QueueRenderCommand(RenderCommand.SetRenderTargets(dsThrowawayBufferDSV.ResourceViewHandle, nonDepthOfFieldBackBufferRTV)); // Switch to reverse copy shader QueueShaderSwitch(copyReverseShader); QueueShaderResourceUpdate(copyReverseShader, copyReverseShaderResPackage); // Draw fullscreen triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(copyReverseShader, copyReverseShaderUnbindResPackage); /* ======================================= * STAGE: DOWNSCALE NON-DoF SCENE * ======================================= */ // Set up output merger QueueRenderCommand(RenderCommand.SetRenderTargets(bloomResizeCopyDSDSV, reducedNonDepthOfFieldBackBufferRTV)); // Switch to copy shader QueueShaderSwitch(copyShader); QueueShaderResourceUpdate(copyShader, copyDoFShaderResPackage); // Set blend state QueueRenderCommand(RenderCommand.SetBlendState(blendState)); // Draw fullscreen triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(copyShader, copyDoFShaderUnbindResPackage); /* ======================================= * STAGE: BLUR NON-DoF SCENE * ======================================= */ // Set up output merger QueueRenderCommand(RenderCommand.SetRenderTargets(bloomResizeCopyDSDSV, depthOfFieldBackBufferRTV)); // Switch to copy shader QueueShaderSwitch(blurShader); QueueShaderResourceUpdate(blurShader, blurShaderResPackage); // Set blend state QueueRenderCommand(RenderCommand.SetBlendState(blendState)); // Draw fullscreen triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(blurShader, blurShaderUnbindResPackage); /* ======================================= * STAGE: RENDER TO BACK BUFFER WITH DoF SELECTION * ======================================= */ // Set up output merger QueueRenderCommand(RenderCommand.SetRenderTargets(windowDSV, windowRTV)); // Switch to copy shader QueueShaderSwitch(dofShader); QueueShaderResourceUpdate(dofShader, dofShaderResPackage); // Set blend state QueueRenderCommand(RenderCommand.SetBlendState(blendState)); // Draw fullscreen triangles QueueRenderCommand(RenderCommand.Draw(0, 3U)); QueueRenderCommand(RenderCommand.Draw(3, 3U)); // Unbind resources QueueShaderResourceUpdate(dofShader, dofShaderUnbindResPackage); // Flush + present FlushRenderCommands(); if (presentAfterPass) { PresentBackBuffer(output.TargetWindow); } }
protected internal override void Execute(ParallelizationProvider pp) { for (int i = 0; i < NUM_GBUFFER_TEXTURES; ++i) { if (gBufferViews[i] != null) { QueueRenderCommand(RenderCommand.ClearRenderTarget(gBufferViews[i])); } } if (clearOutputBeforePass) { QueueRenderCommand(RenderCommand.ClearRenderTarget(output.TargetWindow)); QueueRenderCommand(RenderCommand.ClearDepthStencil(output.TargetWindow)); } Vector2 outputSizePixels = output.SizePixels; if (gBuffer[0] == null || gBuffer[0].Width != (uint)outputSizePixels.X || gBuffer[0].Height != (uint)outputSizePixels.Y) { for (int i = 0; i < NUM_GBUFFER_TEXTURES; ++i) { if (gBufferViews[i] != null) { gBufferViews[i].Dispose(); } if (gBuffer[i] != null) { gBuffer[i].Dispose(); } gBuffer[i] = gBufferBuilder.WithWidth((uint)outputSizePixels.X).WithHeight((uint)outputSizePixels.Y); gBufferViews[i] = gBuffer[i].CreateRenderTargetView(0U); } } if (primaryDSBuffer == null || primaryDSBuffer.Width != outputSizePixels.X || primaryDSBuffer.Height != outputSizePixels.Y) { if (primaryDSBuffer != null) { primaryDSBuffer.Dispose(); } if (primaryDSBufferDSV != null) { primaryDSBufferDSV.Dispose(); } if (primaryDSBufferSRV != null) { primaryDSBufferSRV.Dispose(); } primaryDSBuffer = dsBufferBuilder.WithWidth((uint)outputSizePixels.X).WithHeight((uint)outputSizePixels.Y); primaryDSBufferDSV = primaryDSBuffer.CreateDepthStencilView <TexelFormat.DepthStencil>(0U); primaryDSBufferSRV = primaryDSBuffer.CreateView <TexelFormat.R24UnormX8Typeless>(0U, 1U); } previousShadowBufferSRV = shadowPass.ShadowBufferSRV; // Clear main DSV QueueRenderCommand(RenderCommand.ClearDepthStencil(primaryDSBufferDSV)); List <GeometryCache> activeCaches = GeometryCache.ActiveCaches; foreach (GeometryCache c in activeCaches) { if (!deferredGeometryVertexShaders.ContainsKey(c)) { continue; } currentVS = deferredGeometryVertexShaders[c]; // Set view/proj matrices var vpMatrices = new GeomPassProjViewMatrices { MainCameraVPMat = (*((Matrix *)Input.GetRecalculatedViewMatrix()) * *((Matrix *)Output.GetRecalculatedProjectionMatrix(Input))).Transpose, ShadowCameraVPMat = (*((Matrix *)shadowPass.LightCam.GetRecalculatedViewMatrix()) * *((Matrix *)Output.GetRecalculatedProjectionMatrix(shadowPass.LightCam))).Transpose }; byte *vpMatPtr = (byte *)&vpMatrices; currentVS.ViewProjMatBinding.SetValue(vpMatPtr); // Set state for current cache cpuInstanceBufferCurIndex = 0; List <SceneLayer> allEnabledLayers = Scene.EnabledLayers; uint maxLayer = 0U; for (int i = 0; i < allEnabledLayers.Count; ++i) { if (allEnabledLayers[i].Index > maxLayer) { maxLayer = allEnabledLayers[i].Index; } } if (allEnabledLayers.Count > 0 && currentSceneLayers.Length <= maxLayer) { currentSceneLayers = new SceneLayer[maxLayer + 1U]; } Array.Clear(currentSceneLayers, 0, currentSceneLayers.Length); foreach (SceneLayer layer in allEnabledLayers) { currentSceneLayers[layer.Index] = layer; } currentCache = c; ++frameNum; Thread.MemoryBarrier(); currentInstanceData = currentCache.GetModelInstanceData(); // Set up each thread pp.InvokeOnAll(setUpCacheForLocalThreadAct, true); // membar here // Iterate all model instances (ordered by material) pp.Execute((int)currentInstanceData.Length, (int)(currentInstanceData.Length / (pp.NumThreads << 3)) + 1, renderCacheIterateMatAct); // Set instance buffer and write to it if (gpuInstanceBuffer == null || gpuInstanceBuffer.Length < cpuInstanceBuffer.Length) { if (gpuInstanceBuffer != null) { gpuInstanceBuffer.Dispose(); } gpuInstanceBuffer = gpuInstanceBufferBuilder.WithLength((uint)cpuInstanceBuffer.Length).Create(); } gpuInstanceBuffer.DiscardWrite(cpuInstanceBuffer); // Happens immediately (required) // Unbind shadow buffer QueueShaderSwitch(geomFSWithShadowSupport); QueueShaderResourceUpdate(geomFSWithShadowSupport, geomFSShadowUnbindPackage); // Set instance buffer and flush all commands, first on immediate context, then on each deferred SetInstanceBufferAndFlushCommands(); pp.InvokeOnAll(setInstanceBufferAndFlushCommandsAct, false); } }
protected internal override void Execute(ParallelizationProvider pp) { // Set up buffers if (!output.TargetWindow.GetWindowRTVAndDSV(out windowRTVH, out windowDSVH)) { return; } Vector2 viewportSizePixels = output.TargetWindow.AddedViewports.First().SizePixels; if (viewportSizePixels.X <= 0f || viewportSizePixels.Y <= 0f) { return; } SetUpBuffers(viewportSizePixels); // Clear pre-glow buffer QueueRenderCommand(RenderCommand.ClearRenderTarget(preGlowTargetBufferRTV)); QueueRenderCommand(RenderCommand.ClearRenderTarget(glowSrcBufferRTV)); QueueRenderCommand(RenderCommand.ClearRenderTarget(glowDstBufferRTV)); List <GeometryCache> activeCaches = GeometryCache.ActiveCaches; foreach (GeometryCache c in activeCaches) { // Set view/proj matrix Matrix vpMat = (*((Matrix *)Input.GetRecalculatedViewMatrix()) * *((Matrix *)Output.GetRecalculatedProjectionMatrix(Input))).Transpose; byte * vpMapPtr = (byte *)&vpMat; VertexShader.ViewProjMatBinding.SetValue(vpMapPtr); // Set state for current cache cpuInstanceBufferCurIndex = 0; List <SceneLayer> allEnabledLayers = Scene.EnabledLayers; uint maxLayer = 0U; for (int i = 0; i < allEnabledLayers.Count; ++i) { if (allEnabledLayers[i].Index > maxLayer) { maxLayer = allEnabledLayers[i].Index; } } if (allEnabledLayers.Count > 0 && currentSceneLayers.Length <= maxLayer) { currentSceneLayers = new SceneLayer[maxLayer + 1U]; } Array.Clear(currentSceneLayers, 0, currentSceneLayers.Length); foreach (SceneLayer layer in allEnabledLayers) { currentSceneLayers[layer.Index] = layer; } currentCache = c; ++frameNum; Thread.MemoryBarrier(); currentInstanceData = currentCache.GetModelInstanceData(); // Set up each thread SetUpCacheForLocalThread(); // Iterate all model instances (ordered by material && ZIndex) //if (instanceDataSortSpace.Length < currentInstanceData.Length) instanceDataSortSpace = new KeyValuePair<Material, ModelInstanceManager.MIDArray>[currentInstanceData.Length * 2]; //for (int i = 0; i < currentInstanceData.Length; i += 2) { // var a = currentInstanceData[i]; // if (currentInstanceData.Length == i + 1) { // if (currentInstanceData.Length >= 3) { // if (a.Key.ZIndex < instanceDataSortSpace[i - 2].Key.ZIndex) { // instanceDataSortSpace[i] = instanceDataSortSpace[i - 1]; // instanceDataSortSpace[i - 1] = instanceDataSortSpace[i - 2]; // instanceDataSortSpace[i - 2] = a; // } // else if (a.Key.ZIndex < instanceDataSortSpace[i - 1].Key.ZIndex) { // instanceDataSortSpace[i] = instanceDataSortSpace[i - 1]; // instanceDataSortSpace[i - 1] = a; // } // else instanceDataSortSpace[i] = a; // } // else instanceDataSortSpace[i] = a; // } // else { // var b = currentInstanceData[i + 1]; // if (a.Key.ZIndex <= b.Key.ZIndex) { // instanceDataSortSpace[i] = a; // instanceDataSortSpace[i + 1] = b; // } // else { // instanceDataSortSpace[i] = b; // instanceDataSortSpace[i + 1] = a; // } // } //} Array.Sort(currentInstanceData.ContainingArray, 0, (int)currentInstanceData.Length, zIndexComparer); foreach (KeyValuePair <Material, ModelInstanceManager.MIDArray> material in currentInstanceData) { for (int i = 0; i < currentInstanceData.Length; ++i) { if (currentInstanceData[i].Value == material.Value && currentInstanceData[i].Key == material.Key) { RenderCache_IterateMaterial(i); break; } } } // Set instance buffer and write to it if (gpuInstanceBuffer == null || gpuInstanceBuffer.Length < cpuInstanceBuffer.Length) { if (gpuInstanceBuffer != null) { gpuInstanceBuffer.Dispose(); } gpuInstanceBuffer = gpuInstanceBufferBuilder.WithLength((uint)cpuInstanceBuffer.Length).Create(); } gpuInstanceBuffer.DiscardWrite(cpuInstanceBuffer); // Happens immediately (required) // Set instance buffer and flush all commands, first on immediate context, then on each deferred SetInstanceBufferAndFlushCommands(); } ///* ============================================= // * PREPARE FOR GLOW // * ============================================= */ //// Clear glow buffers //QueueRenderCommand(RenderCommand.ClearRenderTarget(glowSrcBufferRTV)); //// Set blend state //QueueRenderCommand(RenderCommand.SetBlendState(glowBlendState)); //// Set topology //QueueRenderCommand(RenderCommand.SetPrimitiveTopology(RenderCommand.DEFAULT_PRIMITIVE_TOPOLOGY)); //// Set input layout //QueueRenderCommand(RenderCommand.SetInputLayout(glowPlaneInputLayout)); //// Enqueue VS commands //QueueShaderSwitch(glowVS); //QueueShaderResourceUpdate(glowVS); ///* ============================================= // * DOWNSCALE TO GLOW SRC BUFFER // * ============================================= */ //// Set up output merger //QueueRenderCommand(RenderCommand.SetRenderTargets(glowDSBufferDSV, glowSrcBufferRTV)); //// Switch to copy shader //QueueShaderSwitch(scaleDownShader); //QueueShaderResourceUpdate(scaleDownShader, scaleDownShaderResPkg); //// Draw fullscreen triangles //QueueRenderCommand(RenderCommand.Draw(0, 3U)); //QueueRenderCommand(RenderCommand.Draw(3, 3U)); //// Unbind resources //QueueShaderResourceUpdate(scaleDownShader, scaleDownShaderResUnbindPkg); ///* ============================================= // * RENDER GLOW // * ============================================= */ //// Set up output merger //QueueRenderCommand(RenderCommand.SetRenderTargets(glowDSBufferDSV, glowDstBufferRTV)); //// Switch to glow shader //QueueShaderSwitch(glowShader); //QueueShaderResourceUpdate(glowShader, glowShaderVResPkg); //// Set blend state //QueueRenderCommand(RenderCommand.SetBlendState(dstMergeBlend)); //// Draw fullscreen triangles //QueueRenderCommand(RenderCommand.Draw(0, 3U)); //QueueRenderCommand(RenderCommand.Draw(3, 3U)); //// Unbind resources //QueueShaderResourceUpdate(glowShader, glowShaderVResUnbindPkg); ///* ============================================= // * UPSCALE TO BACK BUFFER // * ============================================= */ //// Set up output merger //QueueRenderCommand(RenderCommand.SetRenderTargets(output.TargetWindow)); //// Switch to copy shader //QueueShaderSwitch(scaleUpShader); //QueueShaderResourceUpdate(scaleUpShader, scaleUpShaderResPkg); //// Draw fullscreen triangles //QueueRenderCommand(RenderCommand.Draw(0, 3U)); //QueueRenderCommand(RenderCommand.Draw(3, 3U)); //// Unbind resources //QueueShaderResourceUpdate(scaleUpShader, scaleUpShaderResUnbindPkg); // Present FlushRenderCommands(); if (presentAfterPass) { PresentBackBuffer(Output.TargetWindow); } }