Difference between revisions of "Example/SPIRV Full Compile Linking"

From OpenGL Wiki
Jump to: navigation, 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);