void Renderer::OcclusionCull(const Scene * scene, const Array<SceneObject*> & scene_objects) { if (!scene->GetOcclusionCulling()) { return; } for (auto it = scene_objects.Begin(); it != scene_objects.End(); ++it) { RenderData* render_data = (*it)->GetRenderData(); if (render_data == nullptr) { continue; } if (render_data->GetMaterial() == nullptr) { continue; } //If a query was issued on an earlier or same frame and if results are //available, then update the same. If results are unavailable, do nothing if (!(*it)->IsQueryIssued()) { continue; } GLuint query_result = GL_FALSE; GLuint *query = (*it)->GetOcclusionArray(); glGetQueryObjectuiv(query[0], GL_QUERY_RESULT_AVAILABLE, &query_result); if (query_result) { GLuint pixel_count; glGetQueryObjectuiv(query[0], GL_QUERY_RESULT, &pixel_count); bool visibility = ((pixel_count & GL_TRUE) == GL_TRUE); (*it)->SetVisible(visibility); (*it)->SetQueryIssued(false); } } }
static bool probe_buffers(const GLuint *xfb, const GLuint *queries, unsigned primitive_n) { bool pass; unsigned i; GLuint query_result; float *first; float *second; const unsigned first_n = primitive_n * BUF_1_FLOAT_N; const unsigned second_n = primitive_n * BUF_2_FLOAT_N; glGetQueryObjectuiv(queries[0], GL_QUERY_RESULT, &query_result); if (query_result != primitive_n) { printf("Expected %u primitives written, got %u\n", primitive_n, query_result); piglit_report_result(PIGLIT_FAIL); } glGetQueryObjectuiv(queries[1], GL_QUERY_RESULT, &query_result); if (query_result != primitive_n) { printf("Expected %u primitives generated, got %u\n", primitive_n, query_result); piglit_report_result(PIGLIT_FAIL); } first = malloc(first_n * sizeof(float)); second = malloc(second_n * sizeof(float)); for (i = 0; i < primitive_n; ++i) { first[i * BUF_1_FLOAT_N + 0] = i + 1.0; /* x1 */ first[i * BUF_1_FLOAT_N + 1] = i + 2.0; /* x2[0] */ first[i * BUF_1_FLOAT_N + 2] = i + 3.0; /* x2[1] */ first[i * BUF_1_FLOAT_N + 3] = i + 4.0; /* x3[0] */ first[i * BUF_1_FLOAT_N + 4] = i + 5.0; /* x3[1] */ first[i * BUF_1_FLOAT_N + 5] = i + 6.0; /* x3[2] */ second[i * BUF_2_FLOAT_N + 0] = i + 7.0; /* y1 */ second[i * BUF_2_FLOAT_N + 1] = i + 8.0; /* y2[0] */ second[i * BUF_2_FLOAT_N + 2] = i + 9.0; /* y2[1] */ second[i * BUF_2_FLOAT_N + 3] = i + 10.0; /* y2[2] */ second[i * BUF_2_FLOAT_N + 4] = i + 11.0; /* y2u3] */ } pass = piglit_probe_buffer(xfb[0], GL_TRANSFORM_FEEDBACK_BUFFER, "first", 1, first_n, first); pass = piglit_probe_buffer(xfb[1], GL_TRANSFORM_FEEDBACK_BUFFER, "second", 1, second_n, second) && pass; free(first); free(second); return pass; }
/*virtual*/ void GPUTimer::stop(){ glEndQuery(GL_TIME_ELAPSED_EXT); GLuint available = 0; while (!available) { glGetQueryObjectuiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available); } unsigned int timeElapsed; glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &timeElapsed); m_time = sensor::timevalue(0,timeElapsed); }
uint64_t OGLOcclusionQuery::SamplesPassed() { GLuint available = 0; while (!available) { glGetQueryObjectuiv(query_, GL_QUERY_RESULT_AVAILABLE, &available); } GLuint ret; glGetQueryObjectuiv(query_, GL_QUERY_RESULT, &ret); return static_cast<uint64_t>(ret); }
GLuint TQuery<target>::getResultAsync(GLuint resultIfNotAvailable, GLuint id) { GLuint result; glGetQueryObjectuiv(mHandles[id], GL_QUERY_RESULT_AVAILABLE, &result); FLOG_CHECK("Could not get querry result state"); if (result) { glGetQueryObjectuiv(mHandles[id], GL_QUERY_RESULT, &result); FLOG_CHECK("Could not get query async result"); return result; } else { return resultIfNotAvailable; } }
bool OGLConditionalRender::AnySamplesPassed() { GLuint available = 0; while (!available) { glGetQueryObjectuiv(query_, GL_QUERY_RESULT_AVAILABLE, &available); } GLuint ret; glGetQueryObjectuiv(query_, GL_QUERY_RESULT, &ret); return (ret != 0); }
unsigned GPUTimer::elapsedTimeus() { if (!initialised) return 0; GLuint result; glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &result); if (result == GL_FALSE) return lastResult; glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result); lastResult = result / 1000; canSubmitQuery = true; return result / 1000; }
float CoronaVisibility (int nQuery) { GLuint nSamples = 0; GLint bAvailable = 0; int nAttempts = 2; float fIntensity; #if DBG GLint nError; #endif if (! (ogl.m_states.bOcclusionQuery && nQuery) || (CoronaStyle () != 1)) return 1; if (! (gameStates.render.bQueryCoronas || gameData.render.lights.coronaSamples [nQuery - 1])) return 0; for (;;) { glGetQueryObjectiv (gameData.render.lights.coronaQueries [nQuery - 1], GL_QUERY_RESULT_AVAILABLE_ARB, &bAvailable); if (glGetError ()) { #if DBG glGetQueryObjectiv (gameData.render.lights.coronaQueries [nQuery - 1], GL_QUERY_RESULT_AVAILABLE_ARB, &bAvailable); if ((nError = glGetError ())) #endif return 0; } if (bAvailable) break; if (!--nAttempts) return 0; G3_SLEEP (1); }; glGetQueryObjectuiv (gameData.render.lights.coronaQueries [nQuery - 1], GL_QUERY_RESULT_ARB, &nSamples); if (glGetError ()) return 0; if (gameStates.render.bQueryCoronas == 1) { #if DBG if (!nSamples) { GLint nBits; glGetQueryiv (GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &nBits); glGetQueryObjectuiv (gameData.render.lights.coronaQueries [nQuery - 1], GL_QUERY_RESULT_ARB, &nSamples); } #endif return (float) (gameData.render.lights.coronaSamples [nQuery - 1] = nSamples); } fIntensity = (float) nSamples / (float) gameData.render.lights.coronaSamples [nQuery - 1]; #if DBG if (fIntensity > 1) fIntensity = 1; #endif return (fIntensity > 1) ? 1 : (float) sqrt (fIntensity); }
void FeedbackTransformPass::DoRun() { glDisable(GL_DEPTH_TEST); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf->vbo); { Use shader(program); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query); glBeginTransformFeedback(objtype); glEnable(GL_RASTERIZER_DISCARD); out->Draw(program); glDisable(GL_RASTERIZER_DISCARD); glEndTransformFeedback(); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); // performance loss of 15ms order TODO_W("Move this query to the *start* of the transform, use the old objects in the drawing phase."); glGetQueryObjectuiv(query, GL_QUERY_RESULT, &buf->count); } glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0); swap(*buf, *out); }
// -------------------------------------------------------------------------------------------------------------------- void UntexturedObjectsGLBindlessIndirect::resolveQueries() { // Only happens the first time, and we don't need to resolve to move forward. if (m_currentQueryGet == -1) { m_currentQueryGet = 0; return; } while (1) { GLuint available = GL_FALSE; glGetQueryObjectuiv(m_queries[m_currentQueryGet], GL_QUERY_RESULT_AVAILABLE, &available); if (available == GL_FALSE && ((m_currentQueryIssue + 1) % kQueryCount) != m_currentQueryGet) { // If we're not already overlapping, can just exit if the result is unavailable. break; } GLint64 timeElapsed = 0; glGetQueryObjecti64v(m_queries[m_currentQueryGet], GL_QUERY_RESULT, &timeElapsed); console::debug("Elapsed GPU: %.2f ms\n", float(timeElapsed) / 1000000.0f); m_currentQueryGet = (m_currentQueryGet + 1) % kQueryCount; if (m_currentQueryGet == m_currentQueryIssue) { break; } } }
void IrrDriver::computeSunVisibility() { // Is the lens flare enabled & visible? Check last frame's query. bool hasgodrays = false; if (World::getWorld() != NULL) { hasgodrays = World::getWorld()->getTrack()->hasGodRays(); } if (UserConfigParams::m_light_shaft && hasgodrays) { GLuint res = 0; if (m_query_issued) glGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res); m_post_processing->setSunPixels(res); // Prepare the query for the next frame. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query); m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID); m_scene_manager->drawAll(scene::ESNRP_CAMERA); irr_driver->setPhase(GLOW_PASS); m_sun_interposer->render(); glEndQuery(GL_SAMPLES_PASSED_ARB); m_query_issued = true; m_lensflare->setStrength(res / 4000.0f); // Make sure the color mask is reset glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } }
double GpuTimer::elapsed() { glQueryCounter(inflightPairs.back().endQuery, GL_TIMESTAMP); // Query just issued is not going to be available just yet. // We'll return the oldest available result. // On startup, there won't be any available. if (inflightPairs.size() == 1) return 0.; // Check if a previously issued query is available. Since startQuery // is issued before endQuery, we check endQuery only. QueryPair qp = inflightPairs.front(); GLuint queryAvailable = GL_FALSE; glGetQueryObjectuiv(qp.endQuery, GL_QUERY_RESULT_AVAILABLE, &queryAvailable); if (queryAvailable) { availablePairs.push(qp); inflightPairs.pop(); GLuint64 startTime, endTime; glGetQueryObjectui64v(qp.startQuery, GL_QUERY_RESULT, &startTime); glGetQueryObjectui64v(qp.endQuery, GL_QUERY_RESULT, &endTime); double duration = double(endTime-startTime) * 0.001 * 0.001; // Milliseconds. return duration; } return 0.; }
void TransitionParticles::update(const ofBufferObject & blobs, const ofxTexture3d & noiseField, float now){ auto numParticles = totalVertices / every; computeShader.begin(); computeShader.setUniform1f("every", every); computeShader.setUniform1f("now", now); computeShader.setUniform1f("dt",ofGetLastFrameTime()*speed); computeShader.setUniform1f("repulsionForce", repulsion); computeShader.setUniform1f("attractionForce", attraction); computeShader.setUniform1f("elapsedTime",now); computeShader.setUniform1f("bufferSize", totalVertices); computeShader.setUniform1f("noiseSize", noiseField.texData.width); computeShader.setUniform1f("frameNum", ofGetFrameNum()); computeShader.setUniformTexture("noiseField", GL_TEXTURE_3D, noiseField.texData.textureID, 0); computeShader.dispatchCompute(numParticles / 1024 + 1, 1, 1); computeShader.end(); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, numVerticesQuery); shader.beginTransformFeedback(GL_TRIANGLES, feedbackBuffer); blobs.bindBase(GL_SHADER_STORAGE_BUFFER, 0); shader.setUniform1f("every", every); shader.setUniform1f("scale", scale); shader.setUniform4f("particleColor", color); model.drawInstanced(GL_TRIANGLES, 0, model.getNumVertices(), numParticles); shader.endTransformFeedback(feedbackBuffer); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glGetQueryObjectuiv(numVerticesQuery, GL_QUERY_RESULT, &numPrimitives); }
void LODmodel::getLODvalue() { // ================================== // occlusion query alg glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf( transformMatrix.m ); // draw bbox and query it... glBeginQuery(GL_SAMPLES_PASSED, queryID); lods[0]->drawForLOD(); glEndQuery(GL_SAMPLES_PASSED); glPopMatrix(); // decide which LOD depending on query result... GLuint result = 0; glGetQueryObjectuiv(queryID, GL_QUERY_RESULT, &result); *LODvalue = result; /* // =================================== // distance alg // get distance to camera // decide which LOD depending distance... */ }
void hge::render::GeometryUnit::draw() { #else void hge::render::GeometryUnit::draw(const math::Matrix4D<> &vp) { #endif #ifdef HGE_BASIC_QUERY_SUPPORT #ifdef HGE_CONDITIONAL_RENDERING_SUPPORT glBeginConditionalRender(queries[HGEGEOMETRYOCCLUSIONQUERYINDEX], GL_QUERY_WAIT); #else GLuint query_result = 0; glGetQueryObjectuiv(queries[HGEGEOMETRYOCCLUSIONQUERYINDEX], GL_QUERY_RESULT, &query_result); if(query_result == 0) { return; } #endif #endif //std::cout << "Render Testing." << std::endl; mesh->bindVBO(); shader->use(); texture->bind(GL_TEXTURE0); shader->setModelMatrix(modelMatrix.getConstRotateMatrix()); #ifndef HGE_BASIC_QUERY_SUPPORT auto mvp = vp * modelMatrix.getConstRotateScaleTranslateMatrix(); #endif shader->setModelViewProjectionMatrix(mvp); mesh->bindIBO(); mesh->draw(); #ifdef HGE_BASIC_QUERY_SUPPORT #ifdef HGE_CONDITIONAL_RENDERING_SUPPORT glEndConditionalRender(); #endif #endif }
//============================================================================== OcclusionQueryImpl::Result OcclusionQueryImpl::getResult() const { ANKI_ASSERT(isCreated()); Result result = Result::NOT_AVAILABLE; GLuint params; glGetQueryObjectuiv(m_glName, GL_QUERY_RESULT_AVAILABLE, ¶ms); if(params != 0) { glGetQueryObjectuiv(m_glName, GL_QUERY_RESULT, ¶ms); result = (params == 1) ? Result::VISIBLE : Result::NOT_VISIBLE; } return result; }
// This expects to only be called when the read_query is ready to be read. static void handle_ready_read_query() { // Get read_query's time delta and update total_time. GLuint time_elapsed_ns; glGetQueryObjectuiv(timer_queries[read_query], GL_QUERY_RESULT, &time_elapsed_ns); total_time += (time_elapsed_ns / 1e9f); // Find out which callbacks end at this checkpoint. const char *to = query_names[read_query]; map__key_value *pair = map__find(checkpoint_callbacks, (void *)to); if (pair == NULL) { goto finish_up; } // No callbacks end at this checkpoint. Map cbs_from_name = (Map)pair->value; // Call all callbacks ending at this checkpoint. map__for(from_cb_pair, cbs_from_name) { const char * from = (const char *) from_cb_pair->key; gl_timer__Callback cb = (gl_timer__Callback)from_cb_pair->value; map__key_value *name_time_pair = map__find(checkpoint_times, (void *)from); if (name_time_pair) { double from_time = *(double *)name_time_pair->value; cb(from, to, total_time - from_time); } } finish_up:; record_time_for_name(total_time, to); read_query = (read_query + 1) % num_timer_queries; }
void OGLFrustumCulling::Render(double time) { if (!useExternalCamera) camera.Update(); glClearBufferfv(GL_COLOR, 0, glm::value_ptr(glm::vec4(0.2f, 0.2f, 0.2f, 1.0f))); programs[1]->Use(); glm::mat4 makeHorizontal = glm::rotate(glm::mat4(1), glm::half_pi<float>(), glm::vec3(1,0,0)); glUniformMatrix4fv(programs[1]->GetUniform("MVP"), 1, GL_FALSE, glm::value_ptr(camera.GetViewProjectionMatrix() * makeHorizontal)); ground.Render(); programs[0]->Use(); vaos[0]->BindVAO(); vbos[0]->BindVBO(); glm::mat4 mvp = (useExternalCamera) ? cameraExternal.GetViewProjectionMatrix() : camera.GetViewProjectionMatrix(); glUniformMatrix4fv(programs[0]->GetUniform("MVP"), 1, GL_FALSE, glm::value_ptr(mvp)); glUniform1f(programs[0]->GetUniform("time"), (float)time); glUniform1f(programs[0]->GetUniform("amplitude"), waveAmplitude); auto planes = frustumComputer.GetFrustumPlanes(); glUniform4fv(programs[0]->GetUniform("frustumPlanes"), 6, glm::value_ptr(planes[0])); primitiveQuery.BeginQuery(); glDrawArrays(GL_POINTS, 0, totalVertices); primitiveQuery.EndQuery(); GLuint nbPoints = 0; glGetQueryObjectuiv(primitiveQuery.get(), GL_QUERY_RESULT, &nbPoints); float cullPercentage = 100.0f - (nbPoints/(float)totalVertices * 100.0f); std::cout << "Culling percentage: " << cullPercentage << std::endl; }
bool check_results(unsigned test, unsigned expect_written, const float *expect_data, GLuint q0, GLuint q1) { float *data; bool pass = true; GLuint written[2]; GLuint total; glGetQueryObjectuiv(q0, GL_QUERY_RESULT, &written[0]); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glGetQueryObjectuiv(q0, GL_QUERY_RESULT, &written[1]); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; total = written[0] + written[1]; if (total != expect_written) { fprintf(stderr, "XFB %d GL_PRIMITIVES_WRITTEN: " "Expected %d, got %d\n", test, expect_written, total); pass = false; } data = glMapBufferRange(GL_ARRAY_BUFFER, 0, 512, GL_MAP_READ_BIT); if (!piglit_check_gl_error(GL_NO_ERROR) || data == NULL) { fprintf(stderr, "XFB %d: Could not map results buffer.\n", test); pass = false; } else { unsigned i; for (i = 0; i < expect_written; i++) { if (data[i] != expect_data[i]) { fprintf(stderr, "XFB %d data %d: " "Expected %f, got %f\n", test, i, expect_data[i], data[i]); pass = false; } } glUnmapBuffer(GL_ARRAY_BUFFER); } return pass; }
unsigned int GPU_select_end(void) { unsigned int hits = 0; if (!g_query_state.use_gpu_select) { glPopName(); hits = glRenderMode(GL_RENDER); } else { int i; if (g_query_state.query_issued) { glEndQuery(GL_SAMPLES_PASSED); } for (i = 0; i < g_query_state.active_query; i++) { unsigned int result; glGetQueryObjectuiv(g_query_state.queries[i], GL_QUERY_RESULT, &result); if (result > 0) { if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) { int maxhits = g_query_state.bufsize / 4; if (hits < maxhits) { g_query_state.buffer[hits * 4] = 1; g_query_state.buffer[hits * 4 + 1] = 0xFFFF; g_query_state.buffer[hits * 4 + 2] = 0xFFFF; g_query_state.buffer[hits * 4 + 3] = g_query_state.id[i]; hits++; } else { hits = -1; break; } } else { int j; /* search in buffer and make selected object first */ for (j = 0; j < g_query_state.oldhits; j++) { if (g_query_state.buffer[j * 4 + 3] == g_query_state.id[i]) { g_query_state.buffer[j * 4 + 1] = 0; g_query_state.buffer[j * 4 + 2] = 0; } } break; } } } glDeleteQueries(g_query_state.num_of_queries, g_query_state.queries); MEM_freeN(g_query_state.queries); MEM_freeN(g_query_state.id); glPopAttrib(); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } g_query_state.select_is_active = false; return hits; }
static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, void *data, DWORD size, DWORD flags) { struct wined3d_timestamp_query *tq = query->extendedData; struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context; GLuint available; GLuint64 timestamp; HRESULT res; TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); if (!tq->context) query->state = QUERY_CREATED; if (query->state == QUERY_CREATED) { /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */ TRACE("Query wasn't yet started, returning S_OK.\n"); timestamp = 0; fill_query_data(data, size, ×tamp, sizeof(timestamp)); return S_OK; } if (tq->context->tid != GetCurrentThreadId()) { FIXME("%p Wrong thread, returning 1.\n", query); timestamp = 1; fill_query_data(data, size, ×tamp, sizeof(timestamp)); return S_OK; } context = context_acquire(query->device, tq->context->current_rt); GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available)); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); TRACE("available %#x.\n", available); if (available) { if (size) { GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); fill_query_data(data, size, ×tamp, sizeof(timestamp)); } res = S_OK; } else { res = S_FALSE; } context_release(context); return res; }
bool GPUClock::timeAvailable() { if(!mStopped) return false; GLuint status; glGetQueryObjectuiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &status); return status == GL_TRUE; }
static void fgl_stats_end_recording(void) { unsigned i; for(i=0 ; i<11 ; ++i) glEndQuery(fgl_stats.targets[i]); for(i=0 ; i<11 ; ++i) glGetQueryObjectuiv(fgl_stats.names[i], GL_QUERY_RESULT, fgl_stats.results + i); }
GLuint Query::get(const GLenum pname) const { GLuint value = 0; glGetQueryObjectuiv(id(), pname, &value); return value; }
bool AbstractQuery::resultAvailable() { GLuint result; #ifndef MAGNUM_TARGET_GLES2 glGetQueryObjectuiv(_id, GL_QUERY_RESULT_AVAILABLE, &result); #else glGetQueryObjectuivEXT(_id, GL_QUERY_RESULT_AVAILABLE_EXT, &result); #endif return result == GL_TRUE; }
template<> UnsignedInt AbstractQuery::result<UnsignedInt>() { UnsignedInt result; #ifndef MAGNUM_TARGET_GLES2 glGetQueryObjectuiv(_id, GL_QUERY_RESULT, &result); #else glGetQueryObjectuivEXT(_id, GL_QUERY_RESULT_EXT, &result); #endif return result; }
bool Query::available() { if (!resultAvailable) { GLuint result; glGetQueryObjectuiv(id, GL_QUERY_RESULT_AVAILABLE, &result); resultAvailable = result != 0; } return resultAvailable; }
unsigned int occlusion_query::result() { assert(state_ != inactive); assert(id_ != 0); GLuint count (0); glCheck(glGetQueryObjectuiv(id_, GL_QUERY_RESULT, &count)); return count; }
unsigned int GpuQuery::GetResult() const { Context::EnsureContext(); GLuint result; glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result); return result; }
enum piglit_result piglit_display(void) { bool pass = true; GLfloat *v; int i; GLuint q, num_prims; glClear(GL_COLOR_BUFFER_BIT); glGenQueries(1, &q); glBeginQuery(GL_PRIMITIVES_GENERATED_EXT, q); glBeginTransformFeedback(GL_POINTS); glBindBuffer(GL_ARRAY_BUFFER, vert_buf); glVertexPointer(3, GL_FLOAT, 0, 0); glEnable(GL_VERTEX_ARRAY); glDrawArrays(GL_POINTS, 0, 3); glEndTransformFeedback(); glEndQuery(GL_PRIMITIVES_GENERATED); glGetQueryObjectuiv(q, GL_QUERY_RESULT, &num_prims); glDeleteQueries(1, &q); printf("%u primitives generated:\n", num_prims); if (num_prims != NUM_VERTS) { printf("Incorrect number of prims generated.\n"); printf("Found %u, expected %u\n", num_prims, NUM_VERTS); pass = false; } glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, xfb_buf); v = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, GL_READ_ONLY); for (i = 0; i < num_prims; i++) { printf("vertex %2d: pos %5.2g, %5.2g, %5.2g, %5.2g " "color %5.2g, %5.2g, %5.2g, %5.2g\n", i, v[i*8+0], v[i*8+1], v[i*8+2], v[i*8+3], v[i*8+4], v[i*8+5], v[i*8+6], v[i*8+7]); /* spot-check results */ if (!equal(v[i*8+1], 0.1)) { printf("Incorrect Y coord for point %d: %f\n", i, v[i*8+1]); pass = false; } if (!equal(v[i*8+4], 0.9)) { printf("Incorrect red value for point %d: %f\n", i, v[i*8+4]); pass = false; } } glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT); piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }