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 }; } } }
private unsafe void SetUniformLocationDataSlow(OpenGLConstantBuffer cb, OpenGLUniformStorageAdapter storageAdapter) { // NOTE: This is slow -- avoid using uniform locations in shader code. Prefer uniform blocks. int dataSizeInBytes = cb.BufferSize; byte *data = stackalloc byte[dataSizeInBytes]; cb.GetData((IntPtr)data, dataSizeInBytes); storageAdapter.SetData((IntPtr)data, dataSizeInBytes); }
public UniformLocationBinding( int programID, int uniformLocation) : base(programID) { StorageAdapter = new OpenGLUniformStorageAdapter(ProgramID, uniformLocation); }
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 }; } } }