/** * Extract Shader Storage Buffer data from the shader */ void Program::ExtractStorageBlockData() { GLint numBlocks = 0; glGetProgramInterfaceiv(_program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numBlocks); char tempNameAR[1024]; Log("\tBuffer :") for (int blockIdx = 0; blockIdx < numBlocks; blockIdx++) { std::vector<BufferVariableInfo> vars; glGetProgramResourceName(_program, GL_SHADER_STORAGE_BLOCK, blockIdx, 1024, NULL, tempNameAR); std::string bufferName(tempNameAR); GLint binding = 0; { GLenum prop[] = { GL_BUFFER_BINDING }; glGetProgramResourceiv(_program, GL_SHADER_STORAGE_BLOCK, blockIdx, 1, prop, 1, NULL, &binding); } Log("\t\t" + bufferName + " index " + ToString(blockIdx) + " binding " + ToString(binding)); GLint vcount = 0; { GLenum prop[] = { GL_NUM_ACTIVE_VARIABLES }; glGetProgramResourceiv(_program, GL_SHADER_STORAGE_BLOCK, blockIdx, 1, prop, 1, NULL, &vcount); } std::vector<GLint> variables(vcount); { GLenum prop[] = { GL_ACTIVE_VARIABLES }; glGetProgramResourceiv(_program, GL_SHADER_STORAGE_BLOCK, blockIdx, 1, prop, vcount, NULL, &variables.front()); } GLchar vnameAR[128] = { 0 }; for (int k = 0; k < vcount; k++) { GLenum propsAR[] = { GL_OFFSET, GL_TYPE, GL_ARRAY_STRIDE, GL_MATRIX_STRIDE, GL_IS_ROW_MAJOR, GL_TOP_LEVEL_ARRAY_STRIDE }; GLint paramsAR[sizeof(propsAR) / sizeof(GLenum)]; glGetProgramResourceiv(_program, GL_BUFFER_VARIABLE, variables[k], sizeof(propsAR) / sizeof(GLenum), propsAR, sizeof(paramsAR) / sizeof(GLenum), NULL, paramsAR); glGetProgramResourceName(_program, GL_BUFFER_VARIABLE, variables[k], sizeof(vnameAR), NULL, vnameAR); Log("\t\t\t" + std::string(vnameAR) + " offset " + ToString(paramsAR[0]) + " type " + GLUtil::GLSLTypeToStr(GLenum(paramsAR[1])) + " array stride " + ToString(paramsAR[2]) + " top level stride " + ToString(paramsAR[5])); vars.push_back(BufferVariableInfo(std::string(vnameAR), paramsAR[0], GLenum(paramsAR[1]), paramsAR[2], paramsAR[3], GLboolean(paramsAR[4]), paramsAR[5])); } _buffers.insert(std::make_pair(bufferName, BufferInfo(bufferName, blockIdx, vars))); } }
/** * Extract Attribute data from the shader */ void Program::ExtractAttributeData() { Log("\tInput :"); char tempNameAR[1024]; { GLint numInput = 0; glGetProgramInterfaceiv(_program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numInput); const GLenum propertiesAR[2] = { GL_TYPE, GL_LOCATION }; for (int input = 0; input < numInput; input++) { GLint valuesAR[2]; glGetProgramResourceiv(_program, GL_PROGRAM_INPUT, input, 2, propertiesAR, 2, NULL, valuesAR); glGetProgramResourceName(_program, GL_PROGRAM_INPUT, input, 1024, NULL, tempNameAR); std::string inputName(tempNameAR); if (inputName.size() >= 3 && inputName.substr(0, 3) == "gl_") continue; else { _inputs.insert(std::make_pair(inputName, AttributeInfo(inputName, GLenum(valuesAR[0]), valuesAR[1], GLUtil::SizeofGLSLType(GLenum(valuesAR[0]))))); Log("\t\t" + inputName + " " + ToString(valuesAR[1]) + " " + GLUtil::GLSLTypeToStr(GLenum(valuesAR[0]))); } } } Log("\tOutput :"); { GLint numOutput = 0; glGetProgramInterfaceiv(_program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, &numOutput); const GLenum propertiesAR[2] = { GL_TYPE, GL_LOCATION }; for (int outpout = 0; outpout < numOutput; outpout++) { GLint valuesAR[2]; glGetProgramResourceiv(_program, GL_PROGRAM_OUTPUT, outpout, 2, propertiesAR, 2, NULL, valuesAR); glGetProgramResourceName(_program, GL_PROGRAM_OUTPUT, outpout, 1024, NULL, tempNameAR); std::string outputName(tempNameAR); if (outputName.size() >= 3 && outputName.substr(0, 3) != "gl_") { _outputs.insert(std::make_pair(outputName, AttributeInfo(outputName, GLenum(valuesAR[0]), valuesAR[1], GLUtil::SizeofGLSLType(GLenum(valuesAR[0]))))); Log("\t\t" + outputName + " " + ToString(valuesAR[1]) + " " + GLUtil::GLSLTypeToStr(GLenum(valuesAR[0]))); } } } }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglGetProgramResourceiv(JNIEnv *env, jclass clazz, jint program, jint programInterface, jint index, jint propCount, jlong props, jint bufSize, jlong length, jlong params, jlong function_pointer) { const GLenum *props_address = (const GLenum *)(intptr_t)props; GLsizei *length_address = (GLsizei *)(intptr_t)length; GLint *params_address = (GLint *)(intptr_t)params; glGetProgramResourceivPROC glGetProgramResourceiv = (glGetProgramResourceivPROC)((intptr_t)function_pointer); glGetProgramResourceiv(program, programInterface, index, propCount, props_address, bufSize, length_address, params_address); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBProgramInterfaceQuery_nglGetProgramResourceiv__IIIIJIJJ(JNIEnv *__env, jclass clazz, jint program, jint programInterface, jint index, jint propCount, jlong propsAddress, jint bufSize, jlong lengthAddress, jlong paramsAddress) { glGetProgramResourceivPROC glGetProgramResourceiv = (glGetProgramResourceivPROC)tlsGetFunction(899); intptr_t props = (intptr_t)propsAddress; intptr_t length = (intptr_t)lengthAddress; intptr_t params = (intptr_t)paramsAddress; UNUSED_PARAM(clazz) glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglGetProgramResourceiv(JNIEnv *__env, jclass clazz, jint program, jint programInterface, jint index, jint propCount, jlong propsAddress, jint bufSize, jlong lengthAddress, jlong paramsAddress, jlong __functionAddress) { const GLenum *props = (const GLenum *)(intptr_t)propsAddress; GLsizei *length = (GLsizei *)(intptr_t)lengthAddress; GLint *params = (GLint *)(intptr_t)paramsAddress; glGetProgramResourceivPROC glGetProgramResourceiv = (glGetProgramResourceivPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params); }
static void setup_ubos(void) { static const char *names[NUM_SSBOS] = { "ssbo_pos_size", "ssbo_color", "ssbo_rot" }; static GLubyte zeros[1000] = {0}; int i; glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment); printf("GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = %d\n", alignment); if (test_buffer_offset) { printf("Testing buffer offset %d\n", alignment); } else { /* we use alignment as the offset */ alignment = 0; } glGenBuffers(NUM_SSBOS, buffers); for (i = 0; i < NUM_SSBOS; i++) { GLint index, size; /* query SSBO index */ index = glGetProgramResourceIndex(prog, GL_SHADER_STORAGE_BLOCK, names[i]); GLenum prop = GL_BUFFER_DATA_SIZE; /* query SSBO size */ glGetProgramResourceiv(prog, GL_SHADER_STORAGE_BLOCK, index, 1, &prop, 1, NULL, &size); printf("SSBO %s: index = %d, size = %d\n", names[i], index, size); /* Allocate SSBO */ glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[i]); glBufferData(GL_SHADER_STORAGE_BUFFER, size + alignment, zeros, GL_DYNAMIC_DRAW); /* Attach SSBO */ glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, buffers[i], alignment, /* offset */ size); glShaderStorageBlockBinding(prog, index, i); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); } }
void Shader::printActiveUniformBlocks() const { GLint numBlocks = 0; glGetProgramInterfaceiv(id_, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, &numBlocks); GLenum blockProps[] = { GL_NUM_ACTIVE_VARIABLES, GL_NAME_LENGTH }; GLenum blockIndex[] = { GL_ACTIVE_VARIABLES }; GLenum props[] = { GL_NAME_LENGTH, GL_TYPE, GL_BLOCK_INDEX }; for (int block = 0; block < numBlocks; ++block) { GLint blockInfo[2]; glGetProgramResourceiv(id_, GL_UNIFORM_BLOCK, block, 2, blockProps, 2, NULL, blockInfo); GLint numUnis = blockInfo[0]; char *blockName = new char[blockInfo[1] + 1]; glGetProgramResourceName(id_, GL_UNIFORM_BLOCK, block, blockInfo[1] + 1, NULL, blockName); printf("Uniform block \"%s\":\n", blockName); delete[] blockName; GLint *unifIndexes = new GLint[numUnis]; glGetProgramResourceiv(id_, GL_UNIFORM_BLOCK, block, 1, blockIndex, numUnis, NULL, unifIndexes); for (int unif = 0; unif < numUnis; ++unif) { GLint uniIndex = unifIndexes[unif]; GLint results[3]; glGetProgramResourceiv(id_, GL_UNIFORM, uniIndex, 3, props, 3, NULL, results); GLint nameBufSize = results[0] + 1; char *name = new char[nameBufSize]; glGetProgramResourceName(id_, GL_UNIFORM, uniIndex, nameBufSize, NULL, name); printf(" %s (%s)\n", name, getTypeString(results[1])); delete[] name; } delete[] unifIndexes; } }
Program::Uniforms Program::getActiveBufferVariables( std::vector<GLuint> const & locationIndices ) { Program::Uniforms uniforms; GLint numActiveVariables; glGetProgramInterfaceiv( getGLId(), GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &numActiveVariables ); for ( size_t idx = 0; idx < locationIndices.size(); ++idx ) { GLuint index = locationIndices[idx]; GLenum const properties[] = { GL_NAME_LENGTH // 0 , GL_BLOCK_INDEX // 1 , GL_TYPE // 2 , GL_ARRAY_SIZE // 3 , GL_OFFSET // 4 , GL_ARRAY_STRIDE // 5 , GL_MATRIX_STRIDE// 6 , GL_IS_ROW_MAJOR // 7 }; GLsizei const numProperties = sizeof dp::util::array(properties); GLint values[numProperties]; glGetProgramResourceiv( getGLId(), GL_BUFFER_VARIABLE, index, numProperties, properties, numProperties, NULL, values ); Uniform uniform; // get uniform name uniform.name.resize(values[0]); glGetProgramResourceName( getGLId(), GL_BUFFER_VARIABLE, index, GLsizei(uniform.name.size()), NULL, &uniform.name[0]); uniform.blockIndex = values[1]; uniform.uniformLocation = -1; uniform.type = values[2]; uniform.arraySize = values[3]; uniform.offset = values[4]; uniform.arrayStride = values[5]; uniform.matrixStride = values[6]; uniform.isRowMajor = (values[7] != 0); uniforms[uniform.name] = uniform; } return uniforms; }
void CDecalsDrawerGL4::CreateStructureVBOs() { { // Decal Groups UBO GLsizei uniformBlockSize = 0; GLuint uniformBlockIndex = glGetUniformBlockIndex(decalShader->GetObjID(), "decalGroupsUBO"); glGetActiveUniformBlockiv(decalShader->GetObjID(), uniformBlockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlockSize); uboDecalGroups.Bind(GL_UNIFORM_BUFFER); uboDecalGroups.New(uniformBlockSize, GL_DYNAMIC_DRAW); uboDecalGroups.Unbind(); glUniformBlockBinding(decalShader->GetObjID(), uniformBlockIndex, 4); glBindBufferBase(GL_UNIFORM_BUFFER, 4, uboDecalGroups.GetId()); } { // Decals UBO GLint uniformBlockSize = 0; GLuint uniformBlockIndex = 0; if (useSSBO) { uniformBlockIndex = glGetProgramResourceIndex(decalShader->GetObjID(), GL_SHADER_STORAGE_BLOCK, "decalsUBO"); constexpr GLenum props[] = {GL_BUFFER_DATA_SIZE}; glGetProgramResourceiv(decalShader->GetObjID(), GL_SHADER_STORAGE_BLOCK, uniformBlockIndex, 1, props, 1, nullptr, &uniformBlockSize); } else { uniformBlockIndex = glGetUniformBlockIndex(decalShader->GetObjID(), "decalsUBO"); glGetActiveUniformBlockiv(decalShader->GetObjID(), uniformBlockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlockSize); } uboDecalsStructures.Bind(GL_UNIFORM_BUFFER); uboDecalsStructures.New(uniformBlockSize, GL_DYNAMIC_DRAW); uboDecalsStructures.Unbind(); if (useSSBO) { glShaderStorageBlockBinding(decalShader->GetObjID(), uniformBlockIndex, 3); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, uboDecalsStructures.GetId()); } else { glUniformBlockBinding(decalShader->GetObjID(), uniformBlockIndex, 3); glBindBufferBase(GL_UNIFORM_BUFFER, 3, uboDecalsStructures.GetId()); } } }
void Shader::addAllUniforms() { /* Get all active uniforms except uniforms in blocks */ GLenum program_interface = GL_UNIFORM; GLint num_uniforms = 0; glGetProgramInterfaceiv(m_program_id, program_interface, GL_ACTIVE_RESOURCES, &num_uniforms); const GLenum properties[] = { GL_BLOCK_INDEX, GL_TYPE, GL_NAME_LENGTH, GL_LOCATION }; const GLint properties_size = sizeof(properties) / sizeof(properties[0]); for(GLint i = 0; i < num_uniforms; ++i) { GLint values[properties_size]; glGetProgramResourceiv(m_program_id, program_interface, i, properties_size, properties, properties_size, nullptr, values); /* Skip all uniforms in blocks */ if(values[0] != -1) { continue; } std::vector<char> name_data(values[2]); glGetProgramResourceName(m_program_id, program_interface, i, name_data.size(), nullptr, &name_data[0]); std::string uniform_name(name_data.begin(), name_data.end() - 1); std::string prefix = uniform_name.substr(0, 2); if(GLOBAL_UNIFORM_PREFIX == prefix) { m_global_uniforms_types.push_back(values[1]); m_global_uniforms_names.push_back(uniform_name); m_uniforms_locations[uniform_name] = values[3]; } else if(SKIP_UNIFORM_PREFIX == prefix) { m_uniforms_locations[uniform_name] = values[3]; } else { m_uniforms_types.push_back(values[1]); m_uniforms_names.push_back(uniform_name); m_uniforms_locations[uniform_name] = values[3]; } } }
void Shader::printActiveAttribs() const { GLint numAttribs; glGetProgramInterfaceiv(id_, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numAttribs); GLenum properties[] = { GL_NAME_LENGTH, GL_TYPE, GL_LOCATION }; printf("Active attributes:\n"); for (int i = 0; i < numAttribs; ++i) { GLint results[3]; glGetProgramResourceiv(id_, GL_PROGRAM_INPUT, i, 3, properties, 3, NULL, results); GLint nameBufSize = results[0] + 1; char *name = new char[nameBufSize]; glGetProgramResourceName(id_, GL_PROGRAM_INPUT, i, nameBufSize, NULL, name); printf("%-5d %s (%s)\n", results[2], name, getTypeString(results[1])); delete[] name; } }
shaderBuffer::shaderBuffer( const std::string &name, unsigned int programId ) { target = GL_SHADER_STORAGE_BUFFER; size = 0; unsigned int idx = glGetProgramResourceIndex( programId, GL_BUFFER_VARIABLE, name.c_str() ); int props[] = { GL_BUFFER_DATA_SIZE }; int paramLen = 4; int params; glGetProgramResourceiv( programId, GL_BUFFER_VARIABLE, idx, 1, (const GLenum *) props, 4, ¶mLen, ¶ms ); glGenBuffersARB( 1, &bufferId ); glBindBufferARB( target, bufferId ); glBufferDataARB( target, params, 0, GL_DYNAMIC_COPY ); glBindBufferARB( target, 0 ); assert( glGetError() == GL_NO_ERROR ); }
int32 gfxGetShaderUniforms(uint32 program, uint8* namesBuffer, uint32 namesBufferSize, uint8* types, uint8* locations) { uint32 namesBufferOffset = 0; GLint numUniforms = 0; glGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES, &numUniforms); const GLenum properties[4] = {GL_BLOCK_INDEX, GL_TYPE, GL_NAME_LENGTH, GL_LOCATION}; for(int ii = 0; ii < numUniforms; ++ii) { GLint values[4]; glGetProgramResourceiv(program, GL_UNIFORM, ii, 4, properties, 4, NULL, values); //Skip any iiorms that are in a block. // values[0] = GL_BLOCK_INDEX if(values[0] != -1) continue; // values[2] = GL_NAME_LENGTH int32 len = values[2] + 1; if (namesBufferOffset + len > namesBufferSize) { break; } glGetProgramResourceName(program, GL_UNIFORM, ii, 128, NULL, s_uniformName); // Write to out buffers memcpy(namesBuffer+namesBufferOffset, s_uniformName, len); namesBufferOffset += len; locations[ii] = (uint8)values[3]; uint8 type = UNIFORM_TYPES; for (uint8 t=0; t < UNIFORM_TYPES; t++) { if (values[1] == s_uniformTypeMap[t]) { type = t; break; } } types[ii] = type; } return numUniforms; }
void Program::ExtractUniformData() { Log("\tUniform : "); char tempNameAR[1024]; GLint numUni = 0; glGetProgramInterfaceiv(_program, GL_UNIFORM, GL_ACTIVE_RESOURCES, &numUni); const GLenum propertiesAR[3] = { GL_TYPE, GL_LOCATION, GL_BLOCK_INDEX }; for (int uni = 0; uni < numUni; uni++) { GLint valuesAR[3]; glGetProgramResourceiv(_program, GL_UNIFORM, uni, 3, propertiesAR, 2, NULL, valuesAR); glGetProgramResourceName(_program, GL_UNIFORM, uni, 1024, NULL, tempNameAR); std::string uniName(tempNameAR); _uniforms.insert(std::make_pair(uniName,AttributeInfo(uniName, GLenum(valuesAR[0]), valuesAR[1], GLUtil::SizeofGLSLType(GLenum(valuesAR[0]))))); Log("\t\t" + uniName + " " + ToString(valuesAR[1]) + " " + GLUtil::GLSLTypeToStr(GLenum(valuesAR[0]))); } }
void kore::ShaderProgram::constructShaderOutputInfo(std::vector<ShaderOutput>& rOutputVector) { GLint iNumActiveElements = 0; glGetProgramInterfaceiv(_programHandle, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, &iNumActiveElements); const GLenum properties[3] = {GL_TYPE, GL_NAME_LENGTH, GL_LOCATION}; for (int i = 0; i < iNumActiveElements; ++i) { GLchar szNameBuf[BUFSIZE]; GLsizei iActualNameLength = 0; GLint iElementSize = 1; GLenum eElementType; GLint iElementLoc = -1; GLint values[3]; glGetProgramResourceiv(_programHandle, GL_PROGRAM_OUTPUT, i, 3, properties, BUFSIZE, NULL, values); eElementType = values[0]; iActualNameLength = values[1]; iElementLoc = values[2]; glGetProgramResourceName(_programHandle, GL_PROGRAM_OUTPUT, i, BUFSIZE, &iActualNameLength, szNameBuf); std::string szName = std::string(szNameBuf); ShaderOutput element; element.name = szName; element.type = eElementType; element.size = iElementSize; rOutputVector.push_back(element); } }
void gle::fill_input(GLuint pid, input_vars_map_t &input_vars, input_arrays_map_t &input_arrays) { GLint num_active; GLint max_name_length; glGetProgramInterfaceiv(pid, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &num_active); glGetProgramInterfaceiv(pid, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &max_name_length); std::vector<char> name_buf(max_name_length); char * name_buf_ptr = &name_buf[0]; for (int i = 0; i < num_active; i++) { glGetProgramResourceName(pid, GL_PROGRAM_INPUT, i, max_name_length, NULL, name_buf_ptr); static GLenum const props[] = { GL_LOCATION, GL_TYPE, GL_ARRAY_SIZE, GL_IS_PER_PATCH }; static const int num_props = sizeof(props) / sizeof(GLenum); #pragma pack(push, 1) struct params_t { GLint loc; GLint type; GLint arr_size; GLint is_per_patch; }; #pragma pack(pop) params_t params; glGetProgramResourceiv(pid, GL_PROGRAM_INPUT, i, num_props, props, num_props, NULL, reinterpret_cast<GLint*>(¶ms)); if (params.arr_size != 0) input_arrays.insert(std::make_pair(std::string(name_buf_ptr), iface_input_array_data_t(name_buf_ptr, params.arr_size, params.type, params.loc, params.is_per_patch))); else input_vars.insert(std::make_pair(std::string(name_buf_ptr), iface_input_variable_data_t(name_buf_ptr, params.type, params.loc, params.is_per_patch))); } }
void Shader::addAllSubroutines() { GLenum interfaces[] = { GL_VERTEX_SUBROUTINE, GL_FRAGMENT_SUBROUTINE }; GLenum shader_stages[] = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER }; GLint interfaces_count = sizeof(interfaces) / sizeof(interfaces[0]); for(GLint i = 0; i < interfaces_count; ++i) { /* Get all active subroutines */ GLenum program_interface = interfaces[i]; GLint num_subroutines = 0; glGetProgramInterfaceiv(m_program_id, program_interface, GL_ACTIVE_RESOURCES, &num_subroutines); const GLenum properties[] = { GL_NAME_LENGTH }; const GLint properties_size = sizeof(properties) / sizeof(properties[0]); GLint count_subroutine_locations = 0; glGetProgramStageiv(m_program_id, shader_stages[i], GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &count_subroutine_locations); m_active_subroutine_uniform_locations[shader_stages[i]] = count_subroutine_locations; for (GLint j = 0; j < num_subroutines; ++j) { GLint values[properties_size]; GLint length = 0; glGetProgramResourceiv(m_program_id, program_interface, j, properties_size, properties, properties_size, &length, values); std::vector<char> name_data(values[0]); glGetProgramResourceName(m_program_id, program_interface, j, name_data.size(), nullptr, &name_data[0]); std::string subroutine_name(name_data.begin(), name_data.end() - 1); GLuint subroutine_index = glGetSubroutineIndex(m_program_id, shader_stages[i], subroutine_name.c_str()); m_subroutine_indices[subroutine_name] = subroutine_index; } } }
void Shader::printActiveUniforms() const { GLint numUniforms = 0; glGetProgramInterfaceiv(id_, GL_UNIFORM, GL_ACTIVE_RESOURCES, &numUniforms); GLenum properties[] = { GL_NAME_LENGTH, GL_TYPE, GL_LOCATION, GL_BLOCK_INDEX }; printf("Active uniforms:\n"); for (int i = 0; i < numUniforms; ++i) { GLint results[4]; glGetProgramResourceiv(id_, GL_UNIFORM, i, 4, properties, 4, NULL, results); if (results[3] != -1) continue; GLint nameBufSize = results[0] + 1; char *name = new char[nameBufSize]; glGetProgramResourceName(id_, GL_UNIFORM, i, nameBufSize, NULL, name); printf("%-5d %s (%s)\n", results[2], name, getTypeString(results[1])); delete[] name; } }
Shader::Shader(const std::string &vshaderFilename, const std::string &fshaderFilename){ std::string vshaderCode = readFile(vshaderFilename); std::string fshaderCode = readFile(fshaderFilename); if (vshaderCode == "ERR" || vshaderCode == "ERR"){ std::cout << "One or both of the shader files didn't load." << std::endl; return; } std::cout << "Read code for " << vshaderFilename << " and " << fshaderFilename << "." << std::endl; vshaderID = glCreateShader(GL_VERTEX_SHADER); fshaderID = glCreateShader(GL_FRAGMENT_SHADER); std::cout << "Read code for " << vshaderFilename << " and " << fshaderFilename << "." << std::endl; compileShader(vshaderID, vshaderCode, vshaderFilename); compileShader(fshaderID, fshaderCode, fshaderFilename); std::cout << "Linking program." << std::endl; programID = glCreateProgram(); glAttachShader(programID, vshaderID); glAttachShader(programID, fshaderID); glLinkProgram(programID); //check for linking errors GLint compileStatus = GL_FALSE; GLint infoLogLength; glGetProgramiv(programID, GL_LINK_STATUS, &compileStatus); glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength); std::vector<char> linkErrorMessage( std::max(infoLogLength, int(1)) ); glGetProgramInfoLog(programID, infoLogLength, NULL, &linkErrorMessage[0]); std::cout << &linkErrorMessage[0] << std::endl; GLint numUniforms = 0; glGetProgramInterfaceiv(programID, GL_UNIFORM, GL_ACTIVE_RESOURCES, &numUniforms); std::vector<GLchar> nameData(256); for(GLint i=0; i<numUniforms; i++) { //Get name length. GLenum thingToGet = GL_NAME_LENGTH; GLint nameLength; glGetProgramResourceiv(programID, GL_UNIFORM, i, 1, &thingToGet, 1, NULL, &nameLength); //Read name into vector. nameData.resize(nameLength); //The length of the name. glGetProgramResourceName(programID, GL_UNIFORM, i, nameData.size(), NULL, &nameData[0]); //Put vector into string, add it to map. std::string name((char*)&nameData[0], nameData.size() - 1); GLint uniformID = glGetUniformLocation(programID, name.c_str()); std::cout << "Found uniform named " << name << " at ID " << uniformID << "." << std::endl; programUniformIDs[name] = uniformID; } std::cout << "Done with " << vshaderFilename << " and " << fshaderFilename << "." << std::endl << std::endl; }
void piglit_init(int argc, char **argv) { bool pass = true; GLint index; const GLenum prop[NUM_QUERIES] = {GL_TOP_LEVEL_ARRAY_SIZE, GL_TOP_LEVEL_ARRAY_STRIDE, GL_TYPE, GL_ARRAY_SIZE, GL_BLOCK_INDEX, GL_OFFSET, GL_ARRAY_STRIDE, GL_MATRIX_STRIDE, GL_IS_ROW_MAJOR, GL_REFERENCED_BY_VERTEX_SHADER, GL_REFERENCED_BY_FRAGMENT_SHADER }; const char *prop_names[NUM_QUERIES] = {"GL_TOP_LEVEL_ARRAY_SIZE", "GL_TOP_LEVEL_ARRAY_STRIDE", "GL_TYPE", "GL_ARRAY_SIZE", "GL_BLOCK_INDEX", "GL_OFFSET", "GL_ARRAY_STRIDE", "GL_MATRIX_STRIDE", "GL_IS_ROW_MAJOR", "GL_REFERENCED_BY_VERTEX_SHADER", "GL_REFERENCED_BY_FRAGMENT_SHADER" }; int query_std140[NUM_QUERIES] = {0}; int query_std430[NUM_QUERIES] = {0}; const int expected_std140[NUM_QUERIES] = { 0, 112, GL_FLOAT_MAT2, 3, 0, 16, 32, 16, 1, 1, 0 }; const int expected_std430[NUM_QUERIES] = { 2, 56, GL_FLOAT_MAT2, 3, 2, 16, 16, 8, 0, 0, 1 }; int i; piglit_require_extension("GL_ARB_shader_storage_buffer_object"); piglit_require_extension("GL_ARB_program_interface_query"); prog = piglit_build_simple_program(vs_pass_thru_text, fs_source); glUseProgram(prog); /* First ssbo_std140 */ index = glGetProgramResourceIndex(prog, GL_BUFFER_VARIABLE, "ssbo_std140.s[0].b[0]"); glGetProgramResourceiv(prog, GL_BUFFER_VARIABLE, index, NUM_QUERIES, prop, NUM_QUERIES, NULL, query_std140); if (!piglit_check_gl_error(GL_NO_ERROR)) pass = false; /* Now ssbo_std430 */ index = glGetProgramResourceIndex(prog, GL_BUFFER_VARIABLE, "ssbo_std430.s[0].b[0]"); glGetProgramResourceiv(prog, GL_BUFFER_VARIABLE, index, NUM_QUERIES, prop, NUM_QUERIES, NULL, query_std430); if (!piglit_check_gl_error(GL_NO_ERROR)) pass = false; for (i = 0 ; i < NUM_QUERIES; i++) { if (query_std140[i] != expected_std140[i]) { printf("std140 %s expected = %d. Value = %d.\n", prop_names[i], expected_std140[i], query_std140[i]); pass = false; } if (query_std430[i] != expected_std430[i]) { printf("std430 %s expected = %d. Value = %d.\n", prop_names[i], expected_std430[i], query_std430[i]); pass = false; } } piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
GLProgram *GLCompiler::make( ) { bool errors= false; bool shaders= false; for(unsigned int i= 0; i < GLProgram::SHADERTYPE_LAST; i++) { if(sources[i].source.empty()) continue; // construit le source shaders= true; sources[i].build= build_source(i); // cree le program if(program == GLProgram::null()) program= (new GLProgram(program_label))->create(); // cree le shader GLuint shader= program->shaders[i]; if(shader == 0) { shader= glCreateShader(GLProgram::types[i]); glAttachShader(program->name, shader); program->shaders[i]= shader; } // compile le shader const char *text[]= { sources[i].build.c_str() }; glShaderSource(shader, 1, text, NULL); glCompileShader(shader); GLint status= 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if(status == GL_FALSE) { errors= true; GLint length= 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); if(length > 0) { char *log= new char[length +1]; glGetShaderInfoLog(shader, length, NULL, log); ERROR("error compiling %s shader:\n", GLProgram::labels[i]); printErrors(log, sources[i]); ERROR("shader defines:\n%s\n", sources[i].definitions.c_str()); delete [] log; } else MESSAGE("error compiling %s shader: no log. failed.\n", GLProgram::labels[i]); } #if 0 { GLint length= 0; glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length); if(length > 0) { char log[4096]; glGetShaderSource(shader, sizeof(log), NULL, log); DEBUGLOG("shader:\n%s\n", log); } } #endif } if(shaders == false || program == GLProgram::null()) { ERROR("no shader. failed.\n"); return program; } if(errors == true) { program->resources(); program->errors= true; return program; } // link GLint status= 0; glLinkProgram(program->name); glGetProgramiv(program->name, GL_LINK_STATUS, &status); if(status == GL_FALSE) { GLint length= 0; glGetProgramiv(program->name, GL_INFO_LOG_LENGTH, &length); if(length > 0) { char *log= new char[length +1]; glGetProgramInfoLog(program->name, length, NULL, log); MESSAGE("error linking program:\n%s\nfailed.\n", log); delete [] log; } else MESSAGE("error linking program: no log. failed.\n"); program->errors= true; return program; } //~ #ifdef GK_OPENGL4 #if 0 { // interface matching // introspection opengl >= 4.3 // recompile chaque shader dans un program separe et recupere les varyings avec queryinterface(program_inputs / program_outputs)... std::vector<parameter> stage_inputs[GLProgram::SHADERTYPE_LAST]; std::vector<parameter> stage_outputs[GLProgram::SHADERTYPE_LAST]; for(unsigned int i= 0; i < GLProgram::SHADERTYPE_LAST; i++) { if(program->shaders[i] == 0) continue; // recupere le source du shader GLint stage_length= 0; glGetShaderiv(program->shaders[i], GL_SHADER_SOURCE_LENGTH, &stage_length); std::vector<GLchar> stage_source(stage_length +1); glGetShaderSource(program->shaders[i], stage_source.size(), NULL, &stage_source.front()); // construit un program pipeline avec uniquement ce shader const GLchar *sources[]= { &stage_source.front() }; GLuint stage= glCreateShader(GLProgram::types[i]); glShaderSource(stage, 1, sources, NULL); glCompileShader(stage); GLuint pipeline= glCreateProgram(); glProgramParameteri(pipeline, GL_PROGRAM_SEPARABLE, GL_TRUE); glAttachShader(pipeline, stage); glLinkProgram(pipeline); glValidateProgram(pipeline); // recupere les varyings in / out GLint inputs; glGetProgramInterfaceiv(pipeline, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &inputs); for(int k= 0; k < inputs; k++) { GLenum properties[3]= { GL_TYPE, GL_LOCATION, GL_LOCATION_COMPONENT }; GLint values[3]= { 0, -1, -1 }; glGetProgramResourceiv(pipeline, GL_PROGRAM_INPUT, k, 3, properties, 3, NULL, values); GLchar name[4096]= { 0 }; glGetProgramResourceName(pipeline, GL_PROGRAM_INPUT, k, sizeof(name), NULL, name); stage_inputs[i].push_back( parameter(name, k, values[0], values[1], -1, values[2]) ); } std::stable_sort(stage_inputs[i].begin(), stage_inputs[i].end()); GLint outputs; glGetProgramInterfaceiv(pipeline, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, &outputs); for(int k= 0; k < outputs; k++) { GLenum properties[4]= { GL_TYPE, GL_LOCATION, GL_LOCATION_INDEX, GL_LOCATION_COMPONENT }; GLint values[4]= { 0, -1, -1, -1 }; glGetProgramResourceiv(pipeline, GL_PROGRAM_OUTPUT, k, 4, properties, 4, NULL, values); GLchar name[4096]= { 0 }; glGetProgramResourceName(pipeline, GL_PROGRAM_OUTPUT, k, sizeof(name), NULL, name); stage_outputs[i].push_back( parameter(name, k, values[0], values[1], values[2], values[3]) ); } std::stable_sort(stage_outputs[i].begin(), stage_outputs[i].end()); // nettoyage glDeleteShader(stage); glDeleteProgram(pipeline); } // affichage : les sorties d'un shader doivent correspondre aux entrees du shader suivant dans le pipeline printf("program interfaces...\n"); for(unsigned int i= 0; i < GLProgram::SHADERTYPE_LAST; i++) { if(stage_inputs[i].size()) { printf(" %s shader inputs:\n", GLProgram::labels[i]); for(unsigned int k= 0; k < stage_inputs[i].size(); k++) { const char *type= glsl::type_string(stage_inputs[i][k].type); if(type) printf(" %02d/-1: '%s', type '%s'\n", stage_inputs[i][k].location, stage_inputs[i][k].name.c_str(), type); else printf(" %02d/-1: '%s', type 0x%x\n", stage_inputs[i][k].location, stage_inputs[i][k].name.c_str(), stage_inputs[i][k].type); } } if(stage_outputs[i].size()) { printf(" %s shader outputs:\n", GLProgram::labels[i]); for(unsigned int k= 0; k < stage_outputs[i].size(); k++) { const char *type= glsl::type_string(stage_outputs[i][k].type); if(type) printf(" %02d/%02d: '%s', type '%s'\n", stage_outputs[i][k].location, stage_outputs[i][k].location_index, stage_outputs[i][k].name.c_str(), type); else printf(" %02d/%02d: '%s', type 0x%x\n", stage_outputs[i][k].location, stage_outputs[i][k].location_index, stage_outputs[i][k].name.c_str(), stage_outputs[i][k].type); } } //! \todo verification des interfaces } } #endif program->resources(); program->errors= false; MESSAGE("done.\n"); return program; }
void GLProgram::create(const GLShader& _vsh, const GLShader& _fsh) { m_id = glCreateProgram(); GLint linked(0); if (_vsh.m_id != 0) { GL_CHECK(glAttachShader(m_id, _vsh.m_id)); if (_fsh.m_id != 0) { GL_CHECK(glAttachShader(m_id, _fsh.m_id)); } GL_CHECK(glLinkProgram(m_id)); GL_CHECK(glGetProgramiv(m_id, GL_LINK_STATUS, &linked)); if (!linked) { char log[1024]; GL_CHECK(glGetProgramInfoLog(m_id, sizeof(log), NULL, log)); MOTI_TRACE("%d: %s", linked, log); } } if (!linked) { GL_CHECK(glDeleteProgram(m_id)); m_id = 0; MOTI_TRACE("Invalid shaders: vsh %d, fsh %d", _vsh.m_id, _fsh.m_id); return; } GLint numActiveAttribs{ 0 }; GLint numActiveUniforms{ 0 }; GL_CHECK(glGetProgramInterfaceiv(m_id, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numActiveAttribs)); GL_CHECK(glGetProgramInterfaceiv(m_id, GL_UNIFORM, GL_ACTIVE_RESOURCES, &numActiveUniforms)); glGetProgramiv(m_id, GL_ACTIVE_UNIFORMS, &numActiveUniforms); GLint max0, max1; GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max0)); GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max1)); uint32_t nameMaxLength = std::max(max0, max1); char* name = static_cast<char*>(alloca(nameMaxLength + 1)); MOTI_TRACE("Program %d", m_id); MOTI_TRACE("Attribute count %d", numActiveAttribs); for (int32_t i = 0; i < numActiveAttribs; ++i) { GLint size; GLenum type; glGetActiveAttrib(m_id, i, nameMaxLength + 1, nullptr, &size, &type, name); MOTI_TRACE("%s is at location %d", name, glGetAttribLocation(m_id, name)); } MOTI_TRACE("Uniform count %d", numActiveUniforms); for (int32_t i = 0; i < numActiveUniforms; ++i) { struct Info { GLenum type; GLint loc; GLint count; }; Info info; GLenum props[] = { GL_TYPE, GL_LOCATION, GL_ARRAY_SIZE }; GL_CHECK(glGetProgramResourceiv( m_id, GL_UNIFORM, i, MOTI_COUNTOF(props), props, MOTI_COUNTOF(props), NULL, (GLint*)&info)); GL_CHECK(glGetProgramResourceName( m_id, GL_UNIFORM, i, nameMaxLength + 1, NULL, name)); uint16_t count = std::max(info.count, 1); PredefinedUniform::Enum predef = nameToPredefinedUniform(name); if (predef != PredefinedUniform::Count) { m_predefinedUniforms[m_uniformCount].m_type = uint8_t(predef); m_predefinedUniforms[m_uniformCount].m_loc = info.loc; m_predefinedUniforms[m_uniformCount].m_count = count; m_uniformCount++; } else { // its user defined uniform const UniformInfo* uniformInfo = s_ctx->m_uniformReg.find(name); if (uniformInfo == nullptr) { MOTI_TRACE("User defined uniform %s is not found", name); } else { UniformType::Enum type = glTypeToUniformType(info.type); UniformDecl decl; decl.m_handle = uniformInfo->m_handle; decl.m_loc = info.loc; decl.m_count = count; decl.m_type = type; m_uniforms.push_back(decl); } } MOTI_TRACE("uniform %s is at location %d, count %d", name, info.loc, count); } memset(m_attributes, 0xff, sizeof(m_attributes)); uint32_t used(0); for (uint8_t i = 0; i < Attribute::Count; ++i) { GLint loc = glGetAttribLocation(m_id, s_attribNames[i]); if (loc != -1) { MOTI_TRACE("attribute %s: %d", s_attribNames[i], loc); m_attributes[i] = loc; m_used[used++] = i; } } MOTI_ASSERT(used < MOTI_COUNTOF(m_used), "Out of bounds %d > array size %d", used, MOTI_COUNTOF(m_used)); m_used[used] = Attribute::Count; }
void Shader::info() { std::cout << "------------------------------" << m_Name << " Interface-------------------------" << std::endl; GLint outputs = 0; glGetProgramInterfaceiv(m_Program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &outputs); static const GLenum props[] = {GL_TYPE, GL_LOCATION}; GLint params[2]; GLchar name[64]; const char *type_name; if (outputs > 0) std::cout << "***Input***" << std::endl; for (int i = 0; i != outputs; ++i) { glGetProgramResourceName(m_Program, GL_PROGRAM_INPUT, i, sizeof(name), NULL, name); glGetProgramResourceiv(m_Program, GL_PROGRAM_INPUT, i, 2, props, 2, NULL, params); type_name = name; //std::cout << "Index " << i << std::endl; std::cout << "(" << type_name << ")" << " locatoin: " << params[1] << std::endl; } glGetProgramInterfaceiv(m_Program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, &outputs); if (outputs > 0) std::cout << "***Onput***" << std::endl; for (int i = 0; i != outputs; ++i) { glGetProgramResourceName(m_Program, GL_PROGRAM_OUTPUT, i, sizeof(name), NULL, name); glGetProgramResourceiv( m_Program, GL_PROGRAM_OUTPUT, i, 2, props, 2, NULL, params); type_name = name; //std::cout << "Index " << i << std::endl; std::cout << "(" << type_name << ")" << " locatoin: " << params[1] << std::endl; } glGetProgramInterfaceiv(m_Program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, &outputs); if (outputs > 0) std::cout << "***Uniform Block***" << std::endl; for (int i = 0; i != outputs; ++i) { glGetProgramResourceName(m_Program, GL_UNIFORM_BLOCK, i, sizeof(name), NULL, name); glGetProgramResourceiv( m_Program, GL_UNIFORM_BLOCK, i, 2, props, 2, NULL, params); type_name = name; //std::cout << "Index " << i << std::endl; std::cout << "(" << type_name << ")" << " locatoin: " << params[1] << std::endl; } glGetProgramInterfaceiv(m_Program, GL_UNIFORM, GL_ACTIVE_RESOURCES, &outputs); if (outputs > 0) std::cout << "***Uniform***" << std::endl; if (outputs > 100) return ; for (int i = 0; i != outputs; ++i) { glGetProgramResourceName(m_Program, GL_UNIFORM, i, sizeof(name), NULL, name); glGetProgramResourceiv( m_Program, GL_UNIFORM, i, 2, props, 2, NULL, params); type_name = name; //std::cout << "Index " << i << std::endl; std::cout << "(" << type_name << ")" << " locatoin: " << params[1] << std::endl; } std::cout << "--------------------------------------------------------------------------------" << std::endl; }
void piglit_init(int argc, char **argv) { bool pass = true; bool active_res = true; bool max_active = true; bool buff_bind[2] = { true, true }; bool num_active[2] = { false, false }; bool varying_idx[2] = { false, false }; GLuint prog; piglit_require_GLSL_version(150); piglit_require_extension("GL_ARB_transform_feedback3"); piglit_require_extension("GL_ARB_enhanced_layouts"); prog = build_and_use_program(vs_two_buff_text); GLint value; GLint values[5]; glGetProgramInterfaceiv(prog, GL_TRANSFORM_FEEDBACK_BUFFER, GL_ACTIVE_RESOURCES, &value); if (value != 2) { printf("Expected 2 ACTIVE_RESOURCES found %d\n", value); active_res = false; } piglit_report_subtest_result(active_res ? PIGLIT_PASS : PIGLIT_FAIL, "Query ACTIVE_RESOURCES"); glGetProgramInterfaceiv(prog, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &value); if (value != 3) { printf("Expected MAX_NUM_ACTIVE_VARIABLES to be 3 found %d\n", value); max_active = false; } piglit_report_subtest_result(active_res ? PIGLIT_PASS : PIGLIT_FAIL, "Query MAX_NUM_ACTIVE_VARIABLES"); GLenum props[] = {GL_BUFFER_BINDING, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES}; for (unsigned i = 0; i < 2; i++) { glGetProgramResourceiv(prog, GL_TRANSFORM_FEEDBACK_BUFFER, i, 3, props, 5, NULL, values); if (values[0] != 1 && values[0] != 3) buff_bind[i] = false; if (values[0] == 1) { if(values[1] == 3) { num_active[i] = true; } else { printf("Expected 3 NUM_ACTIVE_VARIABLES " "found %d\n", values[1]); } varying_idx[i] = check_varyings_match(prog, &values[2], 3, 0); } else if (values[0] == 3) { if (values[1] == 2) { num_active[i] = true; } else { printf("Expected 2 NUM_ACTIVE_VARIABLES " "found %d\n", values[1]); } varying_idx[i] = check_varyings_match(prog, &values[2], 2, 1); } } piglit_report_subtest_result(buff_bind[0] && buff_bind[1] ? PIGLIT_PASS : PIGLIT_FAIL, "Query BUFFER_BINDING"); piglit_report_subtest_result(num_active[0] && num_active[1] ? PIGLIT_PASS : PIGLIT_FAIL, "Query NUM_ACTIVE_VARIABLES"); piglit_report_subtest_result(varying_idx[0] && varying_idx[1] ? PIGLIT_PASS : PIGLIT_FAIL, "Query ACTIVE_VARIABLES"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); pass = active_res && max_active && buff_bind[0] && buff_bind[1] && num_active[0] && num_active[1] && varying_idx[0] && varying_idx[1]; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
static void check_prop(GLuint prog, GLenum programInterface, int index, const char *name, void *inputs, struct check_t c, bool *pass) { int values[10], parent_idx, i; char subsubtest[150]; GLsizei length, tmp = -1; char buf[21]; GLenum pif; GLuint loc; /* skip the test if it is not supported */ if(!check_extensions_prop(c.prop)) { return; } /* generate the name of the subsubtest for error-reporting purposes */ snprintf(subsubtest, sizeof(subsubtest), "%s: %s on %s", name, piglit_get_gl_enum_name(c.prop), piglit_get_gl_enum_name(programInterface)); /* retrieve the property */ glGetProgramResourceiv(prog, programInterface, index, 1, &c.prop, 10, &length, values); if (!piglit_check_gl_error(GL_NO_ERROR)) { printf(" Latest error generated while running '%s'\n", subsubtest); *pass = false; return; } /* check the return value */ switch (c.prop) { case GL_OFFSET: case GL_ARRAY_STRIDE: case GL_ATOMIC_COUNTER_BUFFER_INDEX: basic_check(subsubtest, values[0], c.values[0], pass); break; case GL_BLOCK_INDEX: /* check that the index of the parent matches the name * of the parent */ switch (programInterface) { case GL_UNIFORM: pif = GL_UNIFORM_BLOCK; break; case GL_BUFFER_VARIABLE: pif = GL_SHADER_STORAGE_BLOCK; break; default: assert(!"unexpected programInterface value"); pif = GL_NONE; } parent_idx = glGetProgramResourceIndex(prog, pif, (char*)inputs); piglit_check_gl_error(GL_NO_ERROR); if (parent_idx != values[0]) { glGetProgramResourceName(prog, programInterface, values[0], sizeof(buf), NULL, buf); fprintf(stderr, "'%s' expected parent name to be %s" "(idx = %i) but got parent name %s(idx = %i)\n", subsubtest, (char*)inputs, parent_idx, buf, values[0]); *pass = false; } break; case GL_BUFFER_BINDING: if (values[0] < 0) { fprintf(stderr, "'%s' invalid buffer binding point\n", subsubtest); *pass = false; } /* Binding index is necessary for ATOMIC_COUNTER_BUFFER */ if (programInterface == GL_ATOMIC_COUNTER_BUFFER) { if (values[0] != c.values[0]) { fprintf(stderr, "'%s' expected binding point %i" " but got %i\n", subsubtest, c.values[0], values[0]); *pass = false; } break; } /* check against another API call */ if (programInterface != GL_UNIFORM_BLOCK) { break; } glGetActiveUniformBlockiv(prog, index, GL_UNIFORM_BLOCK_BINDING, &tmp); piglit_check_gl_error(GL_NO_ERROR); if (tmp != values[0]) { fprintf(stderr, "'%s' inconsistent buffer binding point" "(%i) with glGetActiveUniformBlockiv" "(%i)\n", subsubtest, values[0], tmp); *pass = false; } break; case GL_ACTIVE_VARIABLES: case GL_COMPATIBLE_SUBROUTINES: switch (programInterface) { case GL_UNIFORM_BLOCK: pif = GL_UNIFORM; break; case GL_SHADER_STORAGE_BLOCK: pif = GL_BUFFER_VARIABLE; break; case GL_VERTEX_SUBROUTINE_UNIFORM: pif = GL_VERTEX_SUBROUTINE; break; case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: pif = GL_TESS_CONTROL_SUBROUTINE; break; case GL_COMPUTE_SUBROUTINE_UNIFORM: pif = GL_COMPUTE_SUBROUTINE; break; case GL_ATOMIC_COUNTER_BUFFER: /* do nothing */ break; default: assert(!"unexpected programInterface value"); pif = GL_NONE; } /* check that the return count is as expected */ if (c.count != length) { fprintf(stderr, "'%s' expected %zu entries but got %i" "\n", subsubtest, c.count, length); length = 1; *pass = false; break; } /* harcode the index test for GL_ATOMIC_COUNTER_BUFFER */ if (programInterface == GL_ATOMIC_COUNTER_BUFFER) { if (values[0] != 0) { fprintf(stderr, "'%s' expected index 0 but got " "%i", subsubtest, values[0]); *pass = false; } break; } for (i = 0; i < length; i++) { buf[0] = '\0'; glGetProgramResourceName(prog, pif, values[i], sizeof(buf), NULL, buf); piglit_check_gl_error(GL_NO_ERROR); if (!is_resource_in_list(inputs, buf, i, false)) { fprintf(stderr, "'%s' could not find active " "resource '%s' (idx = %i) in the active" " list\n", subsubtest, buf, values[i]); *pass = false; } } break; case GL_BUFFER_DATA_SIZE: /* Nothing we can check here... */ break; case GL_LOCATION: loc = glGetProgramResourceLocation(prog, programInterface, name); piglit_check_gl_error(GL_NO_ERROR); if (loc != values[0]) { fprintf(stderr, "'%s' inconsistent value between " "glGetProgramResourceiv(%i) and " "glGetProgramResourceLocation(%i).\n", subsubtest, values[0], loc); *pass = false; break; } if (prog == prog_loc && values[0] != c.values[0]) { fprintf(stderr, "'%s' expected location %i but got " "%i\n", subsubtest, c.values[0], values[0]); *pass = false; break; } /* continue by testing the (in)validity of the index */ basic_check(subsubtest, values[0], c.values[0], pass); break; case GL_LOCATION_INDEX: loc = glGetProgramResourceLocationIndex(prog, programInterface, name); piglit_check_gl_error(GL_NO_ERROR); if (loc != values[0]) { fprintf(stderr, "'%s' inconsistent value between " "glGetProgramResourceiv(%i) and " "glGetProgramResourceLocationIndex(%i)." "\n", subsubtest, values[0], loc); *pass = false; break; } /* continue by testing the (in)validity of the index */ basic_check(subsubtest, values[0], c.values[0], pass); break; default: /* check that the return count is as expected */ if (c.count != length) { fprintf(stderr, "'%s' expected %zu entries but got %i" "\n", subsubtest, c.count, length); length = 1; *pass = false; break; } /* go through all the values returned */ for (i = 0; i < length; i++) { if (values[i] != c.values[i]) { fprintf(stderr, "'%s' expected %i but got %i at" " index %i\n", subsubtest, c.values[i], values[i], i); *pass = false; } } break; } }
static void test_error_cases(bool *pass) { GLenum props[] = {GL_NAME_LENGTH}; GLenum props_invalid[] = {GL_NAME_LENGTH, GL_TRUE, GL_TYPE}; GLenum props_error[] = {GL_NAME_LENGTH, GL_OFFSET, GL_TYPE}; int values[10]; GLuint shader; bool prg_tst; /* test using an unexisting program ID */ glGetProgramResourceiv(1337, GL_UNIFORM, 0, 1, props, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_VALUE); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "Invalid program (undefined ID)"); /* test using a shader ID */ shader = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_empty); glGetProgramResourceIndex(shader, GL_UNIFORM, "resource"); prg_tst = piglit_check_gl_error(GL_INVALID_OPERATION); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "Invalid program (call on shader)"); /* invalid index. This is unspecified but let's check it is consistent * with GetProgramResourceName. */ glGetProgramResourceiv(prog_std, GL_UNIFORM, 1337, 0, props, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_VALUE); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "Invalid index"); /* test propcount == 0 */ glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, 0, props, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_VALUE); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "<propcount> == 0"); /* test propcount < 0 */ glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, -1, props, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_VALUE); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "<propcount> < 0"); /* one invalid property */ glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, 3, props_invalid, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_ENUM); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "prop == GL_TRUE"); /* property not acceptable for one program interface */ glGetProgramResourceiv(prog_std, GL_PROGRAM_INPUT, 0, 3, props_error, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_OPERATION); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "GL_OFFSET on GL_PROGRAM_INPUT"); }
bool validate(GLuint const & ProgramName) { bool Error = false; // Pipeline object validation { GLint Status(0); GLint LengthMax(0); glValidateProgramPipeline(PipelineName); glGetProgramPipelineiv(PipelineName, GL_VALIDATE_STATUS, &Status); glGetProgramPipelineiv(PipelineName, GL_INFO_LOG_LENGTH, &LengthMax); GLsizei LengthQuery(0); std::vector<GLchar> InfoLog(LengthMax + 1, '\0'); glGetProgramPipelineInfoLog(PipelineName, GLsizei(InfoLog.size()), &LengthQuery, &InfoLog[0]); glDebugMessageInsertARB( GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 76, GL_DEBUG_SEVERITY_LOW_ARB, LengthQuery, &InfoLog[0]); } GLint ActiveAttributeMaxLength(0); GLint ActiveAttribute(0); glGetProgramiv(ProgramName, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &ActiveAttributeMaxLength); glGetProgramiv(ProgramName, GL_ACTIVE_ATTRIBUTES, &ActiveAttribute); GLsizei AttribLength(0); GLint AttribSize(0); GLenum AttribType(0); std::vector<GLchar> AttribName(ActiveAttributeMaxLength, '\0'); for(GLint i = 0; i < ActiveAttribute; ++i) { GLenum Props[3] = {GL_TYPE, GL_ARRAY_SIZE, GL_LOCATION}; GLint Params[3]; GLsizei Length(0); glGetProgramResourceiv(ProgramName, GL_PROGRAM_INPUT, i, 3, Props, 3, &Length, Params); vertexattrib VertexAttrib; glGetActiveAttrib(ProgramName, GLuint(i), GLsizei(ActiveAttributeMaxLength), &AttribLength, &AttribSize, &AttribType, &AttribName[0]); std::string NameString; NameString.insert(NameString.begin(), AttribName.begin(), AttribName.end()); std::vector<GLchar> NameSwap(ActiveAttributeMaxLength, '\0'); std::swap(AttribName, NameSwap); GLint AttribLocation = glGetAttribLocation(ProgramName, NameString.c_str()); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &VertexAttrib.Enabled); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &VertexAttrib.Binding); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_SIZE, &VertexAttrib.Size); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &VertexAttrib.Stride); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_TYPE, &VertexAttrib.Type); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &VertexAttrib.Normalized); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &VertexAttrib.Integer); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &VertexAttrib.Divisor); glGetVertexAttribiv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_LONG, &VertexAttrib.Long); glGetVertexAttribPointerv(AttribLocation, GL_VERTEX_ATTRIB_ARRAY_POINTER, &VertexAttrib.Pointer); if(VertexAttrib.Integer == GL_TRUE) { if(!( VertexAttrib.Type == GL_INT || VertexAttrib.Type == GL_INT_VEC2 || VertexAttrib.Type == GL_INT_VEC3 || VertexAttrib.Type == GL_INT_VEC4 || VertexAttrib.Type == GL_UNSIGNED_INT || VertexAttrib.Type == GL_UNSIGNED_INT_VEC2 || VertexAttrib.Type == GL_UNSIGNED_INT_VEC3 || VertexAttrib.Type == GL_UNSIGNED_INT_VEC4)) return true; if(!( VertexAttrib.Type == GL_BYTE || VertexAttrib.Type == GL_UNSIGNED_BYTE || VertexAttrib.Type == GL_SHORT || VertexAttrib.Type == GL_UNSIGNED_SHORT || VertexAttrib.Type == GL_INT || VertexAttrib.Type == GL_UNSIGNED_INT)) return true; //if(AttribSize > 1) //GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT, and GL_DOUBLE } else if(VertexAttrib.Long == GL_TRUE) { if(!( VertexAttrib.Type == GL_DOUBLE || VertexAttrib.Type == GL_DOUBLE_VEC2 || VertexAttrib.Type == GL_DOUBLE_VEC3 || VertexAttrib.Type == GL_DOUBLE_VEC4 || VertexAttrib.Type == GL_DOUBLE_MAT2 || VertexAttrib.Type == GL_DOUBLE_MAT3 || VertexAttrib.Type == GL_DOUBLE_MAT4 || VertexAttrib.Type == GL_DOUBLE_MAT2x3 || VertexAttrib.Type == GL_DOUBLE_MAT2x4 || VertexAttrib.Type == GL_DOUBLE_MAT3x2 || VertexAttrib.Type == GL_DOUBLE_MAT3x4 || VertexAttrib.Type == GL_DOUBLE_MAT4x2 || VertexAttrib.Type == GL_DOUBLE_MAT4x3)) return true; } else// if((VertexAttrib.Normalized == GL_TRUE) || (GL_VERTEX_ATTRIB_ARRAY_FLOAT == GL_TRUE)) { if(!( VertexAttrib.Type == GL_FLOAT || VertexAttrib.Type == GL_FLOAT_VEC2 || VertexAttrib.Type == GL_FLOAT_VEC3 || VertexAttrib.Type == GL_FLOAT_VEC4 || VertexAttrib.Type == GL_FLOAT_MAT2 || VertexAttrib.Type == GL_FLOAT_MAT3 || VertexAttrib.Type == GL_FLOAT_MAT4 || VertexAttrib.Type == GL_FLOAT_MAT2x3 || VertexAttrib.Type == GL_FLOAT_MAT2x4 || VertexAttrib.Type == GL_FLOAT_MAT3x2 || VertexAttrib.Type == GL_FLOAT_MAT3x4 || VertexAttrib.Type == GL_FLOAT_MAT4x2 || VertexAttrib.Type == GL_FLOAT_MAT4x3)) return true; // It could be any vertex array attribute type } printf("glGetActiveAttrib(\n\t%d, \n\t%d, \n\t%d, \n\t%d, \n\t%d, \n\t%s)\n", i, AttribLocation, AttribLength, AttribSize, AttribType, NameString.c_str()); } return Error; }
void Program::getResource(gl::GLenum programInterface, gl::GLuint index, gl::GLsizei propCount, const gl::GLenum * props, gl::GLsizei bufSize, gl::GLsizei * length, gl::GLint * params) const { checkDirty(); glGetProgramResourceiv(id(), programInterface, index, propCount, props, bufSize, length, params); }