using Ghost.Core; using Ghost.Graphics.Data; using TerraFX.Interop.DirectX; namespace Ghost.Graphics.RHI; /// /// D3D12-style command buffer interface for recording rendering commands /// public interface ICommandBuffer : IDisposable { public CommandBufferType Type { get; } public bool IsEmpty { get; } /// /// Begins recording commands into this command buffer /// public void Begin(); /// /// Ends recording commands and prepares for submission /// public void End(); /// /// Sets the optional render targets and optional depth target for subsequent rendering operations. /// /// /// To specify no render targets, provide an empty span for . /// Use for if no depth target is required. /// /// A read-only span of handles to textures that will be used as render targets. /// The order of handles determines the order in which render targets are bound. /// A handle to the texture to be used as the depth target. Specify a invalid handle if no depth target is required. public void SetRenderTargets(ReadOnlySpan> renderTargets, Handle depthTarget); /// /// Begins a render pass with the specified render target /// /// Render target to render into (can be invalid) /// Depth target to use (can be invalid) /// Color to clear the render target with public void BeginRenderPass(Handle renderTarget, Handle depthTarget, Color128 clearColor); /// /// Ends the current render pass /// public void EndRenderPass(); /// /// Sets the viewport for rendering /// /// Viewport to set public void SetViewport(ViewportDesc viewport); /// /// Sets the scissor rectangle /// /// Scissor rectangle to set public void SetScissorRect(RectDesc rect); /// /// Inserts a resource barrier for state transitions /// /// Resource to transition /// Current resource state /// Target resource state public void ResourceBarrier(Handle resource, ResourceState before, ResourceState after); /// /// Sets the graphics root signature /// /// Root signature to set public void SetRootSignature(IRootSignature rootSignature); /// /// Sets the pipeline state object /// /// Pipeline state to set public void SetPipelineState(IShaderPipeline pipelineState); public void SetVertexBuffer(uint slot, Handle buffer, ulong offset = 0); public void SetIndexBuffer(Handle buffer, IndexType type, ulong offset = 0); public void Draw(uint vertexCount, uint instanceCount = 1, uint startVertex = 0, uint startInstance = 0); public void DrawIndexed(uint indexCount, uint instanceCount = 1, uint startIndex = 0, int baseVertex = 0, uint startInstance = 0); /// /// Dispatches compute threads /// /// Thread groups in X dimension /// Thread groups in Y dimension /// Thread groups in Z dimension public void Dispatch(uint threadGroupCountX, uint threadGroupCountY = 1, uint threadGroupCountZ = 1); /// /// Uploads the specified data to the buffer represented by the given handle. /// /// The unmanaged value type of the elements to upload to the buffer. /// A handle to the buffer that will receive the uploaded data. /// A read-only span containing the data to upload to the buffer. The span must contain elements of type /// . public void Upload(Handle buffer, ReadOnlySpan data) where T : unmanaged; /// /// Uploads texture data to the specified texture resource starting at the given subresource index. /// /// The texture resource to which the subresource data will be uploaded. Must be a valid, initialized texture handle. /// The index of the first subresource in the texture to receive data. Must be less than the total number of subresources in the texture. /// A reference to the structure containing the subresource data to upload. The data must match the format and layout expected by the texture. /// The number of subresources to upload, starting from . /// Must be greater than zero and not exceed the remaining subresources in the texture. public void Upload(Handle texture, params ReadOnlySpan subresources); /// /// Copies a specified number of bytes from the source graphics buffer to the destination graphics buffer. /// /// The handle to the destination graphics buffer where data will be written. Cannot be null. /// The handle to the source graphics buffer from which data will be read. Cannot be null. /// The byte offset in the destination buffer at which to begin writing. Must be zero or greater. /// The byte offset in the source buffer at which to begin reading. Must be zero or greater. /// The number of bytes to copy. If zero, copies the remaining bytes from the source buffer starting at . public void CopyBuffer(Handle dest, Handle src, ulong destOffset = 0, ulong srcOffset = 0, ulong numBytes = 0); } internal static class ResourceStateExtensions { public static D3D12_RESOURCE_STATES ToD3D12States(this ResourceState state) { return state switch { ResourceState.Common or ResourceState.Present => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COMMON, ResourceState.VertexAndConstantBuffer => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, ResourceState.IndexBuffer => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_INDEX_BUFFER, ResourceState.RenderTarget => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET, ResourceState.UnorderedAccess => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_UNORDERED_ACCESS, ResourceState.DepthWrite => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_DEPTH_WRITE, ResourceState.DepthRead => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_DEPTH_READ, ResourceState.PixelShaderResource => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, ResourceState.CopyDest => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST, ResourceState.CopySource => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_SOURCE, _ => throw new ArgumentException($"Unknown resource state: {state}") }; } }