* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "util/u_memory.h"
-#include "util/u_simple_list.h"
+#include "util/simple_list.h"
#include "r300_context.h"
#include "r300_screen.h"
#include <stdio.h>
static struct pipe_query *r300_create_query(struct pipe_context *pipe,
- unsigned query_type)
+ unsigned query_type,
+ unsigned index)
{
struct r300_context *r300 = r300_context(pipe);
struct r300_screen *r300screen = r300->screen;
struct r300_query *q;
- if (query_type != PIPE_QUERY_OCCLUSION_COUNTER) {
+ if (query_type != PIPE_QUERY_OCCLUSION_COUNTER &&
+ query_type != PIPE_QUERY_OCCLUSION_PREDICATE &&
+ query_type != PIPE_QUERY_GPU_FINISHED) {
return NULL;
}
return NULL;
q->type = query_type;
- q->domain = RADEON_DOMAIN_GTT;
- q->buffer_size = 4096;
- if (r300screen->caps.family == CHIP_FAMILY_RV530)
- q->num_pipes = r300screen->caps.num_z_pipes;
- else
- q->num_pipes = r300screen->caps.num_frag_pipes;
+ if (query_type == PIPE_QUERY_GPU_FINISHED) {
+ return (struct pipe_query*)q;
+ }
- insert_at_tail(&r300->query_list, q);
+ if (r300screen->caps.family == CHIP_RV530)
+ q->num_pipes = r300screen->info.r300_num_z_pipes;
+ else
+ q->num_pipes = r300screen->info.r300_num_gb_pipes;
- /* Open up the occlusion query buffer. */
- q->buf = r300->rws->buffer_create(r300->rws, q->buffer_size, 4096,
- PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM,
- q->domain);
+ q->buf = r300->rws->buffer_create(r300->rws, 4096, 4096, TRUE,
+ RADEON_DOMAIN_GTT, 0);
+ if (!q->buf) {
+ FREE(q);
+ return NULL;
+ }
q->cs_buf = r300->rws->buffer_get_cs_handle(q->buf);
return (struct pipe_query*)q;
struct r300_query* q = r300_query(query);
pb_reference(&q->buf, NULL);
- remove_from_list(q);
FREE(query);
}
struct r300_context* r300 = r300_context(pipe);
struct r300_query* q = r300_query(query);
+ if (q->type == PIPE_QUERY_GPU_FINISHED)
+ return;
+
if (r300->query_current != NULL) {
fprintf(stderr, "r300: begin_query: "
"Some other query has already been started.\n");
struct r300_context* r300 = r300_context(pipe);
struct r300_query *q = r300_query(query);
+ if (q->type == PIPE_QUERY_GPU_FINISHED) {
+ pb_reference(&q->buf, NULL);
+ r300_flush(pipe, RADEON_FLUSH_ASYNC,
+ (struct pipe_fence_handle**)&q->buf);
+ return;
+ }
+
if (q != r300->query_current) {
fprintf(stderr, "r300: end_query: Got invalid query.\n");
assert(0);
static boolean r300_get_query_result(struct pipe_context* pipe,
struct pipe_query* query,
boolean wait,
- void* vresult)
+ union pipe_query_result *vresult)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_query *q = r300_query(query);
unsigned i;
uint32_t temp, *map;
- map = r300->rws->buffer_map(q->buf, r300->cs,
+ if (q->type == PIPE_QUERY_GPU_FINISHED) {
+ if (wait) {
+ r300->rws->buffer_wait(q->buf, RADEON_USAGE_READWRITE);
+ vresult->b = TRUE;
+ } else {
+ vresult->b = !r300->rws->buffer_is_busy(q->buf, RADEON_USAGE_READWRITE);
+ }
+ return vresult->b;
+ }
+
+ map = r300->rws->buffer_map(q->cs_buf, r300->cs,
PIPE_TRANSFER_READ |
(!wait ? PIPE_TRANSFER_DONTBLOCK : 0));
if (!map)
/* Sum up the results. */
temp = 0;
for (i = 0; i < q->num_results; i++) {
- temp += *map;
+ /* Convert little endian values written by GPU to CPU byte order */
+ temp += util_le32_to_cpu(*map);
map++;
}
- r300->rws->buffer_unmap(q->buf);
+ r300->rws->buffer_unmap(q->cs_buf);
- *((uint64_t*)vresult) = temp;
+ if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE) {
+ vresult->b = temp != 0;
+ } else {
+ vresult->u64 = temp;
+ }
return TRUE;
}
static void r300_render_condition(struct pipe_context *pipe,
struct pipe_query *query,
+ boolean condition,
uint mode)
{
struct r300_context *r300 = r300_context(pipe);
- uint64_t result = 0;
+ union pipe_query_result result;
boolean wait;
+ r300->skip_rendering = FALSE;
+
if (query) {
wait = mode == PIPE_RENDER_COND_WAIT ||
mode == PIPE_RENDER_COND_BY_REGION_WAIT;
- if (!r300_get_query_result(pipe, query, wait, &result)) {
- r300->skip_rendering = FALSE;
- } else {
- r300->skip_rendering = result == 0;
+ if (r300_get_query_result(pipe, query, wait, &result)) {
+ if (r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE) {
+ r300->skip_rendering = condition == result.b;
+ } else {
+ r300->skip_rendering = condition == !!result.u64;
+ }
}
- } else {
- r300->skip_rendering = FALSE;
}
}
-void r300_init_query_functions(struct r300_context* r300) {
+void r300_init_query_functions(struct r300_context* r300)
+{
r300->context.create_query = r300_create_query;
r300->context.destroy_query = r300_destroy_query;
r300->context.begin_query = r300_begin_query;