private void SetUpCacheForLocalThread() { // Set topology QueueRenderCommand(RenderCommand.SetPrimitiveTopology(RenderCommand.DEFAULT_PRIMITIVE_TOPOLOGY)); // Set input layout GeometryInputLayout shaderInputLayout = currentCache.GetInputLayout(currentVS); QueueRenderCommand(RenderCommand.SetInputLayout(shaderInputLayout)); // Enqueue VS commands QueueRenderCommand(RenderCommand.SetIndexBuffer(currentCache.IndexBuffer)); QueueShaderSwitch(currentVS); QueueShaderResourceUpdate(currentVS, shaderInputLayout.ResourcePackage); // 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(output.TargetWindow, primaryDSBufferDSV, gBufferViews)); // Reserve a space for setting the instance buffer reservedSetIBCommandSlot = ReserveCommandSlot(); }
public void TestSetInputLayout() { GeometryCacheBuilder <DefaultVertex> gcb = new GeometryCacheBuilder <DefaultVertex>(); gcb.AddModel("TSIL_a", new DefaultVertex[] { new DefaultVertex(Vector3.ONE) }, new uint[] { 0U }); GeometryCache cache = gcb.Build(); ConstantBuffer <Matrix> vpMat = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite); VertexShader shader = new VertexShader( @"Tests\SimpleVS.cso", new VertexInputBinding(0U, "INSTANCE_TRANSFORM"), new ConstantBufferBinding(0U, "CameraTransform", vpMat), new VertexInputBinding(1U, "POSITION") ); GeometryInputLayout gil = cache.GetInputLayout(shader); RenderCommand testCommand = RenderCommand.SetInputLayout(gil); Assert.AreEqual(RenderCommandInstruction.SetInputLayout, testCommand.Instruction); Assert.AreEqual((RenderCommandArgument)(IntPtr)gil.ResourceHandle, testCommand.Arg1); #if !DEVELOPMENT && !RELEASE try { RenderCommand.SetInputLayout(null); Assert.Fail(); } catch (AssuranceFailedException) { } #endif shader.Dispose(); vpMat.Dispose(); cache.Dispose(); gil.Dispose(); #if !DEVELOPMENT && !RELEASE try { RenderCommand.SetInputLayout(gil); 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); } }