From 506e51b8560f30bc67ee84def535a324b5748208 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 22 Nov 2019 14:47:59 +1000 Subject: [PATCH] llvmpipe: initial query buffer object support. (v2) This fails a couple of piglits due to other bugs in llvmpipe, but it adds support for the feature properly. v2: don't reset pipestats, just recalc, fix CI expectation --- .gitlab-ci/piglit/quick_gl.txt | 9 +- src/gallium/drivers/llvmpipe/lp_query.c | 151 +++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_screen.c | 3 +- 3 files changed, 157 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci/piglit/quick_gl.txt b/.gitlab-ci/piglit/quick_gl.txt index 8f5df1f80dc..b9f7cc78a73 100644 --- a/.gitlab-ci/piglit/quick_gl.txt +++ b/.gitlab-ci/piglit/quick_gl.txt @@ -328,8 +328,7 @@ spec/arb_post_depth_coverage/arb_post_depth_coverage-basic: skip spec/arb_post_depth_coverage/arb_post_depth_coverage-multisampling: skip spec/arb_post_depth_coverage/arb_post_depth_coverage-sample-shading: skip spec/arb_program_interface_query/arb_program_interface_query-getprogramresourceindex: fail -spec/arb_query_buffer_object/coherency: skip -spec/arb_query_buffer_object/qbo: skip +spec/arb_query_buffer_object/qbo: fail spec/arb_sample_locations/test: skip spec/arb_sample_shading/arb_sample_shading-api: skip spec/arb_sample_shading/arb_sample_shading-builtin-gl-sample-mask-mrt-alpha: skip @@ -1758,10 +1757,10 @@ wgl/wgl-sanity: skip summary: name: results ---- -------- - pass: 4519 - fail: 101 + pass: 4520 + fail: 102 crash: 2 - skip: 1652 + skip: 1650 timeout: 0 warn: 2 incomplete: 0 diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c index 7f86c3791b4..8fd5ab52614 100644 --- a/src/gallium/drivers/llvmpipe/lp_query.c +++ b/src/gallium/drivers/llvmpipe/lp_query.c @@ -185,6 +185,156 @@ llvmpipe_get_query_result(struct pipe_context *pipe, return true; } +static void +llvmpipe_get_query_result_resource(struct pipe_context *pipe, + struct pipe_query *q, + bool wait, + enum pipe_query_value_type result_type, + int index, + struct pipe_resource *resource, + unsigned offset) +{ + struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); + unsigned num_threads = MAX2(1, screen->num_threads); + struct llvmpipe_query *pq = llvmpipe_query(q); + struct llvmpipe_resource *lpr = llvmpipe_resource(resource); + bool unflushed = false; + bool unsignalled = false; + if (pq->fence) { + /* only have a fence if there was a scene */ + if (!lp_fence_signalled(pq->fence)) { + unsignalled = true; + if (!lp_fence_issued(pq->fence)) + unflushed = true; + } + } + + + uint64_t value = 0; + if (index == -1) + if (unsignalled) + value = 0; + else + value = 1; + else { + unsigned i; + + if (unflushed) { + llvmpipe_flush(pipe, NULL, __FUNCTION__); + + if (!wait) + return; + + lp_fence_wait(pq->fence); + } + + switch (pq->type) { + case PIPE_QUERY_OCCLUSION_COUNTER: + for (i = 0; i < num_threads; i++) { + value += pq->end[i]; + } + break; + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + for (i = 0; i < num_threads; i++) { + /* safer (still not guaranteed) when there's an overflow */ + value = value || pq->end[i]; + } + break; + case PIPE_QUERY_PRIMITIVES_GENERATED: + value = pq->num_primitives_generated; + break; + case PIPE_QUERY_PRIMITIVES_EMITTED: + value = pq->num_primitives_written; + break; + case PIPE_QUERY_TIMESTAMP: + for (i = 0; i < num_threads; i++) { + if (pq->end[i] > value) { + value = pq->end[i]; + } + } + break; + case PIPE_QUERY_SO_OVERFLOW_PREDICATE: + case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: + value = !!(pq->num_primitives_generated > pq->num_primitives_written); + break; + case PIPE_QUERY_PIPELINE_STATISTICS: + switch ((enum pipe_statistics_query_index)index) { + case PIPE_STAT_QUERY_IA_VERTICES: + value = pq->stats.ia_vertices; + break; + case PIPE_STAT_QUERY_IA_PRIMITIVES: + value = pq->stats.ia_primitives; + break; + case PIPE_STAT_QUERY_VS_INVOCATIONS: + value = pq->stats.vs_invocations; + break; + case PIPE_STAT_QUERY_GS_INVOCATIONS: + value = pq->stats.gs_invocations; + break; + case PIPE_STAT_QUERY_GS_PRIMITIVES: + value = pq->stats.gs_primitives; + break; + case PIPE_STAT_QUERY_C_INVOCATIONS: + value = pq->stats.c_invocations; + break; + case PIPE_STAT_QUERY_C_PRIMITIVES: + value = pq->stats.c_primitives; + break; + case PIPE_STAT_QUERY_PS_INVOCATIONS: + value = 0; + for (i = 0; i < num_threads; i++) { + value += pq->end[i]; + } + value *= LP_RASTER_BLOCK_SIZE * LP_RASTER_BLOCK_SIZE; + break; + case PIPE_STAT_QUERY_HS_INVOCATIONS: + value = pq->stats.hs_invocations; + break; + case PIPE_STAT_QUERY_DS_INVOCATIONS: + value = pq->stats.ds_invocations; + break; + case PIPE_STAT_QUERY_CS_INVOCATIONS: + value = pq->stats.cs_invocations; + break; + } + break; + default: + fprintf(stderr, "Unknown query type %d\n", pq->type); + break; + } + } + + void *dst = (uint8_t *)lpr->data + offset; + switch (result_type) { + case PIPE_QUERY_TYPE_I32: { + int32_t *iptr = (int32_t *)dst; + if (value > 0x7fffffff) + *iptr = 0x7fffffff; + else + *iptr = (int32_t)value; + break; + } + case PIPE_QUERY_TYPE_U32: { + uint32_t *uptr = (uint32_t *)dst; + if (value > 0xffffffff) + *uptr = 0xffffffff; + else + *uptr = (uint32_t)value; + break; + } + case PIPE_QUERY_TYPE_I64: { + int64_t *iptr = (int64_t *)dst; + *iptr = (int64_t)value; + break; + } + case PIPE_QUERY_TYPE_U64: { + uint64_t *uptr = (uint64_t *)dst; + *uptr = (uint64_t)value; + break; + } + } +} static bool llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) @@ -341,6 +491,7 @@ void llvmpipe_init_query_funcs(struct llvmpipe_context *llvmpipe ) llvmpipe->pipe.begin_query = llvmpipe_begin_query; llvmpipe->pipe.end_query = llvmpipe_end_query; llvmpipe->pipe.get_query_result = llvmpipe_get_query_result; + llvmpipe->pipe.get_query_result_resource = llvmpipe_get_query_result_resource; llvmpipe->pipe.set_active_query_state = llvmpipe_set_active_query_state; } diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 7c35d148d26..d2364c183d7 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -318,6 +318,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 32; case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: return 1; + case PIPE_CAP_QUERY_BUFFER_OBJECT: + return 1; case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: @@ -337,7 +339,6 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_STRING_MARKER: case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY: case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: - case PIPE_CAP_QUERY_BUFFER_OBJECT: case PIPE_CAP_QUERY_MEMORY_INFO: case PIPE_CAP_PCI_GROUP: case PIPE_CAP_PCI_BUS: -- 2.30.2