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); }
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); }
private unsafe void CommitNewConstantBufferBindings_MultiBind() { Debug.Assert(_extensions.ARB_MultiBind); int * buffers = stackalloc int[_maxConstantBufferSlots]; IntPtr *sizes = stackalloc IntPtr[_maxConstantBufferSlots]; IntPtr *offsets = stackalloc IntPtr[_maxConstantBufferSlots]; int currentIndex = 0; // Index into stack allocated buffers. int currentBaseSlot = -1; int remainingBuffers = _newConstantBuffersCount; void AddBinding(OpenGLConstantBuffer cb) { buffers[currentIndex] = cb.BufferID; sizes[currentIndex] = new IntPtr(cb.BufferSize); currentIndex += 1; } void EmitBindings() { int count = currentIndex; GL.BindBuffersRange(BufferRangeTarget.UniformBuffer, currentBaseSlot, count, buffers, offsets, sizes); Utilities.CheckLastGLError(); currentIndex = 0; currentBaseSlot = -1; remainingBuffers -= count; Debug.Assert(remainingBuffers >= 0); } for (int slot = 0; slot < _maxConstantBufferSlots; slot++) { OpenGLConstantBuffer cb = _newConstantBuffersBySlot[slot]; if (cb != null) { AddBinding(cb); if (currentBaseSlot == -1) { currentBaseSlot = slot; } _constantBuffersBySlot[slot] = cb; } else if (currentIndex != 0) { EmitBindings(); if (remainingBuffers == 0) { return; } } } if (currentIndex != 0) { EmitBindings(); } }
public bool BindConstantBuffer(int slot, int blockLocation, OpenGLConstantBuffer cb) { // NOTE: slot == uniformBlockIndex if (_boundConstantBuffers.TryGetValue(slot, out OpenGLConstantBuffer boundCB) && boundCB == cb) { return(false); } GL.UniformBlockBinding(ProgramID, blockLocation, slot); _boundConstantBuffers[slot] = cb; return(true); }
public UniformBlockBinding( int programID, int blockIndex, int bindingIndex, OpenGLConstantBuffer constantBuffer, int dataSizeInBytes) : base(programID) { _dataSizeInBytes = dataSizeInBytes; BlockIndex = blockIndex; BindingIndex = bindingIndex; ConstantBuffer = constantBuffer; }
private void CommitNewConstantBufferBindings_SingleBind() { int remainingBindings = _newConstantBuffersCount; for (int slot = 0; slot < _maxConstantBufferSlots; slot++) { if (remainingBindings == 0) { return; } OpenGLConstantBuffer cb = _newConstantBuffersBySlot[slot]; if (cb != null) { GL.BindBufferRange(BufferRangeTarget.UniformBuffer, slot, cb.BufferID, IntPtr.Zero, cb.BufferSize); remainingBindings -= 1; } } }