public bool GetStorageBufferBindingForSlot(uint set, uint slot, out OpenGLShaderStorageBinding binding) { Debug.Assert(_setInfos != null, "EnsureResourcesCreated must be called before accessing resource set information."); SetBindingsInfo setInfo = _setInfos[set]; return(setInfo.GetStorageBufferBindingForSlot(slot, out binding)); }
public bool GetStorageBufferBindingForSlot(uint slot, out OpenGLShaderStorageBinding binding) { return(_storageBufferBindings.TryGetValue(slot, out binding)); }
private void ProcessResourceSetLayouts(ResourceLayout[] layouts) { int resourceLayoutCount = layouts.Length; _setInfos = new SetBindingsInfo[resourceLayoutCount]; int lastTextureLocation = -1; int relativeTextureIndex = -1; int relativeImageIndex = -1; uint storageBlockIndex = 0; // Tracks OpenGL ES storage buffers. for (uint setSlot = 0; setSlot < resourceLayoutCount; setSlot++) { ResourceLayout setLayout = layouts[setSlot]; OpenGLResourceLayout glSetLayout = Util.AssertSubtype <ResourceLayout, OpenGLResourceLayout>(setLayout); ResourceLayoutElementDescription[] resources = glSetLayout.Elements; Dictionary <uint, OpenGLUniformBinding> uniformBindings = new Dictionary <uint, OpenGLUniformBinding>(); Dictionary <uint, OpenGLTextureBindingSlotInfo> textureBindings = new Dictionary <uint, OpenGLTextureBindingSlotInfo>(); Dictionary <uint, OpenGLSamplerBindingSlotInfo> samplerBindings = new Dictionary <uint, OpenGLSamplerBindingSlotInfo>(); Dictionary <uint, OpenGLShaderStorageBinding> storageBufferBindings = new Dictionary <uint, OpenGLShaderStorageBinding>(); List <int> samplerTrackedRelativeTextureIndices = new List <int>(); for (uint i = 0; i < resources.Length; i++) { ResourceLayoutElementDescription resource = resources[i]; if (resource.Kind == ResourceKind.UniformBuffer) { string resourceName = resource.Name; int byteCount = Encoding.UTF8.GetByteCount(resourceName) + 1; byte * resourceNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = resourceName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, resourceName.Length, resourceNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } resourceNamePtr[byteCount - 1] = 0; // Add null terminator. uint blockIndex = glGetUniformBlockIndex(_program, resourceNamePtr); CheckLastError(); if (blockIndex != GL_INVALID_INDEX) { int blockSize; glGetActiveUniformBlockiv(_program, blockIndex, ActiveUniformBlockParameter.UniformBlockDataSize, &blockSize); CheckLastError(); uniformBindings[i] = new OpenGLUniformBinding(_program, blockIndex, (uint)blockSize); } } else if (resource.Kind == ResourceKind.TextureReadOnly) { string resourceName = resource.Name; int byteCount = Encoding.UTF8.GetByteCount(resourceName) + 1; byte * resourceNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = resourceName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, resourceName.Length, resourceNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } resourceNamePtr[byteCount - 1] = 0; // Add null terminator. int location = glGetUniformLocation(_program, resourceNamePtr); CheckLastError(); relativeTextureIndex += 1; textureBindings[i] = new OpenGLTextureBindingSlotInfo() { RelativeIndex = relativeTextureIndex, UniformLocation = location }; lastTextureLocation = location; samplerTrackedRelativeTextureIndices.Add(relativeTextureIndex); } else if (resource.Kind == ResourceKind.TextureReadWrite) { string resourceName = resource.Name; int byteCount = Encoding.UTF8.GetByteCount(resourceName) + 1; byte * resourceNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = resourceName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, resourceName.Length, resourceNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } resourceNamePtr[byteCount - 1] = 0; // Add null terminator. int location = glGetUniformLocation(_program, resourceNamePtr); CheckLastError(); relativeImageIndex += 1; textureBindings[i] = new OpenGLTextureBindingSlotInfo() { RelativeIndex = relativeImageIndex, UniformLocation = location }; } else if (resource.Kind == ResourceKind.StructuredBufferReadOnly || resource.Kind == ResourceKind.StructuredBufferReadWrite) { uint storageBlockBinding; if (_gd.BackendType == GraphicsBackend.OpenGL) { string resourceName = resource.Name; int byteCount = Encoding.UTF8.GetByteCount(resourceName) + 1; byte * resourceNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = resourceName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, resourceName.Length, resourceNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } resourceNamePtr[byteCount - 1] = 0; // Add null terminator. storageBlockBinding = glGetProgramResourceIndex( _program, ProgramInterface.ShaderStorageBlock, resourceNamePtr); CheckLastError(); } else { storageBlockBinding = storageBlockIndex; storageBlockIndex += 1; } storageBufferBindings[i] = new OpenGLShaderStorageBinding(storageBlockBinding); } else { Debug.Assert(resource.Kind == ResourceKind.Sampler); int[] relativeIndices = samplerTrackedRelativeTextureIndices.ToArray(); samplerTrackedRelativeTextureIndices.Clear(); samplerBindings[i] = new OpenGLSamplerBindingSlotInfo() { RelativeIndices = relativeIndices }; } } _setInfos[setSlot] = new SetBindingsInfo(uniformBindings, textureBindings, samplerBindings, storageBufferBindings); } }
private void ProcessResourceSetLayouts(ResourceLayout[] layouts) { int resourceLayoutCount = layouts.Length; _setInfos = new SetBindingsInfo[resourceLayoutCount]; int lastTextureLocation = -1; int relativeTextureIndex = -1; int relativeImageIndex = -1; uint storageBlockIndex = 0; // Tracks OpenGL ES storage buffers. for (uint setSlot = 0; setSlot < resourceLayoutCount; setSlot++) { ResourceLayout setLayout = layouts[setSlot]; OpenGLResourceLayout glSetLayout = Util.AssertSubtype <ResourceLayout, OpenGLResourceLayout>(setLayout); ResourceLayoutElementDescription[] resources = glSetLayout.Elements; Dictionary <uint, OpenGLUniformBinding> uniformBindings = new Dictionary <uint, OpenGLUniformBinding>(); Dictionary <uint, OpenGLTextureBindingSlotInfo> textureBindings = new Dictionary <uint, OpenGLTextureBindingSlotInfo>(); Dictionary <uint, OpenGLSamplerBindingSlotInfo> samplerBindings = new Dictionary <uint, OpenGLSamplerBindingSlotInfo>(); Dictionary <uint, OpenGLShaderStorageBinding> storageBufferBindings = new Dictionary <uint, OpenGLShaderStorageBinding>(); List <int> samplerTrackedRelativeTextureIndices = new List <int>(); for (uint i = 0; i < resources.Length; i++) { ResourceLayoutElementDescription resource = resources[i]; if (resource.Kind == ResourceKind.UniformBuffer) { string resourceName = resource.Name; int byteCount = Encoding.UTF8.GetByteCount(resourceName) + 1; byte * resourceNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = resourceName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, resourceName.Length, resourceNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } resourceNamePtr[byteCount - 1] = 0; // Add null terminator. uint blockIndex = glGetUniformBlockIndex(_program, resourceNamePtr); CheckLastError(); if (blockIndex != GL_INVALID_INDEX) { int blockSize; glGetActiveUniformBlockiv(_program, blockIndex, ActiveUniformBlockParameter.UniformBlockDataSize, &blockSize); CheckLastError(); uniformBindings[i] = new OpenGLUniformBinding(_program, blockIndex, (uint)blockSize); } #if DEBUG && GL_VALIDATE_SHADER_RESOURCE_NAMES else { uint uniformBufferIndex = 0; uint bufferNameByteCount = 64; byte *bufferNamePtr = stackalloc byte[(int)bufferNameByteCount]; var names = new List <string>(); while (true) { uint actualLength; glGetActiveUniformBlockName(_program, uniformBufferIndex, bufferNameByteCount, &actualLength, bufferNamePtr); if (glGetError() != 0) { break; } string name = Encoding.UTF8.GetString(bufferNamePtr, (int)actualLength); names.Add(name); uniformBufferIndex++; } throw new VeldridException($"Unable to bind uniform buffer \"{resourceName}\" by name. Valid names for this pipeline are: {string.Join(", ", names)}"); } #endif } else if (resource.Kind == ResourceKind.TextureReadOnly) { string resourceName = resource.Name; int byteCount = Encoding.UTF8.GetByteCount(resourceName) + 1; byte * resourceNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = resourceName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, resourceName.Length, resourceNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } resourceNamePtr[byteCount - 1] = 0; // Add null terminator. int location = glGetUniformLocation(_program, resourceNamePtr); CheckLastError(); #if DEBUG && GL_VALIDATE_SHADER_RESOURCE_NAMES if (location == -1) { ReportInvalidResourceName(resourceName); } #endif relativeTextureIndex += 1; textureBindings[i] = new OpenGLTextureBindingSlotInfo() { RelativeIndex = relativeTextureIndex, UniformLocation = location }; lastTextureLocation = location; samplerTrackedRelativeTextureIndices.Add(relativeTextureIndex); } else if (resource.Kind == ResourceKind.TextureReadWrite) { string resourceName = resource.Name; int byteCount = Encoding.UTF8.GetByteCount(resourceName) + 1; byte * resourceNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = resourceName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, resourceName.Length, resourceNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } resourceNamePtr[byteCount - 1] = 0; // Add null terminator. int location = glGetUniformLocation(_program, resourceNamePtr); CheckLastError(); #if DEBUG && GL_VALIDATE_SHADER_RESOURCE_NAMES if (location == -1) { ReportInvalidResourceName(resourceName); } #endif relativeImageIndex += 1; textureBindings[i] = new OpenGLTextureBindingSlotInfo() { RelativeIndex = relativeImageIndex, UniformLocation = location }; } else if (resource.Kind == ResourceKind.StructuredBufferReadOnly || resource.Kind == ResourceKind.StructuredBufferReadWrite) { uint storageBlockBinding; if (_gd.BackendType == GraphicsBackend.OpenGL) { string resourceName = resource.Name; int byteCount = Encoding.UTF8.GetByteCount(resourceName) + 1; byte * resourceNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = resourceName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, resourceName.Length, resourceNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } resourceNamePtr[byteCount - 1] = 0; // Add null terminator. storageBlockBinding = glGetProgramResourceIndex( _program, ProgramInterface.ShaderStorageBlock, resourceNamePtr); CheckLastError(); } else { storageBlockBinding = storageBlockIndex; storageBlockIndex += 1; } storageBufferBindings[i] = new OpenGLShaderStorageBinding(storageBlockBinding); } else { Debug.Assert(resource.Kind == ResourceKind.Sampler); int[] relativeIndices = samplerTrackedRelativeTextureIndices.ToArray(); samplerTrackedRelativeTextureIndices.Clear(); samplerBindings[i] = new OpenGLSamplerBindingSlotInfo() { RelativeIndices = relativeIndices }; } } _setInfos[setSlot] = new SetBindingsInfo(uniformBindings, textureBindings, samplerBindings, storageBufferBindings); } }