Esempio n. 1
0
        public Program(IShader[] shaders, TransformFeedbackDescriptor[] transformFeedbackDescriptors)
        {
            _ubBindingPoints = new int[UbsPerStage * ShaderStages];
            _sbBindingPoints = new int[SbsPerStage * ShaderStages];
            _textureUnits    = new int[TexsPerStage * ShaderStages];
            _imageUnits      = new int[ImgsPerStage * ShaderStages];

            for (int index = 0; index < _ubBindingPoints.Length; index++)
            {
                _ubBindingPoints[index] = -1;
            }

            for (int index = 0; index < _sbBindingPoints.Length; index++)
            {
                _sbBindingPoints[index] = -1;
            }

            for (int index = 0; index < _textureUnits.Length; index++)
            {
                _textureUnits[index] = -1;
            }

            for (int index = 0; index < _imageUnits.Length; index++)
            {
                _imageUnits[index] = -1;
            }

            Handle = GL.CreateProgram();

            for (int index = 0; index < shaders.Length; index++)
            {
                int shaderHandle = ((Shader)shaders[index]).Handle;

                GL.AttachShader(Handle, shaderHandle);
            }

            if (transformFeedbackDescriptors != null)
            {
                List <string> varyings = new List <string>();

                int cbi = 0;

                foreach (var tfd in transformFeedbackDescriptors.OrderBy(x => x.BufferIndex))
                {
                    if (tfd.VaryingLocations.Length == 0)
                    {
                        continue;
                    }

                    while (cbi < tfd.BufferIndex)
                    {
                        varyings.Add("gl_NextBuffer");

                        cbi++;
                    }

                    int stride = Math.Min(128 * 4, (tfd.Stride + 3) & ~3);

                    int j = 0;

                    for (; j < tfd.VaryingLocations.Length && j * 4 < stride; j++)
                    {
                        byte location = tfd.VaryingLocations[j];

                        varyings.Add(Varying.GetName(location) ?? "gl_SkipComponents1");

                        j += Varying.GetSize(location) - 1;
                    }

                    int feedbackBytes = j * 4;

                    while (feedbackBytes < stride)
                    {
                        int bytes = Math.Min(16, stride - feedbackBytes);

                        varyings.Add($"gl_SkipComponents{(bytes / 4)}");

                        feedbackBytes += bytes;
                    }
                }

                GL.TransformFeedbackVaryings(Handle, varyings.Count, varyings.ToArray(), TransformFeedbackMode.InterleavedAttribs);
            }

            GL.LinkProgram(Handle);

            for (int index = 0; index < shaders.Length; index++)
            {
                int shaderHandle = ((Shader)shaders[index]).Handle;

                GL.DetachShader(Handle, shaderHandle);
            }

            CheckProgramLink();

            Bind();

            int ubBindingPoint = 0;
            int sbBindingPoint = 0;
            int textureUnit    = 0;
            int imageUnit      = 0;

            for (int index = 0; index < shaders.Length; index++)
            {
                Shader shader = (Shader)shaders[index];

                foreach (BufferDescriptor descriptor in shader.Info.CBuffers)
                {
                    int location = GL.GetUniformBlockIndex(Handle, descriptor.Name);

                    if (location < 0)
                    {
                        continue;
                    }

                    GL.UniformBlockBinding(Handle, location, ubBindingPoint);

                    int bpIndex = (int)shader.Stage << UbStageShift | descriptor.Slot;

                    _ubBindingPoints[bpIndex] = ubBindingPoint;

                    ubBindingPoint++;
                }

                foreach (BufferDescriptor descriptor in shader.Info.SBuffers)
                {
                    int location = GL.GetProgramResourceIndex(Handle, ProgramInterface.ShaderStorageBlock, descriptor.Name);

                    if (location < 0)
                    {
                        continue;
                    }

                    GL.ShaderStorageBlockBinding(Handle, location, sbBindingPoint);

                    int bpIndex = (int)shader.Stage << SbStageShift | descriptor.Slot;

                    _sbBindingPoints[bpIndex] = sbBindingPoint;

                    sbBindingPoint++;
                }

                int samplerIndex = 0;

                foreach (TextureDescriptor descriptor in shader.Info.Textures)
                {
                    int location = GL.GetUniformLocation(Handle, descriptor.Name);

                    if (location < 0)
                    {
                        continue;
                    }

                    GL.Uniform1(location, textureUnit);

                    int uIndex = (int)shader.Stage << TexStageShift | samplerIndex++;

                    _textureUnits[uIndex] = textureUnit;

                    textureUnit++;
                }

                int imageIndex = 0;

                foreach (TextureDescriptor descriptor in shader.Info.Images)
                {
                    int location = GL.GetUniformLocation(Handle, descriptor.Name);

                    if (location < 0)
                    {
                        continue;
                    }

                    GL.Uniform1(location, imageUnit);

                    int uIndex = (int)shader.Stage << ImgStageShift | imageIndex++;

                    _imageUnits[uIndex] = imageUnit;

                    imageUnit++;
                }
            }

            FragmentIsBgraUniform      = GL.GetUniformLocation(Handle, "is_bgra");
            FragmentRenderScaleUniform = GL.GetUniformLocation(Handle, "fp_renderScale");
            ComputeRenderScaleUniform  = GL.GetUniformLocation(Handle, "cp_renderScale");
        }
Esempio n. 2
0
        public Program(IShader[] shaders, TransformFeedbackDescriptor[] transformFeedbackDescriptors)
        {
            Handle = GL.CreateProgram();

            for (int index = 0; index < shaders.Length; index++)
            {
                int shaderHandle = ((Shader)shaders[index]).Handle;

                GL.AttachShader(Handle, shaderHandle);
            }

            if (transformFeedbackDescriptors != null)
            {
                List <string> varyings = new List <string>();

                int cbi = 0;

                foreach (var tfd in transformFeedbackDescriptors.OrderBy(x => x.BufferIndex))
                {
                    if (tfd.VaryingLocations.Length == 0)
                    {
                        continue;
                    }

                    while (cbi < tfd.BufferIndex)
                    {
                        varyings.Add("gl_NextBuffer");

                        cbi++;
                    }

                    int stride = Math.Min(128 * 4, (tfd.Stride + 3) & ~3);

                    int j = 0;

                    for (; j < tfd.VaryingLocations.Length && j * 4 < stride; j++)
                    {
                        byte location = tfd.VaryingLocations[j];

                        varyings.Add(Varying.GetName(location) ?? "gl_SkipComponents1");

                        j += Varying.GetSize(location) - 1;
                    }

                    int feedbackBytes = j * 4;

                    while (feedbackBytes < stride)
                    {
                        int bytes = Math.Min(16, stride - feedbackBytes);

                        varyings.Add($"gl_SkipComponents{(bytes / 4)}");

                        feedbackBytes += bytes;
                    }
                }

                GL.TransformFeedbackVaryings(Handle, varyings.Count, varyings.ToArray(), TransformFeedbackMode.InterleavedAttribs);
            }

            GL.LinkProgram(Handle);

            for (int index = 0; index < shaders.Length; index++)
            {
                int shaderHandle = ((Shader)shaders[index]).Handle;

                GL.DetachShader(Handle, shaderHandle);
            }

            CheckProgramLink();

            FragmentIsBgraUniform      = GL.GetUniformLocation(Handle, "is_bgra");
            FragmentRenderScaleUniform = GL.GetUniformLocation(Handle, "fp_renderScale");
            ComputeRenderScaleUniform  = GL.GetUniformLocation(Handle, "cp_renderScale");
        }