From 2e1cfcc431471c68ba79c9323716bed7da79c909 Mon Sep 17 00:00:00 2001 From: Charmaine Lee Date: Fri, 19 Aug 2016 08:49:17 -0600 Subject: [PATCH] svga: add guest statistic gathering interface With this patch, guest statistic gathering interface is added to svga winsys interface that can be used to gather svga driver statistic. The winsys module can then share the statistic info with the VMX host via the mksstats interface. The statistic enums used in the svga driver are defined in svga_stats_count and svga_stats_time in svga_winsys.h Reviewed-by: Brian Paul --- src/gallium/drivers/svga/svga_context.c | 7 + src/gallium/drivers/svga/svga_context.h | 5 + src/gallium/drivers/svga/svga_draw.c | 16 +- src/gallium/drivers/svga/svga_draw_arrays.c | 22 +-- src/gallium/drivers/svga/svga_draw_elements.c | 13 +- src/gallium/drivers/svga/svga_pipe_blend.c | 2 + .../drivers/svga/svga_pipe_depthstencil.c | 3 + src/gallium/drivers/svga/svga_pipe_draw.c | 42 +++-- src/gallium/drivers/svga/svga_pipe_fs.c | 3 + src/gallium/drivers/svga/svga_pipe_gs.c | 3 + .../drivers/svga/svga_pipe_rasterizer.c | 2 + src/gallium/drivers/svga/svga_pipe_sampler.c | 11 +- src/gallium/drivers/svga/svga_pipe_vertex.c | 2 + src/gallium/drivers/svga/svga_pipe_vs.c | 3 + .../drivers/svga/svga_resource_buffer.c | 19 ++- .../svga/svga_resource_buffer_upload.c | 4 + .../drivers/svga/svga_resource_texture.c | 37 +++-- src/gallium/drivers/svga/svga_screen.c | 19 ++- src/gallium/drivers/svga/svga_shader.c | 11 +- src/gallium/drivers/svga/svga_state.c | 8 +- src/gallium/drivers/svga/svga_state_fs.c | 12 +- src/gallium/drivers/svga/svga_state_gs.c | 12 +- src/gallium/drivers/svga/svga_state_vs.c | 10 +- src/gallium/drivers/svga/svga_surface.c | 46 +++++- src/gallium/drivers/svga/svga_swtnl_backend.c | 35 +++- src/gallium/drivers/svga/svga_swtnl_draw.c | 3 + src/gallium/drivers/svga/svga_swtnl_state.c | 13 +- src/gallium/drivers/svga/svga_tgsi.c | 12 +- src/gallium/drivers/svga/svga_tgsi_vgpu10.c | 5 +- src/gallium/drivers/svga/svga_winsys.h | 153 ++++++++++++++++++ src/gallium/winsys/svga/drm/vmw_screen_svga.c | 20 +++ 31 files changed, 468 insertions(+), 85 deletions(-) diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index 52956fab297..cbc312edbde 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -307,6 +307,8 @@ void svga_context_flush( struct svga_context *svga, struct pipe_fence_handle *fence = NULL; uint64_t t0; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFLUSH); + svga->curr.nr_fbs = 0; /* Ensure that texture dma uploads are processed @@ -355,6 +357,8 @@ void svga_context_flush( struct svga_context *svga, svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence); svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL); + + SVGA_STATS_TIME_POP(svga_sws(svga)); } @@ -413,6 +417,8 @@ void svga_surfaces_flush(struct svga_context *svga) struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); unsigned i; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SURFACEFLUSH); + /* Emit buffered drawing commands. */ svga_hwtnl_flush_retry( svga ); @@ -427,6 +433,7 @@ void svga_surfaces_flush(struct svga_context *svga) if (svga->curr.framebuffer.zsbuf) svga_propagate_surface(svga, svga->curr.framebuffer.zsbuf); + SVGA_STATS_TIME_POP(svga_sws(svga)); } diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 1e62e715c3e..4316c44ae29 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -676,6 +676,11 @@ svga_context( struct pipe_context *pipe ) return (struct svga_context *)pipe; } +static inline struct svga_winsys_screen * +svga_sws(struct svga_context *svga) +{ + return svga_screen(svga->pipe.screen)->sws; +} static inline boolean svga_have_gb_objects(const struct svga_context *svga) diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c index 9d3f9eff29e..9e0dfe514e4 100644 --- a/src/gallium/drivers/svga/svga_draw.c +++ b/src/gallium/drivers/svga/svga_draw.c @@ -703,11 +703,17 @@ draw_vgpu10(struct svga_hwtnl *hwtnl, enum pipe_error svga_hwtnl_flush(struct svga_hwtnl *hwtnl) { + enum pipe_error ret = PIPE_OK; + + SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH); + if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) { /* we only queue up primitive for VGPU9 */ - return draw_vgpu9(hwtnl); + ret = draw_vgpu9(hwtnl); } - return PIPE_OK; + + SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws); + return ret; } @@ -881,6 +887,8 @@ svga_hwtnl_prim(struct svga_hwtnl *hwtnl, { enum pipe_error ret = PIPE_OK; + SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM); + if (svga_have_vgpu10(hwtnl->svga)) { /* draw immediately */ ret = draw_vgpu10(hwtnl, range, vcount, min_index, max_index, ib, @@ -905,7 +913,7 @@ svga_hwtnl_prim(struct svga_hwtnl *hwtnl, if (hwtnl->cmd.prim_count + 1 >= QSZ) { ret = svga_hwtnl_flush(hwtnl); if (ret != PIPE_OK) - return ret; + goto done; } /* min/max indices are relative to bias */ @@ -919,5 +927,7 @@ svga_hwtnl_prim(struct svga_hwtnl *hwtnl, hwtnl->cmd.prim_count++; } +done: + SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws); return ret; } diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c index e5fab886f10..b968fb03044 100644 --- a/src/gallium/drivers/svga/svga_draw_arrays.c +++ b/src/gallium/drivers/svga/svga_draw_arrays.c @@ -100,6 +100,8 @@ retrieve_or_generate_indices(struct svga_hwtnl *hwtnl, enum pipe_error ret = PIPE_OK; int i; + SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_GENERATEINDICES); + for (i = 0; i < IDX_CACHE_MAX; i++) { if (hwtnl->index_cache[prim][i].buffer != NULL && hwtnl->index_cache[prim][i].generate == generate) { @@ -110,7 +112,7 @@ retrieve_or_generate_indices(struct svga_hwtnl *hwtnl, if (DBG) debug_printf("%s retrieve %d/%d\n", __FUNCTION__, i, gen_nr); - return PIPE_OK; + goto done; } else if (gen_type == U_GENERATE_REUSABLE) { pipe_resource_reference(&hwtnl->index_cache[prim][i].buffer, @@ -154,7 +156,7 @@ retrieve_or_generate_indices(struct svga_hwtnl *hwtnl, ret = generate_indices(hwtnl, gen_nr, gen_size, generate, out_buf); if (ret != PIPE_OK) - return ret; + goto done; hwtnl->index_cache[prim][i].generate = generate; hwtnl->index_cache[prim][i].gen_nr = gen_nr; @@ -164,7 +166,9 @@ retrieve_or_generate_indices(struct svga_hwtnl *hwtnl, debug_printf("%s cache %d/%d\n", __FUNCTION__, i, hwtnl->index_cache[prim][i].gen_nr); - return PIPE_OK; +done: + SVGA_STATS_TIME_POP(svga_sws(hwtnl->svga)); + return ret; } @@ -213,6 +217,8 @@ svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl, unsigned api_pv = hwtnl->api_pv; struct svga_context *svga = hwtnl->svga; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_HWTNLDRAWARRAYS); + if (svga->curr.rast->templ.fill_front != svga->curr.rast->templ.fill_back) { assert(hwtnl->api_fillmode == PIPE_POLYGON_MODE_FILL); @@ -266,7 +272,7 @@ svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl, } if (gen_type == U_GENERATE_LINEAR) { - return simple_draw_arrays(hwtnl, gen_prim, start, count, + ret = simple_draw_arrays(hwtnl, gen_prim, start, count, start_instance, instance_count); } else { @@ -296,13 +302,11 @@ svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl, gen_prim, 0, gen_nr, start_instance, instance_count); - if (ret != PIPE_OK) - goto done; - done: if (gen_buf) pipe_resource_reference(&gen_buf, NULL); - - return ret; } + + SVGA_STATS_TIME_POP(svga_sws(svga)); + return ret; } diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c index 54a6826329a..f7953bcaefe 100644 --- a/src/gallium/drivers/svga/svga_draw_elements.c +++ b/src/gallium/drivers/svga/svga_draw_elements.c @@ -139,6 +139,9 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl, u_translate_func gen_func; enum pipe_error ret = PIPE_OK; + SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), + SVGA_STATS_TIME_HWTNLDRAWELEMENTS); + if (svga_need_unfilled_fallback(hwtnl, prim)) { gen_type = u_unfilled_translator(prim, index_size, @@ -161,7 +164,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl, if (gen_type == U_TRANSLATE_MEMCPY) { /* No need for translation, just pass through to hardware: */ - return svga_hwtnl_simple_draw_range_elements(hwtnl, index_buffer, + ret = svga_hwtnl_simple_draw_range_elements(hwtnl, index_buffer, index_size, index_bias, min_index, @@ -196,13 +199,11 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl, gen_prim, 0, gen_nr, start_instance, instance_count); - if (ret != PIPE_OK) - goto done; - done: if (gen_buf) pipe_resource_reference(&gen_buf, NULL); - - return ret; } + + SVGA_STATS_TIME_POP(svga_sws(hwtnl->svga)); + return ret; } diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c index 9a4fcc35d38..a9f1c4fa0c8 100644 --- a/src/gallium/drivers/svga/svga_pipe_blend.c +++ b/src/gallium/drivers/svga/svga_pipe_blend.c @@ -334,6 +334,8 @@ svga_create_blend_state(struct pipe_context *pipe, } svga->hud.num_blend_objects++; + SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, + SVGA_STATS_COUNT_BLENDSTATE); return blend; } diff --git a/src/gallium/drivers/svga/svga_pipe_depthstencil.c b/src/gallium/drivers/svga/svga_pipe_depthstencil.c index fb7b556f6c4..1b62290446b 100644 --- a/src/gallium/drivers/svga/svga_pipe_depthstencil.c +++ b/src/gallium/drivers/svga/svga_pipe_depthstencil.c @@ -206,6 +206,9 @@ svga_create_depth_stencil_state(struct pipe_context *pipe, svga->hud.num_depthstencil_objects++; + SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, + SVGA_STATS_COUNT_DEPTHSTENCILSTATE); + return ds; } diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index c9bcf3a5b6c..f9d0f0ff162 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -59,6 +59,8 @@ retry_draw_range_elements( struct svga_context *svga, { enum pipe_error ret = PIPE_OK; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_DRAWELEMENTS); + svga_hwtnl_set_fillmode(svga->hwtnl, svga->curr.rast->hw_fillmode); ret = svga_update_state( svga, SVGA_STATE_HW_DRAW ); @@ -81,20 +83,22 @@ retry_draw_range_elements( struct svga_context *svga, if (ret != PIPE_OK) goto retry; - return PIPE_OK; + goto done; retry: svga_context_flush( svga, NULL ); if (do_retry) { - return retry_draw_range_elements( svga, - index_buffer, index_size, index_bias, - min_index, max_index, - prim, start, count, - start_instance, instance_count, FALSE ); + ret = retry_draw_range_elements(svga, + index_buffer, index_size, index_bias, + min_index, max_index, + prim, start, count, + start_instance, instance_count, FALSE); } +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); return ret; } @@ -107,6 +111,8 @@ retry_draw_arrays( struct svga_context *svga, { enum pipe_error ret; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_DRAWARRAYS); + svga_hwtnl_set_fillmode(svga->hwtnl, svga->curr.rast->hw_fillmode); ret = svga_update_state( svga, SVGA_STATE_HW_DRAW ); @@ -126,18 +132,20 @@ retry_draw_arrays( struct svga_context *svga, if (ret != PIPE_OK) goto retry; - return PIPE_OK; + goto done; retry: if (ret == PIPE_ERROR_OUT_OF_MEMORY && do_retry) { svga_context_flush( svga, NULL ); - return retry_draw_arrays(svga, prim, start, count, - start_instance, instance_count, - FALSE ); + ret = retry_draw_arrays(svga, prim, start, count, + start_instance, instance_count, + FALSE); } +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); return ret; } @@ -177,11 +185,13 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) enum pipe_error ret = 0; boolean needed_swtnl; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_DRAWVBO); + svga->hud.num_draw_calls++; /* for SVGA_QUERY_NUM_DRAW_CALLS */ if (u_reduced_prim(info->mode) == PIPE_PRIM_TRIANGLES && svga->curr.rast->templ.cull_face == PIPE_FACE_FRONT_AND_BACK) - return; + goto done; /* * Mark currently bound target surfaces as dirty @@ -202,11 +212,11 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) r = util_draw_vbo_without_prim_restart(pipe, &svga->curr.ib, info); assert(r == PIPE_OK); (void) r; - return; + goto done; } if (!u_trim_pipe_prim( info->mode, &count )) - return; + goto done; needed_swtnl = svga->state.sw.need_swtnl; @@ -215,7 +225,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) #ifdef DEBUG if (svga->curr.vs->base.id == svga->debug.disable_shader || svga->curr.fs->base.id == svga->debug.disable_shader) - return; + goto done; #endif if (svga->state.sw.need_swtnl) { @@ -270,6 +280,10 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) svga_hwtnl_flush_retry( svga ); svga_context_flush(svga, NULL); } + +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); +; } diff --git a/src/gallium/drivers/svga/svga_pipe_fs.c b/src/gallium/drivers/svga/svga_pipe_fs.c index 4a9b3c96a54..aadfb1a54e1 100644 --- a/src/gallium/drivers/svga/svga_pipe_fs.c +++ b/src/gallium/drivers/svga/svga_pipe_fs.c @@ -48,6 +48,8 @@ svga_create_fs_state(struct pipe_context *pipe, if (!fs) return NULL; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATEFS); + fs->base.tokens = tgsi_dup_tokens(templ->tokens); /* Collect basic info that we'll need later: @@ -62,6 +64,7 @@ svga_create_fs_state(struct pipe_context *pipe, fs->draw_shader = draw_create_fragment_shader(svga->swtnl.draw, templ); + SVGA_STATS_TIME_POP(svga_sws(svga)); return fs; } diff --git a/src/gallium/drivers/svga/svga_pipe_gs.c b/src/gallium/drivers/svga/svga_pipe_gs.c index d614e9d6c01..2fe5477529f 100644 --- a/src/gallium/drivers/svga/svga_pipe_gs.c +++ b/src/gallium/drivers/svga/svga_pipe_gs.c @@ -46,6 +46,8 @@ svga_create_gs_state(struct pipe_context *pipe, if (!gs) return NULL; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATEGS); + gs->base.tokens = tgsi_dup_tokens(templ->tokens); /* Collect basic info that we'll need later: @@ -64,6 +66,7 @@ svga_create_gs_state(struct pipe_context *pipe, &templ->stream_output); } + SVGA_STATS_TIME_POP(svga_sws(svga)); return gs; } diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c index ce566efc513..70d89f5cc63 100644 --- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c +++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c @@ -365,6 +365,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe, } svga->hud.num_rasterizer_objects++; + SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, + SVGA_STATS_COUNT_RASTERIZERSTATE); return rast; } diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 63771ac8892..326519caeff 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -277,6 +277,8 @@ svga_create_sampler_state(struct pipe_context *pipe, cso->mipfilter == SVGA3D_TEX_FILTER_NONE ? "SVGA3D_TEX_FILTER_NONE" : "SOMETHING"); svga->hud.num_sampler_objects++; + SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, + SVGA_STATS_COUNT_SAMPLER); return cso; } @@ -367,6 +369,8 @@ svga_create_sampler_view(struct pipe_context *pipe, sv->id = SVGA3D_INVALID_ID; svga->hud.num_samplerview_objects++; + SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, + SVGA_STATS_COUNT_SAMPLERVIEW); return &sv->base; } @@ -433,6 +437,8 @@ svga_set_sampler_views(struct pipe_context *pipe, if (!svga_have_vgpu10(svga) && shader != PIPE_SHADER_FRAGMENT) return; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SETSAMPLERVIEWS); + /* This bit of code works around a quirk in the CSO module. * If start=num=0 it means all sampler views should be released. * Note that the CSO module treats sampler views for fragment shaders @@ -475,7 +481,7 @@ svga_set_sampler_views(struct pipe_context *pipe, } if (!any_change) { - return; + goto done; } /* find highest non-null sampler_views[] entry */ @@ -527,6 +533,9 @@ svga_set_sampler_views(struct pipe_context *pipe, } } } + +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); } diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c index 075cf5f91bf..4b3f5d82e8c 100644 --- a/src/gallium/drivers/svga/svga_pipe_vertex.c +++ b/src/gallium/drivers/svga/svga_pipe_vertex.c @@ -276,6 +276,8 @@ svga_create_vertex_elements_state(struct pipe_context *pipe, } svga->hud.num_vertexelement_objects++; + SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, + SVGA_STATS_COUNT_VERTEXELEMENT); return velems; } diff --git a/src/gallium/drivers/svga/svga_pipe_vs.c b/src/gallium/drivers/svga/svga_pipe_vs.c index 50cd0ac9a11..ba87cb43e8f 100644 --- a/src/gallium/drivers/svga/svga_pipe_vs.c +++ b/src/gallium/drivers/svga/svga_pipe_vs.c @@ -104,6 +104,8 @@ svga_create_vs_state(struct pipe_context *pipe, if (!vs) return NULL; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATEVS); + /* substitute a debug shader? */ vs->base.tokens = tgsi_dup_tokens(substitute_vs(svga->debug.shader_id, @@ -132,6 +134,7 @@ svga_create_vs_state(struct pipe_context *pipe, &templ->stream_output); } + SVGA_STATS_TIME_POP(svga_sws(svga)); return vs; } diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c index 94788e70e31..b47b07be254 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.c +++ b/src/gallium/drivers/svga/svga_resource_buffer.c @@ -76,9 +76,11 @@ svga_buffer_transfer_map(struct pipe_context *pipe, struct svga_screen *ss = svga_screen(pipe->screen); struct svga_buffer *sbuf = svga_buffer(resource); struct pipe_transfer *transfer; - uint8_t *map; + uint8_t *map = NULL; int64_t begin = svga_get_time(svga); + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_BUFFERTRANSFERMAP); + assert(box->y == 0); assert(box->z == 0); assert(box->height == 1); @@ -86,7 +88,7 @@ svga_buffer_transfer_map(struct pipe_context *pipe, transfer = MALLOC_STRUCT(pipe_transfer); if (!transfer) { - return NULL; + goto done; } transfer->resource = resource; @@ -203,7 +205,7 @@ svga_buffer_transfer_map(struct pipe_context *pipe, */ FREE(transfer); - return NULL; + goto done; } svga_context_flush(svga, NULL); @@ -230,7 +232,7 @@ svga_buffer_transfer_map(struct pipe_context *pipe, sbuf->swbuf = align_malloc(sbuf->b.b.width0, 16); if (!sbuf->swbuf) { FREE(transfer); - return NULL; + goto done; } } } @@ -267,6 +269,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe, svga->hud.map_buffer_time += (svga_get_time(svga) - begin); +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); return map; } @@ -299,6 +303,8 @@ svga_buffer_transfer_unmap( struct pipe_context *pipe, struct svga_context *svga = svga_context(pipe); struct svga_buffer *sbuf = svga_buffer(transfer->resource); + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_BUFFERTRANSFERUNMAP); + pipe_mutex_lock(ss->swc_mutex); assert(sbuf->map.count); @@ -328,6 +334,7 @@ svga_buffer_transfer_unmap( struct pipe_context *pipe, pipe_mutex_unlock(ss->swc_mutex); FREE(transfer); + SVGA_STATS_TIME_POP(svga_sws(svga)); } @@ -381,6 +388,8 @@ svga_buffer_create(struct pipe_screen *screen, struct svga_screen *ss = svga_screen(screen); struct svga_buffer *sbuf; + SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_CREATEBUFFER); + sbuf = CALLOC_STRUCT(svga_buffer); if (!sbuf) goto error1; @@ -437,12 +446,14 @@ svga_buffer_create(struct pipe_screen *screen, ss->hud.total_resource_bytes += sbuf->size; ss->hud.num_resources++; + SVGA_STATS_TIME_POP(ss->sws); return &sbuf->b.b; error2: FREE(sbuf); error1: + SVGA_STATS_TIME_POP(ss->sws); return NULL; } diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c index d519c9d06ff..e1e65c1ccb3 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c @@ -835,6 +835,8 @@ svga_context_flush_buffers(struct svga_context *svga) { struct list_head *curr, *next; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_BUFFERSFLUSH); + curr = svga->dirty_buffers.next; next = curr->next; while (curr != &svga->dirty_buffers) { @@ -848,4 +850,6 @@ svga_context_flush_buffers(struct svga_context *svga) curr = next; next = curr->next; } + + SVGA_STATS_TIME_POP(svga_sws(svga)); } diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c index 30dc4d9a082..eaab49ddaad 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.c +++ b/src/gallium/drivers/svga/svga_resource_texture.c @@ -334,20 +334,22 @@ svga_texture_transfer_map(struct pipe_context *pipe, boolean use_direct_map = svga_have_gb_objects(svga) && !svga_have_gb_dma(svga); unsigned d; - void *returnVal; + void *returnVal = NULL; int64_t begin = svga_get_time(svga); + SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_TEXTRANSFERMAP); + /* We can't map texture storage directly unless we have GB objects */ if (usage & PIPE_TRANSFER_MAP_DIRECTLY) { if (svga_have_gb_objects(svga)) use_direct_map = TRUE; else - return NULL; + goto done; } st = CALLOC_STRUCT(svga_transfer); if (!st) - return NULL; + goto done; st->base.level = level; st->base.usage = usage; @@ -415,7 +417,7 @@ svga_texture_transfer_map(struct pipe_context *pipe, if (!st->hwbuf) { FREE(st); - return NULL; + goto done; } if (st->hw_nblocksy < nblocksy) { @@ -434,7 +436,7 @@ svga_texture_transfer_map(struct pipe_context *pipe, if (!st->swbuf) { sws->buffer_destroy(sws, st->hwbuf); FREE(st); - return NULL; + goto done; } } @@ -449,7 +451,7 @@ svga_texture_transfer_map(struct pipe_context *pipe, if (!surf) { FREE(st); - return NULL; + goto done; } /* If this is the first time mapping to the surface in this @@ -472,6 +474,7 @@ svga_texture_transfer_map(struct pipe_context *pipe, } svga->hud.num_readbacks++; + SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK); assert(ret == PIPE_OK); (void) ret; @@ -495,6 +498,7 @@ svga_texture_transfer_map(struct pipe_context *pipe, svga_surfaces_flush(svga); if (!sws->surface_is_flushed(sws, surf)) { svga->hud.surface_write_flushes++; + SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_SURFACEWRITEFLUSH); svga_context_flush(svga, NULL); } } @@ -545,7 +549,8 @@ svga_texture_transfer_map(struct pipe_context *pipe, */ if (!map) { FREE(st); - return map; + returnVal = map; + goto done; } /** @@ -581,6 +586,8 @@ svga_texture_transfer_map(struct pipe_context *pipe, svga->hud.map_buffer_time += (svga_get_time(svga) - begin); svga->hud.num_resources_mapped++; +done: + SVGA_STATS_TIME_POP(sws); return returnVal; } @@ -661,6 +668,8 @@ svga_texture_transfer_unmap(struct pipe_context *pipe, struct svga_transfer *st = svga_transfer(transfer); struct svga_texture *tex = svga_texture(transfer->resource); + SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_TEXTRANSFERUNMAP); + if (!st->swbuf) { if (st->use_direct_map) { svga_texture_surface_unmap(svga, transfer); @@ -757,6 +766,7 @@ svga_texture_transfer_unmap(struct pipe_context *pipe, sws->buffer_destroy(sws, st->hwbuf); } FREE(st); + SVGA_STATS_TIME_POP(sws); } @@ -789,21 +799,24 @@ svga_texture_create(struct pipe_screen *screen, struct svga_texture *tex; unsigned bindings = template->bind; + SVGA_STATS_TIME_PUSH(svgascreen->sws, + SVGA_STATS_TIME_CREATETEXTURE); + assert(template->last_level < SVGA_MAX_TEXTURE_LEVELS); if (template->last_level >= SVGA_MAX_TEXTURE_LEVELS) { - return NULL; + goto fail_notex; } tex = CALLOC_STRUCT(svga_texture); if (!tex) { - return NULL; + goto fail_notex; } tex->defined = CALLOC(template->depth0 * template->array_size, sizeof(tex->defined[0])); if (!tex->defined) { FREE(tex); - return NULL; + goto fail_notex; } tex->rendered_to = CALLOC(template->depth0 * template->array_size, @@ -990,6 +1003,8 @@ svga_texture_create(struct pipe_screen *screen, svgascreen->hud.total_resource_bytes += tex->size; svgascreen->hud.num_resources++; + SVGA_STATS_TIME_POP(svgascreen->sws); + return &tex->b.b; fail: @@ -1000,6 +1015,8 @@ fail: if (tex->defined) FREE(tex->defined); FREE(tex); +fail_notex: + SVGA_STATS_TIME_POP(svgascreen->sws); return NULL; } diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index c5f8c87927d..7567af77892 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -810,14 +810,23 @@ svga_fence_finish(struct pipe_screen *screen, uint64_t timeout) { struct svga_winsys_screen *sws = svga_screen(screen)->sws; + boolean retVal; - if (!timeout) - return sws->fence_signalled(sws, fence, 0) == 0; + SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_FENCEFINISH); - SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", - __FUNCTION__, fence); + if (!timeout) { + retVal = sws->fence_signalled(sws, fence, 0) == 0; + } + else { + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", + __FUNCTION__, fence); + + retVal = sws->fence_finish(sws, fence, 0) == 0; + } + + SVGA_STATS_TIME_POP(sws); - return sws->fence_finish(sws, fence, 0) == 0; + return retVal; } diff --git a/src/gallium/drivers/svga/svga_shader.c b/src/gallium/drivers/svga/svga_shader.c index 9e37e237a7d..9ba60555bf0 100644 --- a/src/gallium/drivers/svga/svga_shader.c +++ b/src/gallium/drivers/svga/svga_shader.c @@ -350,19 +350,22 @@ svga_define_shader(struct svga_context *svga, unsigned codeLen = variant->nr_tokens * sizeof(variant->tokens[0]); enum pipe_error ret; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_DEFINESHADER); + variant->id = UTIL_BITMASK_INVALID_INDEX; if (svga_have_gb_objects(svga)) { if (svga_have_vgpu10(svga)) - return define_gb_shader_vgpu10(svga, type, variant, codeLen); + ret = define_gb_shader_vgpu10(svga, type, variant, codeLen); else - return define_gb_shader_vgpu9(svga, type, variant, codeLen); + ret = define_gb_shader_vgpu9(svga, type, variant, codeLen); } else { /* Allocate an integer ID for the shader */ variant->id = util_bitmask_add(svga->shader_id_bm); if (variant->id == UTIL_BITMASK_INVALID_INDEX) { - return PIPE_ERROR_OUT_OF_MEMORY; + ret = PIPE_ERROR_OUT_OF_MEMORY; + goto done; } /* Issue SVGA3D device command to define the shader */ @@ -379,6 +382,8 @@ svga_define_shader(struct svga_context *svga, } } +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); return ret; } diff --git a/src/gallium/drivers/svga/svga_state.c b/src/gallium/drivers/svga/svga_state.c index 4479a271262..777321ead1d 100644 --- a/src/gallium/drivers/svga/svga_state.c +++ b/src/gallium/drivers/svga/svga_state.c @@ -202,6 +202,8 @@ svga_update_state(struct svga_context *svga, unsigned max_level) enum pipe_error ret = PIPE_OK; unsigned i; + SVGA_STATS_TIME_PUSH(screen->sws, SVGA_STATS_TIME_UPDATESTATE); + /* Check for updates to bound textures. This can't be done in an * atom as there is no flag which could provoke this test, and we * cannot create one. @@ -219,7 +221,7 @@ svga_update_state(struct svga_context *svga, unsigned max_level) state_levels[i], &svga->dirty ); if (ret != PIPE_OK) - return ret; + goto done; svga->state.dirty[i] = 0; } @@ -232,7 +234,9 @@ svga_update_state(struct svga_context *svga, unsigned max_level) svga->hud.num_validations++; - return PIPE_OK; +done: + SVGA_STATS_TIME_POP(screen->sws); + return ret; } diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c index 72d591bb1bb..2c7c5bbd346 100644 --- a/src/gallium/drivers/svga/svga_state_fs.c +++ b/src/gallium/drivers/svga/svga_state_fs.c @@ -407,6 +407,8 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty) struct svga_fragment_shader *fs = svga->curr.fs; struct svga_compile_key key; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITFS); + /* SVGA_NEW_BLEND * SVGA_NEW_TEXTURE_BINDING * SVGA_NEW_RAST @@ -418,13 +420,13 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty) */ ret = make_fs_key(svga, fs, &key); if (ret != PIPE_OK) - return ret; + goto done; variant = svga_search_shader_key(&fs->base, &key); if (!variant) { ret = compile_fs(svga, fs, &key, &variant); if (ret != PIPE_OK) - return ret; + goto done; } assert(variant); @@ -432,7 +434,7 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty) if (variant != svga->state.hw_draw.fs) { ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, variant); if (ret != PIPE_OK) - return ret; + goto done; svga->rebind.flags.fs = FALSE; @@ -440,7 +442,9 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty) svga->state.hw_draw.fs = variant; } - return PIPE_OK; +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); + return ret; } struct svga_tracked_state svga_hw_fs = diff --git a/src/gallium/drivers/svga/svga_state_gs.c b/src/gallium/drivers/svga/svga_state_gs.c index 618bec248dd..cff11ad5c3f 100644 --- a/src/gallium/drivers/svga/svga_state_gs.c +++ b/src/gallium/drivers/svga/svga_state_gs.c @@ -175,6 +175,8 @@ emit_hw_gs(struct svga_context *svga, unsigned dirty) enum pipe_error ret = PIPE_OK; struct svga_compile_key key; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITGS); + /* If there's a user-defined GS, we should have a pointer to a derived * GS. This should have been resolved in update_tgsi_transform(). */ @@ -190,7 +192,7 @@ emit_hw_gs(struct svga_context *svga, unsigned dirty) ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL); svga->state.hw_draw.gs = NULL; } - return ret; + goto done; } /* If there is stream output info for this geometry shader, then use @@ -218,7 +220,7 @@ emit_hw_gs(struct svga_context *svga, unsigned dirty) if (!variant) { ret = compile_gs(svga, gs, &key, &variant); if (ret != PIPE_OK) - return ret; + goto done; /* insert the new variant at head of linked list */ assert(variant); @@ -231,14 +233,16 @@ emit_hw_gs(struct svga_context *svga, unsigned dirty) /* Bind the new variant */ ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, variant); if (ret != PIPE_OK) - return ret; + goto done; svga->rebind.flags.gs = FALSE; svga->dirty |= SVGA_NEW_GS_VARIANT; svga->state.hw_draw.gs = variant; } - return PIPE_OK; +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); + return ret; } struct svga_tracked_state svga_hw_gs = diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c index f46e6b3d4da..7162e8884f2 100644 --- a/src/gallium/drivers/svga/svga_state_vs.c +++ b/src/gallium/drivers/svga/svga_state_vs.c @@ -346,6 +346,8 @@ emit_hw_vs(struct svga_context *svga, unsigned dirty) enum pipe_error ret = PIPE_OK; struct svga_compile_key key; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITVS); + /* If there is an active geometry shader, and it has stream output * defined, then we will skip the stream output from the vertex shader */ @@ -381,7 +383,7 @@ emit_hw_vs(struct svga_context *svga, unsigned dirty) ret = compile_vs(svga, vs, &key, &variant); } if (ret != PIPE_OK) - return ret; + goto done; /* insert the new variant at head of linked list */ assert(variant); @@ -395,7 +397,7 @@ emit_hw_vs(struct svga_context *svga, unsigned dirty) if (variant) { ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, variant); if (ret != PIPE_OK) - return ret; + goto done; svga->rebind.flags.vs = FALSE; } @@ -403,7 +405,9 @@ emit_hw_vs(struct svga_context *svga, unsigned dirty) svga->state.hw_draw.vs = variant; } - return PIPE_OK; +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); + return ret; } struct svga_tracked_state svga_hw_vs = diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c index 8dd1868f6dc..43a00c35d1e 100644 --- a/src/gallium/drivers/svga/svga_surface.c +++ b/src/gallium/drivers/svga/svga_surface.c @@ -212,11 +212,14 @@ svga_create_surface_view(struct pipe_context *pipe, unsigned nlayers = 1; SVGA3dSurfaceFlags flags = 0; SVGA3dSurfaceFormat format; + struct pipe_surface *retVal = NULL; s = CALLOC_STRUCT(svga_surface); if (!s) return NULL; + SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_CREATESURFACEVIEW); + if (pt->target == PIPE_TEXTURE_CUBE) { layer = surf_tmpl->u.tex.first_layer; zslice = 0; @@ -299,7 +302,7 @@ svga_create_surface_view(struct pipe_context *pipe, layer, nlayers, zslice, &s->key); if (!s->handle) { FREE(s); - return NULL; + goto done; } s->key.format = format; @@ -320,8 +323,11 @@ svga_create_surface_view(struct pipe_context *pipe, } svga->hud.num_surface_views++; + retVal = &s->base; - return &s->base; +done: + SVGA_STATS_TIME_POP(ss->sws); + return retVal; } @@ -332,8 +338,11 @@ svga_create_surface(struct pipe_context *pipe, { struct svga_context *svga = svga_context(pipe); struct pipe_screen *screen = pipe->screen; + struct pipe_surface *surf = NULL; boolean view = FALSE; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATESURFACE); + if (svga_screen(screen)->debug.force_surface_view) view = TRUE; @@ -347,7 +356,11 @@ svga_create_surface(struct pipe_context *pipe, if (svga_have_vgpu10(svga) || svga_screen(screen)->debug.no_surface_view) view = FALSE; - return svga_create_surface_view(pipe, pt, surf_tmpl, view); + surf = svga_create_surface_view(pipe, pt, surf_tmpl, view); + + SVGA_STATS_TIME_POP(svga_sws(svga)); + + return surf; } @@ -359,6 +372,9 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s) { struct svga_surface *bs = s->backed; + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_CREATEBACKEDSURFACEVIEW); + if (!bs) { struct svga_texture *tex = svga_texture(s->base.texture); struct pipe_surface *backed_view; @@ -376,6 +392,8 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s) svga_mark_surface_dirty(&bs->base); + SVGA_STATS_TIME_POP(svga_sws(svga)); + return bs; } @@ -388,9 +406,13 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s) { enum pipe_error ret = PIPE_OK; unsigned shader; + struct pipe_surface *surf = NULL; assert(svga_have_vgpu10(svga)); + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VALIDATESURFACEVIEW); + /** * DX spec explicitly specifies that no resource can be bound to a render * target view and a shader resource view simultanously. @@ -406,7 +428,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s) s->handle); s = create_backed_surface_view(svga, s); if (!s) - return NULL; + goto done; break; } @@ -475,10 +497,15 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s) if (ret != PIPE_OK) { util_bitmask_clear(svga->surface_view_id_bm, s->view_id); s->view_id = SVGA3D_INVALID_ID; - return NULL; + goto done; } } - return &s->base; + surf = &s->base; + +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); + + return surf; } @@ -493,6 +520,8 @@ svga_surface_destroy(struct pipe_context *pipe, struct svga_screen *ss = svga_screen(surf->texture->screen); enum pipe_error ret = PIPE_OK; + SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_DESTROYSURFACE); + /* Destroy the backed view surface if it exists */ if (s->backed) { svga_surface_destroy(pipe, &s->backed->base); @@ -527,6 +556,7 @@ svga_surface_destroy(struct pipe_context *pipe, FREE(surf); svga->hud.num_surface_views--; + SVGA_STATS_TIME_POP(ss->sws); } @@ -587,6 +617,8 @@ svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf) if (!s->dirty) return; + SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_PROPAGATESURFACE); + if (surf->texture->target == PIPE_TEXTURE_CUBE) { zslice = 0; layer = surf->u.tex.first_layer; @@ -622,6 +654,8 @@ svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf) svga_define_texture_level(tex, layer + i, surf->u.tex.level); } } + + SVGA_STATS_TIME_POP(ss->sws); } diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c index 82fb11d59c2..576fd853e7f 100644 --- a/src/gallium/drivers/svga/svga_swtnl_backend.c +++ b/src/gallium/drivers/svga/svga_swtnl_backend.c @@ -68,6 +68,9 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render, boolean new_vbuf = FALSE; boolean new_ibuf = FALSE; + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VBUFRENDERALLOCVERT); + if (svga_render->vertex_size != vertex_size) svga->swtnl.new_vdecl = TRUE; svga_render->vertex_size = (size_t)vertex_size; @@ -113,6 +116,8 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render, if (svga->swtnl.new_vdecl) svga_render->vdecl_offset = svga_render->vbuf_offset; + SVGA_STATS_TIME_POP(svga_sws(svga)); + return TRUE; } @@ -121,6 +126,10 @@ svga_vbuf_render_map_vertices( struct vbuf_render *render ) { struct svga_vbuf_render *svga_render = svga_vbuf_render(render); struct svga_context *svga = svga_render->svga; + void * retPtr = NULL; + + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VBUFRENDERMAPVERT); if (svga_render->vbuf) { char *ptr = (char*)pipe_buffer_map(&svga->pipe, @@ -132,18 +141,21 @@ svga_vbuf_render_map_vertices( struct vbuf_render *render ) &svga_render->vbuf_transfer); if (ptr) { svga_render->vbuf_ptr = ptr; - return ptr + svga_render->vbuf_offset; + retPtr = ptr + svga_render->vbuf_offset; } else { svga_render->vbuf_ptr = NULL; svga_render->vbuf_transfer = NULL; - return NULL; + retPtr = NULL; } } else { /* we probably ran out of memory when allocating the vertex buffer */ - return NULL; + retPtr = NULL; } + + SVGA_STATS_TIME_POP(svga_sws(svga)); + return retPtr; } static void @@ -156,6 +168,9 @@ svga_vbuf_render_unmap_vertices( struct vbuf_render *render, unsigned offset, length; size_t used = svga_render->vertex_size * ((size_t)max_index + 1); + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VBUFRENDERUNMAPVERT); + offset = svga_render->vbuf_offset + svga_render->vertex_size * min_index; length = svga_render->vertex_size * (max_index + 1 - min_index); @@ -177,6 +192,8 @@ svga_vbuf_render_unmap_vertices( struct vbuf_render *render, svga_render->min_index = min_index; svga_render->max_index = max_index; svga_render->vbuf_used = MAX2(svga_render->vbuf_used, used); + + SVGA_STATS_TIME_POP(svga_sws(svga)); } static void @@ -200,6 +217,9 @@ svga_vbuf_submit_state( struct svga_vbuf_render *svga_render ) if (!svga->swtnl.new_vdecl) return; + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VBUFSUBMITSTATE); + memcpy(vdecl, svga_render->vdecl, sizeof(vdecl)); /* flush the hw state */ @@ -249,6 +269,7 @@ svga_vbuf_submit_state( struct svga_vbuf_render *svga_render ) } svga->swtnl.new_vdecl = FALSE; + SVGA_STATS_TIME_POP(svga_sws(svga)); } static void @@ -263,6 +284,8 @@ svga_vbuf_render_draw_arrays( struct vbuf_render *render, const unsigned start_instance = 0; const unsigned instance_count = 1; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_VBUFDRAWARRAYS); + /* off to hardware */ svga_vbuf_submit_state(svga_render); @@ -282,6 +305,7 @@ svga_vbuf_render_draw_arrays( struct vbuf_render *render, svga->swtnl.new_vbuf = TRUE; assert(ret == PIPE_OK); } + SVGA_STATS_TIME_POP(svga_sws(svga)); } @@ -302,6 +326,8 @@ svga_vbuf_render_draw_elements( struct vbuf_render *render, assert(( svga_render->vbuf_offset - svga_render->vdecl_offset) % svga_render->vertex_size == 0); + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_VBUFDRAWELEMENTS); + if (svga_render->ibuf_size < svga_render->ibuf_offset + size) pipe_resource_reference(&svga_render->ibuf, NULL); @@ -350,8 +376,9 @@ svga_vbuf_render_draw_elements( struct vbuf_render *render, svga->swtnl.new_vbuf = TRUE; assert(ret == PIPE_OK); } - svga_render->ibuf_offset += size; + + SVGA_STATS_TIME_POP(svga_sws(svga)); } diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c index faebfdeebc1..24b4f5cdc28 100644 --- a/src/gallium/drivers/svga/svga_swtnl_draw.c +++ b/src/gallium/drivers/svga/svga_swtnl_draw.c @@ -49,6 +49,8 @@ svga_swtnl_draw_vbo(struct svga_context *svga, const void *map; enum pipe_error ret; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLDRAWVBO); + assert(!svga->dirty); assert(svga->state.sw.need_swtnl); assert(draw); @@ -139,6 +141,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga, svga->state.sw.in_swtnl_draw = FALSE; svga->dirty |= SVGA_NEW_NEED_PIPELINE | SVGA_NEW_NEED_SWVFETCH; + SVGA_STATS_TIME_POP(svga_sws(svga)); return ret; } diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c index 4d21f4f0e60..db41f3cdab0 100644 --- a/src/gallium/drivers/svga/svga_swtnl_state.c +++ b/src/gallium/drivers/svga/svga_swtnl_state.c @@ -97,6 +97,8 @@ static enum pipe_error update_swtnl_draw( struct svga_context *svga, unsigned dirty ) { + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLUPDATEDRAW); + draw_flush( svga->swtnl.draw ); if (dirty & SVGA_NEW_VS) @@ -141,6 +143,7 @@ update_swtnl_draw( struct svga_context *svga, (svga->curr.framebuffer.zsbuf) ? svga->curr.framebuffer.zsbuf->format : PIPE_FORMAT_NONE); + SVGA_STATS_TIME_POP(svga_sws(svga)); return PIPE_OK; } @@ -227,6 +230,8 @@ svga_swtnl_update_vdecl( struct svga_context *svga ) unsigned i; int any_change; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLUPDATEVDECL); + memset(vinfo, 0, sizeof(*vinfo)); memset(vdecl, 0, sizeof(vdecl)); @@ -299,7 +304,7 @@ svga_swtnl_update_vdecl( struct svga_context *svga ) enum pipe_error ret; if (!any_change && svga_render->layout_id != SVGA3D_INVALID_ID) { - return PIPE_OK; + goto done; } if (svga_render->layout_id != SVGA3D_INVALID_ID) { @@ -343,13 +348,15 @@ svga_swtnl_update_vdecl( struct svga_context *svga ) } else { if (!any_change) - return PIPE_OK; + goto done; } memcpy(svga_render->vdecl, vdecl, sizeof(vdecl)); svga->swtnl.new_vdecl = TRUE; - return 0; +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); + return PIPE_OK; } diff --git a/src/gallium/drivers/svga/svga_tgsi.c b/src/gallium/drivers/svga/svga_tgsi.c index 7396ad08e27..7cbd5166900 100644 --- a/src/gallium/drivers/svga/svga_tgsi.c +++ b/src/gallium/drivers/svga/svga_tgsi.c @@ -173,6 +173,8 @@ svga_tgsi_vgpu9_translate(struct svga_context *svga, struct svga_shader_variant *variant = NULL; struct svga_shader_emitter emit; + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_TGSIVGPU9TRANSLATE); + memset(&emit, 0, sizeof(emit)); emit.size = 1024; @@ -252,11 +254,15 @@ svga_tgsi_vgpu9_translate(struct svga_context *svga, } #endif - return variant; + goto done; - fail: +fail: FREE(variant); if (emit.buf != err_buf) FREE(emit.buf); - return NULL; + variant = NULL; + +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); + return variant; } diff --git a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c index 3b44730df52..ef5d78e0483 100644 --- a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c +++ b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c @@ -6715,12 +6715,13 @@ svga_tgsi_vgpu10_translate(struct svga_context *svga, /* These two flags cannot be used together */ assert(key->vs.need_prescale + key->vs.undo_viewport <= 1); + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_TGSIVGPU10TRANSLATE); /* * Setup the code emitter */ emit = alloc_emitter(); if (!emit) - return NULL; + goto done; emit->unit = unit; emit->key = *key; @@ -6885,5 +6886,7 @@ svga_tgsi_vgpu10_translate(struct svga_context *svga, cleanup: free_emitter(emit); +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); return variant; } diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index 90e4f81da8d..5eb73087470 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -43,6 +43,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_defines.h" +#include "svga_mksstats.h" struct svga_winsys_screen; struct svga_winsys_buffer; @@ -88,6 +89,139 @@ struct winsys_handle; #define SVGA_HINT_FLAG_CAN_PRE_FLUSH (1 << 0) /* Can preemptively flush */ +/** + * SVGA mks statistics info + */ +struct svga_winsys_stats_timeframe { + void *counterTime; + uint64 startTime; + uint64 adjustedStartTime; + struct svga_winsys_stats_timeframe *enclosing; +}; + +enum svga_stats_count { + SVGA_STATS_COUNT_BLENDSTATE, + SVGA_STATS_COUNT_DEPTHSTENCILSTATE, + SVGA_STATS_COUNT_RASTERIZERSTATE, + SVGA_STATS_COUNT_SAMPLER, + SVGA_STATS_COUNT_SAMPLERVIEW, + SVGA_STATS_COUNT_SURFACEWRITEFLUSH, + SVGA_STATS_COUNT_TEXREADBACK, + SVGA_STATS_COUNT_VERTEXELEMENT, + SVGA_STATS_COUNT_MAX +}; + +enum svga_stats_time { + SVGA_STATS_TIME_BUFFERSFLUSH, + SVGA_STATS_TIME_BUFFERTRANSFERMAP, + SVGA_STATS_TIME_BUFFERTRANSFERUNMAP, + SVGA_STATS_TIME_CONTEXTFINISH, + SVGA_STATS_TIME_CONTEXTFLUSH, + SVGA_STATS_TIME_CREATEBACKEDSURFACEVIEW, + SVGA_STATS_TIME_CREATEBUFFER, + SVGA_STATS_TIME_CREATECONTEXT, + SVGA_STATS_TIME_CREATEFS, + SVGA_STATS_TIME_CREATEGS, + SVGA_STATS_TIME_CREATESURFACE, + SVGA_STATS_TIME_CREATESURFACEVIEW, + SVGA_STATS_TIME_CREATETEXTURE, + SVGA_STATS_TIME_CREATEVS, + SVGA_STATS_TIME_DEFINESHADER, + SVGA_STATS_TIME_DESTROYSURFACE, + SVGA_STATS_TIME_DRAWVBO, + SVGA_STATS_TIME_DRAWARRAYS, + SVGA_STATS_TIME_DRAWELEMENTS, + SVGA_STATS_TIME_EMITFS, + SVGA_STATS_TIME_EMITGS, + SVGA_STATS_TIME_EMITVS, + SVGA_STATS_TIME_FENCEFINISH, + SVGA_STATS_TIME_GENERATEINDICES, + SVGA_STATS_TIME_HWTNLDRAWARRAYS, + SVGA_STATS_TIME_HWTNLDRAWELEMENTS, + SVGA_STATS_TIME_HWTNLFLUSH, + SVGA_STATS_TIME_HWTNLPRIM, + SVGA_STATS_TIME_PROPAGATESURFACE, + SVGA_STATS_TIME_SETSAMPLERVIEWS, + SVGA_STATS_TIME_SURFACEFLUSH, + SVGA_STATS_TIME_SWTNLDRAWVBO, + SVGA_STATS_TIME_SWTNLUPDATEDRAW, + SVGA_STATS_TIME_SWTNLUPDATEVDECL, + SVGA_STATS_TIME_TEXTRANSFERMAP, + SVGA_STATS_TIME_TEXTRANSFERUNMAP, + SVGA_STATS_TIME_TGSIVGPU10TRANSLATE, + SVGA_STATS_TIME_TGSIVGPU9TRANSLATE, + SVGA_STATS_TIME_UPDATESTATE, + SVGA_STATS_TIME_VALIDATESURFACEVIEW, + SVGA_STATS_TIME_VBUFDRAWARRAYS, + SVGA_STATS_TIME_VBUFDRAWELEMENTS, + SVGA_STATS_TIME_VBUFRENDERALLOCVERT, + SVGA_STATS_TIME_VBUFRENDERMAPVERT, + SVGA_STATS_TIME_VBUFRENDERUNMAPVERT, + SVGA_STATS_TIME_VBUFSUBMITSTATE, + SVGA_STATS_TIME_MAX +}; + +#define SVGA_STATS_PREFIX "GuestGL_" + +#define SVGA_STATS_COUNT_NAMES \ + SVGA_STATS_PREFIX "BlendState", \ + SVGA_STATS_PREFIX "DepthStencilState", \ + SVGA_STATS_PREFIX "RasterizerState", \ + SVGA_STATS_PREFIX "Sampler", \ + SVGA_STATS_PREFIX "SamplerView", \ + SVGA_STATS_PREFIX "TextureReadback", \ + SVGA_STATS_PREFIX "SurfaceWriteFlush", \ + SVGA_STATS_PREFIX "VertexElement" \ + +#define SVGA_STATS_TIME_NAMES \ + SVGA_STATS_PREFIX "BuffersFlush", \ + SVGA_STATS_PREFIX "BufferTransferMap", \ + SVGA_STATS_PREFIX "BufferTransferUnmap", \ + SVGA_STATS_PREFIX "ContextFinish", \ + SVGA_STATS_PREFIX "ContextFlush", \ + SVGA_STATS_PREFIX "CreateBackedSurfaceView", \ + SVGA_STATS_PREFIX "CreateBuffer", \ + SVGA_STATS_PREFIX "CreateContext", \ + SVGA_STATS_PREFIX "CreateFS", \ + SVGA_STATS_PREFIX "CreateGS", \ + SVGA_STATS_PREFIX "CreateSurface", \ + SVGA_STATS_PREFIX "CreateSurfaceView", \ + SVGA_STATS_PREFIX "CreateTexture", \ + SVGA_STATS_PREFIX "CreateVS", \ + SVGA_STATS_PREFIX "DefineShader", \ + SVGA_STATS_PREFIX "DestroySurface", \ + SVGA_STATS_PREFIX "DrawVBO", \ + SVGA_STATS_PREFIX "DrawArrays", \ + SVGA_STATS_PREFIX "DrawElements", \ + SVGA_STATS_PREFIX "EmitFS", \ + SVGA_STATS_PREFIX "EmitGS", \ + SVGA_STATS_PREFIX "EmitVS", \ + SVGA_STATS_PREFIX "FenceFinish", \ + SVGA_STATS_PREFIX "GenerateIndices", \ + SVGA_STATS_PREFIX "HWtnlDrawArrays", \ + SVGA_STATS_PREFIX "HWtnlDrawElements", \ + SVGA_STATS_PREFIX "HWtnlFlush", \ + SVGA_STATS_PREFIX "HWtnlPrim", \ + SVGA_STATS_PREFIX "PropagateSurface", \ + SVGA_STATS_PREFIX "SetSamplerViews", \ + SVGA_STATS_PREFIX "SurfaceFlush", \ + SVGA_STATS_PREFIX "SwtnlDrawVBO", \ + SVGA_STATS_PREFIX "SwtnlUpdateDraw", \ + SVGA_STATS_PREFIX "SwtnlUpdateVDecl", \ + SVGA_STATS_PREFIX "TextureTransferMap", \ + SVGA_STATS_PREFIX "TextureTransferUnmap", \ + SVGA_STATS_PREFIX "TGSIVGPU10Translate", \ + SVGA_STATS_PREFIX "TGSIVGPU9Translate", \ + SVGA_STATS_PREFIX "UpdateState", \ + SVGA_STATS_PREFIX "ValidateSurfaceView", \ + SVGA_STATS_PREFIX "VbufDrawArrays", \ + SVGA_STATS_PREFIX "VbufDrawElements", \ + SVGA_STATS_PREFIX "VbufRenderAllocVertices", \ + SVGA_STATS_PREFIX "VbufRenderMapVertices", \ + SVGA_STATS_PREFIX "VbufRenderUnmapVertices", \ + SVGA_STATS_PREFIX "VbufSubmitState" + + /** Opaque surface handle */ struct svga_winsys_surface; @@ -547,6 +681,25 @@ struct svga_winsys_screen SVGA3dQueryState *queryState, void *result, uint32 resultLen); + /** + * Increment a statistic counter + */ + void + (*stats_inc)(enum svga_stats_count); + + /** + * Push a time frame onto the stack + */ + void + (*stats_time_push)(enum svga_stats_time, struct svga_winsys_stats_timeframe *); + + /** + * Pop a time frame. + */ + void + (*stats_time_pop)(); + + /** Have VGPU v10 hardware? */ boolean have_vgpu10; diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c index f8c9180e9bc..3a936e7e690 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_svga.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c @@ -407,6 +407,22 @@ vmw_svga_winsys_shader_destroy(struct svga_winsys_screen *sws, vmw_svga_winsys_shader_reference(&d_shader, NULL); } +static void +vmw_svga_winsys_stats_inc(enum svga_stats_count index) +{ +} + +static void +vmw_svga_winsys_stats_time_push(enum svga_stats_time index, + struct svga_winsys_stats_timeframe *tf) +{ +} + +static void +vmw_svga_winsys_stats_time_pop() +{ +} + boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws) { @@ -434,6 +450,10 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws) vws->base.query_destroy = vmw_svga_winsys_query_destroy; vws->base.query_get_result = vmw_svga_winsys_query_get_result; + vws->base.stats_inc = vmw_svga_winsys_stats_inc; + vws->base.stats_time_push = vmw_svga_winsys_stats_time_push; + vws->base.stats_time_pop = vmw_svga_winsys_stats_time_pop; + return TRUE; } -- 2.30.2