aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/OpenGL/OGLShaderProgram.cs
blob: c87b0d4053f6a0e7a02783dda2a2019a63e37fb3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using OpenTK.Graphics.OpenGL;
using System;
using System.Collections.Generic;

namespace Ryujinx.Graphics.Gal.OpenGL
{
    struct OGLShaderProgram
    {
        public OGLShaderStage Vertex;
        public OGLShaderStage TessControl;
        public OGLShaderStage TessEvaluation;
        public OGLShaderStage Geometry;
        public OGLShaderStage Fragment;
    }

    class OGLShaderStage : IDisposable
    {
        public int Handle { get; private set; }

        public bool IsCompiled { get; private set; }

        public GalShaderType Type { get; private set; }

        public string Code { get; private set; }

        public IEnumerable<ShaderDeclInfo> ConstBufferUsage { get; private set; }
        public IEnumerable<ShaderDeclInfo> TextureUsage     { get; private set; }

        public OGLShaderStage(
            GalShaderType               Type,
            string                      Code,
            IEnumerable<ShaderDeclInfo> ConstBufferUsage,
            IEnumerable<ShaderDeclInfo> TextureUsage)
        {
            this.Type             = Type;
            this.Code             = Code;
            this.ConstBufferUsage = ConstBufferUsage;
            this.TextureUsage     = TextureUsage;
        }

        public void Compile()
        {
            if (Handle == 0)
            {
                Handle = GL.CreateShader(OGLEnumConverter.GetShaderType(Type));

                CompileAndCheck(Handle, Code);
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool Disposing)
        {
            if (Disposing && Handle != 0)
            {
                GL.DeleteShader(Handle);

                Handle = 0;
            }
        }

        public static void CompileAndCheck(int Handle, string Code)
        {
            GL.ShaderSource(Handle, Code);
            GL.CompileShader(Handle);

            CheckCompilation(Handle);
        }

        private static void CheckCompilation(int Handle)
        {
            int Status = 0;

            GL.GetShader(Handle, ShaderParameter.CompileStatus, out Status);

            if (Status == 0)
            {
                throw new ShaderException(GL.GetShaderInfoLog(Handle));
            }
        }
    }
}