diff --git a/Graphite.sln b/Graphite.sln index e592b95..a4d4dd3 100644 --- a/Graphite.sln +++ b/Graphite.sln @@ -16,6 +16,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Graphite.Vulkan", "src\Grap EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Graphite.D3D11", "src\Graphite.D3D11\Graphite.D3D11.csproj", "{4DEE157C-DDCE-4133-A562-4C869765A07F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Graphite.OpenGL", "src\Graphite.OpenGL\Graphite.OpenGL.csproj", "{DAE5F38B-568D-45D9-AAEF-A71E49B564FD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -50,6 +52,10 @@ Global {4DEE157C-DDCE-4133-A562-4C869765A07F}.Debug|Any CPU.Build.0 = Debug|Any CPU {4DEE157C-DDCE-4133-A562-4C869765A07F}.Release|Any CPU.ActiveCfg = Release|Any CPU {4DEE157C-DDCE-4133-A562-4C869765A07F}.Release|Any CPU.Build.0 = Release|Any CPU + {DAE5F38B-568D-45D9-AAEF-A71E49B564FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DAE5F38B-568D-45D9-AAEF-A71E49B564FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DAE5F38B-568D-45D9-AAEF-A71E49B564FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DAE5F38B-568D-45D9-AAEF-A71E49B564FD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {7E5E2B62-B479-4BD2-A8E9-3974FE6A3C76} = {0802471C-F455-4B4B-A50C-93EB36406339} diff --git a/src/Graphite.D3D11/D3D11Device.cs b/src/Graphite.D3D11/D3D11Device.cs index 7065dbe..363cd25 100644 --- a/src/Graphite.D3D11/D3D11Device.cs +++ b/src/Graphite.D3D11/D3D11Device.cs @@ -49,7 +49,8 @@ public override CommandList CreateCommandList() return new D3D11CommandList(_device); } - public override ShaderModule CreateShaderModule(byte[] code, string entryPoint, ShaderMappingInfo mapping = default) + public override ShaderModule CreateShaderModule(ShaderStage stage, byte[] code, string entryPoint, + ShaderMappingInfo mapping = default) { return new D3D11ShaderModule(code, in mapping); } diff --git a/src/Graphite.OpenGL/GLBuffer.cs b/src/Graphite.OpenGL/GLBuffer.cs new file mode 100644 index 0000000..e9caa35 --- /dev/null +++ b/src/Graphite.OpenGL/GLBuffer.cs @@ -0,0 +1,24 @@ +using Silk.NET.OpenGL; + +namespace Graphite.OpenGL; + +internal sealed unsafe class GLBuffer : Buffer +{ + private readonly GL _gl; + + public readonly uint Buffer; + + public GLBuffer(GL gl, ref readonly BufferInfo info, void* pData) : base(info) + { + _gl = gl; + + Buffer = _gl.GenBuffer(); + _gl.BindBuffer(BufferTargetARB.ArrayBuffer, Buffer); + _gl.BufferData(BufferTargetARB.ArrayBuffer, info.SizeInBytes, pData, BufferUsageARB.StaticDraw); + } + + public override void Dispose() + { + _gl.DeleteBuffer(Buffer); + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLCommandList.cs b/src/Graphite.OpenGL/GLCommandList.cs new file mode 100644 index 0000000..52a7a47 --- /dev/null +++ b/src/Graphite.OpenGL/GLCommandList.cs @@ -0,0 +1,91 @@ +using Graphite.Core; +using Graphite.OpenGL.Instructions; + +namespace Graphite.OpenGL; + +internal sealed class GLCommandList : CommandList +{ + public readonly List Instructions; + + public GLCommandList() + { + Instructions = []; + } + + public override void Begin() + { + Instructions.Clear(); + } + + public override void End() { } + + public override void CopyBufferToBuffer(Buffer src, uint srcOffset, Buffer dest, uint destOffset, uint copySize = 0) + { + throw new NotImplementedException(); + } + + public override void CopyBufferToTexture(Buffer src, uint srcOffset, Texture dest, Region3D? region = null) + { + throw new NotImplementedException(); + } + + public override void GenerateMipmaps(Texture texture) + { + throw new NotImplementedException(); + } + + public override void BeginRenderPass(in ReadOnlySpan colorAttachments) + { + Instructions.Add(new BeginRenderPassInstruction + { + ColorAttachments = Array.ConvertAll(colorAttachments.ToArray(), input => (GLTexture) input.Texture), + ClearColor = colorAttachments[0].ClearColor + }); + } + + public override void EndRenderPass() { } + + public override void SetGraphicsPipeline(Pipeline pipeline) + { + Instructions.Add(new SetPipelineInstruction() + { + Pipeline = (GLPipeline) pipeline + }); + } + + public override void SetDescriptorSet(uint slot, Pipeline pipeline, DescriptorSet set) + { + throw new NotImplementedException(); + } + + public override void SetVertexBuffer(uint slot, Buffer buffer, uint stride, uint offset = 0) + { + Instructions.Add(new SetVertexBufferInstruction(slot, (GLBuffer) buffer, stride, offset)); + } + + public override void SetIndexBuffer(Buffer buffer, Format format, uint offset = 0) + { + Instructions.Add(new SetIndexBufferInstruction((GLBuffer) buffer, format, offset)); + } + + public override void PushDescriptors(uint slot, Pipeline pipeline, params ReadOnlySpan descriptors) + { + throw new NotImplementedException(); + } + + public override void Draw(uint numVertices, uint firstVertex = 0) + { + Instructions.Add(new DrawInstruction() + { + NumVertices = numVertices, + FirstVertex = firstVertex + }); + } + + public override void DrawIndexed(uint numIndices, uint firstIndex = 0, int baseVertex = 0) + { + Instructions.Add(new DrawIndexedInstruction(numIndices, firstIndex, baseVertex)); + } + + public override void Dispose() { } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLContext.cs b/src/Graphite.OpenGL/GLContext.cs new file mode 100644 index 0000000..6396204 --- /dev/null +++ b/src/Graphite.OpenGL/GLContext.cs @@ -0,0 +1,14 @@ +namespace Graphite.OpenGL; + +public class GLContext +{ + public Func GetProcAddressFunc; + + public Action PresentFunc; + + public GLContext(Func getProcAddressFunc, Action presentFunc) + { + GetProcAddressFunc = getProcAddressFunc; + PresentFunc = presentFunc; + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLDevice.cs b/src/Graphite.OpenGL/GLDevice.cs new file mode 100644 index 0000000..910d1ea --- /dev/null +++ b/src/Graphite.OpenGL/GLDevice.cs @@ -0,0 +1,196 @@ +using Graphite.Core; +using Graphite.OpenGL.Instructions; +using Silk.NET.OpenGL; + +namespace Graphite.OpenGL; + +internal sealed unsafe class GLDevice : Device +{ + private readonly GL _gl; + private readonly GLContext _context; + + private readonly Dictionary _framebufferCache; + + public override Backend Backend => OpenGLBackend.Backend; + + public GLDevice(GL gl, GLContext context) + { + _gl = gl; + _context = context; + + _framebufferCache = []; + } + + public override Swapchain CreateSwapchain(in SwapchainInfo info) + { + return new GLSwapchain(_gl, _context, in info); + } + + public override CommandList CreateCommandList() + { + return new GLCommandList(); + } + + public override ShaderModule CreateShaderModule(ShaderStage stage, byte[] code, string entryPoint, + ShaderMappingInfo mapping = default) + { + return new GLShaderModule(_gl, stage, code); + } + + public override Pipeline CreateGraphicsPipeline(in GraphicsPipelineInfo info) + { + return new GLPipeline(_gl, in info); + } + + public override unsafe Buffer CreateBuffer(in BufferInfo info, void* data) + { + return new GLBuffer(_gl, in info, data); + } + + public override unsafe Texture CreateTexture(in TextureInfo info, void* pData) + { + throw new NotImplementedException(); + } + + public override DescriptorLayout CreateDescriptorLayout(in DescriptorLayoutInfo info) + { + throw new NotImplementedException(); + } + + public override DescriptorSet CreateDescriptorSet(DescriptorLayout layout, params ReadOnlySpan descriptors) + { + throw new NotImplementedException(); + } + + public override Sampler CreateSampler(in SamplerInfo info) + { + throw new NotImplementedException(); + } + + public override void ExecuteCommandList(CommandList cl) + { + GLCommandList glList = (GLCommandList) cl; + + DrawElementsType elementsType = 0; + + foreach (IInstruction instruction in glList.Instructions) + { + switch (instruction) + { + case BeginRenderPassInstruction renderPass: + { + uint framebuffer = GetFramebuffer(renderPass.ColorAttachments); + _gl.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer); + + _gl.ClearColor(renderPass.ClearColor.R, renderPass.ClearColor.G, renderPass.ClearColor.B, + renderPass.ClearColor.A); + _gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + + break; + } + + case SetPipelineInstruction setPipeline: + { + GLPipeline pipeline = setPipeline.Pipeline; + _gl.BindVertexArray(pipeline.VertexArray); + _gl.UseProgram(pipeline.ShaderProgram); + break; + } + + case SetVertexBufferInstruction setVertexBuffer: + { + _gl.BindVertexBuffer(setVertexBuffer.Slot, setVertexBuffer.Buffer.Buffer, + (nint) setVertexBuffer.Offset, setVertexBuffer.Stride); + break; + } + + case SetIndexBufferInstruction setIndexBuffer: + { + _gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, setIndexBuffer.Buffer.Buffer); + elementsType = setIndexBuffer.Format switch + { + Format.R8_UInt => DrawElementsType.UnsignedByte, + Format.R16_UInt => DrawElementsType.UnsignedShort, + Format.R32_UInt => DrawElementsType.UnsignedInt, + _ => throw new NotSupportedException() + }; + break; + } + + case DrawInstruction draw: + { + _gl.DrawArrays(PrimitiveType.Triangles, (int) draw.FirstVertex, draw.NumVertices); + break; + } + + case DrawIndexedInstruction drawIndexed: + { + _gl.DrawElementsBaseVertex(PrimitiveType.Triangles, drawIndexed.NumIndices, elementsType, + (void*) drawIndexed.FirstIndex, drawIndexed.BaseVertex); + break; + } + + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + public override void UpdateBuffer(Buffer buffer, uint offset, uint size, void* pData) + { + throw new NotImplementedException(); + } + + public override void UpdateTexture(Texture texture, in Region3D region, void* pData) + { + throw new NotImplementedException(); + } + + public override IntPtr MapBuffer(Buffer buffer) + { + throw new NotImplementedException(); + } + + public override void UnmapBuffer(Buffer buffer) + { + throw new NotImplementedException(); + } + + public override void Dispose() { } + + public uint GetFramebuffer(ReadOnlySpan colorAttachments, GLTexture? depthAttachment = null) + { + HashCode code = new HashCode(); + + foreach (GLTexture texture in colorAttachments) + code.Add(texture); + + if (depthAttachment != null) + code.Add(depthAttachment); + + int hashCode = code.ToHashCode(); + + if (!_framebufferCache.TryGetValue(hashCode, out uint framebuffer)) + { + GraphiteLog.Log($"Creating framebuffer {hashCode}."); + framebuffer = _gl.CreateFramebuffer(); + _gl.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer); + + foreach (GLTexture texture in colorAttachments) + { + _gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, + TextureTarget.Texture2D, texture.Texture, 0); + } + + if (depthAttachment != null) + throw new NotImplementedException(); + + if (_gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != GLEnum.FramebufferComplete) + throw new Exception("Framebuffer is not complete!"); + + _framebufferCache.Add(hashCode, framebuffer); + } + + return framebuffer; + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLInstance.cs b/src/Graphite.OpenGL/GLInstance.cs new file mode 100644 index 0000000..b7bdfde --- /dev/null +++ b/src/Graphite.OpenGL/GLInstance.cs @@ -0,0 +1,43 @@ +using System.Diagnostics; +using Silk.NET.OpenGL; + +namespace Graphite.OpenGL; + +internal sealed class GLInstance : Instance +{ + private readonly GLContext _context; + private readonly GL _gl; + + public override string BackendName => OpenGLBackend.Name; + + public override Backend Backend => OpenGLBackend.Backend; + + public GLInstance(ref readonly InstanceInfo info) + { + Debug.Assert(OpenGLBackend.Context != null, "OpenGLBackend.Context was null. This value must be set to use the OpenGL backend."); + _context = OpenGLBackend.Context; + + _gl = GL.GetApi(_context.GetProcAddressFunc); + } + + public override Adapter[] EnumerateAdapters() + { + string name = _gl.GetStringS(StringName.Renderer); + return [new Adapter(0, 0, name)]; + } + + public override Surface CreateSurface(in SurfaceInfo info) + { + return new GLSurface(); + } + + public override Device CreateDevice(Surface surface, Adapter? adapter = null) + { + return new GLDevice(_gl, _context); + } + + public override void Dispose() + { + _gl.Dispose(); + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLPipeline.cs b/src/Graphite.OpenGL/GLPipeline.cs new file mode 100644 index 0000000..fa290e7 --- /dev/null +++ b/src/Graphite.OpenGL/GLPipeline.cs @@ -0,0 +1,70 @@ +using Silk.NET.OpenGL; + +namespace Graphite.OpenGL; + +internal sealed class GLPipeline : Pipeline +{ + private readonly GL _gl; + + public readonly uint VertexArray; + + public readonly uint ShaderProgram; + + public GLPipeline(GL gl, ref readonly GraphicsPipelineInfo info) + { + _gl = gl; + + VertexArray = _gl.GenVertexArray(); + _gl.BindVertexArray(VertexArray); + + for (int i = 0; i < info.InputLayout.Length; i++) + { + ref readonly InputElementDescription element = ref info.InputLayout[i]; + + uint location = element.Location; + uint offset = element.Offset; + + _gl.EnableVertexAttribArray(location); + _gl.VertexAttribBinding(location, element.Slot); + + switch (element.Format) + { + case Format.R32_Float: + _gl.VertexAttribFormat(location, 1, VertexAttribType.Float, false, offset); + break; + case Format.R32G32_Float: + _gl.VertexAttribFormat(location, 2, VertexAttribType.Float, false, offset); + break; + case Format.R32G32B32_Float: + _gl.VertexAttribFormat(location, 3, VertexAttribType.Float, false, offset); + break; + case Format.R32G32B32A32_Float: + _gl.VertexAttribFormat(location, 4, VertexAttribType.Float, false, offset); + break; + default: + throw new NotImplementedException(); + } + } + + GLShaderModule vertexShader = (GLShaderModule) info.VertexShader; + GLShaderModule pixelShader = (GLShaderModule) info.PixelShader; + + ShaderProgram = _gl.CreateProgram(); + _gl.AttachShader(ShaderProgram, vertexShader.Shader); + _gl.AttachShader(ShaderProgram, pixelShader.Shader); + + _gl.LinkProgram(ShaderProgram); + + if (_gl.GetProgram(ShaderProgram, ProgramPropertyARB.LinkStatus) != (int) GLEnum.True) + throw new Exception($"Failed to link program: {_gl.GetProgramInfoLog(ShaderProgram)}"); + + _gl.DetachShader(ShaderProgram, pixelShader.Shader); + _gl.DetachShader(ShaderProgram, vertexShader.Shader); + } + + public override void Dispose() + { + _gl.DeleteProgram(ShaderProgram); + _gl.DeleteVertexArray(VertexArray); + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLShaderModule.cs b/src/Graphite.OpenGL/GLShaderModule.cs new file mode 100644 index 0000000..95a6ff6 --- /dev/null +++ b/src/Graphite.OpenGL/GLShaderModule.cs @@ -0,0 +1,36 @@ +using System.Text; +using Silk.NET.OpenGL; + +namespace Graphite.OpenGL; + +internal sealed class GLShaderModule : ShaderModule +{ + private readonly GL _gl; + + public readonly uint Shader; + + public GLShaderModule(GL gl, ShaderStage stage, byte[] glsl) + { + _gl = gl; + string sglsl = Encoding.UTF8.GetString(glsl); + + ShaderType type = stage switch + { + ShaderStage.Vertex => ShaderType.VertexShader, + ShaderStage.Pixel => ShaderType.FragmentShader, + _ => throw new ArgumentOutOfRangeException(nameof(stage), stage, null) + }; + + Shader = _gl.CreateShader(type); + _gl.ShaderSource(Shader, sglsl); + _gl.CompileShader(Shader); + + if (_gl.GetShader(Shader, ShaderParameterName.CompileStatus) != (int) GLEnum.True) + throw new Exception($"Failed to compile {stage} shader: {_gl.GetShaderInfoLog(Shader)}"); + } + + public override void Dispose() + { + _gl.DeleteShader(Shader); + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLSurface.cs b/src/Graphite.OpenGL/GLSurface.cs new file mode 100644 index 0000000..766d9d4 --- /dev/null +++ b/src/Graphite.OpenGL/GLSurface.cs @@ -0,0 +1,6 @@ +namespace Graphite.OpenGL; + +internal sealed class GLSurface : Surface +{ + public override void Dispose() { } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLSwapchain.cs b/src/Graphite.OpenGL/GLSwapchain.cs new file mode 100644 index 0000000..6905c69 --- /dev/null +++ b/src/Graphite.OpenGL/GLSwapchain.cs @@ -0,0 +1,140 @@ +using Graphite.Core; +using Silk.NET.OpenGL; + +namespace Graphite.OpenGL; + +internal sealed class GLSwapchain : Swapchain +{ + private readonly GL _gl; + private readonly GLContext _context; + private readonly uint _vao; + private readonly uint _program; + + private GLTexture _texture; + + public override Size2D Size { get; } + + public override Format Format { get; } + + public GLSwapchain(GL gl, GLContext context, ref readonly SwapchainInfo info) + { + _gl = gl; + _context = context; + + Size = info.Size; + Format = info.Format; + + (_, SizedInternalFormat iFormat, _) = info.Format.ToGL(); + + uint texture = _gl.GenTexture(); + _gl.BindTexture(TextureTarget.Texture2D, texture); + _gl.TexStorage2D(TextureTarget.Texture2D, 1, iFormat, info.Size.Width, info.Size.Height); + + _texture = new GLTexture(_gl, texture, TextureInfo.Texture2D(info.Format, info.Size, 1, TextureUsage.None)); + + _vao = _gl.GenVertexArray(); + _gl.BindVertexArray(_vao); + + uint vertexShader = _gl.CreateShader(ShaderType.VertexShader); + _gl.ShaderSource(vertexShader, VertexShader); + _gl.CompileShader(vertexShader); + _gl.GetShader(vertexShader, ShaderParameterName.CompileStatus, out int status); + if (status != (int) GLEnum.True) + throw new Exception($"Failed to compile vertex shader: {_gl.GetShaderInfoLog(vertexShader)}"); + + uint fragmentShader = _gl.CreateShader(GLEnum.FragmentShader); + _gl.ShaderSource(fragmentShader, FragmentShader); + _gl.CompileShader(fragmentShader); + _gl.GetShader(fragmentShader, ShaderParameterName.CompileStatus, out status); + if (status != (int) GLEnum.True) + throw new Exception($"Failed to compile fragment shader: {_gl.GetShaderInfoLog(fragmentShader)}"); + + _program = _gl.CreateProgram(); + _gl.AttachShader(_program, vertexShader); + _gl.AttachShader(_program, fragmentShader); + + _gl.LinkProgram(_program); + _gl.GetProgram(_program, ProgramPropertyARB.LinkStatus, out status); + if (status != (int) GLEnum.True) + throw new Exception($"Failed to link program: {_gl.GetProgramInfoLog(_program)}"); + + _gl.DetachShader(_program, vertexShader); + _gl.DetachShader(_program, fragmentShader); + _gl.DeleteShader(vertexShader); + _gl.DeleteShader(fragmentShader); + } + + public override Texture GetNextTexture() + { + return _texture; + } + + public override void Present() + { + _gl.Disable(EnableCap.Blend); + _gl.Disable(EnableCap.DepthTest); + + _gl.Enable(EnableCap.CullFace); + _gl.CullFace(TriangleFace.Back); + _gl.FrontFace(FrontFaceDirection.CW); + + _gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0); + _gl.BindVertexArray(_vao); + + _gl.UseProgram(_program); + _gl.ActiveTexture(TextureUnit.Texture0); + _gl.BindTexture(TextureTarget.Texture2D, _texture.Texture); + _gl.DrawArrays(PrimitiveType.Triangles, 0, 6); + + _context.PresentFunc(1); + } + + public override void Dispose() + { + _texture.Dispose(); + } + + private const string VertexShader = """ + #version 330 core + + out vec2 frag_TexCoord; + + // XY = Position, ZW = TexCoord + const vec4 vertices[4] = vec4[] + ( + vec4(-1.0, -1.0, 0.0, 0.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4( 1.0, 1.0, 1.0, 1.0), + vec4( 1.0, -1.0, 1.0, 0.0) + ); + + const int indices[6] = int[] + ( + 0, 1, 3, + 1, 2, 3 + ); + + void main() + { + vec4 vertex = vertices[indices[gl_VertexID]]; + gl_Position = vec4(vertex.xy, 0.0, 1.0); + frag_TexCoord = vertex.zw; + } + """; + + private const string FragmentShader = """ + #version 330 core + + in vec2 frag_TexCoord; + + out vec4 out_Color; + + uniform sampler2D uTexture; + + void main() + { + out_Color = texture(uTexture, frag_TexCoord); + //out_Color = vec4(frag_TexCoord, 0.0, 1.0); + } + """; +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLTexture.cs b/src/Graphite.OpenGL/GLTexture.cs new file mode 100644 index 0000000..4bbd933 --- /dev/null +++ b/src/Graphite.OpenGL/GLTexture.cs @@ -0,0 +1,21 @@ +using Silk.NET.OpenGL; + +namespace Graphite.OpenGL; + +internal sealed class GLTexture : Texture +{ + private readonly GL _gl; + + public readonly uint Texture; + + public GLTexture(GL gl, uint texture, TextureInfo info) : base(info) + { + _gl = gl; + Texture = texture; + } + + public override void Dispose() + { + _gl.DeleteTexture(Texture); + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/GLUtils.cs b/src/Graphite.OpenGL/GLUtils.cs new file mode 100644 index 0000000..14eff17 --- /dev/null +++ b/src/Graphite.OpenGL/GLUtils.cs @@ -0,0 +1,79 @@ +using Silk.NET.OpenGL; + +namespace Graphite.OpenGL; + +internal static class GLUtils +{ + public static (PixelFormat format, SizedInternalFormat iFormat, PixelType type) ToGL(this Format format) + { + return format switch + { + Format.Unknown => (0, 0, 0), + Format.B5G6R5_UNorm => (PixelFormat.Bgr, SizedInternalFormat.Rgb5, PixelType.UnsignedByte), + Format.B5G5R5A1_UNorm => (PixelFormat.Bgra, SizedInternalFormat.Rgb5A1, PixelType.UnsignedByte), + Format.A8_UNorm => (PixelFormat.Alpha, SizedInternalFormat.R8, PixelType.UnsignedByte), + Format.R8_UNorm => (PixelFormat.Red, SizedInternalFormat.R8, PixelType.UnsignedByte), + Format.R8_UInt => (PixelFormat.RedInteger, SizedInternalFormat.R8ui, PixelType.UnsignedInt), + Format.R8_SNorm => (PixelFormat.Red, SizedInternalFormat.R8SNorm, PixelType.Byte), + Format.R8_SInt => (PixelFormat.RedInteger, SizedInternalFormat.R8i, PixelType.Int), + Format.R8G8_UNorm => (PixelFormat.RG, SizedInternalFormat.RG8, PixelType.UnsignedByte), + Format.R8G8_UInt => (PixelFormat.RGInteger, SizedInternalFormat.RG8ui, PixelType.UnsignedInt), + Format.R8G8_SNorm => (PixelFormat.RG, SizedInternalFormat.RG8SNorm, PixelType.Byte), + Format.R8G8_SInt => (PixelFormat.RGInteger, SizedInternalFormat.RG8i, PixelType.Int), + Format.R8G8B8A8_UNorm => (PixelFormat.Rgba, SizedInternalFormat.Rgba8, PixelType.UnsignedByte), + Format.R8G8B8A8_UNorm_SRGB => (PixelFormat.Rgba, SizedInternalFormat.Srgb8Alpha8, PixelType.UnsignedByte), + Format.R8G8B8A8_UInt => (PixelFormat.RgbaInteger, SizedInternalFormat.Rgba8ui, PixelType.UnsignedInt), + Format.R8G8B8A8_SNorm => (PixelFormat.Rgba, SizedInternalFormat.Rgba8SNorm, PixelType.Byte), + Format.R8G8B8A8_SInt => (PixelFormat.RgbaInteger, SizedInternalFormat.Rgba8i, PixelType.Int), + Format.B8G8R8A8_UNorm => (PixelFormat.Bgra, SizedInternalFormat.Rgba8, PixelType.UnsignedByte), + Format.B8G8R8A8_UNorm_SRGB => (PixelFormat.Bgra, SizedInternalFormat.Srgb8Alpha8, PixelType.UnsignedByte), + Format.R10G10B10A2_UNorm => (PixelFormat.Rgba, SizedInternalFormat.Rgb10A2, PixelType.UnsignedByte), + Format.R10G10B10A2_UInt => (PixelFormat.RgbaInteger, SizedInternalFormat.Rgb10A2ui, PixelType.UnsignedInt), + Format.R16_Float => (PixelFormat.Red, SizedInternalFormat.R16f, PixelType.Float), + Format.R16_UNorm => (PixelFormat.Red, SizedInternalFormat.R16, PixelType.UnsignedByte), + Format.R16_UInt => (PixelFormat.Red, SizedInternalFormat.R16ui, PixelType.UnsignedInt), + Format.R16_SNorm => (PixelFormat.Red, SizedInternalFormat.R16SNorm, PixelType.Byte), + Format.R16_SInt => (PixelFormat.Red, SizedInternalFormat.R16i, PixelType.Int), + Format.R16G16_Float => (PixelFormat.RG, SizedInternalFormat.RG16f, PixelType.Float), + Format.R16G16_UNorm => (PixelFormat.RG, SizedInternalFormat.RG16, PixelType.UnsignedByte), + Format.R16G16_UInt => (PixelFormat.RGInteger, SizedInternalFormat.RG16ui, PixelType.UnsignedInt), + Format.R16G16_SNorm => (PixelFormat.RG, SizedInternalFormat.RG16SNorm, PixelType.Byte), + Format.R16G16_SInt => (PixelFormat.RG, SizedInternalFormat.RG16i, PixelType.Int), + Format.R16G16B16A16_Float => (PixelFormat.Rgba, SizedInternalFormat.Rgba16f, PixelType.Float), + Format.R16G16B16A16_UNorm => (PixelFormat.Rgba, SizedInternalFormat.Rgba16, PixelType.UnsignedByte), + Format.R16G16B16A16_UInt => (PixelFormat.RgbaInteger, SizedInternalFormat.Rgba16ui, PixelType.UnsignedInt), + Format.R16G16B16A16_SNorm => (PixelFormat.Rgba, SizedInternalFormat.Rgba16SNorm, PixelType.Byte), + Format.R16G16B16A16_SInt => (PixelFormat.Rgba, SizedInternalFormat.Rgba16i, PixelType.Int), + Format.R32_Float => (PixelFormat.Red, SizedInternalFormat.R32f, PixelType.Float), + Format.R32_UInt => (PixelFormat.RedInteger, SizedInternalFormat.R32ui, PixelType.UnsignedInt), + Format.R32_SInt => (PixelFormat.RedInteger, SizedInternalFormat.R32i, PixelType.Int), + Format.R32G32_Float => (PixelFormat.RG, SizedInternalFormat.RG32f, PixelType.Float), + Format.R32G32_UInt => (PixelFormat.RGInteger, SizedInternalFormat.RG32ui, PixelType.UnsignedInt), + Format.R32G32_SInt => (PixelFormat.RGInteger, SizedInternalFormat.RG32i, PixelType.Int), + Format.R32G32B32_Float => (PixelFormat.Rgb, SizedInternalFormat.Rgb32f, PixelType.Float), + Format.R32G32B32_UInt => (PixelFormat.RgbInteger, SizedInternalFormat.Rgb32ui, PixelType.UnsignedInt), + Format.R32G32B32_SInt => (PixelFormat.RgbInteger, SizedInternalFormat.Rgb32i, PixelType.Int), + Format.R32G32B32A32_Float => (PixelFormat.Rgba, SizedInternalFormat.Rgba32f, PixelType.Float), + Format.R32G32B32A32_UInt => (PixelFormat.RgbaInteger, SizedInternalFormat.Rgba32ui, PixelType.UnsignedInt), + Format.R32G32B32A32_SInt => (PixelFormat.RgbaInteger, SizedInternalFormat.Rgba32i, PixelType.Int), + Format.D16_UNorm => (PixelFormat.DepthComponent, SizedInternalFormat.DepthComponent16, PixelType.UnsignedInt), + Format.D24_UNorm_S8_UInt => (PixelFormat.DepthStencil, SizedInternalFormat.Depth24Stencil8, PixelType.UnsignedByte), + Format.D32_Float => (PixelFormat.DepthComponent, SizedInternalFormat.DepthComponent32f, PixelType.Float), + Format.BC1_UNorm => throw new NotImplementedException(), + Format.BC1_UNorm_SRGB => throw new NotImplementedException(), + Format.BC2_UNorm => throw new NotImplementedException(), + Format.BC2_UNorm_SRGB => throw new NotImplementedException(), + Format.BC3_UNorm => throw new NotImplementedException(), + Format.BC3_UNorm_SRGB => throw new NotImplementedException(), + Format.BC4_UNorm => throw new NotImplementedException(), + Format.BC4_SNorm => throw new NotImplementedException(), + Format.BC5_UNorm => throw new NotImplementedException(), + Format.BC5_SNorm => throw new NotImplementedException(), + Format.BC6H_UF16 => throw new NotImplementedException(), + Format.BC6H_SF16 => throw new NotImplementedException(), + Format.BC7_UNorm => throw new NotImplementedException(), + Format.BC7_UNorm_SRGB => throw new NotImplementedException(), + _ => throw new ArgumentOutOfRangeException(nameof(format), format, null) + }; + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/Graphite.OpenGL.csproj b/src/Graphite.OpenGL/Graphite.OpenGL.csproj new file mode 100644 index 0000000..744fe18 --- /dev/null +++ b/src/Graphite.OpenGL/Graphite.OpenGL.csproj @@ -0,0 +1,18 @@ + + + + net9.0 + enable + enable + true + + + + + + + + + + + diff --git a/src/Graphite.OpenGL/Instructions/BeginRenderPassInstruction.cs b/src/Graphite.OpenGL/Instructions/BeginRenderPassInstruction.cs new file mode 100644 index 0000000..920f69e --- /dev/null +++ b/src/Graphite.OpenGL/Instructions/BeginRenderPassInstruction.cs @@ -0,0 +1,16 @@ +using Graphite.Core; + +namespace Graphite.OpenGL.Instructions; + +internal struct BeginRenderPassInstruction : IInstruction +{ + public GLTexture[] ColorAttachments; + + public ColorF ClearColor; + + public BeginRenderPassInstruction(GLTexture[] colorAttachments, ColorF clearColor) + { + ColorAttachments = colorAttachments; + ClearColor = clearColor; + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/Instructions/DrawIndexedInstruction.cs b/src/Graphite.OpenGL/Instructions/DrawIndexedInstruction.cs new file mode 100644 index 0000000..78c8628 --- /dev/null +++ b/src/Graphite.OpenGL/Instructions/DrawIndexedInstruction.cs @@ -0,0 +1,17 @@ +namespace Graphite.OpenGL.Instructions; + +internal struct DrawIndexedInstruction : IInstruction +{ + public uint NumIndices; + + public uint FirstIndex; + + public int BaseVertex; + + public DrawIndexedInstruction(uint numIndices, uint firstIndex, int baseVertex) + { + NumIndices = numIndices; + FirstIndex = firstIndex; + BaseVertex = baseVertex; + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/Instructions/DrawInstruction.cs b/src/Graphite.OpenGL/Instructions/DrawInstruction.cs new file mode 100644 index 0000000..e6b8a12 --- /dev/null +++ b/src/Graphite.OpenGL/Instructions/DrawInstruction.cs @@ -0,0 +1,8 @@ +namespace Graphite.OpenGL.Instructions; + +public struct DrawInstruction : IInstruction +{ + public uint NumVertices; + + public uint FirstVertex; +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/Instructions/IInstruction.cs b/src/Graphite.OpenGL/Instructions/IInstruction.cs new file mode 100644 index 0000000..913186f --- /dev/null +++ b/src/Graphite.OpenGL/Instructions/IInstruction.cs @@ -0,0 +1,6 @@ +namespace Graphite.OpenGL.Instructions; + +internal interface IInstruction +{ + +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/Instructions/InstructionType.cs b/src/Graphite.OpenGL/Instructions/InstructionType.cs new file mode 100644 index 0000000..1ab5ae0 --- /dev/null +++ b/src/Graphite.OpenGL/Instructions/InstructionType.cs @@ -0,0 +1,6 @@ +namespace Graphite.OpenGL.Instructions; + +internal enum InstructionType +{ + BeginRenderPass +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/Instructions/SetIndexBufferInstruction.cs b/src/Graphite.OpenGL/Instructions/SetIndexBufferInstruction.cs new file mode 100644 index 0000000..874ef2a --- /dev/null +++ b/src/Graphite.OpenGL/Instructions/SetIndexBufferInstruction.cs @@ -0,0 +1,17 @@ +namespace Graphite.OpenGL.Instructions; + +internal struct SetIndexBufferInstruction : IInstruction +{ + public GLBuffer Buffer; + + public Format Format; + + public uint Offset; + + public SetIndexBufferInstruction(GLBuffer buffer, Format format, uint offset) + { + Buffer = buffer; + Format = format; + Offset = offset; + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/Instructions/SetPipelineInstruction.cs b/src/Graphite.OpenGL/Instructions/SetPipelineInstruction.cs new file mode 100644 index 0000000..b207f09 --- /dev/null +++ b/src/Graphite.OpenGL/Instructions/SetPipelineInstruction.cs @@ -0,0 +1,6 @@ +namespace Graphite.OpenGL.Instructions; + +internal struct SetPipelineInstruction : IInstruction +{ + public GLPipeline Pipeline; +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/Instructions/SetVertexBufferInstruction.cs b/src/Graphite.OpenGL/Instructions/SetVertexBufferInstruction.cs new file mode 100644 index 0000000..2392fa0 --- /dev/null +++ b/src/Graphite.OpenGL/Instructions/SetVertexBufferInstruction.cs @@ -0,0 +1,20 @@ +namespace Graphite.OpenGL.Instructions; + +internal struct SetVertexBufferInstruction : IInstruction +{ + public uint Slot; + + public GLBuffer Buffer; + + public uint Stride; + + public uint Offset; + + public SetVertexBufferInstruction(uint slot, GLBuffer buffer, uint stride, uint offset) + { + Slot = slot; + Buffer = buffer; + Stride = stride; + Offset = offset; + } +} \ No newline at end of file diff --git a/src/Graphite.OpenGL/OpenGLBackend.cs b/src/Graphite.OpenGL/OpenGLBackend.cs new file mode 100644 index 0000000..69ccb95 --- /dev/null +++ b/src/Graphite.OpenGL/OpenGLBackend.cs @@ -0,0 +1,17 @@ +namespace Graphite.OpenGL; + +public class OpenGLBackend : IBackend +{ + public const int MajorVersion = 4; + + public const int MinorVersion = 3; + + public static string Name => "OpenGL"; + + public static Backend Backend => Backend.OpenGL; + + public static GLContext? Context; + + public Instance CreateInstance(ref readonly InstanceInfo info) + => new GLInstance(in info); +} \ No newline at end of file diff --git a/src/Graphite.ShaderTools/Compiler.cs b/src/Graphite.ShaderTools/Compiler.cs index 2866d00..0fcd751 100644 --- a/src/Graphite.ShaderTools/Compiler.cs +++ b/src/Graphite.ShaderTools/Compiler.cs @@ -218,7 +218,24 @@ public static byte[] TranspileSpirv(GrBackend backend, byte[] spirv, ShaderStage CompilerOptions* options; CheckResult(_spirv.CompilerCreateCompilerOptions(compiler, &options), "Create compiler options"); - CheckResult(_spirv.CompilerOptionsSetUint(options, CompilerOption.HlslShaderModel, 50), "Set shader model"); + + switch (spvBackend) + { + case SpvBackend.Hlsl: + { + CheckResult(_spirv.CompilerOptionsSetUint(options, CompilerOption.HlslShaderModel, 50), "Set shader model"); + break; + } + case SpvBackend.Glsl: + { + CheckResult(_spirv.CompilerOptionsSetUint(options, CompilerOption.GlslVersion, 430), "Set GLSL version"); + break; + } + + default: + throw new ArgumentOutOfRangeException(); + } + CheckResult(_spirv.CompilerInstallCompilerOptions(compiler, options), "Install compiler options"); ExecutionModel model = stage switch @@ -278,6 +295,16 @@ public static byte[] TranspileSpirv(GrBackend backend, byte[] spirv, ShaderStage mapping.VertexInput = vertexInput; return CompileDXBC(compiled, "main", stage); } + + if (backend == GrBackend.OpenGL) + { + nuint length = strlen(compiled); + byte[] glslBytes = new byte[length]; + fixed (byte* pGlsl = glslBytes) + Unsafe.CopyBlock(pGlsl, compiled, (uint) length); + + return glslBytes; + } } finally { diff --git a/src/Graphite.ShaderTools/DeviceExtensions.cs b/src/Graphite.ShaderTools/DeviceExtensions.cs index 44c3445..38ed871 100644 --- a/src/Graphite.ShaderTools/DeviceExtensions.cs +++ b/src/Graphite.ShaderTools/DeviceExtensions.cs @@ -18,7 +18,7 @@ public static ShaderModule CreateShaderModuleFromHLSL(this Device device, Shader byte[] compiled = Compiler.CompileHLSL(device.Backend, stage, hlsl, entryPoint, out ShaderMappingInfo mapping, includeDir, debug); - return device.CreateShaderModule(compiled, entryPoint, mapping); + return device.CreateShaderModule(stage, compiled, entryPoint, mapping); } /// @@ -35,6 +35,6 @@ public static ShaderModule CreateShaderModuleFromSpirv(this Device device, Shade byte[] compiled = Compiler.TranspileSpirv(device.Backend, spirv, stage, entryPoint, out ShaderMappingInfo mapping); - return device.CreateShaderModule(compiled, entryPoint, mapping); + return device.CreateShaderModule(stage, compiled, entryPoint, mapping); } } \ No newline at end of file diff --git a/src/Graphite.Vulkan/VulkanCommandList.cs b/src/Graphite.Vulkan/VulkanCommandList.cs index 6e89d6b..fe79140 100644 --- a/src/Graphite.Vulkan/VulkanCommandList.cs +++ b/src/Graphite.Vulkan/VulkanCommandList.cs @@ -130,7 +130,7 @@ public override void GenerateMipmaps(Texture texture) for (uint i = 1; i < vkTexture.MipLevels; i++) { - ImageBlit blit = new ImageBlit + ImageBlit blit = new() { SrcSubresource = new ImageSubresourceLayers { diff --git a/src/Graphite.Vulkan/VulkanDevice.cs b/src/Graphite.Vulkan/VulkanDevice.cs index 5c0b372..06cfa6b 100644 --- a/src/Graphite.Vulkan/VulkanDevice.cs +++ b/src/Graphite.Vulkan/VulkanDevice.cs @@ -204,7 +204,8 @@ public override CommandList CreateCommandList() return new VulkanCommandList(_vk, Instance, Device, _pool); } - public override ShaderModule CreateShaderModule(byte[] code, string entryPoint, ShaderMappingInfo mapping = default) + public override ShaderModule CreateShaderModule(ShaderStage stage, byte[] code, string entryPoint, + ShaderMappingInfo mapping = default) { // Vulkan natively supports descriptor sets and does not need any vertex remapping, so we ignore any mapping values. return new VulkanShaderModule(_vk, Device, code, entryPoint); diff --git a/src/Graphite/Device.cs b/src/Graphite/Device.cs index 30a3ea4..582beb4 100644 --- a/src/Graphite/Device.cs +++ b/src/Graphite/Device.cs @@ -50,11 +50,13 @@ public abstract class Device : IDisposable /// In order to translate vertex input and descriptors for backends that may not support them, you must provide the /// parameter. /// + /// /// The shader bytecode/string. /// The entry point of the shader. /// The shader mapping to other backends, if appropriate. /// The created . - public abstract ShaderModule CreateShaderModule(byte[] code, string entryPoint, ShaderMappingInfo mapping = default); + public abstract ShaderModule CreateShaderModule(ShaderStage stage, byte[] code, string entryPoint, + ShaderMappingInfo mapping = default); /// /// Create a graphics . diff --git a/tests/Graphite.SimpleTest/Graphite.SimpleTest.csproj b/tests/Graphite.SimpleTest/Graphite.SimpleTest.csproj index 0745aba..45f997e 100644 --- a/tests/Graphite.SimpleTest/Graphite.SimpleTest.csproj +++ b/tests/Graphite.SimpleTest/Graphite.SimpleTest.csproj @@ -12,14 +12,14 @@ + - - + diff --git a/tests/Graphite.SimpleTest/Program.cs b/tests/Graphite.SimpleTest/Program.cs index a4bf2c3..4eba2e5 100644 --- a/tests/Graphite.SimpleTest/Program.cs +++ b/tests/Graphite.SimpleTest/Program.cs @@ -1,9 +1,11 @@ using System.Drawing; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Graphite; using Graphite.Core; using Graphite.D3D11; +using Graphite.OpenGL; using Graphite.ShaderTools; using Graphite.Vulkan; using SDL3; @@ -18,20 +20,35 @@ if (!SDL.Init(SDL.InitFlags.Video | SDL.InitFlags.Events)) throw new Exception($"Failed to initialize SDL: {SDL.GetError()}"); -Instance.RegisterBackend(); +Instance.RegisterBackend(); +//Instance.RegisterBackend(); Instance.RegisterBackend(); -Instance instance = Instance.Create(new InstanceInfo("Graphite.SimpleTest", true)); -Console.WriteLine($"Adapters: {string.Join(", ", instance.EnumerateAdapters())}"); - const int width = 800; const int height = 600; -// Note: The Vulkan flag is here for DXVK support. This flag does not ordinarily need to be passed to CreateWindow. -IntPtr window = SDL.CreateWindow($"Graphite.SimpleTest - {instance.BackendName}", width, height, SDL.WindowFlags.Resizable | SDL.WindowFlags.Vulkan); +SDL.GLSetAttribute(SDL.GLAttr.ContextMajorVersion, OpenGLBackend.MajorVersion); +SDL.GLSetAttribute(SDL.GLAttr.ContextMinorVersion, OpenGLBackend.MinorVersion); +SDL.GLSetAttribute(SDL.GLAttr.ContextProfileMask, (int) SDL.GLProfile.Core); + +IntPtr window = SDL.CreateWindow($"Graphite.SimpleTest", width, height, SDL.WindowFlags.Resizable | SDL.WindowFlags.OpenGL); if (window == IntPtr.Zero) throw new Exception($"Failed to create window: {SDL.GetError()}"); +IntPtr context = SDL.GLCreateContext(window); +SDL.GLMakeCurrent(window, context); + +OpenGLBackend.Context = new GLContext(s => Marshal.GetFunctionPointerForDelegate(SDL.GLGetProcAddress(s)), i => +{ + SDL.GLSetSwapInterval(i); + SDL.GLSwapWindow(window); +}); + +Instance instance = Instance.Create(new InstanceInfo("Graphite.SimpleTest", true)); +SDL.SetWindowTitle(window, SDL.GetWindowTitle(window) + $" - {instance.BackendName}"); + +Console.WriteLine($"Adapters: {string.Join(", ", instance.EnumerateAdapters())}"); + uint properties = SDL.GetWindowProperties(window); SurfaceInfo surfaceInfo; @@ -84,7 +101,7 @@ 1, 2, 3 ]; -ImageResult result0 = ImageResult.FromMemory(File.ReadAllBytes("DEBUG.png"), ColorComponents.RedGreenBlueAlpha); +/*ImageResult result0 = ImageResult.FromMemory(File.ReadAllBytes("DEBUG.png"), ColorComponents.RedGreenBlueAlpha); ImageResult result1 = ImageResult.FromMemory(File.ReadAllBytes("Bagel.png"), ColorComponents.RedGreenBlueAlpha); TextureInfo textureInfo = new() @@ -97,20 +114,20 @@ }; Texture texture0 = device.CreateTexture(in textureInfo, result0.Data); -Sampler sampler = device.CreateSampler(SamplerInfo.LinearClamp); +Sampler sampler = device.CreateSampler(SamplerInfo.LinearClamp);*/ Buffer vertexBuffer = device.CreateBuffer(BufferUsage.VertexBuffer, vertices); Buffer indexBuffer = device.CreateBuffer(BufferUsage.IndexBuffer, indices); Buffer constantBuffer = device.CreateBuffer(BufferUsage.ConstantBuffer | BufferUsage.MapWrite, Matrix4x4.CreateRotationZ(1)); -textureInfo.Size = new Size3D((uint) result1.Width, (uint) result1.Height); +/*textureInfo.Size = new Size3D((uint) result1.Width, (uint) result1.Height); Texture texture1 = device.CreateTexture(in textureInfo, result1.Data); cl.Begin(); cl.GenerateMipmaps(texture0); cl.GenerateMipmaps(texture1); cl.End(); -device.ExecuteCommandList(cl); +device.ExecuteCommandList(cl);*/ /*uint vertexSize = (uint) vertices.Length * sizeof(float); uint indexSize = (uint) indices.Length * sizeof(ushort); @@ -158,7 +175,7 @@ ShaderModule vertexShader = device.CreateShaderModuleFromHLSL(ShaderStage.Vertex, shader, "VSMain"); ShaderModule pixelShader = device.CreateShaderModuleFromHLSL(ShaderStage.Pixel, shader, "PSMain"); -DescriptorLayout textureLayout = device.CreateDescriptorLayout(new DescriptorLayoutInfo +/*DescriptorLayout textureLayout = device.CreateDescriptorLayout(new DescriptorLayoutInfo { Bindings = [ @@ -174,7 +191,7 @@ { Bindings = [new DescriptorBinding(0, DescriptorType.ConstantBuffer, ShaderStage.Vertex)], PushDescriptor = true -}); +});*/ Pipeline pipeline = device.CreateGraphicsPipeline(new GraphicsPipelineInfo { @@ -186,7 +203,7 @@ new InputElementDescription(Format.R32G32_Float, 0, 0, 0), new InputElementDescription(Format.R32G32_Float, 8, 1, 0) ], - Descriptors = [textureLayout, transformLayout] + //Descriptors = [textureLayout, transformLayout] }); pixelShader.Dispose(); @@ -209,21 +226,21 @@ Texture swapchainTexture = swapchain.GetNextTexture(); - nint map = device.MapBuffer(constantBuffer); + /*nint map = device.MapBuffer(constantBuffer); Matrix4x4 matrix = Matrix4x4.CreateRotationZ(value); unsafe { Unsafe.CopyBlock((void*) map, Unsafe.AsPointer(ref matrix), 64); } device.UnmapBuffer(constantBuffer); value += 0.01f; if (value >= float.Pi * 2) - value -= float.Pi * 2; + value -= float.Pi * 2;*/ cl.Begin(); cl.BeginRenderPass([new ColorAttachmentInfo(swapchainTexture, new ColorF(Color.CornflowerBlue))]); cl.SetGraphicsPipeline(pipeline); - cl.SetDescriptorSet(0, pipeline, textureSet); - cl.PushDescriptors(1, pipeline, new Descriptor(0, DescriptorType.ConstantBuffer, constantBuffer)); + /*cl.SetDescriptorSet(0, pipeline, textureSet); + cl.PushDescriptors(1, pipeline, new Descriptor(0, DescriptorType.ConstantBuffer, constantBuffer));*/ cl.SetVertexBuffer(0, vertexBuffer, 4 * sizeof(float)); cl.SetIndexBuffer(indexBuffer, Format.R16_UInt); @@ -239,7 +256,7 @@ } pipeline.Dispose(); -transformLayout.Dispose(); +/*transformLayout.Dispose(); textureSet.Dispose(); textureLayout.Dispose(); sampler.Dispose(); @@ -247,7 +264,7 @@ texture0.Dispose(); constantBuffer.Dispose(); indexBuffer.Dispose(); -vertexBuffer.Dispose(); +vertexBuffer.Dispose();*/ swapchain.Dispose(); cl.Dispose(); device.Dispose(); diff --git a/tests/Graphite.SimpleTest/Shader.hlsl b/tests/Graphite.SimpleTest/Shader.hlsl index 96132cb..b05c66e 100644 --- a/tests/Graphite.SimpleTest/Shader.hlsl +++ b/tests/Graphite.SimpleTest/Shader.hlsl @@ -24,8 +24,8 @@ VSOutput VSMain(const in VSInput input) { VSOutput output; - output.Position = mul(Transform, float4(input.Position, 0.0, 1.0)); - //output.Position = float4(input.Position, 0.0, 1.0); + //output.Position = mul(Transform, float4(input.Position, 0.0, 1.0)); + output.Position = float4(input.Position, 0.0, 1.0); output.TexCoord = input.TexCoord; return output; @@ -33,6 +33,6 @@ VSOutput VSMain(const in VSInput input) float4 PSMain(const in VSOutput input): SV_Target0 { - return lerp(Texture0.Sample(Sampler0, input.TexCoord), Texture1.Sample(Sampler1, input.TexCoord), 0.5); - //return float4(input.TexCoord, 0.0, 1.0); + //return lerp(Texture0.Sample(Sampler0, input.TexCoord), Texture1.Sample(Sampler1, input.TexCoord), 0.5); + return float4(input.TexCoord, 0.0, 1.0); } \ No newline at end of file