Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        protected override Shader CreateShaderCore(ref ShaderDescription description)
        {
            StagingBlock stagingBlock = _pool.Stage(description.ShaderBytes);
            OpenGLShader shader       = new OpenGLShader(_gd, description.Stage, stagingBlock, description.EntryPoint);

            _gd.EnsureResourceInitialized(shader);
            return(shader);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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;
        }