private void CreateComputeGLResources() { _program = glCreateProgram(); CheckLastError(); OpenGLShader glShader = Util.AssertSubtype <Shader, OpenGLShader>(ComputeShader); glShader.EnsureResourcesCreated(); glAttachShader(_program, glShader.Shader); CheckLastError(); glLinkProgram(_program); CheckLastError(); int linkStatus; glGetProgramiv(_program, GetProgramParameterName.LinkStatus, &linkStatus); CheckLastError(); if (linkStatus != 1) { byte *infoLog = stackalloc byte[4096]; uint bytesWritten; glGetProgramInfoLog(_program, 4096, &bytesWritten, infoLog); CheckLastError(); string log = Encoding.UTF8.GetString(infoLog, (int)bytesWritten); throw new VeldridException($"Error linking GL program: {log}"); } ProcessResourceSetLayouts(ResourceLayouts); }
private void CreateGraphicsGLResources() { _program = glCreateProgram(); CheckLastError(); foreach (Shader stage in GraphicsShaders) { OpenGLShader glShader = Util.AssertSubtype <Shader, OpenGLShader>(stage); glShader.EnsureResourcesCreated(); glAttachShader(_program, glShader.Shader); CheckLastError(); } uint slot = 0; foreach (VertexLayoutDescription layoutDesc in VertexLayouts) { for (int i = 0; i < layoutDesc.Elements.Length; i++) { string elementName = layoutDesc.Elements[i].Name; int byteCount = Encoding.UTF8.GetByteCount(elementName) + 1; byte * elementNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = elementName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, elementName.Length, elementNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } elementNamePtr[byteCount - 1] = 0; // Add null terminator. glBindAttribLocation(_program, slot, elementNamePtr); CheckLastError(); slot += 1; } } glLinkProgram(_program); CheckLastError(); #if DEBUG && GL_VALIDATE_VERTEX_INPUT_ELEMENTS slot = 0; foreach (VertexLayoutDescription layoutDesc in VertexLayouts) { for (int i = 0; i < layoutDesc.Elements.Length; i++) { string elementName = layoutDesc.Elements[i].Name; int byteCount = Encoding.UTF8.GetByteCount(elementName) + 1; byte * elementNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = elementName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, elementName.Length, elementNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } elementNamePtr[byteCount - 1] = 0; // Add null terminator. int location = glGetAttribLocation(_program, elementNamePtr); if (location == -1) { throw new VeldridException("There was no attribute variable with the name " + layoutDesc.Elements[i].Name); } slot += 1; } } #endif int linkStatus; glGetProgramiv(_program, GetProgramParameterName.LinkStatus, &linkStatus); CheckLastError(); if (linkStatus != 1) { byte *infoLog = stackalloc byte[4096]; uint bytesWritten; glGetProgramInfoLog(_program, 4096, &bytesWritten, infoLog); CheckLastError(); string log = Encoding.UTF8.GetString(infoLog, (int)bytesWritten); throw new VeldridException($"Error linking GL program: {log}"); } ProcessResourceSetLayouts(ResourceLayouts); }
private void CreateGLResources() { ShaderSetDescription shaderSet = Description.ShaderSet; _program = glCreateProgram(); CheckLastError(); foreach (ShaderStageDescription stageDesc in shaderSet.ShaderStages) { OpenGLShader glShader = Util.AssertSubtype <Shader, OpenGLShader>(stageDesc.Shader); glShader.EnsureResourcesCreated(); glAttachShader(_program, glShader.Shader); CheckLastError(); } uint slot = 0; foreach (VertexLayoutDescription layoutDesc in shaderSet.VertexLayouts) { for (int i = 0; i < layoutDesc.Elements.Length; i++) { string elementName = layoutDesc.Elements[i].Name; int byteCount = Encoding.UTF8.GetByteCount(elementName) + 1; byte * elementNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = elementName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, elementName.Length, elementNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } elementNamePtr[byteCount - 1] = 0; // Add null terminator. glBindAttribLocation(_program, slot, elementNamePtr); CheckLastError(); slot += 1; } } glLinkProgram(_program); CheckLastError(); #if DEBUG && GL_VALIDATE_VERTEX_INPUT_ELEMENTS slot = 0; foreach (VertexLayoutDescription layoutDesc in shaderSet.VertexLayouts) { for (int i = 0; i < layoutDesc.Elements.Length; i++) { string elementName = layoutDesc.Elements[i].Name; int byteCount = Encoding.UTF8.GetByteCount(elementName) + 1; byte * elementNamePtr = stackalloc byte[byteCount]; fixed(char *charPtr = elementName) { int bytesWritten = Encoding.UTF8.GetBytes(charPtr, elementName.Length, elementNamePtr, byteCount); Debug.Assert(bytesWritten == byteCount - 1); } elementNamePtr[byteCount - 1] = 0; // Add null terminator. int location = glGetAttribLocation(_program, elementNamePtr); if (location == -1) { throw new VeldridException("There was no attribute variable with the name " + layoutDesc.Elements[i].Name); } slot += 1; } } #endif int linkStatus; glGetProgramiv(_program, GetProgramParameterName.LinkStatus, &linkStatus); CheckLastError(); if (linkStatus != 1) { byte *infoLog = stackalloc byte[4096]; uint bytesWritten; glGetProgramInfoLog(_program, 4096, &bytesWritten, infoLog); CheckLastError(); string log = Encoding.UTF8.GetString(infoLog, (int)bytesWritten); throw new VeldridException($"Error linking GL program: {log}"); } int resourceLayoutCount = Description.ResourceLayouts.Length; _setInfos = new SetBindingsInfo[resourceLayoutCount]; int lastTextureLocation = -1; int relativeTextureIndex = -1; for (uint setSlot = 0; setSlot < resourceLayoutCount; setSlot++) { ResourceLayout setLayout = Description.ResourceLayouts[setSlot]; OpenGLResourceLayout glSetLayout = Util.AssertSubtype <ResourceLayout, OpenGLResourceLayout>(setLayout); ResourceLayoutElementDescription[] resources = glSetLayout.Description.Elements; Dictionary <uint, OpenGLUniformBinding> uniformBindings = new Dictionary <uint, OpenGLUniformBinding>(); Dictionary <uint, OpenGLTextureBindingSlotInfo> textureBindings = new Dictionary <uint, OpenGLTextureBindingSlotInfo>(); Dictionary <uint, OpenGLTextureBindingSlotInfo> samplerBindings = new Dictionary <uint, OpenGLTextureBindingSlotInfo>(); for (uint i = 0; i < resources.Length; i++) { ResourceLayoutElementDescription resource = resources[i]; if (resource.Kind == ResourceKind.Uniform) { 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); if (blockIndex != GL_INVALID_INDEX) { uniformBindings[i] = new OpenGLUniformBinding(_program, blockIndex); } else { throw new System.NotImplementedException(); //int uniformLocation = glGetUniformLocation(_program, resource.Name); //OpenGLUniformStorageAdapter storageAdapter = new OpenGLUniformStorageAdapter(_program, uniformLocation); //_constantBindings[i] = new OpenGLUniformBinding(_program, storageAdapter); } } else if (resource.Kind == ResourceKind.Texture) { 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); relativeTextureIndex += 1; textureBindings[i] = new OpenGLTextureBindingSlotInfo() { RelativeIndex = relativeTextureIndex, UniformLocation = location }; lastTextureLocation = location; } else { Debug.Assert(resource.Kind == ResourceKind.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 }; } } _setInfos[setSlot] = new SetBindingsInfo(uniformBindings, textureBindings, samplerBindings); } Created = true; }