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);
        }
示例#5
0
 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;
                }
            }
        }