void piglit_init(int argc, char **argv) { GLint maxMaskWords = 0, result = 0, mask = 0; int i; piglit_require_extension("GL_ARB_texture_multisample"); glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxMaskWords); for (i=0; i < maxMaskWords; i++) { glGetIntegeri_v(GL_SAMPLE_MASK_VALUE, i, &mask); if (!piglit_check_gl_error(GL_NO_ERROR)) { printf("Could not get word %d of sample mask value\n", i); piglit_report_result(PIGLIT_FAIL); } if ((GLuint)mask != ~0u) { printf("Initial mask for word %d is bogus; expected all bits set, got %08x\n", i, mask); } } if (!piglit_khr_no_error) { printf("Checking that correct errors are generated for out of bounds\n"); glGetIntegeri_v(GL_SAMPLE_MASK_VALUE, maxMaskWords, &result); if (!piglit_check_gl_error(GL_INVALID_VALUE)) piglit_report_result(PIGLIT_FAIL); } piglit_report_result(PIGLIT_PASS); }
/// \brief Return the maximum size of work group allowed on this GPU /// \link https://www.opengl.org/wiki/Compute_Shader#Limitations static glm::ivec3 get_max_work_group_size() { glm::ivec3 ret; glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &ret.x); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &ret.y); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &ret.z); return ret; }
/// \brief Return the maximum number of work group available on this GPU /// \link https://www.opengl.org/wiki/Compute_Shader#Limitations static glm::ivec3 get_max_work_group_count() { glm::ivec3 ret; glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &ret.x); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &ret.y); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &ret.z); return ret; }
static std::uint32_t GLGetUIntIndexed(GLenum param, GLuint index) { GLint attr = 0; if (HasExtension(GLExt::EXT_draw_buffers2)) glGetIntegeri_v(param, index, &attr); return static_cast<std::uint32_t>(attr); };
bool begin() { bool Validated = true; if(Validated) Validated = initProgram(); if(Validated) Validated = initBuffer(); if(Validated) Validated = initVertexArray(); if(Validated) Validated = initTexture(); if(Validated) Validated = initFramebuffer(); GLint MaxMasks = 0; glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &MaxMasks); Validated = Validated && (MaxMasks > 0); GLint Masks = 0; glGetIntegeri_v(GL_SAMPLE_MASK_VALUE, 0, &Masks); glEnable(GL_SAMPLE_MASK); glSampleMaski(0, 0xf); return Validated && this->checkError("begin"); }
inline std::enable_if_t<(N>1),std::array<int,N>> getIntegerVal(GLenum eParamName) { std::array<int,N> anVal; for(uint n=0; n<N; ++n) glGetIntegeri_v(eParamName,n,&anVal[n]); glErrorCheck; return anVal; }
bool ComputeShader::isAvailable() { GLint max_x; glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &max_x); return (glGetError() == GL_NO_ERROR && max_x > 0); }
void piglit_init(int argc, char **argv) { GLuint bo[2]; int size = 1024; GLint max_bindings; GLint junk; GLint alignment; piglit_require_extension("GL_ARB_uniform_buffer_object"); test_range(__LINE__, 0, 0, -1, -1); glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &alignment); glGenBuffers(2, bo); glBindBuffer(GL_UNIFORM_BUFFER, bo[0]); glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STATIC_READ); glBindBuffer(GL_UNIFORM_BUFFER, bo[1]); glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STATIC_READ); glBindBufferRange(GL_UNIFORM_BUFFER, 0, bo[0], 0, 1); glBindBufferRange(GL_UNIFORM_BUFFER, 1, bo[1], 2 * alignment, 3); test_range(__LINE__, 0, bo[0], 0, 1); test_range(__LINE__, 1, bo[1], 2 * alignment, 3); /* There's a bit of a contradiction in the spec. On the one * hand, "BindBufferBase is equivalent to calling * BindBufferRange with offset zero and size equal to the size * of buffer", but on the other hand, " If the parameter * (starting offset or size) was not specified when the buffer * object was bound, zero is returned". This is clarified by * the GL 4.2 specification, which says that "BindBufferBase * binds the entire buffer, even when the size of the buffer * is changed after the binding is established.", so the zero * return for the size makes sense since it's effectively * computed at render time. */ glBindBufferBase(GL_UNIFORM_BUFFER, 1, bo[1]); test_range(__LINE__, 1, bo[1], 0, 0); /* Is binding a BO of 0 valid? It's not clear to me from the * spec ("The error INVALID_OPERATION is generated by * BindBufferRange and BindBufferBase if <buffer> is not the * name of a valid buffer object.", and glIsBuffer returns * false for 0), but it seems obviously parallel to the rest * of the GL API, including glBindBuffer(), to allow it */ glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0); test_range(__LINE__, 0, 0, -1, -1); /* Test the error condition. */ glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_bindings); glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, max_bindings, &junk); if (!piglit_check_gl_error(GL_INVALID_VALUE)) pass = false; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
GLint getInteger(const GLenum pname, const GLuint index) { GLint value; glGetIntegeri_v(pname, index, &value); return value; }
GLint query::getInteger(GLenum pname, unsigned index) { GLint value; glGetIntegeri_v(pname, index, &value); CheckGLError(); return value; }
void PrintNicelyWorkGroupsCapabilities() { int workgroup_count[3]; int workgroup_size[3]; int workgroup_invocations; for (int i=0; i < 3; i++) { glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, i, &workgroup_count[i]); } printf ("DSGL: MAXIMUM WORK GROUP COUNT:\n\tx:%u\n\ty:%u\n\tz:%u\n", workgroup_size[0], workgroup_size[1], workgroup_size[2]); for (int i=0; i < 3; i++) { glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, i, &workgroup_size[i]); } printf ("DSGL: MAXIMUM WORK GROUP SIZE:\n\tx:%u\n\ty:%u\n\tz:%u\n", workgroup_size[0], workgroup_size[1], workgroup_size[2]); glGetIntegerv (GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &workgroup_invocations); printf ("DSGL: MAXIMUM WORK GROUP INVOCATIONS:\n\t%u\n", workgroup_invocations); }
void printProperties() { // Compute Shader Props int groupMax_x; int groupMax_y; int groupMax_z; int maxInvocations; glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &groupMax_x); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &groupMax_y); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &groupMax_z); glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &maxInvocations); std::cout << "Max work group size as (x,y,z): (" << groupMax_x << "," << groupMax_y << "," << groupMax_z << ")" << std::endl; std::cout << "Max work group invocations: " << maxInvocations << std::endl; // Texture Props int maxTexture; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexture); std::cout << "Max texture size: " << maxTexture << std::endl; int maxTexture3D; glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxTexture3D); std::cout << "Max 3D texture size: " << maxTexture3D << std::endl; // GLuint tex3d; // glGenTextures(1, &tex3d); // glBindTexture(GL_TEXTURE_3D, tex3d); // glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, maxTexture3D, maxTexture3D, 64, 0, GL_RGBA, GL_FLOAT, 0); int err = glGetError(); printf("%d\n", err); // int maxAtomicCountersFrag; // glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &maxAtomicCountersFrag); // std::cout << "GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: " << maxAtomicCountersFrag << std::endl; }
void StateSystem::BlendState::getGL() { GLuint stateSet = 0; separateEnable = 0; for (GLuint i = 0; i < MAX_DRAWBUFFERS; i++){ if (setBitState(separateEnable,i, glIsEnabledi( GL_BLEND, i))) stateSet++; } if (stateSet == MAX_DRAWBUFFERS){ separateEnable = 0; } GLuint numEqual = 1; for (GLuint i = 0; i < MAX_DRAWBUFFERS; i++){ glGetIntegeri_v(GL_BLEND_SRC_RGB,i,(GLint*)&blends[i].rgb.srcw); glGetIntegeri_v(GL_BLEND_DST_RGB,i,(GLint*)&blends[i].rgb.dstw); glGetIntegeri_v(GL_BLEND_EQUATION_RGB,i,(GLint*)&blends[i].rgb.equ); glGetIntegeri_v(GL_BLEND_SRC_ALPHA,i,(GLint*)&blends[i].alpha.srcw); glGetIntegeri_v(GL_BLEND_DST_ALPHA,i,(GLint*)&blends[i].alpha.dstw); glGetIntegeri_v(GL_BLEND_EQUATION_ALPHA,i,(GLint*)&blends[i].alpha.equ); if (i > 1 && memcmp(&blends[i].rgb,&blends[i-1].rgb,sizeof(blends[i].rgb))==0 && memcmp(&blends[i].alpha,&blends[i-1].alpha,sizeof(blends[i].alpha))==0){ numEqual++; } } useSeparate = numEqual != MAX_DRAWBUFFERS; //glGetFloatv(GL_BLEND_COLOR,color); }
static void test_index(int line, GLenum e, int index, int expected) { GLint val; glGetIntegeri_v(e, index, &val); if (val != expected) { printf("%s:%d: %s[%d] was %d, expected %d\n", __FILE__, line, piglit_get_gl_enum_name(e), index, val, expected); pass = false; } }
static void piglit_test_int_v(GLenum token, GLuint index, GLint limit, bool max) { char *name; GLint val = 9999; (void)!asprintf(&name, "%s[%d]", piglit_get_gl_enum_name(token), index); glGetIntegeri_v(token, index, &val); piglit_report_int(name, limit, val, (max && val <= limit) || (!max && val >= limit)); }
PIGLIT_GL_TEST_CONFIG_END /** * Test that ScissorArrayv, ScissorIndexed(v), GetIntegeri_v give the * "expected_error" gl error. Given the values for "first" and "count" * or "index" in range [first, first+count). */ static bool check_sc_index(GLuint first, GLsizei count, GLenum expected_error) { static const GLint sv[] = {0, 10, 20, 35}; GLint *mv, svGet[4]; unsigned int i; bool pass = true; const unsigned int numIterate = (expected_error == GL_NO_ERROR) ? count : 1; mv = malloc(sizeof(GLint) * 4 * count); if (mv == NULL) return false; for (i = 0; i < count; i++) { mv[i * 4] = sv[0]; mv[i * 4 + 1] = sv[1]; mv[i * 4 + 2] = sv[2]; mv[i * 4 + 3] = sv[3]; } glScissorArrayv(first, count, mv); free(mv); pass = piglit_check_gl_error(expected_error) && pass; /* only iterate multiple indices for no error case */ for (i = count; i > count - numIterate; i--) { glScissorIndexed(first + i - 1, sv[0], sv[1], sv[2], sv[3]); pass = piglit_check_gl_error(expected_error) && pass; glGetIntegeri_v(GL_SCISSOR_BOX, first + i - 1, svGet); pass = piglit_check_gl_error(expected_error) && pass; glEnablei(GL_SCISSOR_TEST, first + i - 1); pass = piglit_check_gl_error(expected_error) && pass; glDisablei(GL_SCISSOR_TEST, first + i - 1); pass = piglit_check_gl_error(expected_error) && pass; glIsEnabledi(GL_SCISSOR_TEST, first + i - 1); pass = piglit_check_gl_error(expected_error) && pass; } return pass; }
static int GetEnumOptIndex(lua_State *L, GLenum pname, uint32_t domain) /* index is optional */ { GLint data; GLuint index; if(!lua_isnoneornil(L, 2)) { index = luaL_checkinteger(L, 2); glGetIntegeri_v(pname, index, &data); } else glGetIntegerv(pname, &data); CheckError(L); return enums_push(L, domain, data); }
void StateSystem::VertexFormatState::getGL() { for (GLuint i = 0; i < MAX_VERTEXATTRIBS; i++){ GLint status = 0; glGetVertexAttribiv(i,GL_VERTEX_ATTRIB_RELATIVE_OFFSET, (GLint*)&formats[i].relativeoffset); glGetVertexAttribiv(i,GL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint*)&formats[i].size); glGetVertexAttribiv(i,GL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint*)&formats[i].type); glGetVertexAttribiv(i,GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, (GLint*)&status); formats[i].normalized = (GLboolean) status; glGetVertexAttribiv(i,GL_VERTEX_ATTRIB_ARRAY_INTEGER, (GLint*)&status); if (status){ formats[i].mode = VERTEXMODE_INT; } else{ formats[i].mode = VERTEXMODE_FLOAT; } glGetVertexAttribiv(i,GL_VERTEX_ATTRIB_BINDING, (GLint*)&formats[i].binding); } for (GLuint i = 0; i < MAX_VERTEXBINDINGS; i++){ glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR,i,(GLint*)&bindings[i].divisor); glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, i,(GLint*)&bindings[i].stride); } }
void ScanSystem::update( const Programs& progs ) { GLuint maxGroups[3]; glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT,0,(GLint*)&maxGroups[0]); //GLuint groupSize[3]; //glGetProgramiv(progs.combine, GL_COMPUTE_WORK_GROUP_SIZE, (GLint*)groupSize); maxGrpsCombine = maxGroups[0]; //glGetProgramiv(progs.offsets, GL_COMPUTE_WORK_GROUP_SIZE, (GLint*)groupSize); maxGrpsOffsets = maxGroups[0]; //glGetProgramiv(progs.prefixsum, GL_COMPUTE_WORK_GROUP_SIZE, (GLint*)groupSize); maxGrpsPrefix = maxGroups[0]; programs = progs; }
static bool check_integer(GLenum name, unsigned idx, int expect) { int v = 0xdeadcafe; glGetIntegeri_v(name, idx, &v); if (v != expect) { fprintf(stderr, "Invalid value for integer %s index %d\n" " Expected: %d\n" " Observed: %d\n", piglit_get_gl_enum_name(name), idx, expect, v); return false; } return true; }
void piglit_init(int argc, char **argv) { bool pass = true; GLint box[9 * 4] = {0}; int max; piglit_require_extension("GL_EXT_window_rectangles"); glGetIntegerv(GL_MAX_WINDOW_RECTANGLES_EXT, &max); glWindowRectanglesEXT(0, 0, NULL); if (!piglit_check_gl_error(GL_INVALID_ENUM)) pass = false; glWindowRectanglesEXT(GL_EXCLUSIVE_EXT, -1, NULL); if (!piglit_check_gl_error(GL_INVALID_VALUE)) pass = false; if (max < 9) { GLint t[4]; glWindowRectanglesEXT(GL_EXCLUSIVE_EXT, max + 1, box); if (!piglit_check_gl_error(GL_INVALID_VALUE)) pass = false; glGetIntegeri_v(GL_WINDOW_RECTANGLE_EXT, max + 1, t); if (!piglit_check_gl_error(GL_INVALID_VALUE)) pass = false; } if (max > 9) max = 9; box[2] = -1; glWindowRectanglesEXT(GL_EXCLUSIVE_EXT, max, box); if (!piglit_check_gl_error(GL_INVALID_VALUE)) pass = false; box[2] = 0; box[3] = -1; glWindowRectanglesEXT(GL_EXCLUSIVE_EXT, max, box); if (!piglit_check_gl_error(GL_INVALID_VALUE)) pass = false; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void piglit_init(int argc, char **argv) { GLuint bo[2]; int size = 1024; GLint max_bindings; GLint junk; GLint alignment; piglit_require_extension("GL_ARB_shader_storage_buffer_object"); /* If no buffer object is bound to index, zero is returned. */ test_range(__LINE__, 1, 0, 0, 0); glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment); glGenBuffers(2, bo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, bo[0]); glBufferData(GL_SHADER_STORAGE_BUFFER, size, NULL, GL_STATIC_READ); glBindBuffer(GL_SHADER_STORAGE_BUFFER, bo[1]); glBufferData(GL_SHADER_STORAGE_BUFFER, size, NULL, GL_STATIC_READ); glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, bo[0], 0, 1); glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, bo[1], 2 * alignment, 3); test_range(__LINE__, 0, bo[0], 0, 1); test_range(__LINE__, 1, bo[1], 2 * alignment, 3); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bo[1]); test_range(__LINE__, 1, bo[1], 0, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); test_range(__LINE__, 0, 0, 0, 0); /* Test the error condition. */ glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &max_bindings); glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, max_bindings, &junk); if (!piglit_check_gl_error(GL_INVALID_VALUE)) pass = false; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
/** * Test invalid values for scissor left, bottom, width, height * INVALID_VALUE for negative w,h. Test default values for left, bottom, * width, height. * OpenGL 4.3 Core section 13.6.1 ref: * "In the initial state, left = bottom = 0, and width and * height are determined by the size of the window into which the GL is * to do its rendering for all viewports. If the default framebuffer is * bound but no default framebuffer is associated with the GL context * (see chapter 4), then width and height are initially set to zero." * * "If either width or height is less than zero for any scissor rectangle, * then an INVALID_VALUE error is generated." */ static bool scissor_bounds(GLint maxVP) { GLint sc[4]; bool pass = true; int i; /* intial values for left, bottom, width, height */ for (i = 0; i < maxVP; i++) { glGetIntegeri_v(GL_SCISSOR_BOX, i, sc); if (sc[0] != 0 || sc[1] != 0 || sc[2] != piglit_width || sc[3] != piglit_height) { printf("scissor box default value wrong for idx %d\n", i); pass = false; } } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; /* make sure large values don't cause gl errors */ glScissorIndexed(0, 0x8000, 0x80000000, 0x7ffff, 0x7fffffff); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; /* negative width, height gives gl error */ sc[2] = -10; sc[3] = 0; for (i = 0; i < 2; i++) { glScissorArrayv(0, 1, sc); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glScissorIndexed(1, sc[0], sc[1], sc[2], sc[3]); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glScissorIndexedv(2, sc); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; sc[2] = 5; sc[3] = -12345; } return pass; }
void StateSystem::SampleState::getGL() { glGetIntegerv(GL_SAMPLE_COVERAGE_VALUE,(GLint*)&coverage); glGetIntegerv(GL_SAMPLE_COVERAGE_INVERT,(GLint*)&invert); glGetIntegeri_v(GL_SAMPLE_MASK_VALUE,0,(GLint*)&mask); }
static inline void dumpTransformFeedback(StateWriter &writer, GLint program) { GLint transform_feedback_varyings = 0; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &transform_feedback_varyings); if (!transform_feedback_varyings) { return; } GLint max_name_length = 0; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_name_length); std::vector<GLchar> name(max_name_length); GLint buffer_mode = GL_INTERLEAVED_ATTRIBS; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &buffer_mode); std::vector<TransformFeedbackAttrib> attribs(transform_feedback_varyings); // Calculate the offsets and strides of each attribute according to // the value of GL_TRANSFORM_FEEDBACK_BUFFER_MODE GLsizei cum_attrib_offset = 0; for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; GLsizei length = 0; GLsizei size = 0; GLenum type = GL_NONE; glGetTransformFeedbackVarying(program, slot, max_name_length, &length, &size, &type, &name[0]); attrib.name = &name[0]; const AttribDesc & desc = attrib.desc = AttribDesc(type, size); if (!desc) { return; } attrib.size = desc.arrayStride; switch (buffer_mode) { case GL_INTERLEAVED_ATTRIBS: attrib.offset = cum_attrib_offset; break; case GL_SEPARATE_ATTRIBS: attrib.offset = 0; attrib.stride = desc.arrayStride; break; default: assert(0); attrib.offset = 0; attrib.stride = 0; } cum_attrib_offset += desc.arrayStride; } if (buffer_mode == GL_INTERLEAVED_ATTRIBS) { for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; attrib.stride = cum_attrib_offset; } } GLint previous_tbo = 0; glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &previous_tbo); // Map the buffers and calculate how many vertices can they hold // XXX: We currently limit to 1024, or things can get significantly slow. unsigned numVertices = 16*1024; for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; attrib.map = NULL; if (slot == 0 || buffer_mode != GL_INTERLEAVED_ATTRIBS) { GLint tbo = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, slot, &tbo); if (!tbo) { numVertices = 0; continue; } GLint start = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_START, slot, &start); GLint size = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, slot, &size); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo); if (size == 0) { glGetBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &size); assert(size >= start); size -= start; } unsigned numAttribVertices = calcNumElements(size, attrib.offset, attrib.size, attrib.stride); numVertices = std::min(numVertices, numAttribVertices); attrib.map = (const GLbyte *)attrib.mapping.map(GL_TRANSFORM_FEEDBACK_BUFFER, tbo) + start; } else { attrib.map = attribs[0].map; } } glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, previous_tbo); // Actually dump the vertices writer.beginMember("GL_TRANSFORM_FEEDBACK"); writer.beginArray(); for (unsigned vertex = 0; vertex < numVertices; ++vertex) { writer.beginObject(); for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; if (!attrib.map) { continue; } const AttribDesc & desc = attrib.desc; assert(desc); const GLbyte *vertex_data = attrib.map + attrib.stride*vertex + attrib.offset; dumpAttribArray(writer, attrib.name, desc, vertex_data); } writer.endObject(); } writer.endArray(); writer.endMember(); }
/** * Dump an uniform that belows to an uniform block. */ static void dumpUniformBlock(StateWriter &writer, GLint program, GLint size, GLenum type, const GLchar *name, GLuint index, GLuint block_index) { GLint offset = 0; GLint array_stride = 0; GLint matrix_stride = 0; GLint is_row_major = GL_FALSE; glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_OFFSET, &offset); glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_ARRAY_STRIDE, &array_stride); glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride); glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_IS_ROW_MAJOR, &is_row_major); GLint slot = -1; glGetActiveUniformBlockiv(program, block_index, GL_UNIFORM_BLOCK_BINDING, &slot); if (slot == -1) { return; } AttribDesc desc(type, size, array_stride, matrix_stride, is_row_major); if (!desc) { return; } if (0) { GLint active_uniform_block_max_name_length = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &active_uniform_block_max_name_length); GLchar* block_name = new GLchar[active_uniform_block_max_name_length]; GLint block_data_size = 0; glGetActiveUniformBlockiv(program, index, GL_UNIFORM_BLOCK_DATA_SIZE, &block_data_size); GLsizei length = 0; glGetActiveUniformBlockName(program, index, active_uniform_block_max_name_length, &length, block_name); std::cerr << "uniform `" << name << "`, size " << size << ", type " << enumToString(desc.type) << "\n" << " block " << block_index << ", name `" << block_name << "`, size " << block_data_size << "; binding " << slot << "; \n" << " offset " << offset << ", array stride " << array_stride << ", matrix stride " << matrix_stride << ", row_major " << is_row_major << "\n" ; delete [] block_name; } GLint ubo = 0; glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, slot, &ubo); GLint start = 0; glGetIntegeri_v(GL_UNIFORM_BUFFER_START, slot, &start); BufferMapping mapping; const GLbyte *raw_data = (const GLbyte *)mapping.map(GL_UNIFORM_BUFFER, ubo); if (raw_data) { std::string qualifiedName = resolveUniformName(name, size); dumpAttribArray(writer, qualifiedName, desc, raw_data + start + offset); } }
/// <summary> /// Execute http get request /// </summary> /// <param name="idstr">OpenGL enum as string</param> /// <param name="id">OpenGL enum to query</param> /// <param name="type">Internal OpenGL enum type (glint, glstring)</param> /// <param name="dim">No of dimensions to query</param> void capsGroup::addCapability(string idstr, GLenum id, string type, int dim) { string errorValue = "n/a"; // Flush OpenGL error state glGetError(); if (type == "glint") { GLint* intVal; intVal = new GLint[dim]; glGetIntegerv(id, intVal); GLint glerr = glGetError(); if (dim == 1) { capabilities[idstr] = to_string(intVal[0]); } else { for (int i = 0; i < dim; i++) capabilities[idstr + "[" + to_string(i) + "]"] = to_string(intVal[i]); } if (glerr != GL_NO_ERROR) capabilities[idstr] = errorValue; delete[] intVal; } if (type == "glint64") { GLint64* intVal; intVal = new GLint64[dim]; glGetInteger64v(id, intVal); string valString = ""; for (int i = 0; i < dim; i++) { if (i > 0) { valString += " ,"; } valString += to_string(intVal[i]); } GLint glerr = glGetError(); capabilities[idstr] = valString; if (glerr != GL_NO_ERROR) { capabilities[idstr] = errorValue; } delete[] intVal; } if (type == "glintindex") { GLint *intVal; intVal = new GLint[dim]; for (int i = 0; i < dim; i++) glGetIntegeri_v(id, i, &intVal[i]); GLint glerr = glGetError(); if (dim == 1) { capabilities[idstr] = to_string(intVal[0]); } else { for (int i = 0; i < dim; i++) capabilities[idstr+"["+to_string(i)+"]"] = to_string(intVal[i]); } if (glerr != GL_NO_ERROR) capabilities[idstr] = errorValue; delete[] intVal; } if (type == "glintfragmentprogram") { GLint* intVal; intVal = new GLint[dim]; glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, id, intVal); string valString = ""; for (int i = 0; i < dim; i++) { if (i > 0) { valString += " ,"; } valString += to_string(intVal[i]); } GLint glerr = glGetError(); capabilities[idstr] = valString; if (glerr != GL_NO_ERROR) { capabilities[idstr] = errorValue; } delete[] intVal; } if (type == "glintvertexprogram") { GLint* intVal; intVal = new GLint[dim]; glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, id, intVal); string valString = ""; for (int i = 0; i < dim; i++) { if (i > 0) { valString += " ,"; } valString += to_string(intVal[i]); } GLint glerr = glGetError(); capabilities[idstr] = valString; if (glerr != GL_NO_ERROR) { capabilities[idstr] = errorValue; } delete[] intVal; } if (type == "glfloat") { GLfloat* floatVal; floatVal = new GLfloat[dim]; glGetFloatv(id, floatVal); string valString = ""; for (int i = 0; i < dim; i++) { if (i > 0) { valString += " ,"; } valString += to_string(floatVal[i]); } GLint glerr = glGetError(); capabilities[idstr] = valString; if (glerr != GL_NO_ERROR) { capabilities[idstr] = errorValue; } delete[] floatVal; } if (type == "glstring") { string valString = reinterpret_cast<const char*>(glGetString(id)); GLint glerr = glGetError(); capabilities[idstr] = valString; if (glerr != GL_NO_ERROR) { capabilities[idstr] = ""; } } }
void caps::initLimits() { memset(&LimitsData, 0, sizeof(LimitsData)); if(check(4, 3) || ExtensionData.ARB_compute_shader) { glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &LimitsData.MAX_COMPUTE_TEXTURE_IMAGE_UNITS); glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, &LimitsData.MAX_COMPUTE_UNIFORM_COMPONENTS); glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &LimitsData.MAX_COMPUTE_SHARED_MEMORY_SIZE); glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &LimitsData.MAX_COMPUTE_WORK_GROUP_INVOCATIONS); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &LimitsData.MAX_COMPUTE_WORK_GROUP_COUNT); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &LimitsData.MAX_COMPUTE_WORK_GROUP_SIZE); } if(check(4, 3) || (ExtensionData.ARB_compute_shader && ExtensionData.ARB_uniform_buffer_object)) { glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &LimitsData.MAX_COMPUTE_UNIFORM_BLOCKS); glGetIntegerv(GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS, &LimitsData.MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS); } if(check(4, 3) || (ExtensionData.ARB_compute_shader && ExtensionData.ARB_shader_image_load_store)) glGetIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &LimitsData.MAX_COMPUTE_IMAGE_UNIFORMS); if(check(4, 3) || (ExtensionData.ARB_compute_shader && ExtensionData.ARB_shader_atomic_counters)) { glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTERS, &LimitsData.MAX_COMPUTE_ATOMIC_COUNTERS); glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &LimitsData.MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS); } if(check(4, 3) || (ExtensionData.ARB_compute_shader && ExtensionData.ARB_shader_storage_buffer_object)) glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &LimitsData.MAX_COMPUTE_SHADER_STORAGE_BLOCKS); if(check(2, 1) || ExtensionData.ARB_vertex_shader) { glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &LimitsData.MAX_VERTEX_ATTRIBS); glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &LimitsData.MAX_VERTEX_OUTPUT_COMPONENTS); glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &LimitsData.MAX_VERTEX_TEXTURE_IMAGE_UNITS); glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &LimitsData.MAX_VERTEX_UNIFORM_COMPONENTS); glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &LimitsData.MAX_VERTEX_UNIFORM_VECTORS); } if(check(3, 2) || (ExtensionData.ARB_vertex_shader && ExtensionData.ARB_uniform_buffer_object)) { glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &LimitsData.MAX_VERTEX_UNIFORM_BLOCKS); glGetIntegerv(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, &LimitsData.MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS); } if(check(4, 2) || (ExtensionData.ARB_vertex_shader && ExtensionData.ARB_shader_atomic_counters)) glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &LimitsData.MAX_VERTEX_ATOMIC_COUNTERS); if(check(4, 3) || (ExtensionData.ARB_vertex_shader && ExtensionData.ARB_shader_storage_buffer_object)) glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &LimitsData.MAX_VERTEX_SHADER_STORAGE_BLOCKS); if(check(4, 0) || ExtensionData.ARB_tessellation_shader) { glGetIntegerv(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, &LimitsData.MAX_TESS_CONTROL_INPUT_COMPONENTS); glGetIntegerv(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, &LimitsData.MAX_TESS_CONTROL_OUTPUT_COMPONENTS); glGetIntegerv(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, &LimitsData.MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS); glGetIntegerv(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, &LimitsData.MAX_TESS_CONTROL_UNIFORM_COMPONENTS); } if(check(4, 0) || (ExtensionData.ARB_tessellation_shader && ExtensionData.ARB_uniform_buffer_object)) { glGetIntegerv(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, &LimitsData.MAX_TESS_CONTROL_UNIFORM_BLOCKS); glGetIntegerv(GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS, &LimitsData.MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS); } if(check(4, 2) || (ExtensionData.ARB_tessellation_shader && ExtensionData.ARB_shader_atomic_counters)) glGetIntegerv(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, &LimitsData.MAX_TESS_CONTROL_ATOMIC_COUNTERS); if(check(4, 3) || (ExtensionData.ARB_tessellation_shader && ExtensionData.ARB_shader_storage_buffer_object)) glGetIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &LimitsData.MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS); if(check(4, 0) || ExtensionData.ARB_tessellation_shader) { glGetIntegerv(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, &LimitsData.MAX_TESS_EVALUATION_INPUT_COMPONENTS); glGetIntegerv(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, &LimitsData.MAX_TESS_EVALUATION_OUTPUT_COMPONENTS); glGetIntegerv(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, &LimitsData.MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS); glGetIntegerv(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, &LimitsData.MAX_TESS_EVALUATION_UNIFORM_COMPONENTS); } if(check(4, 0) || (ExtensionData.ARB_tessellation_shader && ExtensionData.ARB_uniform_buffer_object)) { glGetIntegerv(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, &LimitsData.MAX_TESS_EVALUATION_UNIFORM_BLOCKS); glGetIntegerv(GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS, &LimitsData.MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS); } if(check(4, 2) || (ExtensionData.ARB_tessellation_shader && ExtensionData.ARB_shader_atomic_counters)) glGetIntegerv(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, &LimitsData.MAX_TESS_EVALUATION_ATOMIC_COUNTERS); if(check(4, 3) || (ExtensionData.ARB_tessellation_shader && ExtensionData.ARB_shader_storage_buffer_object)) glGetIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &LimitsData.MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS); if(check(3, 2) || ExtensionData.ARB_geometry_shader4) { glGetIntegerv(GL_MAX_GEOMETRY_INPUT_COMPONENTS, &LimitsData.MAX_GEOMETRY_INPUT_COMPONENTS); glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &LimitsData.MAX_GEOMETRY_OUTPUT_COMPONENTS); glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &LimitsData.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS); glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, &LimitsData.MAX_GEOMETRY_UNIFORM_COMPONENTS); } if(check(3, 2) || (ExtensionData.ARB_geometry_shader4 && ExtensionData.ARB_uniform_buffer_object)) { glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &LimitsData.MAX_GEOMETRY_UNIFORM_BLOCKS); glGetIntegerv(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, &LimitsData.MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS); } if(check(4, 0) || (ExtensionData.ARB_geometry_shader4 && ExtensionData.ARB_transform_feedback3)) glGetIntegerv(GL_MAX_VERTEX_STREAMS, &LimitsData.MAX_VERTEX_STREAMS); if(check(4, 2) || (ExtensionData.ARB_geometry_shader4 && ExtensionData.ARB_shader_atomic_counters)) glGetIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTERS, &LimitsData.MAX_GEOMETRY_ATOMIC_COUNTERS); if(check(4, 3) || (ExtensionData.ARB_geometry_shader4 && ExtensionData.ARB_shader_storage_buffer_object)) glGetIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &LimitsData.MAX_GEOMETRY_SHADER_STORAGE_BLOCKS); if(check(2, 1)) glGetIntegerv(GL_MAX_DRAW_BUFFERS, &LimitsData.MAX_DRAW_BUFFERS); if(check(2, 1) || ExtensionData.ARB_fragment_shader) { glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &LimitsData.MAX_FRAGMENT_INPUT_COMPONENTS); glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &LimitsData.MAX_FRAGMENT_UNIFORM_COMPONENTS); glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &LimitsData.MAX_FRAGMENT_UNIFORM_VECTORS); } if(check(3, 2) || (ExtensionData.ARB_fragment_shader && ExtensionData.ARB_uniform_buffer_object)) { glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &LimitsData.MAX_FRAGMENT_UNIFORM_BLOCKS); glGetIntegerv(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, &LimitsData.MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS); } if(check(3, 3) || (ExtensionData.ARB_blend_func_extended)) glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &LimitsData.MAX_DUAL_SOURCE_DRAW_BUFFERS); if(check(4, 2) || (ExtensionData.ARB_fragment_shader && ExtensionData.ARB_shader_atomic_counters)) glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &LimitsData.MAX_FRAGMENT_ATOMIC_COUNTERS); if(check(4, 3) || (ExtensionData.ARB_fragment_shader && ExtensionData.ARB_shader_storage_buffer_object)) glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &LimitsData.MAX_FRAGMENT_SHADER_STORAGE_BLOCKS); if(check(3, 0) || (ExtensionData.ARB_framebuffer_object)) glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &LimitsData.MAX_COLOR_ATTACHMENTS); if(check(4, 3) || (ExtensionData.ARB_framebuffer_no_attachments)) { glGetIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &LimitsData.MAX_FRAMEBUFFER_HEIGHT); glGetIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &LimitsData.MAX_FRAMEBUFFER_WIDTH); glGetIntegerv(GL_MAX_FRAMEBUFFER_LAYERS, &LimitsData.MAX_FRAMEBUFFER_LAYERS); glGetIntegerv(GL_MAX_FRAMEBUFFER_SAMPLES, &LimitsData.MAX_FRAMEBUFFER_SAMPLES); } if(check(4, 0) || (ExtensionData.ARB_transform_feedback3)) glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &LimitsData.MAX_TRANSFORM_FEEDBACK_BUFFERS); if(check(4, 2) || (ExtensionData.ARB_map_buffer_alignment)) glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT, &LimitsData.MIN_MAP_BUFFER_ALIGNMENT); if(ExtensionData.NV_deep_texture3D) { glGetIntegerv(GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV, &LimitsData.MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV); glGetIntegerv(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV, &LimitsData.MAX_DEEP_3D_TEXTURE_DEPTH_NV); } if(check(2, 1)) { glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &LimitsData.MAX_TEXTURE_IMAGE_UNITS); glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &LimitsData.MAX_COMBINED_TEXTURE_IMAGE_UNITS); glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &LimitsData.MAX_TEXTURE_MAX_ANISOTROPY_EXT); } if(check(3, 0) || (ExtensionData.ARB_texture_buffer_object)) glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &LimitsData.MAX_TEXTURE_BUFFER_SIZE); if(check(3, 2) || (ExtensionData.ARB_texture_multisample)) { glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &LimitsData.MAX_SAMPLE_MASK_WORDS); glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &LimitsData.MAX_COLOR_TEXTURE_SAMPLES); glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &LimitsData.MAX_DEPTH_TEXTURE_SAMPLES); glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &LimitsData.MAX_INTEGER_SAMPLES); } if(check(3, 3) || (ExtensionData.ARB_texture_rectangle)) glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, &LimitsData.MAX_RECTANGLE_TEXTURE_SIZE); if(check(2, 2) && VersionData.PROFILE == caps::COMPATIBILITY) { glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &LimitsData.MAX_VARYING_COMPONENTS); glGetIntegerv(GL_MAX_VARYING_VECTORS, &LimitsData.MAX_VARYING_VECTORS); glGetIntegerv(GL_MAX_VARYING_FLOATS, &LimitsData.MAX_VARYING_FLOATS); } if(check(3, 2)) { glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &LimitsData.MAX_COMBINED_UNIFORM_BLOCKS); glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &LimitsData.MAX_UNIFORM_BUFFER_BINDINGS); glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &LimitsData.MAX_UNIFORM_BLOCK_SIZE); glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &LimitsData.UNIFORM_BUFFER_OFFSET_ALIGNMENT); } if(check(4, 0)) { glGetIntegerv(GL_MAX_PATCH_VERTICES, &LimitsData.MAX_PATCH_VERTICES); glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &LimitsData.MAX_TESS_GEN_LEVEL); glGetIntegerv(GL_MAX_SUBROUTINES, &LimitsData.MAX_SUBROUTINES); glGetIntegerv(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS, &LimitsData.MAX_SUBROUTINE_UNIFORM_LOCATIONS); glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTERS, &LimitsData.MAX_COMBINED_ATOMIC_COUNTERS); glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &LimitsData.MAX_COMBINED_SHADER_STORAGE_BLOCKS); glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &LimitsData.MAX_PROGRAM_TEXEL_OFFSET); glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &LimitsData.MIN_PROGRAM_TEXEL_OFFSET); } if(check(4, 1)) { glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &LimitsData.NUM_PROGRAM_BINARY_FORMATS); glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &LimitsData.NUM_SHADER_BINARY_FORMATS); glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, &LimitsData.PROGRAM_BINARY_FORMATS); } if(check(4, 2)) { glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &LimitsData.MAX_COMBINED_SHADER_OUTPUT_RESOURCES); glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &LimitsData.MAX_SHADER_STORAGE_BUFFER_BINDINGS); glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &LimitsData.MAX_SHADER_STORAGE_BLOCK_SIZE); glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &LimitsData.MAX_COMBINED_SHADER_OUTPUT_RESOURCES); glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &LimitsData.SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); } if(check(4, 3)) { glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &LimitsData.MAX_COMBINED_SHADER_OUTPUT_RESOURCES); } if(check(4, 3) || ExtensionData.ARB_explicit_uniform_location) { glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &LimitsData.MAX_UNIFORM_LOCATIONS); } }
void Mercury::initRendering(void) { // OpenGL 4.3 is the minimum for compute shaders if (!requireMinAPIVersion(NvGLAPIVersionES3_1())) return; // Set Clear Color glClearColor(0.25f, 0.25f, 0.25f, 1.0f); CHECK_GL_ERROR(); NvAssetLoaderAddSearchPath("es3aep-kepler/Mercury"); const char* shaderPrefix = (getGLContext()->getConfiguration().apiVer.api == NvGLAPI::GL) ? "#version 430\n" : "#version 310 es\n"; CHECK_GL_ERROR(); { int32_t len; // Initialize Particles Render Program NvScopedShaderPrefix switched(shaderPrefix); std::string renderPartVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderPartVS.glsl"); std::string renderPartGS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderPartGS.glsl"); mParticlesRenderProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesP[2]; sourcesP[0].type = GL_VERTEX_SHADER; sourcesP[0].src = renderPartVS.c_str(); sourcesP[1].type = GL_FRAGMENT_SHADER; sourcesP[1].src = NvAssetLoaderRead("shaders/renderPartFS.glsl", len); mParticlesRenderProg->setSourceFromStrings(sourcesP, 2); NvAssetLoaderFree((char*)sourcesP[1].src); // Initialize Surface Render Program std::string renderSurfVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfVS.glsl"); std::string renderSurfGS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfGS.glsl"); std::string renderSurfFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfFS.glsl"); mSurfaceRenderProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesS[3]; sourcesS[0].type = GL_VERTEX_SHADER; sourcesS[0].src = renderSurfVS.c_str(); sourcesS[1].type = GL_GEOMETRY_SHADER_EXT; sourcesS[1].src = renderSurfGS.c_str(); sourcesS[2].type = GL_FRAGMENT_SHADER; sourcesS[2].src = renderSurfFS.c_str(); mSurfaceRenderProg->setSourceFromStrings(sourcesS, 3); std::string quadVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderQuadVS.glsl"); std::string quadFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderQuadFS.glsl"); mQuadProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesQ[2]; sourcesQ[0].type = GL_VERTEX_SHADER; sourcesQ[0].src = quadVS.c_str(); sourcesQ[1].type = GL_FRAGMENT_SHADER; sourcesQ[1].src = quadFS.c_str(); mQuadProg->setSourceFromStrings(sourcesQ, 2); std::string blurVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/blurVS.glsl"); std::string blurFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/blurFS.glsl"); mBlurProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesB[2]; sourcesB[0].type = GL_VERTEX_SHADER; sourcesB[0].src = blurVS.c_str(); sourcesB[1].type = GL_FRAGMENT_SHADER; sourcesB[1].src = blurFS.c_str(); mBlurProg->setSourceFromStrings(sourcesB, 2); } CHECK_GL_ERROR(); // Set up cubemap for skybox mSkyBoxTexID = NvImageGL::UploadTextureFromDDSFile("textures/sky_cube.dds"); glBindTexture(GL_TEXTURE_CUBE_MAP, mSkyBoxTexID); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECK_GL_ERROR(); // Initialize skybox for screen quad mScreenQuadPos = new ShaderBuffer<nv::vec4f>(4); vec4f* pos = mScreenQuadPos->map(); pos[0] = vec4f(-1.0f, -1.0f, -1.0f, 1.0f); pos[1] = vec4f( 1.0f, -1.0f, -1.0f, 1.0f); pos[2] = vec4f(-1.0f, 1.0f, -1.0f, 1.0f); pos[3] = vec4f( 1.0f, 1.0f, -1.0f, 1.0f); mScreenQuadPos->unmap(); //create ubo and initialize it with the structure data glGenBuffers( 1, &mUBO); glBindBuffer( GL_UNIFORM_BUFFER, mUBO); glBufferData( GL_UNIFORM_BUFFER, sizeof(ShaderParams), &mShaderParams, GL_STREAM_DRAW); CHECK_GL_ERROR(); //create simple single-vertex VBO float vtx_data[] = { 0.0f, 0.0f, 0.0f, 1.0f}; glGenBuffers( 1, &mVBO); glBindBuffer( GL_ARRAY_BUFFER, mVBO); glBufferData( GL_ARRAY_BUFFER, sizeof(vtx_data), vtx_data, GL_STATIC_DRAW); CHECK_GL_ERROR(); // For now, scale back the particle count on mobile. //int32_t particleCount = isMobilePlatform() ? (mNumParticles >> 2) : mNumParticles; int32_t particleCount = mNumParticles; mParticles = new ParticleSystem(particleCount, shaderPrefix); CHECK_GL_ERROR(); int cx, cy, cz; glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &cx ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &cy ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &cz ); LOGI("Max compute work group count = %d, %d, %d\n", cx, cy, cz ); int sx, sy, sz; glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &sx ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &sy ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &sz ); LOGI("Max compute work group size = %d, %d, %d\n", sx, sy, sz ); CHECK_GL_ERROR(); //Set clockwise winding glFrontFace(GL_CW); // Texture const int screen_width = getAppContext()->width(); const int screen_height = getAppContext()->height(); // Frame buffer for final scene glGenTextures(gbuffer_size, gbuffer_tex); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); for (int i = 0; i < gbuffer_size; i++) { glActiveTexture(GL_TEXTURE0 + 3 + i); glBindTexture(GL_TEXTURE_2D, gbuffer_tex[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, screen_width, screen_height, 0, GL_RGBA, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, gbuffer_tex[i], 0); } // Depth buffer glGenRenderbuffers(1, &rbo_depth); glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth); GLuint attachments[gbuffer_size]; for (int i = 0; i < gbuffer_size; i++) { attachments[i] = GL_COLOR_ATTACHMENT0 + i; } glDrawBuffers(gbuffer_size, attachments); GLenum status; if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) { LOGE("glCheckFramebufferStatus: error %p", status); exit(0); } glBindFramebuffer(GL_FRAMEBUFFER, 0); }
PIGLIT_GL_TEST_CONFIG_END void piglit_init(int argc, char **argv) { bool pass = true; GLuint bo[2]; GLint binding; piglit_require_extension("GL_ARB_uniform_buffer_object"); glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, 0, &binding); if (binding != 0) { fprintf(stderr, "Default UBO binding should be 0, was %d\n", binding); piglit_report_result(PIGLIT_FAIL); } glGenBuffers(2, bo); glBindBuffer(GL_UNIFORM_BUFFER, bo[0]); glBufferData(GL_UNIFORM_BUFFER, 4, NULL, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 0, bo[0]); glBindBuffer(GL_UNIFORM_BUFFER, bo[1]); glBufferData(GL_UNIFORM_BUFFER, 4, NULL, GL_STATIC_DRAW); glBindBufferRange(GL_UNIFORM_BUFFER, 1, bo[1], 0, 4); glDeleteBuffers(2, bo); if (glIsBuffer(bo[0]) || glIsBuffer(bo[1])) { fprintf(stderr, "Failed to delete buffers\n"); pass = false; } glGetIntegerv(GL_UNIFORM_BUFFER_BINDING, &binding); if (binding != 0) { printf("Failed to unbind glBindBuffer() buffer %d:\n" " binding set to %d, should be 0\n", bo[1], binding); pass = false; } glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, 0, &binding); if (binding != 0) { printf("Failed to unbind glBindBufferBase() buffer %d:\n" " binding set to %d, should be 0\n", bo[0], binding); pass = false; } glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, 1, &binding); if (binding != 0) { printf("Failed to unbind glBindBufferRange() buffer %d:\n" " binding set to %d, should be 0\n", bo[1], binding); pass = false; } piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }