From 60a49a2e527ce6d9ff81765edbdca82ecf977c7c Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 17 Nov 2022 11:33:42 -0800 Subject: [PATCH] remove params methods + implicit BufferBinding cast --- src/Graphics/CommandBuffer.cs | 950 +++++++++++++++++++++++++------ src/Graphics/Resources/Buffer.cs | 6 +- 2 files changed, 769 insertions(+), 187 deletions(-) diff --git a/src/Graphics/CommandBuffer.cs b/src/Graphics/CommandBuffer.cs index 2af1524..b63563f 100644 --- a/src/Graphics/CommandBuffer.cs +++ b/src/Graphics/CommandBuffer.cs @@ -36,9 +36,8 @@ namespace MoonWorks.Graphics /// /// The color attachment to use in the render pass. public unsafe void BeginRenderPass( - ColorAttachmentInfo colorAttachmentInfo - ) - { + in ColorAttachmentInfo colorAttachmentInfo + ) { #if DEBUG AssertTextureNotNull(colorAttachmentInfo); AssertColorTarget(colorAttachmentInfo); @@ -66,10 +65,9 @@ namespace MoonWorks.Graphics /// The first color attachment to use in the render pass. /// The second color attachment to use in the render pass. public unsafe void BeginRenderPass( - ColorAttachmentInfo colorAttachmentInfoOne, - ColorAttachmentInfo colorAttachmentInfoTwo - ) - { + in ColorAttachmentInfo colorAttachmentInfoOne, + in ColorAttachmentInfo colorAttachmentInfoTwo + ) { #if DEBUG AssertTextureNotNull(colorAttachmentInfoOne); AssertColorTarget(colorAttachmentInfoOne); @@ -104,11 +102,10 @@ namespace MoonWorks.Graphics /// The second color attachment to use in the render pass. /// The third color attachment to use in the render pass. public unsafe void BeginRenderPass( - ColorAttachmentInfo colorAttachmentInfoOne, - ColorAttachmentInfo colorAttachmentInfoTwo, - ColorAttachmentInfo colorAttachmentInfoThree - ) - { + in ColorAttachmentInfo colorAttachmentInfoOne, + in ColorAttachmentInfo colorAttachmentInfoTwo, + in ColorAttachmentInfo colorAttachmentInfoThree + ) { #if DEBUG AssertTextureNotNull(colorAttachmentInfoOne); AssertColorTarget(colorAttachmentInfoOne); @@ -149,12 +146,11 @@ namespace MoonWorks.Graphics /// The third color attachment to use in the render pass. /// The four color attachment to use in the render pass. public unsafe void BeginRenderPass( - ColorAttachmentInfo colorAttachmentInfoOne, - ColorAttachmentInfo colorAttachmentInfoTwo, - ColorAttachmentInfo colorAttachmentInfoThree, - ColorAttachmentInfo colorAttachmentInfoFour - ) - { + in ColorAttachmentInfo colorAttachmentInfoOne, + in ColorAttachmentInfo colorAttachmentInfoTwo, + in ColorAttachmentInfo colorAttachmentInfoThree, + in ColorAttachmentInfo colorAttachmentInfoFour + ) { #if DEBUG AssertTextureNotNull(colorAttachmentInfoOne); AssertColorTarget(colorAttachmentInfoOne); @@ -197,9 +193,8 @@ namespace MoonWorks.Graphics /// /// The depth stencil attachment to use in the render pass. public unsafe void BeginRenderPass( - DepthStencilAttachmentInfo depthStencilAttachmentInfo - ) - { + in DepthStencilAttachmentInfo depthStencilAttachmentInfo + ) { #if DEBUG AssertValidDepthAttachment(depthStencilAttachmentInfo); #endif @@ -225,10 +220,9 @@ namespace MoonWorks.Graphics /// The depth stencil attachment to use in the render pass. /// The color attachment to use in the render pass. public unsafe void BeginRenderPass( - DepthStencilAttachmentInfo depthStencilAttachmentInfo, - ColorAttachmentInfo colorAttachmentInfo - ) - { + in DepthStencilAttachmentInfo depthStencilAttachmentInfo, + in ColorAttachmentInfo colorAttachmentInfo + ) { #if DEBUG AssertValidDepthAttachment(depthStencilAttachmentInfo); @@ -261,11 +255,10 @@ namespace MoonWorks.Graphics /// The first color attachment to use in the render pass. /// The second color attachment to use in the render pass. public unsafe void BeginRenderPass( - DepthStencilAttachmentInfo depthStencilAttachmentInfo, - ColorAttachmentInfo colorAttachmentInfoOne, - ColorAttachmentInfo colorAttachmentInfoTwo - ) - { + in DepthStencilAttachmentInfo depthStencilAttachmentInfo, + in ColorAttachmentInfo colorAttachmentInfoOne, + in ColorAttachmentInfo colorAttachmentInfoTwo + ) { #if DEBUG AssertValidDepthAttachment(depthStencilAttachmentInfo); @@ -305,12 +298,11 @@ namespace MoonWorks.Graphics /// The second color attachment to use in the render pass. /// The third color attachment to use in the render pass. public unsafe void BeginRenderPass( - DepthStencilAttachmentInfo depthStencilAttachmentInfo, - ColorAttachmentInfo colorAttachmentInfoOne, - ColorAttachmentInfo colorAttachmentInfoTwo, - ColorAttachmentInfo colorAttachmentInfoThree - ) - { + in DepthStencilAttachmentInfo depthStencilAttachmentInfo, + in ColorAttachmentInfo colorAttachmentInfoOne, + in ColorAttachmentInfo colorAttachmentInfoTwo, + in ColorAttachmentInfo colorAttachmentInfoThree + ) { #if DEBUG AssertValidDepthAttachment(depthStencilAttachmentInfo); @@ -356,13 +348,12 @@ namespace MoonWorks.Graphics /// The third color attachment to use in the render pass. /// The four color attachment to use in the render pass. public unsafe void BeginRenderPass( - DepthStencilAttachmentInfo depthStencilAttachmentInfo, - ColorAttachmentInfo colorAttachmentInfoOne, - ColorAttachmentInfo colorAttachmentInfoTwo, - ColorAttachmentInfo colorAttachmentInfoThree, - ColorAttachmentInfo colorAttachmentInfoFour - ) - { + in DepthStencilAttachmentInfo depthStencilAttachmentInfo, + in ColorAttachmentInfo colorAttachmentInfoOne, + in ColorAttachmentInfo colorAttachmentInfoTwo, + in ColorAttachmentInfo colorAttachmentInfoThree, + in ColorAttachmentInfo colorAttachmentInfoFour + ) { #if DEBUG AssertValidDepthAttachment(depthStencilAttachmentInfo); @@ -408,8 +399,7 @@ namespace MoonWorks.Graphics /// The compute pipeline to bind. public void BindComputePipeline( ComputePipeline computePipeline - ) - { + ) { Refresh.Refresh_BindComputePipeline( Device.Handle, Handle, @@ -420,25 +410,121 @@ namespace MoonWorks.Graphics } /// - /// Binds buffers to be used in the compute shader. + /// Binds a buffer to be used in the compute shader. /// - /// A set of buffers to bind. + /// A buffer to bind. public unsafe void BindComputeBuffers( - params Buffer[] buffers - ) - { + Buffer buffer + ) { #if DEBUG AssertComputePipelineBound(); + AssertComputeBufferCount(1); +#endif - if (currentComputePipeline.ComputeShaderInfo.BufferBindingCount == 0) - { - throw new System.InvalidOperationException("The current compute shader does not take any buffers!"); - } + var bufferPtrs = stackalloc IntPtr[1]; + bufferPtrs[0] = buffer.Handle; - if (currentComputePipeline.ComputeShaderInfo.BufferBindingCount < buffers.Length) - { - throw new System.InvalidOperationException("Buffer count exceeds the amount used by the current compute shader!"); - } + Refresh.Refresh_BindComputeBuffers( + Device.Handle, + Handle, + (IntPtr) bufferPtrs + ); + } + + /// + /// Binds buffers to be used in the compute shader. + /// + /// A buffer to bind. + /// A buffer to bind. + public unsafe void BindComputeBuffers( + Buffer bufferOne, + Buffer bufferTwo + ) { +#if DEBUG + AssertComputePipelineBound(); + AssertComputeBufferCount(2); +#endif + + var bufferPtrs = stackalloc IntPtr[1]; + bufferPtrs[0] = bufferOne.Handle; + bufferPtrs[1] = bufferTwo.Handle; + + Refresh.Refresh_BindComputeBuffers( + Device.Handle, + Handle, + (IntPtr) bufferPtrs + ); + } + + /// + /// Binds buffers to be used in the compute shader. + /// + /// A buffer to bind. + /// A buffer to bind. + /// A buffer to bind. + public unsafe void BindComputeBuffers( + Buffer bufferOne, + Buffer bufferTwo, + Buffer bufferThree + ) { +#if DEBUG + AssertComputePipelineBound(); + AssertComputeBufferCount(3); +#endif + + var bufferPtrs = stackalloc IntPtr[1]; + bufferPtrs[0] = bufferOne.Handle; + bufferPtrs[1] = bufferTwo.Handle; + bufferPtrs[2] = bufferThree.Handle; + + Refresh.Refresh_BindComputeBuffers( + Device.Handle, + Handle, + (IntPtr) bufferPtrs + ); + } + + /// + /// Binds buffers to be used in the compute shader. + /// + /// A buffer to bind. + /// A buffer to bind. + /// A buffer to bind. + /// A buffer to bind. + public unsafe void BindComputeBuffers( + Buffer bufferOne, + Buffer bufferTwo, + Buffer bufferThree, + Buffer bufferFour + ) { +#if DEBUG + AssertComputePipelineBound(); + AssertComputeBufferCount(4); +#endif + + var bufferPtrs = stackalloc IntPtr[1]; + bufferPtrs[0] = bufferOne.Handle; + bufferPtrs[1] = bufferTwo.Handle; + bufferPtrs[2] = bufferThree.Handle; + bufferPtrs[3] = bufferFour.Handle; + + Refresh.Refresh_BindComputeBuffers( + Device.Handle, + Handle, + (IntPtr) bufferPtrs + ); + } + + /// + /// Binds buffers to be used in the compute shader. + /// + /// A Span of buffers to bind. + public unsafe void BindComputeBuffers( + in Span buffers + ) { +#if DEBUG + AssertComputePipelineBound(); + AssertComputeBufferCount(buffers.Length); #endif var bufferPtrs = stackalloc IntPtr[buffers.Length]; @@ -455,26 +541,122 @@ namespace MoonWorks.Graphics ); } + /// + /// Binds a texture to be used in the compute shader. + /// + /// A texture to bind. + public unsafe void BindComputeTextures( + Texture texture + ) { +#if DEBUG + AssertComputePipelineBound(); + AssertComputeTextureCount(1); +#endif + + var texturePtrs = stackalloc IntPtr[1]; + texturePtrs[0] = texture.Handle; + + Refresh.Refresh_BindComputeTextures( + Device.Handle, + Handle, + (IntPtr) texturePtrs + ); + } + + /// + /// Binds textures to be used in the compute shader. + /// + /// A texture to bind. + /// A texture to bind. + public unsafe void BindComputeTextures( + Texture textureOne, + Texture textureTwo + ) { +#if DEBUG + AssertComputePipelineBound(); + AssertComputeTextureCount(2); +#endif + + var texturePtrs = stackalloc IntPtr[1]; + texturePtrs[0] = textureOne.Handle; + texturePtrs[1] = textureTwo.Handle; + + Refresh.Refresh_BindComputeTextures( + Device.Handle, + Handle, + (IntPtr) texturePtrs + ); + } + + /// + /// Binds textures to be used in the compute shader. + /// + /// A texture to bind. + /// A texture to bind. + /// A texture to bind. + public unsafe void BindComputeTextures( + Texture textureOne, + Texture textureTwo, + Texture textureThree + ) { +#if DEBUG + AssertComputePipelineBound(); + AssertComputeTextureCount(3); +#endif + + var texturePtrs = stackalloc IntPtr[1]; + texturePtrs[0] = textureOne.Handle; + texturePtrs[1] = textureTwo.Handle; + texturePtrs[2] = textureThree.Handle; + + Refresh.Refresh_BindComputeTextures( + Device.Handle, + Handle, + (IntPtr) texturePtrs + ); + } + + /// + /// Binds textures to be used in the compute shader. + /// + /// A texture to bind. + /// A texture to bind. + /// A texture to bind. + /// A texture to bind. + public unsafe void BindComputeTextures( + Texture textureOne, + Texture textureTwo, + Texture textureThree, + Texture textureFour + ) { +#if DEBUG + AssertComputePipelineBound(); + AssertComputeTextureCount(4); +#endif + + var texturePtrs = stackalloc IntPtr[1]; + texturePtrs[0] = textureOne.Handle; + texturePtrs[1] = textureTwo.Handle; + texturePtrs[2] = textureThree.Handle; + texturePtrs[3] = textureFour.Handle; + + Refresh.Refresh_BindComputeTextures( + Device.Handle, + Handle, + (IntPtr) texturePtrs + ); + } + /// /// Binds textures to be used in the compute shader. /// /// A set of textures to bind. public unsafe void BindComputeTextures( - params Texture[] textures - ) - { + in Span textures + ) { #if DEBUG AssertComputePipelineBound(); - - if (currentComputePipeline.ComputeShaderInfo.ImageBindingCount == 0) - { - throw new System.InvalidOperationException("The current compute shader does not take any textures!"); - } - - if (currentComputePipeline.ComputeShaderInfo.ImageBindingCount < textures.Length) - { - throw new System.InvalidOperationException("Texture count exceeds the amount used by the current compute shader!"); - } + AssertComputeTextureCount(textures.Length); #endif var texturePtrs = stackalloc IntPtr[textures.Length]; @@ -503,8 +685,7 @@ namespace MoonWorks.Graphics uint groupCountY, uint groupCountZ, uint computeParamOffset - ) - { + ) { #if DEBUG AssertComputePipelineBound(); @@ -530,8 +711,7 @@ namespace MoonWorks.Graphics /// The graphics pipeline to bind. public void BindGraphicsPipeline( GraphicsPipeline graphicsPipeline - ) - { + ) { #if DEBUG AssertRenderPassActive(); @@ -553,7 +733,7 @@ namespace MoonWorks.Graphics /// /// Sets the viewport. Only valid during a render pass. /// - public void SetViewport(Viewport viewport) + public void SetViewport(in Viewport viewport) { #if DEBUG AssertRenderPassActive(); @@ -569,7 +749,7 @@ namespace MoonWorks.Graphics /// /// Sets the scissor area. Only valid during a render pass. /// - public void SetScissor(Rect scissor) + public void SetScissor(in Rect scissor) { #if DEBUG AssertRenderPassActive(); @@ -585,13 +765,139 @@ namespace MoonWorks.Graphics /// /// Binds vertex buffers to be used by subsequent draw calls. /// - /// The index of the first buffer to bind. - /// Buffers to bind and their associated offsets. + /// Buffer to bind and associated offset. + /// The index of the first vertex input binding whose state is updated by the command. public unsafe void BindVertexBuffers( - uint firstBinding, - params BufferBinding[] bufferBindings - ) - { + in BufferBinding bufferBinding, + uint firstBinding = 0 + ) { + var bufferPtrs = stackalloc IntPtr[1]; + var offsets = stackalloc ulong[1]; + + bufferPtrs[0] = bufferBinding.Buffer.Handle; + offsets[0] = bufferBinding.Offset; + + Refresh.Refresh_BindVertexBuffers( + Device.Handle, + Handle, + firstBinding, + 1, + (IntPtr) bufferPtrs, + (IntPtr) offsets + ); + } + + /// + /// Binds vertex buffers to be used by subsequent draw calls. + /// + /// Buffer to bind and associated offset. + /// Buffer to bind and associated offset. + /// The index of the first vertex input binding whose state is updated by the command. + public unsafe void BindVertexBuffers( + in BufferBinding bufferBindingOne, + in BufferBinding bufferBindingTwo, + uint firstBinding = 0 + ) { + var bufferPtrs = stackalloc IntPtr[2]; + var offsets = stackalloc ulong[2]; + + bufferPtrs[0] = bufferBindingOne.Buffer.Handle; + bufferPtrs[1] = bufferBindingTwo.Buffer.Handle; + + offsets[0] = bufferBindingOne.Offset; + offsets[1] = bufferBindingTwo.Offset; + + Refresh.Refresh_BindVertexBuffers( + Device.Handle, + Handle, + firstBinding, + 2, + (IntPtr) bufferPtrs, + (IntPtr) offsets + ); + } + + /// + /// Binds vertex buffers to be used by subsequent draw calls. + /// + /// Buffer to bind and associated offset. + /// Buffer to bind and associated offset. + /// Buffer to bind and associated offset. + /// The index of the first vertex input binding whose state is updated by the command. + public unsafe void BindVertexBuffers( + in BufferBinding bufferBindingOne, + in BufferBinding bufferBindingTwo, + in BufferBinding bufferBindingThree, + uint firstBinding = 0 + ) { + var bufferPtrs = stackalloc IntPtr[3]; + var offsets = stackalloc ulong[3]; + + bufferPtrs[0] = bufferBindingOne.Buffer.Handle; + bufferPtrs[1] = bufferBindingTwo.Buffer.Handle; + bufferPtrs[2] = bufferBindingThree.Buffer.Handle; + + offsets[0] = bufferBindingOne.Offset; + offsets[1] = bufferBindingTwo.Offset; + offsets[2] = bufferBindingThree.Offset; + + Refresh.Refresh_BindVertexBuffers( + Device.Handle, + Handle, + firstBinding, + 3, + (IntPtr) bufferPtrs, + (IntPtr) offsets + ); + } + + /// + /// Binds vertex buffers to be used by subsequent draw calls. + /// + /// Buffer to bind and associated offset. + /// Buffer to bind and associated offset. + /// Buffer to bind and associated offset. + /// Buffer to bind and associated offset. + /// The index of the first vertex input binding whose state is updated by the command. + public unsafe void BindVertexBuffers( + in BufferBinding bufferBindingOne, + in BufferBinding bufferBindingTwo, + in BufferBinding bufferBindingThree, + in BufferBinding bufferBindingFour, + uint firstBinding = 0 + ) { + var bufferPtrs = stackalloc IntPtr[4]; + var offsets = stackalloc ulong[4]; + + bufferPtrs[0] = bufferBindingOne.Buffer.Handle; + bufferPtrs[1] = bufferBindingTwo.Buffer.Handle; + bufferPtrs[2] = bufferBindingThree.Buffer.Handle; + bufferPtrs[3] = bufferBindingFour.Buffer.Handle; + + offsets[0] = bufferBindingOne.Offset; + offsets[1] = bufferBindingTwo.Offset; + offsets[2] = bufferBindingThree.Offset; + offsets[3] = bufferBindingFour.Offset; + + Refresh.Refresh_BindVertexBuffers( + Device.Handle, + Handle, + firstBinding, + 4, + (IntPtr) bufferPtrs, + (IntPtr) offsets + ); + } + + /// + /// Binds vertex buffers to be used by subsequent draw calls. + /// + /// Spawn of buffers to bind and their associated offsets. + /// The index of the first vertex input binding whose state is updated by the command. + public unsafe void BindVertexBuffers( + in Span bufferBindings, + uint firstBinding = 0 + ) { var bufferPtrs = stackalloc IntPtr[bufferBindings.Length]; var offsets = stackalloc ulong[bufferBindings.Length]; @@ -611,33 +917,6 @@ namespace MoonWorks.Graphics ); } - /// - /// Binds vertex buffers to be used by subsequent draw calls. - /// - /// The buffers to bind. - public unsafe void BindVertexBuffers( - params Buffer[] buffers - ) - { - var bufferPtrs = stackalloc IntPtr[buffers.Length]; - var offsets = stackalloc ulong[buffers.Length]; - - for (var i = 0; i < buffers.Length; i += 1) - { - bufferPtrs[i] = buffers[i].Handle; - offsets[i] = 0; - } - - Refresh.Refresh_BindVertexBuffers( - Device.Handle, - Handle, - 0, - (uint) buffers.Length, - (IntPtr) bufferPtrs, - (IntPtr) offsets - ); - } - /// /// Binds an index buffer to be used by subsequent draw calls. /// @@ -662,29 +941,170 @@ namespace MoonWorks.Graphics /// /// Binds samplers to be used by the vertex shader. /// - /// The texture-sampler pairs to bind. + /// The texture-sampler to bind. public unsafe void BindVertexSamplers( - ArraySegment textureSamplerBindings - ) - { + in TextureSamplerBinding textureSamplerBinding + ) { #if DEBUG AssertGraphicsPipelineBound(); - - if (currentGraphicsPipeline.VertexShaderInfo.SamplerBindingCount == 0) - { - throw new System.InvalidOperationException("The vertex shader of the current graphics pipeline does not take any samplers!"); - } - - if (currentGraphicsPipeline.VertexShaderInfo.SamplerBindingCount < textureSamplerBindings.Count) - { - throw new System.InvalidOperationException("Vertex sampler count exceeds the amount used by the vertex shader!"); - } + AssertVertexSamplerCount(1); + AssertTextureSamplerBindingNonNull(textureSamplerBinding); + AssertTextureBindingUsageFlags(textureSamplerBinding.Texture); #endif - var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Count]; - var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Count]; + var texturePtrs = stackalloc IntPtr[1]; + var samplerPtrs = stackalloc IntPtr[1]; - for (var i = 0; i < textureSamplerBindings.Count; i += 1) + texturePtrs[0] = textureSamplerBinding.Texture.Handle; + samplerPtrs[0] = textureSamplerBinding.Sampler.Handle; + + Refresh.Refresh_BindVertexSamplers( + Device.Handle, + Handle, + (IntPtr) texturePtrs, + (IntPtr) samplerPtrs + ); + } + + /// + /// Binds samplers to be used by the vertex shader. + /// + /// The first texture-sampler to bind. + /// The second texture-sampler to bind. + public unsafe void BindVertexSamplers( + in TextureSamplerBinding textureSamplerBindingOne, + in TextureSamplerBinding textureSamplerBindingTwo + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertVertexSamplerCount(2); + AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); + AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); + AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); +#endif + + var texturePtrs = stackalloc IntPtr[2]; + var samplerPtrs = stackalloc IntPtr[2]; + + texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; + texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle; + + samplerPtrs[0] = textureSamplerBindingOne.Sampler.Handle; + samplerPtrs[1] = textureSamplerBindingTwo.Sampler.Handle; + + Refresh.Refresh_BindVertexSamplers( + Device.Handle, + Handle, + (IntPtr) texturePtrs, + (IntPtr) samplerPtrs + ); + } + + /// + /// Binds samplers to be used by the vertex shader. + /// + /// The first texture-sampler to bind. + /// The second texture-sampler to bind. + /// The third texture-sampler to bind. + public unsafe void BindVertexSamplers( + in TextureSamplerBinding textureSamplerBindingOne, + in TextureSamplerBinding textureSamplerBindingTwo, + in TextureSamplerBinding textureSamplerBindingThree + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertVertexSamplerCount(3); + AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); + AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); + AssertTextureSamplerBindingNonNull(textureSamplerBindingThree); + AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture); +#endif + + var texturePtrs = stackalloc IntPtr[3]; + var samplerPtrs = stackalloc IntPtr[3]; + + texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; + texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle; + texturePtrs[2] = textureSamplerBindingThree.Texture.Handle; + + samplerPtrs[0] = textureSamplerBindingOne.Sampler.Handle; + samplerPtrs[1] = textureSamplerBindingTwo.Sampler.Handle; + samplerPtrs[2] = textureSamplerBindingThree.Sampler.Handle; + + Refresh.Refresh_BindVertexSamplers( + Device.Handle, + Handle, + (IntPtr) texturePtrs, + (IntPtr) samplerPtrs + ); + } + + /// + /// Binds samplers to be used by the vertex shader. + /// + /// The first texture-sampler to bind. + /// The second texture-sampler to bind. + /// The third texture-sampler to bind. + /// The fourth texture-sampler to bind. + public unsafe void BindVertexSamplers( + in TextureSamplerBinding textureSamplerBindingOne, + in TextureSamplerBinding textureSamplerBindingTwo, + in TextureSamplerBinding textureSamplerBindingThree, + in TextureSamplerBinding textureSamplerBindingFour + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertVertexSamplerCount(4); + AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); + AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); + AssertTextureSamplerBindingNonNull(textureSamplerBindingThree); + AssertTextureSamplerBindingNonNull(textureSamplerBindingFour); + AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingFour.Texture); +#endif + + var texturePtrs = stackalloc IntPtr[4]; + var samplerPtrs = stackalloc IntPtr[4]; + + texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; + texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle; + texturePtrs[2] = textureSamplerBindingThree.Texture.Handle; + texturePtrs[3] = textureSamplerBindingFour.Texture.Handle; + + samplerPtrs[0] = textureSamplerBindingOne.Sampler.Handle; + samplerPtrs[1] = textureSamplerBindingTwo.Sampler.Handle; + samplerPtrs[2] = textureSamplerBindingThree.Sampler.Handle; + samplerPtrs[3] = textureSamplerBindingFour.Sampler.Handle; + + Refresh.Refresh_BindVertexSamplers( + Device.Handle, + Handle, + (IntPtr) texturePtrs, + (IntPtr) samplerPtrs + ); + } + + /// + /// Binds samplers to be used by the vertex shader. + /// + /// The texture-sampler pairs to bind. + public unsafe void BindVertexSamplers( + in Span textureSamplerBindings + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertVertexSamplerCount(textureSamplerBindings.Length); +#endif + + var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Length]; + var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Length]; + + for (var i = 0; i < textureSamplerBindings.Length; i += 1) { #if DEBUG AssertTextureSamplerBindingNonNull(textureSamplerBindings[i]); @@ -704,42 +1124,172 @@ namespace MoonWorks.Graphics } /// - /// Binds samplers to be used by the vertex shader. + /// Binds samplers to be used by the fragment shader. /// - /// The texture-sampler pairs to bind. - public unsafe void BindVertexSamplers( - params TextureSamplerBinding[] textureSamplerBindings - ) - { - BindVertexSamplers(new ArraySegment(textureSamplerBindings)); + /// The texture-sampler to bind. + public unsafe void BindFragmentSamplers( + in TextureSamplerBinding textureSamplerBinding + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertFragmentSamplerCount(1); + AssertTextureSamplerBindingNonNull(textureSamplerBinding); + AssertTextureBindingUsageFlags(textureSamplerBinding.Texture); +#endif + + var texturePtrs = stackalloc IntPtr[1]; + var samplerPtrs = stackalloc IntPtr[1]; + + texturePtrs[0] = textureSamplerBinding.Texture.Handle; + samplerPtrs[0] = textureSamplerBinding.Sampler.Handle; + + Refresh.Refresh_BindFragmentSamplers( + Device.Handle, + Handle, + (IntPtr) texturePtrs, + (IntPtr) samplerPtrs + ); } /// - /// Binds samplers to be used by the vertex shader. + /// Binds samplers to be used by the fragment shader. + /// + /// The first texture-sampler to bind. + /// The second texture-sampler to bind. + public unsafe void BindFragmentSamplers( + in TextureSamplerBinding textureSamplerBindingOne, + in TextureSamplerBinding textureSamplerBindingTwo + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertFragmentSamplerCount(2); + AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); + AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); + AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); +#endif + + var texturePtrs = stackalloc IntPtr[2]; + var samplerPtrs = stackalloc IntPtr[2]; + + texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; + texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle; + + samplerPtrs[0] = textureSamplerBindingOne.Sampler.Handle; + samplerPtrs[1] = textureSamplerBindingTwo.Sampler.Handle; + + Refresh.Refresh_BindFragmentSamplers( + Device.Handle, + Handle, + (IntPtr) texturePtrs, + (IntPtr) samplerPtrs + ); + } + + /// + /// Binds samplers to be used by the fragment shader. + /// + /// The first texture-sampler to bind. + /// The second texture-sampler to bind. + /// The third texture-sampler to bind. + public unsafe void BindFragmentSamplers( + in TextureSamplerBinding textureSamplerBindingOne, + in TextureSamplerBinding textureSamplerBindingTwo, + in TextureSamplerBinding textureSamplerBindingThree + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertFragmentSamplerCount(3); + AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); + AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); + AssertTextureSamplerBindingNonNull(textureSamplerBindingThree); + AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture); +#endif + + var texturePtrs = stackalloc IntPtr[3]; + var samplerPtrs = stackalloc IntPtr[3]; + + texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; + texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle; + texturePtrs[2] = textureSamplerBindingThree.Texture.Handle; + + samplerPtrs[0] = textureSamplerBindingOne.Sampler.Handle; + samplerPtrs[1] = textureSamplerBindingTwo.Sampler.Handle; + samplerPtrs[2] = textureSamplerBindingThree.Sampler.Handle; + + Refresh.Refresh_BindFragmentSamplers( + Device.Handle, + Handle, + (IntPtr) texturePtrs, + (IntPtr) samplerPtrs + ); + } + + /// + /// Binds samplers to be used by the fragment shader. + /// + /// The first texture-sampler to bind. + /// The second texture-sampler to bind. + /// The third texture-sampler to bind. + /// The fourth texture-sampler to bind. + public unsafe void BindFragmentSamplers( + in TextureSamplerBinding textureSamplerBindingOne, + in TextureSamplerBinding textureSamplerBindingTwo, + in TextureSamplerBinding textureSamplerBindingThree, + in TextureSamplerBinding textureSamplerBindingFour + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertFragmentSamplerCount(4); + AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); + AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); + AssertTextureSamplerBindingNonNull(textureSamplerBindingThree); + AssertTextureSamplerBindingNonNull(textureSamplerBindingFour); + AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture); + AssertTextureBindingUsageFlags(textureSamplerBindingFour.Texture); +#endif + + var texturePtrs = stackalloc IntPtr[4]; + var samplerPtrs = stackalloc IntPtr[4]; + + texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; + texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle; + texturePtrs[2] = textureSamplerBindingThree.Texture.Handle; + texturePtrs[3] = textureSamplerBindingFour.Texture.Handle; + + samplerPtrs[0] = textureSamplerBindingOne.Sampler.Handle; + samplerPtrs[1] = textureSamplerBindingTwo.Sampler.Handle; + samplerPtrs[2] = textureSamplerBindingThree.Sampler.Handle; + samplerPtrs[3] = textureSamplerBindingFour.Sampler.Handle; + + Refresh.Refresh_BindFragmentSamplers( + Device.Handle, + Handle, + (IntPtr) texturePtrs, + (IntPtr) samplerPtrs + ); + } + + /// + /// Binds samplers to be used by the fragment shader. /// /// The texture-sampler pairs to bind. public unsafe void BindFragmentSamplers( - ArraySegment textureSamplerBindings - ) - { + in Span textureSamplerBindings + ) { #if DEBUG AssertGraphicsPipelineBound(); - - if (currentGraphicsPipeline.FragmentShaderInfo.SamplerBindingCount == 0) - { - throw new System.InvalidOperationException("The fragment shader of the current graphics pipeline does not take any samplers!"); - } - - if (currentGraphicsPipeline.FragmentShaderInfo.SamplerBindingCount < textureSamplerBindings.Count) - { - throw new System.InvalidOperationException("Fragment sampler count exceeds the amount used by the fragment shader!"); - } + AssertFragmentSamplerCount(textureSamplerBindings.Length); #endif - var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Count]; - var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Count]; + var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Length]; + var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Length]; - for (var i = 0; i < textureSamplerBindings.Count; i += 1) + for (var i = 0; i < textureSamplerBindings.Length; i += 1) { #if DEBUG AssertTextureSamplerBindingNonNull(textureSamplerBindings[i]); @@ -758,23 +1308,12 @@ namespace MoonWorks.Graphics ); } - /// - /// Binds samplers to be used by the fragment shader. - /// - /// An array of texture-sampler pairs to bind. - public unsafe void BindFragmentSamplers( - params TextureSamplerBinding[] textureSamplerBindings - ) - { - BindFragmentSamplers(new ArraySegment(textureSamplerBindings)); - } - /// /// Pushes vertex shader uniforms to the device. /// /// A starting offset value to be used with draw calls. public unsafe uint PushVertexShaderUniforms( - T uniforms + in T uniforms ) where T : unmanaged { #if DEBUG @@ -786,12 +1325,15 @@ namespace MoonWorks.Graphics } #endif - return Refresh.Refresh_PushVertexShaderUniforms( - Device.Handle, - Handle, - (IntPtr) (&uniforms), - (uint) sizeof(T) - ); + fixed (T* uniformsPtr = &uniforms) + { + return Refresh.Refresh_PushVertexShaderUniforms( + Device.Handle, + Handle, + (IntPtr) uniformsPtr, + (uint) sizeof(T) + ); + } } /// @@ -799,7 +1341,7 @@ namespace MoonWorks.Graphics /// /// A starting offset to be used with draw calls. public unsafe uint PushFragmentShaderUniforms( - T uniforms + in T uniforms ) where T : unmanaged { #if DEBUG @@ -810,13 +1352,15 @@ namespace MoonWorks.Graphics throw new InvalidOperationException("The current fragment shader does not take a uniform buffer!"); } #endif - - return Refresh.Refresh_PushFragmentShaderUniforms( - Device.Handle, - Handle, - (IntPtr) (&uniforms), - (uint) sizeof(T) - ); + fixed (T* uniformsPtr = &uniforms) + { + return Refresh.Refresh_PushFragmentShaderUniforms( + Device.Handle, + Handle, + (IntPtr) uniformsPtr, + (uint) sizeof(T) + ); + } } /// @@ -824,7 +1368,7 @@ namespace MoonWorks.Graphics /// /// A starting offset to be used with dispatch calls. public unsafe uint PushComputeShaderUniforms( - T uniforms + in T uniforms ) where T : unmanaged { #if DEBUG @@ -836,13 +1380,15 @@ namespace MoonWorks.Graphics } #endif - return Refresh.Refresh_PushComputeShaderUniforms( - Device.Handle, - Handle, - (IntPtr) (&uniforms), - (uint) sizeof(T) - ); - + fixed (T* uniformsPtr = &uniforms) + { + return Refresh.Refresh_PushComputeShaderUniforms( + Device.Handle, + Handle, + (IntPtr) uniformsPtr, + (uint) sizeof(T) + ); + } } /// @@ -995,7 +1541,7 @@ namespace MoonWorks.Graphics /// If null is returned, presentation will not occur. /// It is an error to acquire two swapchain textures from the same window in one command buffer. /// - public Texture? AcquireSwapchainTexture( + public Texture AcquireSwapchainTexture( Window window ) { @@ -1299,6 +1845,22 @@ namespace MoonWorks.Graphics } } + private void AssertVertexSamplerCount(int count) + { + if (currentGraphicsPipeline.VertexShaderInfo.SamplerBindingCount != count) + { + throw new System.InvalidOperationException($"Vertex sampler expected {currentGraphicsPipeline.VertexShaderInfo.SamplerBindingCount} samplers, but received {count}"); + } + } + + private void AssertFragmentSamplerCount(int count) + { + if (currentGraphicsPipeline.FragmentShaderInfo.SamplerBindingCount != count) + { + throw new System.InvalidOperationException($"Fragment sampler expected {currentGraphicsPipeline.FragmentShaderInfo.SamplerBindingCount} samplers, but received {count}"); + } + } + private void AssertComputePipelineBound(string message = "No compute pipeline is bound!") { if (currentComputePipeline == null) @@ -1307,6 +1869,22 @@ namespace MoonWorks.Graphics } } + private void AssertComputeBufferCount(int count) + { + if (currentComputePipeline.ComputeShaderInfo.BufferBindingCount != count) + { + throw new System.InvalidOperationException($"Compute pipeline expects {currentComputePipeline.ComputeShaderInfo.BufferBindingCount} buffers, but received {count}"); + } + } + + private void AssertComputeTextureCount(int count) + { + if (currentComputePipeline.ComputeShaderInfo.ImageBindingCount != count) + { + throw new System.InvalidOperationException($"Compute pipeline expects {currentComputePipeline.ComputeShaderInfo.ImageBindingCount} textures, but received {count}"); + } + } + private void AssertTextureNotNull(ColorAttachmentInfo colorAttachmentInfo) { if (colorAttachmentInfo.Texture == null || colorAttachmentInfo.Texture.Handle == IntPtr.Zero) diff --git a/src/Graphics/Resources/Buffer.cs b/src/Graphics/Resources/Buffer.cs index bd737db..24047aa 100644 --- a/src/Graphics/Resources/Buffer.cs +++ b/src/Graphics/Resources/Buffer.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.InteropServices; using RefreshCS; namespace MoonWorks.Graphics @@ -78,5 +77,10 @@ namespace MoonWorks.Graphics ); } } + + public static implicit operator BufferBinding(Buffer b) + { + return new BufferBinding(b, 0); + } } }