X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_pipe_query.c;h=cec95ed3b6f550c4ba1d5757fb411ad4737e477c;hb=6010d7b8e8bee1bcea2b329cf6d3b44c5fc3ca66;hp=88f41eadc1d272c00e145920382398d21345cc04;hpb=2c3f95d6aaab38cd66dd3dee1b089d5c91928eea;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c index 88f41eadc1d..cec95ed3b6f 100644 --- a/src/gallium/drivers/svga/svga_pipe_query.c +++ b/src/gallium/drivers/svga/svga_pipe_query.c @@ -191,7 +191,8 @@ get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq, if (state == SVGA3D_QUERYSTATE_PENDING) { if (!wait) return FALSE; - sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY); + sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE, + SVGA_FENCE_FLAG_QUERY); state = sq->queryResult->state; } @@ -265,7 +266,7 @@ allocate_query_block(struct svga_context *svga) * any empty memory block around that can be freed up. */ index = -1; - for (i = 0; i < SVGA_QUERY_MAX && index == -1; i++) { + for (i = 0; i < SVGA3D_QUERYTYPE_MAX && index == -1; i++) { struct svga_qmem_alloc_entry *alloc_entry; struct svga_qmem_alloc_entry *prev_alloc_entry = NULL; @@ -380,7 +381,7 @@ allocate_query(struct svga_context *svga, int slot_index = -1; unsigned offset; - assert(type < SVGA_QUERY_MAX); + assert(type < SVGA3D_QUERYTYPE_MAX); alloc_entry = svga->gb_query_map[type]; @@ -453,7 +454,7 @@ destroy_gb_query_obj(struct svga_context *svga) struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; unsigned i; - for (i = 0; i < SVGA_QUERY_MAX; i++) { + for (i = 0; i < SVGA3D_QUERYTYPE_MAX; i++) { struct svga_qmem_alloc_entry *alloc_entry, *next; alloc_entry = svga->gb_query_map[i]; while (alloc_entry) { @@ -610,7 +611,6 @@ begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq) static enum pipe_error end_query_vgpu10(struct svga_context *svga, struct svga_query *sq) { - struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; enum pipe_error ret = PIPE_OK; if (svga->rebind.flags.query) { @@ -623,15 +623,6 @@ end_query_vgpu10(struct svga_context *svga, struct svga_query *sq) ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id); } - /* Finish fence is copied here from get_query_result_vgpu10. This helps - * with cases where svga_begin_query might be called again before - * svga_get_query_result, such as GL_TIME_ELAPSED. - */ - if (!sq->fence) { - svga_context_flush(svga, &sq->fence); - } - sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY); - return ret; } @@ -648,10 +639,21 @@ get_query_result_vgpu10(struct svga_context *svga, struct svga_query *sq, sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen); - if (queryState == SVGA3D_QUERYSTATE_PENDING) { + if (queryState != SVGA3D_QUERYSTATE_SUCCEEDED && !sq->fence) { + /* We don't have the query result yet, and the query hasn't been + * submitted. We need to submit it now since the GL spec says + * "Querying the state for a given occlusion query forces that + * occlusion query to complete within a finite amount of time." + */ + svga_context_flush(svga, &sq->fence); + } + + if (queryState == SVGA3D_QUERYSTATE_PENDING || + queryState == SVGA3D_QUERYSTATE_NEW) { if (!wait) return FALSE; - sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY); + sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE, + SVGA_FENCE_FLAG_QUERY); sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen); } @@ -705,9 +707,14 @@ svga_create_query(struct pipe_context *pipe, } break; case PIPE_QUERY_OCCLUSION_PREDICATE: - assert(svga_have_vgpu10(svga)); - sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE; - define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionPredicateQueryResult)); + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + if (svga_have_vgpu10(svga)) { + sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE; + define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionPredicateQueryResult)); + } else { + sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION; + define_query_vgpu9(svga, sq); + } break; case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_EMITTED: @@ -727,11 +734,10 @@ svga_create_query(struct pipe_context *pipe, case SVGA_QUERY_NUM_FALLBACKS: case SVGA_QUERY_NUM_FLUSHES: case SVGA_QUERY_NUM_VALIDATIONS: - case SVGA_QUERY_MAP_BUFFER_TIME: - case SVGA_QUERY_NUM_RESOURCES_MAPPED: + case SVGA_QUERY_NUM_BUFFERS_MAPPED: + case SVGA_QUERY_NUM_TEXTURES_MAPPED: case SVGA_QUERY_NUM_BYTES_UPLOADED: case SVGA_QUERY_COMMAND_BUFFER_SIZE: - case SVGA_QUERY_FLUSH_TIME: case SVGA_QUERY_SURFACE_WRITE_FLUSHES: case SVGA_QUERY_MEMORY_USED: case SVGA_QUERY_NUM_SHADERS: @@ -744,6 +750,13 @@ svga_create_query(struct pipe_context *pipe, case SVGA_QUERY_NUM_BUFFER_UPLOADS: case SVGA_QUERY_NUM_CONST_BUF_UPDATES: case SVGA_QUERY_NUM_CONST_UPDATES: + case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: + case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: + break; + case SVGA_QUERY_FLUSH_TIME: + case SVGA_QUERY_MAP_BUFFER_TIME: + /* These queries need os_time_get() */ + svga->hud.uses_time = TRUE; break; default: assert(!"unexpected query type in svga_create_query()"); @@ -777,6 +790,8 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q) switch (sq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (svga_have_vgpu10(svga)) { /* make sure to also destroy any associated predicate query */ if (sq->predicate) @@ -787,11 +802,6 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q) } sws->fence_reference(sws, &sq->fence, NULL); break; - case PIPE_QUERY_OCCLUSION_PREDICATE: - assert(svga_have_vgpu10(svga)); - destroy_query_vgpu10(svga, sq); - sws->fence_reference(sws, &sq->fence, NULL); - break; case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_EMITTED: case PIPE_QUERY_SO_STATISTICS: @@ -805,7 +815,8 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q) case SVGA_QUERY_NUM_FLUSHES: case SVGA_QUERY_NUM_VALIDATIONS: case SVGA_QUERY_MAP_BUFFER_TIME: - case SVGA_QUERY_NUM_RESOURCES_MAPPED: + case SVGA_QUERY_NUM_BUFFERS_MAPPED: + case SVGA_QUERY_NUM_TEXTURES_MAPPED: case SVGA_QUERY_NUM_BYTES_UPLOADED: case SVGA_QUERY_COMMAND_BUFFER_SIZE: case SVGA_QUERY_FLUSH_TIME: @@ -821,6 +832,8 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q) case SVGA_QUERY_NUM_BUFFER_UPLOADS: case SVGA_QUERY_NUM_CONST_BUF_UPDATES: case SVGA_QUERY_NUM_CONST_UPDATES: + case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: + case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: /* nothing */ break; default: @@ -854,6 +867,8 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q) switch (sq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (svga_have_vgpu10(svga)) { ret = begin_query_vgpu10(svga, sq); /* also need to start the associated occlusion predicate query */ @@ -869,11 +884,6 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q) assert(ret == PIPE_OK); (void) ret; break; - case PIPE_QUERY_OCCLUSION_PREDICATE: - assert(svga_have_vgpu10(svga)); - ret = begin_query_vgpu10(svga, sq); - assert(ret == PIPE_OK); - break; case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_EMITTED: case PIPE_QUERY_SO_STATISTICS: @@ -897,8 +907,11 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q) case SVGA_QUERY_MAP_BUFFER_TIME: sq->begin_count = svga->hud.map_buffer_time; break; - case SVGA_QUERY_NUM_RESOURCES_MAPPED: - sq->begin_count = svga->hud.num_resources_mapped; + case SVGA_QUERY_NUM_BUFFERS_MAPPED: + sq->begin_count = svga->hud.num_buffers_mapped; + break; + case SVGA_QUERY_NUM_TEXTURES_MAPPED: + sq->begin_count = svga->hud.num_textures_mapped; break; case SVGA_QUERY_NUM_BYTES_UPLOADED: sq->begin_count = svga->hud.num_bytes_uploaded; @@ -933,6 +946,8 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q) case SVGA_QUERY_NUM_STATE_OBJECTS: case SVGA_QUERY_NUM_SURFACE_VIEWS: case SVGA_QUERY_NUM_GENERATE_MIPMAP: + case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: + case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: /* nothing */ break; default: @@ -945,7 +960,7 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q) } -static void +static bool svga_end_query(struct pipe_context *pipe, struct pipe_query *q) { struct svga_context *svga = svga_context(pipe); @@ -967,6 +982,8 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q) switch (sq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (svga_have_vgpu10(svga)) { ret = end_query_vgpu10(svga, sq); /* also need to end the associated occlusion predicate query */ @@ -981,16 +998,6 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q) } assert(ret == PIPE_OK); (void) ret; - /* TODO: Delay flushing. We don't really need to flush here, just ensure - * that there is one flush before svga_get_query_result attempts to get - * the result. - */ - svga_context_flush(svga, NULL); - break; - case PIPE_QUERY_OCCLUSION_PREDICATE: - assert(svga_have_vgpu10(svga)); - ret = end_query_vgpu10(svga, sq); - assert(ret == PIPE_OK); break; case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_EMITTED: @@ -1015,8 +1022,11 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q) case SVGA_QUERY_MAP_BUFFER_TIME: sq->end_count = svga->hud.map_buffer_time; break; - case SVGA_QUERY_NUM_RESOURCES_MAPPED: - sq->end_count = svga->hud.num_resources_mapped; + case SVGA_QUERY_NUM_BUFFERS_MAPPED: + sq->end_count = svga->hud.num_buffers_mapped; + break; + case SVGA_QUERY_NUM_TEXTURES_MAPPED: + sq->end_count = svga->hud.num_textures_mapped; break; case SVGA_QUERY_NUM_BYTES_UPLOADED: sq->end_count = svga->hud.num_bytes_uploaded; @@ -1051,12 +1061,15 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q) case SVGA_QUERY_NUM_STATE_OBJECTS: case SVGA_QUERY_NUM_SURFACE_VIEWS: case SVGA_QUERY_NUM_GENERATE_MIPMAP: + case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: + case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: /* nothing */ break; default: assert(!"unexpected query type in svga_end_query()"); } svga->sq[sq->type] = NULL; + return true; } @@ -1085,15 +1098,21 @@ svga_get_query_result(struct pipe_context *pipe, (void *)&occResult, sizeof(occResult)); *result = (uint64_t)occResult.samplesRendered; } else { - ret = get_query_result_vgpu9(svga, sq, wait, (uint64_t *)result); + ret = get_query_result_vgpu9(svga, sq, wait, result); } break; - case PIPE_QUERY_OCCLUSION_PREDICATE: { - SVGADXOcclusionPredicateQueryResult occResult; - assert(svga_have_vgpu10(svga)); - ret = get_query_result_vgpu10(svga, sq, wait, - (void *)&occResult, sizeof(occResult)); - vresult->b = occResult.anySamplesRendered != 0; + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: { + if (svga_have_vgpu10(svga)) { + SVGADXOcclusionPredicateQueryResult occResult; + ret = get_query_result_vgpu10(svga, sq, wait, + (void *)&occResult, sizeof(occResult)); + vresult->b = occResult.anySamplesRendered != 0; + } else { + uint64_t count = 0; + ret = get_query_result_vgpu9(svga, sq, wait, &count); + vresult->b = count != 0; + } break; } case PIPE_QUERY_SO_STATISTICS: { @@ -1141,7 +1160,8 @@ svga_get_query_result(struct pipe_context *pipe, case SVGA_QUERY_NUM_FLUSHES: case SVGA_QUERY_NUM_VALIDATIONS: case SVGA_QUERY_MAP_BUFFER_TIME: - case SVGA_QUERY_NUM_RESOURCES_MAPPED: + case SVGA_QUERY_NUM_BUFFERS_MAPPED: + case SVGA_QUERY_NUM_TEXTURES_MAPPED: case SVGA_QUERY_NUM_BYTES_UPLOADED: case SVGA_QUERY_COMMAND_BUFFER_SIZE: case SVGA_QUERY_FLUSH_TIME: @@ -1164,7 +1184,12 @@ svga_get_query_result(struct pipe_context *pipe, vresult->u64 = svgascreen->hud.num_resources; break; case SVGA_QUERY_NUM_STATE_OBJECTS: - vresult->u64 = svga->hud.num_state_objects; + vresult->u64 = (svga->hud.num_blend_objects + + svga->hud.num_depthstencil_objects + + svga->hud.num_rasterizer_objects + + svga->hud.num_sampler_objects + + svga->hud.num_samplerview_objects + + svga->hud.num_vertexelement_objects); break; case SVGA_QUERY_NUM_SURFACE_VIEWS: vresult->u64 = svga->hud.num_surface_views; @@ -1172,6 +1197,13 @@ svga_get_query_result(struct pipe_context *pipe, case SVGA_QUERY_NUM_GENERATE_MIPMAP: vresult->u64 = svga->hud.num_generate_mipmap; break; + case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: + vresult->u64 = svgascreen->hud.num_failed_allocations; + break; + case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: + vresult->f = (float) svga->swc->num_commands + / (float) svga->swc->num_draw_commands; + break; default: assert(!"unexpected query type in svga_get_query_result"); } @@ -1183,7 +1215,7 @@ svga_get_query_result(struct pipe_context *pipe, static void svga_render_condition(struct pipe_context *pipe, struct pipe_query *q, - boolean condition, uint mode) + boolean condition, enum pipe_render_cond_flag mode) { struct svga_context *svga = svga_context(pipe); struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; @@ -1213,17 +1245,28 @@ svga_render_condition(struct pipe_context *pipe, struct pipe_query *q, if ((mode == PIPE_RENDER_COND_WAIT || mode == PIPE_RENDER_COND_BY_REGION_WAIT) && sq->fence) { - sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY); + sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE, + SVGA_FENCE_FLAG_QUERY); } } - - ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId, - (uint32) condition); - if (ret != PIPE_OK) { - svga_context_flush(svga, NULL); + /* + * if the kernel module doesn't support the predication command, + * we'll just render unconditionally. + * This is probably acceptable for the typical case of occlusion culling. + */ + if (sws->have_set_predication_cmd) { ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId, (uint32) condition); + if (ret != PIPE_OK) { + svga_context_flush(svga, NULL); + ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId, + (uint32) condition); + } + svga->pred.query_id = queryId; + svga->pred.cond = condition; } + + svga->render_condition = (sq != NULL); } @@ -1246,6 +1289,52 @@ svga_get_timestamp(struct pipe_context *pipe) } +static void +svga_set_active_query_state(struct pipe_context *pipe, boolean enable) +{ +} + + +/** + * \brief Toggle conditional rendering if already enabled + * + * \param svga[in] The svga context + * \param render_condition_enabled[in] Whether to ignore requests to turn + * conditional rendering off + * \param on[in] Whether to turn conditional rendering on or off + */ +void +svga_toggle_render_condition(struct svga_context *svga, + boolean render_condition_enabled, + boolean on) +{ + SVGA3dQueryId query_id; + enum pipe_error ret; + + if (render_condition_enabled || + svga->pred.query_id == SVGA3D_INVALID_ID) { + return; + } + + /* + * If we get here, it means that the system supports + * conditional rendering since svga->pred.query_id has already been + * modified for this context and thus support has already been + * verified. + */ + query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID; + + ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id, + (uint32) svga->pred.cond); + if (ret == PIPE_ERROR_OUT_OF_MEMORY) { + svga_context_flush(svga, NULL); + ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id, + (uint32) svga->pred.cond); + assert(ret == PIPE_OK); + } +} + + void svga_init_query_functions(struct svga_context *svga) { @@ -1254,6 +1343,7 @@ svga_init_query_functions(struct svga_context *svga) svga->pipe.begin_query = svga_begin_query; svga->pipe.end_query = svga_end_query; svga->pipe.get_query_result = svga_get_query_result; + svga->pipe.set_active_query_state = svga_set_active_query_state; svga->pipe.render_condition = svga_render_condition; svga->pipe.get_timestamp = svga_get_timestamp; }