private void BindUniformBlock(OpenGLShaderSet shaderSet, int slot, int blockLocation, OpenGLConstantBuffer cb)
        {
            if (slot > _maxConstantBufferSlots)
            {
                throw new VeldridException($"Too many constant buffers used. Limit is {_maxConstantBufferSlots}.");
            }

            // Bind Constant Buffer to slot
            if (_constantBuffersBySlot[slot] == cb)
            {
                if (_newConstantBuffersBySlot[slot] != null)
                {
                    _newConstantBuffersCount -= 1;
                }
                _newConstantBuffersBySlot[slot] = null;
            }
            else
            {
                if (_newConstantBuffersBySlot[slot] == null)
                {
                    _newConstantBuffersCount += 1;
                }

                _newConstantBuffersBySlot[slot] = cb;
            }

            // Bind slot to uniform block location. Performs internal caching to avoid GL calls.
            shaderSet.BindConstantBuffer(slot, blockLocation, cb);
        }
        protected override void PlatformSetShaderSet(ShaderSet shaderSet)
        {
            OpenGLShaderSet glShaderSet = (OpenGLShaderSet)shaderSet;

            GL.UseProgram(glShaderSet.ProgramID);
            _vertexLayoutChanged = true;
        }
示例#3
0
        public OpenGLShaderResourceBindingSlots(OpenGLShaderSet shaderSet, ShaderResourceDescription[] resources)
        {
            Resources = resources;
            int programID = shaderSet.ProgramID;

            int lastTextureLocation  = -1;
            int relativeTextureIndex = -1;

            for (int i = 0; i < resources.Length; i++)
            {
                ShaderResourceDescription resource = resources[i];
                if (resource.Type == ShaderResourceType.ConstantBuffer)
                {
                    int blockIndex = GL.GetUniformBlockIndex(programID, resource.Name);
                    if (blockIndex != -1)
                    {
                        ValidateBlockSize(programID, blockIndex, resource.DataSizeInBytes, resource.Name);
                        _constantBindings[i] = new OpenGLUniformBinding(programID, blockIndex, resource.DataSizeInBytes);
                    }
                    else
                    {
                        int uniformLocation = GL.GetUniformLocation(programID, resource.Name);

                        OpenGLUniformStorageAdapter storageAdapter = new OpenGLUniformStorageAdapter(programID, uniformLocation);
                        _constantBindings[i] = new OpenGLUniformBinding(programID, storageAdapter);
                    }
                }
                else if (resource.Type == ShaderResourceType.Texture)
                {
                    int location = GL.GetUniformLocation(shaderSet.ProgramID, resource.Name);
                    relativeTextureIndex += 1;
                    _textureBindings[i]   = new OpenGLTextureBindingSlotInfo()
                    {
                        RelativeIndex = relativeTextureIndex, UniformLocation = location
                    };
                    lastTextureLocation = location;
                }
                else
                {
                    Debug.Assert(resource.Type == ShaderResourceType.Sampler);

                    // TODO: Samplers should be able to bind to multiple texture slots
                    // if multiple textures are declared without an intervening sampler. For example:
                    //     Slot    Resource
                    // -------------------------
                    //     [0]     Texture0
                    //     [1]     Sampler0
                    //     [2]     Texture1
                    //     [3]     Texture2
                    //     [4]     Sampler1*
                    // Sampler1 should be active for both Texture1 and Texture2.

                    _samplerBindings[i] = new OpenGLTextureBindingSlotInfo()
                    {
                        RelativeIndex = relativeTextureIndex, UniformLocation = lastTextureLocation
                    };
                }
            }
        }
        public OpenGLShaderResourceBindingSlots(OpenGLShaderSet shaderSet, ShaderResourceDescription[] resources)
        {
            Resources = resources;
            int programID = shaderSet.ProgramID;

            int lastTextureLocation  = -1;
            int relativeTextureIndex = -1;

            for (int i = 0; i < resources.Length; i++)
            {
                ShaderResourceDescription resource = resources[i];
                if (resource.Type == ShaderResourceType.ConstantBuffer)
                {
                    int blockIndex = GL.GetUniformBlockIndex(programID, resource.Name);
                    if (blockIndex != -1)
                    {
                        ValidateBlockSize(programID, blockIndex, resource.DataSizeInBytes, resource.Name);
                        _constantBindings[i] = new OpenGLUniformBinding(programID, blockIndex, resource.DataSizeInBytes);
                    }
                    else
                    {
                        int uniformLocation = GL.GetUniformLocation(programID, resource.Name);
                        if (uniformLocation == -1)
                        {
                            throw new VeldridException($"No uniform or uniform block with name {resource.Name} was found.");
                        }

                        OpenGLUniformStorageAdapter storageAdapter = new OpenGLUniformStorageAdapter(programID, uniformLocation);
                        _constantBindings[i] = new OpenGLUniformBinding(programID, storageAdapter);
                    }
                }
                else if (resource.Type == ShaderResourceType.Texture)
                {
                    int location = GL.GetUniformLocation(shaderSet.ProgramID, resource.Name);
                    if (location == -1)
                    {
                        throw new VeldridException($"No sampler was found with the name {resource.Name}");
                    }

                    relativeTextureIndex += 1;
                    _textureBindings[i]   = new OpenGLTextureBindingSlotInfo()
                    {
                        RelativeIndex = relativeTextureIndex, UniformLocation = location
                    };
                    lastTextureLocation = location;
                }
                else
                {
                    Debug.Assert(resource.Type == ShaderResourceType.Sampler);
                    if (lastTextureLocation == -1)
                    {
                        throw new VeldridException(
                                  "OpenGL Shaders must specify at least one texture before a sampler. Samplers are implicity linked with the closest-previous texture resource in the binding list.");
                    }

                    _samplerBindings[i] = new OpenGLTextureBindingSlotInfo()
                    {
                        RelativeIndex = relativeTextureIndex, UniformLocation = lastTextureLocation
                    };
                }
            }
        }