Difference between revisions of "Example/SPIRV Full Compile Linking"
< Example
Jump to navigation
Jump to search
(SPIR-V compilation example.) |
|||
Line 2: | Line 2: | ||
<source lang="cpp"> | <source lang="cpp"> | ||
− | //Read our shaders into the appropriate buffers | + | // Read our shaders into the appropriate buffers |
− | std::vector<unsigned char> vertexSpirv = //Get SPIR-V for vertex shader. | + | std::vector<unsigned char> vertexSpirv = // Get SPIR-V for vertex shader. |
− | std::vector<unsigned char> fragmentSpirv = //Get SPIR-V for fragment shader. | + | std::vector<unsigned char> fragmentSpirv = // Get SPIR-V for fragment shader. |
− | //Create an empty vertex shader handle | + | // Create an empty vertex shader handle |
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); | GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); | ||
− | //Apply the vertex shader SPIR-V to the shader object. | + | // Apply the vertex shader SPIR-V to the shader object. |
glShaderBinary(1, &vertexShader, GL_SHADER_BINARY_FORMAT_SPIR_V, vertexSpirv.data(), vertexSpirv.size()); | glShaderBinary(1, &vertexShader, GL_SHADER_BINARY_FORMAT_SPIR_V, vertexSpirv.data(), vertexSpirv.size()); | ||
− | //Specialize the vertex shader. | + | // Specialize the vertex shader. |
− | std::string vsEntrypoint = ...; //Get VS entry point name | + | std::string vsEntrypoint = ...; // Get VS entry point name |
glSpecializeShader(vertexShader, (const GLchar*)vsEntrypoint.c_str(), 0, nullptr, nullptr); | glSpecializeShader(vertexShader, (const GLchar*)vsEntrypoint.c_str(), 0, nullptr, nullptr); | ||
− | //Specialization is equivalent to compilation. | + | // Specialization is equivalent to compilation. |
GLint isCompiled = 0; | GLint isCompiled = 0; | ||
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled); | glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled); | ||
− | if(isCompiled == GL_FALSE) | + | if (isCompiled == GL_FALSE) |
{ | { | ||
GLint maxLength = 0; | GLint maxLength = 0; | ||
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); | glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); | ||
− | //The maxLength includes the NULL character | + | // The maxLength includes the NULL character |
std::vector<GLchar> infoLog(maxLength); | std::vector<GLchar> infoLog(maxLength); | ||
glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]); | glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]); | ||
− | //We don't need the shader anymore. | + | // We don't need the shader anymore. |
glDeleteShader(vertexShader); | glDeleteShader(vertexShader); | ||
− | //Use the infoLog as you see fit. | + | // Use the infoLog as you see fit. |
− | //In this simple program, we'll just leave | + | // In this simple program, we'll just leave |
return; | return; | ||
} | } | ||
Line 39: | Line 39: | ||
− | //Create an empty fragment shader handle | + | // Create an empty fragment shader handle |
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | ||
− | //Apply the fragment shader SPIR-V to the shader object. | + | // Apply the fragment shader SPIR-V to the shader object. |
glShaderBinary(1, &fragmentShader, GL_SHADER_BINARY_FORMAT_SPIR_V, fragmentSpirv.data(), fragmentSpirv.size()); | glShaderBinary(1, &fragmentShader, GL_SHADER_BINARY_FORMAT_SPIR_V, fragmentSpirv.data(), fragmentSpirv.size()); | ||
− | //Specialize the fragment shader. | + | // Specialize the fragment shader. |
std::string fsEntrypoint = ...; //Get VS entry point name | std::string fsEntrypoint = ...; //Get VS entry point name | ||
glSpecializeShader(fragmentShader, (const GLchar*)fsEntrypoint.c_str(), 0, nullptr, nullptr); | glSpecializeShader(fragmentShader, (const GLchar*)fsEntrypoint.c_str(), 0, nullptr, nullptr); | ||
− | //Specialization is equivalent to compilation. | + | // Specialization is equivalent to compilation. |
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled); | glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled); | ||
− | if(isCompiled == GL_FALSE) | + | if (isCompiled == GL_FALSE) |
{ | { | ||
GLint maxLength = 0; | GLint maxLength = 0; | ||
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); | glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); | ||
− | //The maxLength includes the NULL character | + | // The maxLength includes the NULL character |
std::vector<GLchar> infoLog(maxLength); | std::vector<GLchar> infoLog(maxLength); | ||
glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]); | glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]); | ||
− | //We don't need the shader anymore. | + | // We don't need the shader anymore. |
glDeleteShader(fragmentShader); | glDeleteShader(fragmentShader); | ||
− | //Either of them. Don't leak shaders. | + | // Either of them. Don't leak shaders. |
glDeleteShader(vertexShader); | glDeleteShader(vertexShader); | ||
− | //Use the infoLog as you see fit. | + | // Use the infoLog as you see fit. |
− | //In this simple program, we'll just leave | + | // In this simple program, we'll just leave |
return; | return; | ||
} | } | ||
− | //Vertex and fragment shaders are successfully compiled. | + | // Vertex and fragment shaders are successfully compiled. |
− | //Now time to link them together into a program. | + | // Now time to link them together into a program. |
− | //Get a program object. | + | // Get a program object. |
GLuint program = glCreateProgram(); | GLuint program = glCreateProgram(); | ||
− | //Attach our shaders to our program | + | // Attach our shaders to our program |
glAttachShader(program, vertexShader); | glAttachShader(program, vertexShader); | ||
glAttachShader(program, fragmentShader); | glAttachShader(program, fragmentShader); | ||
− | //Link our program | + | // Link our program |
glLinkProgram(program); | glLinkProgram(program); | ||
− | //Note the different functions here: glGetProgram* instead of glGetShader*. | + | // Note the different functions here: glGetProgram* instead of glGetShader*. |
GLint isLinked = 0; | GLint isLinked = 0; | ||
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked); | glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked); | ||
− | if(isLinked == GL_FALSE) | + | if (isLinked == GL_FALSE) |
{ | { | ||
GLint maxLength = 0; | GLint maxLength = 0; | ||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); | ||
− | //The maxLength includes the NULL character | + | // The maxLength includes the NULL character |
std::vector<GLchar> infoLog(maxLength); | std::vector<GLchar> infoLog(maxLength); | ||
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); | glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); | ||
− | //We don't need the program anymore. | + | // We don't need the program anymore. |
glDeleteProgram(program); | glDeleteProgram(program); | ||
− | //Don't leak shaders either. | + | // Don't leak shaders either. |
glDeleteShader(vertexShader); | glDeleteShader(vertexShader); | ||
glDeleteShader(fragmentShader); | glDeleteShader(fragmentShader); | ||
− | //Use the infoLog as you see fit. | + | // Use the infoLog as you see fit. |
− | //In this simple program, we'll just leave | + | // In this simple program, we'll just leave |
return; | return; | ||
} | } | ||
− | //Always detach shaders after a successful link. | + | // Always detach shaders after a successful link. |
glDetachShader(program, vertexShader); | glDetachShader(program, vertexShader); | ||
glDetachShader(program, fragmentShader); | glDetachShader(program, fragmentShader); | ||
</source><noinclude>[[Category:Example Code]]</noinclude> | </source><noinclude>[[Category:Example Code]]</noinclude> |
Latest revision as of 11:14, 3 January 2018
Full compile/link through SPIR-V of a Vertex and Fragment Shader.
// Read our shaders into the appropriate buffers
std::vector<unsigned char> vertexSpirv = // Get SPIR-V for vertex shader.
std::vector<unsigned char> fragmentSpirv = // Get SPIR-V for fragment shader.
// Create an empty vertex shader handle
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
// Apply the vertex shader SPIR-V to the shader object.
glShaderBinary(1, &vertexShader, GL_SHADER_BINARY_FORMAT_SPIR_V, vertexSpirv.data(), vertexSpirv.size());
// Specialize the vertex shader.
std::string vsEntrypoint = ...; // Get VS entry point name
glSpecializeShader(vertexShader, (const GLchar*)vsEntrypoint.c_str(), 0, nullptr, nullptr);
// Specialization is equivalent to compilation.
GLint isCompiled = 0;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]);
// We don't need the shader anymore.
glDeleteShader(vertexShader);
// Use the infoLog as you see fit.
// In this simple program, we'll just leave
return;
}
// Create an empty fragment shader handle
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// Apply the fragment shader SPIR-V to the shader object.
glShaderBinary(1, &fragmentShader, GL_SHADER_BINARY_FORMAT_SPIR_V, fragmentSpirv.data(), fragmentSpirv.size());
// Specialize the fragment shader.
std::string fsEntrypoint = ...; //Get VS entry point name
glSpecializeShader(fragmentShader, (const GLchar*)fsEntrypoint.c_str(), 0, nullptr, nullptr);
// Specialization is equivalent to compilation.
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]);
// We don't need the shader anymore.
glDeleteShader(fragmentShader);
// Either of them. Don't leak shaders.
glDeleteShader(vertexShader);
// Use the infoLog as you see fit.
// In this simple program, we'll just leave
return;
}
// Vertex and fragment shaders are successfully compiled.
// Now time to link them together into a program.
// Get a program object.
GLuint program = glCreateProgram();
// Attach our shaders to our program
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
// Link our program
glLinkProgram(program);
// Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
// We don't need the program anymore.
glDeleteProgram(program);
// Don't leak shaders either.
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// Use the infoLog as you see fit.
// In this simple program, we'll just leave
return;
}
// Always detach shaders after a successful link.
glDetachShader(program, vertexShader);
glDetachShader(program, fragmentShader);