예제 #1
0
    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));
        }
    }
예제 #2
0
 /// <inheritdoc />
 protected override void Dispose(bool isDisposing)
 {
     if (isDisposing)
     {
         _waitForIdleFence.Dispose();
         _waitForIdleFence = null !;
     }
     _ = _d3d12CommandQueue.Reset();
 }
예제 #3
0
    /// <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);
    }
예제 #4
0
    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));
        }
    }
예제 #5
0
    /// <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);
    }
예제 #6
0
 private void WaitForFenceUnsafe(GraphicsFence fence)
 {
     ThrowExternalExceptionIfFailed(D3D12CommandQueue->Wait(fence.D3D12Fence, Value: 1));
 }
예제 #7
0
        // 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);
        }