private protected GraphicsCommandQueue(GraphicsDevice device, GraphicsContextKind kind) : base(device) { var d3d12CommandListType = kind.AsD3D12CommandListType(); var d3d12CommandQueue = CreateD3D12CommandQueue(d3d12CommandListType, out _d3d12CommandQueueVersion); _d3d12CommandQueue.Attach(d3d12CommandQueue); _kind = kind; _waitForIdleFence = device.CreateFence(isSignalled: false); SetNameUnsafe(Name); ID3D12CommandQueue *CreateD3D12CommandQueue(D3D12_COMMAND_LIST_TYPE d3d12CommandListType, out uint d3d12CommandQueueVersion) { ID3D12CommandQueue *d3d12CommandQueue; var d3d12CommandQueueDesc = new D3D12_COMMAND_QUEUE_DESC { Type = d3d12CommandListType, Priority = 0, Flags = D3D12_COMMAND_QUEUE_FLAG_NONE, NodeMask = 0, }; ThrowExternalExceptionIfFailed(Device.D3D12Device->CreateCommandQueue(&d3d12CommandQueueDesc, __uuidof <ID3D12CommandQueue>(), (void **)&d3d12CommandQueue)); return(GetLatestD3D12CommandQueue(d3d12CommandQueue, out d3d12CommandQueueVersion)); } }
/// <inheritdoc /> protected override void Dispose(bool isDisposing) { if (isDisposing) { _waitForIdleFence.Dispose(); _waitForIdleFence = null !; } _ = _d3d12CommandQueue.Reset(); }
/// <summary>Enqueues a GPU side wait for a graphics fence.</summary> /// <param name="fence">The graphics fence for which to wait.</param> /// <exception cref="ArgumentNullException"><paramref name="fence" /> is <c>null</c>.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="fence" /> was not created for the same device as the command queue.</exception> /// <exception cref="ObjectDisposedException">The command queue has been disposed.</exception> public void WaitForFence(GraphicsFence fence) { ThrowIfDisposed(); ThrowIfNull(fence); if (fence.Device != Device) { ThrowForInvalidParent(fence.Device); } WaitForFenceUnsafe(fence); }
private protected GraphicsContext(GraphicsCommandQueue commandQueue, GraphicsContextKind kind) : base(commandQueue) { // No need for a CommandQueue.AddContext(this) as it will be done by the underlying pool var d3d12CommandListType = kind.AsD3D12CommandListType(); var d3d12CommandAllocator = CreateD3D12CommandAllocator(d3d12CommandListType, out _d3d12CommandAllocatorVersion); _d3d12CommandAllocator.Attach(d3d12CommandAllocator); var d3d12GraphicsCommandList = CreateD3D12GraphicsCommandList(d3d12CommandListType, out _d3d12GraphicsCommandListVersion); _d3d12GraphicsCommandList.Attach(d3d12GraphicsCommandList); _kind = kind; _fence = Device.CreateFence(isSignalled: true); SetNameUnsafe(Name); ID3D12CommandAllocator *CreateD3D12CommandAllocator(D3D12_COMMAND_LIST_TYPE d3d12CommandListType, out uint d3d12CommandAllocatorVersion) { ID3D12CommandAllocator *d3d12CommandAllocator; ThrowExternalExceptionIfFailed(Device.D3D12Device->CreateCommandAllocator(d3d12CommandListType, __uuidof <ID3D12CommandAllocator>(), (void **)&d3d12CommandAllocator)); return(GetLatestD3D12CommandAllocator(d3d12CommandAllocator, out d3d12CommandAllocatorVersion)); } ID3D12GraphicsCommandList *CreateD3D12GraphicsCommandList(D3D12_COMMAND_LIST_TYPE d3d12CommandListType, out uint d3d12GraphicsCommandListVersion) { ID3D12GraphicsCommandList *d3d12GraphicsCommandList; if (Device.D3D12DeviceVersion >= 4) { var d3d12Device4 = (ID3D12Device4 *)Device.D3D12Device; ThrowExternalExceptionIfFailed(d3d12Device4->CreateCommandList1(nodeMask: 0, d3d12CommandListType, D3D12_COMMAND_LIST_FLAG_NONE, __uuidof <ID3D12GraphicsCommandList>(), (void **)&d3d12GraphicsCommandList)); } else { var d3d12Device = Device.D3D12Device; ThrowExternalExceptionIfFailed(d3d12Device->CreateCommandList(nodeMask: 0, d3d12CommandListType, _d3d12CommandAllocator, pInitialState: null, __uuidof <ID3D12GraphicsCommandList>(), (void **)&d3d12GraphicsCommandList)); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. ThrowExternalExceptionIfFailed(d3d12GraphicsCommandList->Close()); } return(GetLatestD3D12GraphicsCommandList(d3d12GraphicsCommandList, out d3d12GraphicsCommandListVersion)); } }
/// <inheritdoc /> protected override void Dispose(bool isDisposing) { if (isDisposing) { var fence = Fence; fence.Wait(); fence.Reset(); fence.Dispose(); _fence = null !; } _ = _d3d12GraphicsCommandList.Reset(); _ = _d3d12CommandAllocator.Reset(); _ = CommandQueue.RemoveContext(this); }
private void WaitForFenceUnsafe(GraphicsFence fence) { ThrowExternalExceptionIfFailed(D3D12CommandQueue->Wait(fence.D3D12Fence, Value: 1)); }
// Here you can implement the rendering logic. // Use <c>ScriptableRenderContext</c> to issue drawing commands or execute command buffers // https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (m_ReflectionShaderCS == null || m_ReflectionShader == null) { return; } if (m_ReflectionMaterial == null || m_ReflectionMaterial.shader == null) { m_ReflectionMaterial = new Material(m_ReflectionShader); } Camera camera = renderingData.cameraData.camera; // Calculate Our Plane and Matrices Vector3 temp; temp = m_Settings.PlaneRotation * Vector3.up; temp.Normalize(); m_ReflectionData[0].x = temp.x; m_ReflectionData[0].y = temp.y; m_ReflectionData[0].z = temp.z; m_ReflectionData[0].w = -Vector3.Dot(temp, m_Settings.PlaneLocation); m_ReflectionData[1].x = 1.0f / m_Size.x; m_ReflectionData[1].y = 1.0f / m_Size.y; m_ReflectionData[1].z = m_ReflectionData[1].x * 0.5f; m_ReflectionData[1].w = m_ReflectionData[1].y * 0.5f; m_ReflectionData[2].x = camera.transform.forward.z; m_ReflectionData[2].y = m_Settings.StretchThreshold; m_ReflectionData[2].z = m_Settings.StretchIntensity; // The actual projection matrix used in shaders is actually massaged a bit to work across all platforms // (different Z value ranges etc.) var gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, true); Matrix4x4 worldToCamera = camera.cameraToWorldMatrix; Vector4 zaxis = worldToCamera.GetRow(2); worldToCamera.SetRow(2, -zaxis); m_VP = camera.projectionMatrix;// * worldToCamera; m_VP = camera.projectionMatrix; m_VP = gpuProj * camera.worldToCameraMatrix; m_InvVP = m_VP.inverse; bool UseCameraDepth = !renderingData.cameraData.requiresDepthTexture && !renderingData.cameraData.isSceneViewCamera; CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); using (new ProfilingScope(cmd, m_ProfilerSampler)) { // need to run compute shader to clear if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) { cmd.SetComputeBufferParam(m_ReflectionShaderCS, m_ClearKernal, m_PropertyResult, m_MetalBuffer); cmd.SetComputeIntParam(m_ReflectionShaderCS, m_PropertyBufferStep, m_BufferStride); } else { cmd.SetComputeTextureParam(m_ReflectionShaderCS, m_ClearKernal, m_PropertyResult, m_ScreenSpacePlanarReflectionBuffer.Identifier()); } cmd.SetComputeIntParams(m_ReflectionShaderCS, m_PropertyResultSize, m_Size.x, m_Size.y); cmd.DispatchCompute(m_ReflectionShaderCS, m_ClearKernal, m_ThreadSize.x, m_ThreadSize.y, 1); { //GraphicsFence fence = cmd.CreateGraphicsFence(GraphicsFenceType.AsyncQueueSynchronisation, SynchronisationStageFlags.ComputeProcessing); //cmd.WaitOnAsyncGraphicsFence(fence); } if (bDebug && SystemInfo.graphicsDeviceType != GraphicsDeviceType.Metal) { cmd.SetComputeTextureParam(m_ReflectionShaderCS, m_DebugKernal, m_PropertyResult, m_ScreenSpacePlanarReflectionBuffer.Identifier()); cmd.SetComputeTextureParam(m_ReflectionShaderCS, m_DebugKernal, m_PropertyDebugTex, m_DebugBuffer.Identifier()); cmd.SetComputeIntParams(m_ReflectionShaderCS, m_PropertyResultSize, m_Size.x, m_Size.y); cmd.SetComputeMatrixParam(m_ReflectionShaderCS, m_PropertyInvVP, m_InvVP); cmd.SetComputeMatrixParam(m_ReflectionShaderCS, m_PropertyVP, m_VP); cmd.SetComputeVectorArrayParam(m_ReflectionShaderCS, m_PropertyReflectionData, m_ReflectionData); cmd.DispatchCompute(m_ReflectionShaderCS, m_DebugKernal, m_ThreadSize.x, m_ThreadSize.y, 1); } else { int Kernal = m_Settings.ApplyEdgeStretch ? m_RenderStretchKernal : m_RenderKernal; if (UseCameraDepth) { if (m_MSAA) { // okay change the kernal to switch (m_MSAACount) { case 2: Kernal = m_MSSA2Kernal; cmd.SetComputeTextureParam(m_ReflectionShaderCS, Kernal, m_PropertyDepth_MSAA2, m_CameraDepthTarget); break; case 4: Kernal = m_MSSA4Kernal; cmd.SetComputeTextureParam(m_ReflectionShaderCS, Kernal, m_PropertyDepth_MSAA4, m_CameraDepthTarget); break; case 8: Kernal = m_MSSA8Kernal; cmd.SetComputeTextureParam(m_ReflectionShaderCS, Kernal, m_PropertyDepth_MSAA8, m_CameraDepthTarget); break; default: Debug.LogError("Undefined MSAA Level"); break; } } else { cmd.SetComputeTextureParam(m_ReflectionShaderCS, Kernal, m_PropertyDepth, m_CameraDepthTarget); } } else { cmd.SetComputeTextureParam(m_ReflectionShaderCS, Kernal, m_PropertyDepth, m_DepthTexture.Identifier()); } if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) { cmd.SetComputeBufferParam(m_ReflectionShaderCS, Kernal, m_PropertyResult, m_MetalBuffer); cmd.SetComputeIntParam(m_ReflectionShaderCS, m_PropertyBufferStep, m_BufferStride); } else { cmd.SetComputeTextureParam(m_ReflectionShaderCS, Kernal, m_PropertyResult, m_ScreenSpacePlanarReflectionBuffer.Identifier()); } //cmd.SetComputeTextureParam(m_ReflectionShaderCS, Kernal, m_PropertyDepth, m_DepthTexture.Identifier()); //cmd.SetComputeTextureParam(m_ReflectionShaderCS, m_RenderKernal, m_PropertyDepth, BuiltinRenderTextureType.Depth); cmd.SetComputeIntParams(m_ReflectionShaderCS, m_PropertyResultSize, m_Size.x, m_Size.y); cmd.SetComputeMatrixParam(m_ReflectionShaderCS, m_PropertyInvVP, m_InvVP); cmd.SetComputeMatrixParam(m_ReflectionShaderCS, m_PropertyVP, m_VP); cmd.SetComputeVectorArrayParam(m_ReflectionShaderCS, m_PropertyReflectionData, m_ReflectionData); cmd.DispatchCompute(m_ReflectionShaderCS, Kernal, m_ThreadSize.x, m_ThreadSize.y, 1); } { GraphicsFence fence = cmd.CreateGraphicsFence(GraphicsFenceType.AsyncQueueSynchronisation, SynchronisationStageFlags.ComputeProcessing); cmd.WaitOnAsyncGraphicsFence(fence); } if (m_Settings.ApplyBlur) { // now we can render into the temporary texture where the stencil is set or full screen depending if the optimisation is on RenderReflection(cmd, m_Temp[0].Identifier(), camera); // render blur RenderBlur(cmd, m_ScreenSpacePlanarReflection.Identifier(), m_Temp[0].Identifier(), camera); } else { // now we can render into the temporary texture where the stencil is set or full screen depending if the optimisation is on RenderReflection(cmd, m_ScreenSpacePlanarReflection.Identifier(), camera); } // restore target state cmd.SetRenderTarget(m_CameraColorTarget, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store, m_CameraDepthTarget, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store); cmd.SetGlobalTexture(m_ScreenSpacePlanarReflection.id, m_ScreenSpacePlanarReflection.Identifier()); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }