Mesa (master): r300: OQ rework

Dave Airlie airlied at kemper.freedesktop.org
Tue Aug 18 10:11:13 UTC 2009


Module: Mesa
Branch: master
Commit: 9ad76e9479c9c3cb8b2947d5144de33bb31197b8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9ad76e9479c9c3cb8b2947d5144de33bb31197b8

Author: Dave Airlie <airlied at redhat.com>
Date:   Sun Aug 16 18:42:24 2009 +1000

r300: OQ rework

Move to common code base so radeon/r200 can add support for this.
Make OQ start a state emitted like all normal state, and make no-tcl
flushing work in proper places.

Really need a generic post emit space reservation mechanism like max_state
so we can reserve some space for the emit

this code passes demos/arbocclude, piglit occlusion query and
glean occlusion query with TCL and NO-TCL on my rv530.

---

 src/mesa/drivers/dri/r300/Makefile                 |    4 +-
 src/mesa/drivers/dri/r300/r300_cmdbuf.c            |   12 +
 src/mesa/drivers/dri/r300/r300_context.c           |   96 +++++++-
 src/mesa/drivers/dri/r300/r300_context.h           |   22 +--
 src/mesa/drivers/dri/r300/r300_draw.c              |    5 -
 src/mesa/drivers/dri/r300/r300_ioctl.c             |   13 +-
 src/mesa/drivers/dri/r300/r300_queryobj.c          |  250 --------------------
 src/mesa/drivers/dri/r300/r300_queryobj.h          |   34 ---
 src/mesa/drivers/dri/r300/r300_render.c            |    1 -
 src/mesa/drivers/dri/r300/r300_state.c             |    2 +-
 src/mesa/drivers/dri/r300/radeon_queryobj.c        |    1 +
 src/mesa/drivers/dri/r300/radeon_queryobj.h        |    1 +
 src/mesa/drivers/dri/radeon/radeon_common.c        |    6 +
 .../drivers/dri/radeon/radeon_common_context.c     |    2 +
 .../drivers/dri/radeon/radeon_common_context.h     |   20 ++-
 src/mesa/drivers/dri/radeon/radeon_queryobj.c      |  216 +++++++++++++++++
 src/mesa/drivers/dri/radeon/radeon_queryobj.h      |   55 +++++
 17 files changed, 411 insertions(+), 329 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index 77b3d16..188efcb 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -37,7 +37,8 @@ RADEON_COMMON_SOURCES = \
 	radeon_mipmap_tree.c \
 	radeon_span.c \
 	radeon_fbo.c \
-	radeon_buffer_objects.c
+	radeon_buffer_objects.c \
+	radeon_queryobj.c
 
 DRIVER_SOURCES = \
 		 radeon_screen.c \
@@ -54,7 +55,6 @@ DRIVER_SOURCES = \
 		 r300_shader.c \
 		 r300_emit.c \
 		 r300_swtcl.c \
-		 r300_queryobj.c \
 		 $(RADEON_COMMON_SOURCES) \
 		 $(EGL_SOURCES) \
 		 $(CS_SOURCES)
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 9042bbc..1ca9eac 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -54,6 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_mipmap_tree.h"
 #include "r300_state.h"
 #include "radeon_reg.h"
+#include "radeon_queryobj.h"
 
 /** # of dwords reserved for additional instructions that may need to be written
  * during flushing.
@@ -793,6 +794,17 @@ void r300InitCmdBuf(r300ContextPtr r300)
 	r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =
 	    cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, 0);
 
+	radeon_init_query_stateobj(&r300->radeon, R300_QUERYOBJ_CMDSIZE);
+	if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) {
+		r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, RV530_FG_ZBREG_DEST, 1);
+		r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_0] = RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL;
+	} else {
+		r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_REG_DEST, 1);
+		r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_0] = R300_RASTER_PIPE_SELECT_ALL;
+	}
+	r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_ZPASS_DATA, 1);
+	r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_1] = 0;
+
 	r300->radeon.hw.is_dirty = GL_TRUE;
 	r300->radeon.hw.all_dirty = GL_TRUE;
 
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 91fa77a..7508de6 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -64,11 +64,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_ioctl.h"
 #include "r300_tex.h"
 #include "r300_emit.h"
-#include "r300_queryobj.h"
 #include "r300_swtcl.h"
 #include "radeon_bocs_wrapper.h"
 #include "radeon_buffer_objects.h"
-
+#include "radeon_queryobj.h"
 
 #include "vblank.h"
 #include "utils.h"
@@ -234,6 +233,85 @@ static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
 		r300->radeon.Fallback &= ~bit;
 }
 
+static void r300_emit_query_finish(radeonContextPtr radeon)
+{
+	r300ContextPtr r300 = (r300ContextPtr)radeon;
+	struct radeon_query_object *query = radeon->query.current;
+	BATCH_LOCALS(radeon);
+
+	BEGIN_BATCH_NO_AUTOSTATE(3 * 2 *r300->num_z_pipes + 2);
+	switch (r300->num_z_pipes) {
+	case 4:
+		OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
+		OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+		OUT_BATCH_RELOC(0, query->bo, query->curr_offset+3*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+	case 3:
+		OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_2);
+		OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+		OUT_BATCH_RELOC(0, query->bo, query->curr_offset+2*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+	case 2:
+		if (r300->radeon.radeonScreen->chip_family <= CHIP_FAMILY_RV380) {
+			OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
+		} else {
+			OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_1);
+		}
+		OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+		OUT_BATCH_RELOC(0, query->bo, query->curr_offset+1*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+	case 1:
+	default:
+		OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_0);
+		OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+		OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+		break;
+	}
+	OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL);
+	END_BATCH();
+	query->curr_offset += r300->num_z_pipes * sizeof(uint32_t);
+	assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+	query->emitted_begin = GL_FALSE;
+}
+
+static void rv530_emit_query_finish_single_z(radeonContextPtr radeon)
+{
+	r300ContextPtr r300 = (r300ContextPtr)radeon;
+	BATCH_LOCALS(radeon);
+	struct radeon_query_object *query = radeon->query.current;
+
+	BEGIN_BATCH_NO_AUTOSTATE(8);
+	OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
+	OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+	OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+	OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
+	END_BATCH();
+
+	query->curr_offset += sizeof(uint32_t);
+	assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+	query->emitted_begin = GL_FALSE;
+}
+
+#if 0
+static void rv530_emit_query_finish_double_z(radeonContextPtr radeon)
+{
+	r300ContextPtr r300 = (r300ContextPtr)radeon;
+	BATCH_LOCALS(radeon);
+	struct radeon_query_object *query = radeon->query.current;
+
+	BEGIN_BATCH_NO_AUTOSTATE(6);
+	OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
+	OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+	OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+	OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
+	OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+	OUT_BATCH_RELOC(0, query->bo, query->curr_offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+	OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
+	END_BATCH();
+
+	query->curr_offset += 2 * sizeof(uint32_t);
+	assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+	query->emitted_begin = GL_FALSE;
+}
+#endif
+
 static void r300_init_vtbl(radeonContextPtr radeon)
 {
 	radeon->vtbl.get_lock = r300_get_lock;
@@ -242,6 +320,12 @@ static void r300_init_vtbl(radeonContextPtr radeon)
 	radeon->vtbl.swtcl_flush = r300_swtcl_flush;
 	radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms;
 	radeon->vtbl.fallback = r300_fallback;
+	if (radeon->radeonScreen->chip_family == CHIP_FAMILY_RV530)
+		/* single Z gives me correct results on my hw need to check if we ever need
+		 * double z */
+		radeon->vtbl.emit_query_finish = rv530_emit_query_finish_single_z;
+	else
+		radeon->vtbl.emit_query_finish = r300_emit_query_finish;
 }
 
 static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
@@ -361,8 +445,7 @@ static void r300InitGLExtensions(GLcontext *ctx)
 		_mesa_disable_extension(ctx, "GL_EXT_texture_compression_s3tc");
 	}
 
-	if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries ||
-		!r300->options.hw_tcl_enabled) {
+	if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries) {
 		_mesa_disable_extension(ctx, "GL_ARB_occlusion_query");
 	}
 }
@@ -389,6 +472,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 
 	r300ParseOptions(r300, screen);
 
+	r300->radeon.radeonScreen = screen;
 	r300_init_vtbl(&r300->radeon);
 
 	_mesa_init_driver_functions(&functions);
@@ -396,7 +480,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 	r300InitStateFuncs(&functions);
 	r300InitTextureFuncs(&functions);
 	r300InitShaderFuncs(&functions);
-	r300InitQueryObjFunctions(&functions);
+	radeonInitQueryObjFunctions(&functions);
 	radeonInitBufferObjectFuncs(&functions);
 
 	if (!radeonInitContext(&r300->radeon, &functions,
@@ -453,8 +537,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 
 	r300InitGLExtensions(ctx);
 
-	make_empty_list(&r300->query.not_flushed_head);
-
 	return GL_TRUE;
 }
 
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 3ba3426..65e0d46 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -290,6 +290,12 @@ typedef struct r300_context *r300ContextPtr;
 #define R300_TEX_CMDSIZE	(MAX_TEXTURE_UNITS+1)
 */
 
+#define R300_QUERYOBJ_CMD_0  0
+#define R300_QUERYOBJ_DATA_0 1
+#define R300_QUERYOBJ_CMD_1  2
+#define R300_QUERYOBJ_DATA_1  3
+#define R300_QUERYOBJ_CMDSIZE  4
+
 /**
  * Cache for hardware register state.
  */
@@ -380,7 +386,6 @@ struct r300_hw_state {
 		struct radeon_state_atom border_color;
 	} tex;
 	struct radeon_state_atom txe;	/* tex enable (4104) */
-
 	radeonTexObj *textures[R300_MAX_TEXTURE_UNITS];
 };
 
@@ -505,15 +510,6 @@ struct r300_index_buffer {
 	GLuint count;
 };
 
-struct r300_query_object {
-	struct gl_query_object Base;
-	struct radeon_bo *bo;
-	int curr_offset;
-	GLboolean emitted_begin;
-
-	/* Double linked list of not flushed query objects */
-	struct r300_query_object *prev, *next;
-};
 
 /**
  * \brief R300 context structure.
@@ -549,12 +545,6 @@ struct r300_context {
 	uint32_t fallback;
 
 	DECLARE_RENDERINPUTS(render_inputs_bitset);
-
-	struct {
-		struct r300_query_object *current;
-		struct r300_query_object not_flushed_head;
-	} query;
-
 	int num_z_pipes;
 };
 
diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c
index d524d60..239cfe1 100644
--- a/src/mesa/drivers/dri/r300/r300_draw.c
+++ b/src/mesa/drivers/dri/r300/r300_draw.c
@@ -36,7 +36,6 @@
 #include "r300_context.h"
 #include "r300_emit.h"
 #include "r300_render.h"
-#include "r300_queryobj.h"
 #include "r300_state.h"
 #include "r300_tex.h"
 
@@ -583,16 +582,12 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
 	r300EmitCacheFlush(r300);
 	radeonEmitState(&r300->radeon);
 
-	r300EmitQueryBegin(ctx);
-
 	for (i = 0; i < nr_prims; ++i) {
 		r300RunRenderPrimitive(ctx, prim[i].start, prim[i].start + prim[i].count, prim[i].mode);
 	}
 
 	r300EmitCacheFlush(r300);
 
-	r300EmitQueryEnd(ctx);
-
 	r300FreeData(ctx);
 
 	return GL_TRUE;
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index da801f4..7ab6928 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -57,7 +57,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_reg.h"
 #include "r300_emit.h"
 #include "r300_context.h"
-#include "r300_queryobj.h"
 
 #include "vblank.h"
 
@@ -755,19 +754,9 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
 	}
 }
 
-static void r300Flush(GLcontext *ctx)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-
-	radeonFlush(ctx);
-
-	make_empty_list(&r300->query.not_flushed_head);
-}
-
-
 void r300InitIoctlFuncs(struct dd_function_table *functions)
 {
 	functions->Clear = r300Clear;
 	functions->Finish = radeonFinish;
-	functions->Flush = r300Flush;
+	functions->Flush = radeonFlush;
 }
diff --git a/src/mesa/drivers/dri/r300/r300_queryobj.c b/src/mesa/drivers/dri/r300/r300_queryobj.c
deleted file mode 100644
index df1fb32..0000000
--- a/src/mesa/drivers/dri/r300/r300_queryobj.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright © 2008-2009 Maciej Cencora <m.cencora at gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Maciej Cencora <m.cencora at gmail.com>
- *
- */
-
-#include "r300_queryobj.h"
-#include "r300_emit.h"
-
-#include "main/imports.h"
-#include "main/simple_list.h"
-
-#define DDEBUG 0
-
-#define PAGE_SIZE 4096
-
-static void r300QueryGetResult(GLcontext *ctx, struct gl_query_object *q)
-{
-	struct r300_query_object *query = (struct r300_query_object *)q;
-	uint32_t *result;
-	int i;
-
-	if (DDEBUG) fprintf(stderr, "%s: query id %d, result %d\n", __FUNCTION__, query->Base.Id, (int) query->Base.Result);
-
-	radeon_bo_map(query->bo, GL_FALSE);
-
-	result = query->bo->ptr;
-
-	query->Base.Result = 0;
-	for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
-		query->Base.Result += result[i];
-		if (DDEBUG) fprintf(stderr, "result[%d] = %d\n", i, result[i]);
-	}
-
-	radeon_bo_unmap(query->bo);
-}
-
-static struct gl_query_object * r300NewQueryObject(GLcontext *ctx, GLuint id)
-{
-	struct r300_query_object *query;
-
-	query = _mesa_calloc(sizeof(struct r300_query_object));
-
-	query->Base.Id = id;
-	query->Base.Result = 0;
-	query->Base.Active = GL_FALSE;
-	query->Base.Ready = GL_TRUE;
-
-	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, query->Base.Id);
-
-	return &query->Base;
-}
-
-static void r300DeleteQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-	struct r300_query_object *query = (struct r300_query_object *)q;
-
-	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
-
-	if (query->bo) {
-		radeon_bo_unref(query->bo);
-	}
-
-	_mesa_free(query);
-}
-
-static void r300BeginQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	struct r300_query_object *query = (struct r300_query_object *)q;
-
-	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
-
-	assert(r300->query.current == NULL);
-
-	if (!query->bo) {
-		query->bo = radeon_bo_open(r300->radeon.radeonScreen->bom, 0, PAGE_SIZE, PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0);
-	}
-	query->curr_offset = 0;
-
-	r300->query.current = query;
-	insert_at_tail(&r300->query.not_flushed_head, query);
-}
-
-static void r300EndQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-
-	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
-
-	r300EmitQueryEnd(ctx);
-
-	r300->query.current = NULL;
-}
-
-static void r300WaitQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	struct r300_query_object *tmp, *query = (struct r300_query_object *)q;
-
-	/* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
-	{
-		GLboolean found = GL_FALSE;
-		foreach(tmp, &r300->query.not_flushed_head) {
-			if (tmp == query) {
-				found = GL_TRUE;
-				break;
-			}
-		}
-
-		if (found)
-			ctx->Driver.Flush(ctx);
-	}
-
-	if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
-
-	r300QueryGetResult(ctx, q);
-
-	query->Base.Ready = GL_TRUE;
-}
-
-
-/**
- * TODO:
- * should check if bo is idle, bo there's no interface to do it
- * just wait for result now
- */
-static void r300CheckQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
-
-	r300WaitQuery(ctx, q);
-}
-
-void r300EmitQueryBegin(GLcontext *ctx)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	struct r300_query_object *query = r300->query.current;
-	BATCH_LOCALS(&r300->radeon);
-
-	if (!query || query->emitted_begin)
-		return;
-
-	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, query->Base.Id);
-
-	if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) {
-		BEGIN_BATCH_NO_AUTOSTATE(4);
-		OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
-		OUT_BATCH_REGVAL(R300_ZB_ZPASS_DATA, 0);
-		END_BATCH();
-	} else {
-		BEGIN_BATCH_NO_AUTOSTATE(4);
-		OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL);
-		OUT_BATCH_REGVAL(R300_ZB_ZPASS_DATA, 0);
-		END_BATCH();
-	}
-
-	query->emitted_begin = GL_TRUE;
-}
-
-void r300EmitQueryEnd(GLcontext *ctx)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	struct r300_query_object *query = r300->query.current;
-	BATCH_LOCALS(&r300->radeon);
-
-	if (!query || !query->emitted_begin)
-		return;
-
-	if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, query->Base.Id, query->bo, query->curr_offset);
-
-	radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
-								  query->bo,
-								  0, RADEON_GEM_DOMAIN_GTT);
-
-	if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) {
-		BEGIN_BATCH_NO_AUTOSTATE(14);
-		OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
-		OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-		OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
-		OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
-		OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-		OUT_BATCH_RELOC(0, query->bo, query->curr_offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
-		OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
-		END_BATCH();
-	} else {
-		BEGIN_BATCH_NO_AUTOSTATE(3 * 2 *r300->num_z_pipes + 2);
-		switch (r300->num_z_pipes) {
-			case 4:
-				OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
-				OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-				OUT_BATCH_RELOC(0, query->bo, query->curr_offset+3*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
-			case 3:
-				OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_2);
-				OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-				OUT_BATCH_RELOC(0, query->bo, query->curr_offset+2*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
-			case 2:
-				if (r300->radeon.radeonScreen->chip_family <= CHIP_FAMILY_RV380) {
-					OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
-				} else {
-					OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_1);
-				}
-				OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-				OUT_BATCH_RELOC(0, query->bo, query->curr_offset+1*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
-			case 1:
-			default:
-				OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_0);
-				OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-				OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
-				break;
-		}
-		OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL);
-		END_BATCH();
-	}
-
-	query->curr_offset += r300->num_z_pipes * sizeof(uint32_t);
-	assert(query->curr_offset < PAGE_SIZE);
-	query->emitted_begin = GL_FALSE;
-}
-
-void r300InitQueryObjFunctions(struct dd_function_table *functions)
-{
-	functions->NewQueryObject = r300NewQueryObject;
-	functions->DeleteQuery = r300DeleteQuery;
-	functions->BeginQuery = r300BeginQuery;
-	functions->EndQuery = r300EndQuery;
-	functions->CheckQuery = r300CheckQuery;
-	functions->WaitQuery = r300WaitQuery;
-}
diff --git a/src/mesa/drivers/dri/r300/r300_queryobj.h b/src/mesa/drivers/dri/r300/r300_queryobj.h
deleted file mode 100644
index f301f0b..0000000
--- a/src/mesa/drivers/dri/r300/r300_queryobj.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright © 2008 Maciej Cencora <m.cencora at gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Maciej Cencora <m.cencora at gmail.com>
- *
- */
-
-#include "main/imports.h"
-#include "r300_context.h"
-
-extern void r300EmitQueryBegin(GLcontext *ctx);
-extern void r300EmitQueryEnd(GLcontext *ctx);
-
-extern void r300InitQueryObjFunctions(struct dd_function_table *functions);
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 45330cd..e1a6fae 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -76,7 +76,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_tex.h"
 #include "r300_emit.h"
 #include "r300_fragprog_common.h"
-#include "r300_queryobj.h"
 #include "r300_swtcl.h"
 
 /**
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 6081c33..ce0666b 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -471,7 +471,7 @@ static void r300SetEarlyZState(GLcontext * ctx)
 		topZ = R300_ZTOP_DISABLE;
 	else if (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->UsesKill)
 		topZ = R300_ZTOP_DISABLE;
-	else if (r300->query.current)
+	else if (r300->radeon.query.current)
 		topZ = R300_ZTOP_DISABLE;
 
 	if (topZ != r300->hw.zstencil_format.cmd[2]) {
diff --git a/src/mesa/drivers/dri/r300/radeon_queryobj.c b/src/mesa/drivers/dri/r300/radeon_queryobj.c
new file mode 120000
index 0000000..1d6ebc1
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_queryobj.c
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/radeon_queryobj.h b/src/mesa/drivers/dri/r300/radeon_queryobj.h
new file mode 120000
index 0000000..8f6f842
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_queryobj.h
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.h
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 0614c89..0e9a1ae 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -83,6 +83,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_lock.h"
 #include "radeon_drm.h"
 #include "radeon_mipmap_tree.h"
+#include "radeon_queryobj.h"
 
 #define DEBUG_CMDBUF         0
 
@@ -1072,6 +1073,9 @@ void radeonFlush(GLcontext *ctx)
 			}
 		}
 	}
+
+	make_empty_list(&radeon->query.not_flushed_head);
+
 }
 
 /* Make sure all commands have been sent to the hardware and have
@@ -1128,6 +1132,8 @@ int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller)
 			__FUNCTION__, caller, rmesa->numClipRects);
 	}
 
+	radeonEmitQueryEnd(rmesa->glCtx);
+
 	if (rmesa->cmdbuf.cs->cdw) {
 		ret = radeon_cs_emit(rmesa->cmdbuf.cs);
 		rmesa->hw.all_dirty = GL_TRUE;
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index c0abcbf..3562209 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -263,6 +263,8 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
 		radeon->texture_compressed_row_align = 64;
 	}
 
+	make_empty_list(&radeon->query.not_flushed_head);
+
 	return GL_TRUE;
 }
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index ee46c1f..a9480cd 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -163,6 +163,7 @@ struct radeon_hw_state {
   	/* Head of the linked list of state atoms. */
 	struct radeon_state_atom atomlist;
 	int max_state_size;	/* Number of bytes necessary for a full state emit. */
+	int max_post_flush_size; /* Number of bytes necessary for post flushing emits */
 	GLboolean is_dirty, all_dirty;
 };
 
@@ -254,6 +255,17 @@ static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj)
 	return (radeonTexObj*)texObj;
 }
 
+/* occlusion query */
+struct radeon_query_object {
+	struct gl_query_object Base;
+	struct radeon_bo *bo;
+	int curr_offset;
+	GLboolean emitted_begin;
+
+	/* Double linked list of not flushed query objects */
+	struct radeon_query_object *prev, *next;
+};
+
 /* Need refcounting on dma buffers:
  */
 struct radeon_dma_buffer {
@@ -500,6 +512,12 @@ struct radeon_context {
    struct dri_metaops meta;
 
    struct {
+	struct radeon_query_object *current;
+	struct radeon_query_object not_flushed_head;
+	struct radeon_state_atom queryobj;
+   } query;
+
+   struct {
 	   void (*get_lock)(radeonContextPtr radeon);
 	   void (*update_viewport_offset)(GLcontext *ctx);
 	   void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa);
@@ -508,6 +526,7 @@ struct radeon_context {
 	   void (*pre_emit_state)(radeonContextPtr rmesa);
 	   void (*fallback)(GLcontext *ctx, GLuint bit, GLboolean mode);
 	   void (*free_context)(GLcontext *ctx);
+	   void (*emit_query_finish)(radeonContextPtr radeon);
    } vtbl;
 };
 
@@ -523,7 +542,6 @@ static inline __DRIdrawablePrivate* radeon_get_readable(radeonContextPtr radeon)
 	return radeon->dri.context->driReadablePriv;
 }
 
-
 /**
  * This function takes a float and packs it into a uint32_t
  */
diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.c b/src/mesa/drivers/dri/radeon/radeon_queryobj.c
new file mode 100644
index 0000000..7025194
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_queryobj.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright © 2008-2009 Maciej Cencora <m.cencora at gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Maciej Cencora <m.cencora at gmail.com>
+ *
+ */
+#include "radeon_common.h"
+#include "radeon_queryobj.h"
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+
+#define DDEBUG 0
+
+#define PAGE_SIZE 4096
+
+static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q)
+{
+	struct radeon_query_object *query = (struct radeon_query_object *)q;
+	uint32_t *result;
+	int i;
+
+	if (DDEBUG) fprintf(stderr, "%s: query id %d, result %d\n", __FUNCTION__, query->Base.Id, (int) query->Base.Result);
+
+	radeon_bo_map(query->bo, GL_FALSE);
+
+	result = query->bo->ptr;
+
+	query->Base.Result = 0;
+	for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
+		query->Base.Result += result[i];
+		if (DDEBUG) fprintf(stderr, "result[%d] = %d\n", i, result[i]);
+	}
+
+	radeon_bo_unmap(query->bo);
+}
+
+static struct gl_query_object * radeonNewQueryObject(GLcontext *ctx, GLuint id)
+{
+	struct radeon_query_object *query;
+
+	query = _mesa_calloc(sizeof(struct radeon_query_object));
+
+	query->Base.Id = id;
+	query->Base.Result = 0;
+	query->Base.Active = GL_FALSE;
+	query->Base.Ready = GL_TRUE;
+
+	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, query->Base.Id);
+
+	return &query->Base;
+}
+
+static void radeonDeleteQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+	struct radeon_query_object *query = (struct radeon_query_object *)q;
+
+	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+	if (query->bo) {
+		radeon_bo_unref(query->bo);
+	}
+
+	_mesa_free(query);
+}
+
+static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+	struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
+
+	/* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
+	{
+		GLboolean found = GL_FALSE;
+		foreach(tmp, &radeon->query.not_flushed_head) {
+			if (tmp == query) {
+				found = GL_TRUE;
+				break;
+			}
+		}
+
+		if (found)
+			ctx->Driver.Flush(ctx);
+	}
+
+	if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
+
+	radeonQueryGetResult(ctx, q);
+
+	query->Base.Ready = GL_TRUE;
+}
+
+
+static void radeonBeginQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+	struct radeon_query_object *query = (struct radeon_query_object *)q;
+
+	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+	assert(radeon->query.current == NULL);
+
+	if (radeon->dma.flush)
+		radeon->dma.flush(radeon->glCtx);
+
+	if (!query->bo) {
+		query->bo = radeon_bo_open(radeon->radeonScreen->bom, 0, PAGE_SIZE, PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0);
+	}
+	query->curr_offset = 0;
+
+	radeon->query.current = query;
+
+	radeon->query.queryobj.dirty = GL_TRUE;
+	insert_at_tail(&radeon->query.not_flushed_head, query);
+
+}
+
+void radeonEmitQueryEnd(GLcontext *ctx)
+{
+	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+	struct radeon_query_object *query = radeon->query.current;
+
+	if (!query)
+		return;
+
+	if (query->emitted_begin == GL_FALSE)
+		return;
+
+	if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, query->Base.Id, query->bo, query->curr_offset);
+
+	radeon_cs_space_check_with_bo(radeon->cmdbuf.cs,
+				      query->bo,
+				      0, RADEON_GEM_DOMAIN_GTT);
+
+	radeon->vtbl.emit_query_finish(radeon);
+}
+
+static void radeonEndQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+	if (radeon->dma.flush)
+		radeon->dma.flush(radeon->glCtx);
+	radeonEmitQueryEnd(ctx);
+
+	radeon->query.current = NULL;
+}
+
+/**
+ * TODO:
+ * should check if bo is idle, bo there's no interface to do it
+ * just wait for result now
+ */
+static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+	if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+	radeonWaitQuery(ctx, q);
+}
+
+void radeonInitQueryObjFunctions(struct dd_function_table *functions)
+{
+	functions->NewQueryObject = radeonNewQueryObject;
+	functions->DeleteQuery = radeonDeleteQuery;
+	functions->BeginQuery = radeonBeginQuery;
+	functions->EndQuery = radeonEndQuery;
+	functions->CheckQuery = radeonCheckQuery;
+	functions->WaitQuery = radeonWaitQuery;
+}
+
+int radeon_check_query_active(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+	struct radeon_query_object *query = radeon->query.current;
+
+	if (!query || query->emitted_begin)
+		return 0;
+	return atom->cmd_size;
+}
+
+void radeon_emit_queryobj(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+	BATCH_LOCALS(radeon);
+	int dwords;
+
+	dwords = (*atom->check) (ctx, atom);
+
+	BEGIN_BATCH_NO_AUTOSTATE(dwords);
+	OUT_BATCH_TABLE(atom->cmd, dwords);
+	END_BATCH();
+
+	radeon->query.current->emitted_begin = GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.h b/src/mesa/drivers/dri/radeon/radeon_queryobj.h
new file mode 100644
index 0000000..5e70583
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_queryobj.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2008 Maciej Cencora <m.cencora at gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Maciej Cencora <m.cencora at gmail.com>
+ *
+ */
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+#include "radeon_context.h"
+
+extern void radeonEmitQueryBegin(GLcontext *ctx);
+extern void radeonEmitQueryEnd(GLcontext *ctx);
+
+extern void radeonInitQueryObjFunctions(struct dd_function_table *functions);
+
+#define RADEON_QUERY_PAGE_SIZE 4096
+
+int radeon_check_query_active(GLcontext *ctx, struct radeon_state_atom *atom);
+void radeon_emit_queryobj(GLcontext *ctx, struct radeon_state_atom *atom);
+
+static inline void radeon_init_query_stateobj(radeonContextPtr radeon, int SZ)
+{
+	radeon->query.queryobj.cmd_size = (SZ);
+	radeon->query.queryobj.cmd = (uint32_t*)CALLOC((SZ) * sizeof(uint32_t));
+	radeon->query.queryobj.name = "queryobj";
+	radeon->query.queryobj.idx = 0;
+	radeon->query.queryobj.check = radeon_check_query_active;
+	radeon->query.queryobj.dirty = GL_FALSE;
+	radeon->query.queryobj.emit = radeon_emit_queryobj;
+
+	radeon->hw.max_state_size += (SZ);
+	insert_at_tail(&radeon->hw.atomlist, &radeon->query.queryobj);
+}
+




More information about the mesa-commit mailing list