14a49301eSmrg/**********************************************************
24a49301eSmrg * Copyright 2008-2009 VMware, Inc.  All rights reserved.
34a49301eSmrg *
44a49301eSmrg * Permission is hereby granted, free of charge, to any person
54a49301eSmrg * obtaining a copy of this software and associated documentation
64a49301eSmrg * files (the "Software"), to deal in the Software without
74a49301eSmrg * restriction, including without limitation the rights to use, copy,
84a49301eSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies
94a49301eSmrg * of the Software, and to permit persons to whom the Software is
104a49301eSmrg * furnished to do so, subject to the following conditions:
114a49301eSmrg *
124a49301eSmrg * The above copyright notice and this permission notice shall be
134a49301eSmrg * included in all copies or substantial portions of the Software.
144a49301eSmrg *
154a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
164a49301eSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
174a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
184a49301eSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
194a49301eSmrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
204a49301eSmrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
214a49301eSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
224a49301eSmrg * SOFTWARE.
234a49301eSmrg *
244a49301eSmrg **********************************************************/
254a49301eSmrg
264a49301eSmrg#include "svga_cmd.h"
274a49301eSmrg
284a49301eSmrg#include "pipe/p_defines.h"
29cdc920a0Smrg#include "util/u_inlines.h"
304a49301eSmrg#include "pipe/p_screen.h"
314a49301eSmrg#include "util/u_memory.h"
324a49301eSmrg#include "util/u_bitmask.h"
3301e04c3fSmrg#include "util/u_upload_mgr.h"
344a49301eSmrg
354a49301eSmrg#include "svga_context.h"
364a49301eSmrg#include "svga_screen.h"
373464ebd5Sriastradh#include "svga_surface.h"
383464ebd5Sriastradh#include "svga_resource_texture.h"
393464ebd5Sriastradh#include "svga_resource_buffer.h"
403464ebd5Sriastradh#include "svga_resource.h"
414a49301eSmrg#include "svga_winsys.h"
424a49301eSmrg#include "svga_swtnl.h"
434a49301eSmrg#include "svga_draw.h"
444a49301eSmrg#include "svga_debug.h"
454a49301eSmrg#include "svga_state.h"
4601e04c3fSmrg#include "svga_winsys.h"
477ec681f3Smrg#include "svga_streamout.h"
4801e04c3fSmrg
4901e04c3fSmrg#define CONST0_UPLOAD_DEFAULT_SIZE 65536
504a49301eSmrg
513464ebd5SriastradhDEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", FALSE)
523464ebd5SriastradhDEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", FALSE);
533464ebd5SriastradhDEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", FALSE);
543464ebd5SriastradhDEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", FALSE);
553464ebd5SriastradhDEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", FALSE);
564a49301eSmrg
5701e04c3fSmrg
5801e04c3fSmrgstatic void
5901e04c3fSmrgsvga_destroy(struct pipe_context *pipe)
604a49301eSmrg{
6101e04c3fSmrg   struct svga_context *svga = svga_context(pipe);
6201e04c3fSmrg   unsigned shader, i;
6301e04c3fSmrg
6401e04c3fSmrg   /* free any alternate rasterizer states used for point sprite */
6501e04c3fSmrg   for (i = 0; i < ARRAY_SIZE(svga->rasterizer_no_cull); i++) {
6601e04c3fSmrg      if (svga->rasterizer_no_cull[i]) {
6701e04c3fSmrg         pipe->delete_rasterizer_state(pipe, svga->rasterizer_no_cull[i]);
6801e04c3fSmrg      }
6901e04c3fSmrg   }
704a49301eSmrg
7101e04c3fSmrg   /* free depthstencil_disable state */
7201e04c3fSmrg   if (svga->depthstencil_disable) {
7301e04c3fSmrg      pipe->delete_depth_stencil_alpha_state(pipe, svga->depthstencil_disable);
7401e04c3fSmrg   }
7501e04c3fSmrg
7601e04c3fSmrg   /* free HW constant buffers */
7701e04c3fSmrg   for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) {
787ec681f3Smrg      for (i = 0; i < ARRAY_SIZE(svga->state.hw_draw.constbuf[0]); i++) {
797ec681f3Smrg         pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][i], NULL);
807ec681f3Smrg      }
8101e04c3fSmrg   }
82af69d88dSmrg
8301e04c3fSmrg   pipe->delete_blend_state(pipe, svga->noop_blend);
844a49301eSmrg
857ec681f3Smrg   /* destroy stream output statistics queries */
867ec681f3Smrg   svga_destroy_stream_output_queries(svga);
877ec681f3Smrg
8801e04c3fSmrg   /* free query gb object */
8901e04c3fSmrg   if (svga->gb_query) {
9001e04c3fSmrg      pipe->destroy_query(pipe, NULL);
9101e04c3fSmrg      svga->gb_query = NULL;
9201e04c3fSmrg   }
9301e04c3fSmrg
9401e04c3fSmrg   util_blitter_destroy(svga->blitter);
954a49301eSmrg
9601e04c3fSmrg   svga_cleanup_sampler_state(svga);
9701e04c3fSmrg   svga_cleanup_framebuffer(svga);
9801e04c3fSmrg   svga_cleanup_tss_binding(svga);
994a49301eSmrg   svga_cleanup_vertex_state(svga);
1007ec681f3Smrg   svga_cleanup_tcs_state(svga);
1014a49301eSmrg
10201e04c3fSmrg   svga_destroy_swtnl(svga);
10301e04c3fSmrg   svga_hwtnl_destroy(svga->hwtnl);
10401e04c3fSmrg
10501e04c3fSmrg   svga->swc->destroy(svga->swc);
1064a49301eSmrg
10701e04c3fSmrg   util_bitmask_destroy(svga->blend_object_id_bm);
10801e04c3fSmrg   util_bitmask_destroy(svga->ds_object_id_bm);
10901e04c3fSmrg   util_bitmask_destroy(svga->input_element_object_id_bm);
11001e04c3fSmrg   util_bitmask_destroy(svga->rast_object_id_bm);
11101e04c3fSmrg   util_bitmask_destroy(svga->sampler_object_id_bm);
11201e04c3fSmrg   util_bitmask_destroy(svga->sampler_view_id_bm);
11301e04c3fSmrg   util_bitmask_destroy(svga->shader_id_bm);
11401e04c3fSmrg   util_bitmask_destroy(svga->surface_view_id_bm);
11501e04c3fSmrg   util_bitmask_destroy(svga->stream_output_id_bm);
11601e04c3fSmrg   util_bitmask_destroy(svga->query_id_bm);
11701e04c3fSmrg   u_upload_destroy(svga->const0_upload);
11801e04c3fSmrg   u_upload_destroy(svga->pipe.stream_uploader);
11901e04c3fSmrg   u_upload_destroy(svga->pipe.const_uploader);
12001e04c3fSmrg   svga_texture_transfer_map_upload_destroy(svga);
12101e04c3fSmrg
12201e04c3fSmrg   /* free user's constant buffers */
123af69d88dSmrg   for (shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
12401e04c3fSmrg      for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[shader]); ++i) {
12501e04c3fSmrg         pipe_resource_reference(&svga->curr.constbufs[shader][i].buffer, NULL);
12601e04c3fSmrg      }
127af69d88dSmrg   }
1284a49301eSmrg
12901e04c3fSmrg   FREE(svga);
1304a49301eSmrg}
1314a49301eSmrg
1324a49301eSmrg
13301e04c3fSmrgstruct pipe_context *
13401e04c3fSmrgsvga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
1354a49301eSmrg{
1364a49301eSmrg   struct svga_screen *svgascreen = svga_screen(screen);
1374a49301eSmrg   struct svga_context *svga = NULL;
1384a49301eSmrg   enum pipe_error ret;
1394a49301eSmrg
14001e04c3fSmrg   SVGA_STATS_TIME_PUSH(svgascreen->sws, SVGA_STATS_TIME_CREATECONTEXT);
14101e04c3fSmrg
1424a49301eSmrg   svga = CALLOC_STRUCT(svga_context);
14301e04c3fSmrg   if (!svga)
14401e04c3fSmrg      goto done;
1454a49301eSmrg
1467ec681f3Smrg   list_inithead(&svga->dirty_buffers);
147af69d88dSmrg
1484a49301eSmrg   svga->pipe.screen = screen;
149cdc920a0Smrg   svga->pipe.priv = priv;
1504a49301eSmrg   svga->pipe.destroy = svga_destroy;
15101e04c3fSmrg   svga->pipe.stream_uploader = u_upload_create(&svga->pipe, 1024 * 1024,
15201e04c3fSmrg                                                PIPE_BIND_VERTEX_BUFFER |
15301e04c3fSmrg                                                PIPE_BIND_INDEX_BUFFER,
15401e04c3fSmrg                                                PIPE_USAGE_STREAM, 0);
15501e04c3fSmrg   if (!svga->pipe.stream_uploader)
15601e04c3fSmrg      goto cleanup;
15701e04c3fSmrg
1587ec681f3Smrg   u_upload_disable_persistent(svga->pipe.stream_uploader);
1597ec681f3Smrg
16001e04c3fSmrg   svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024,
16101e04c3fSmrg                                               PIPE_BIND_CONSTANT_BUFFER,
16201e04c3fSmrg                                               PIPE_USAGE_STREAM, 0);
16301e04c3fSmrg   if (!svga->pipe.const_uploader)
16401e04c3fSmrg      goto cleanup;
1654a49301eSmrg
1667ec681f3Smrg   u_upload_disable_persistent(svga->pipe.const_uploader);
1677ec681f3Smrg
1684a49301eSmrg   svga->swc = svgascreen->sws->context_create(svgascreen->sws);
16901e04c3fSmrg   if (!svga->swc)
17001e04c3fSmrg      goto cleanup;
1714a49301eSmrg
1723464ebd5Sriastradh   svga_init_resource_functions(svga);
1734a49301eSmrg   svga_init_blend_functions(svga);
1744a49301eSmrg   svga_init_blit_functions(svga);
1754a49301eSmrg   svga_init_depth_stencil_functions(svga);
1764a49301eSmrg   svga_init_draw_functions(svga);
1774a49301eSmrg   svga_init_flush_functions(svga);
1784a49301eSmrg   svga_init_misc_functions(svga);
1794a49301eSmrg   svga_init_rasterizer_functions(svga);
1804a49301eSmrg   svga_init_sampler_functions(svga);
1814a49301eSmrg   svga_init_fs_functions(svga);
1824a49301eSmrg   svga_init_vs_functions(svga);
18301e04c3fSmrg   svga_init_gs_functions(svga);
1847ec681f3Smrg   svga_init_ts_functions(svga);
1854a49301eSmrg   svga_init_vertex_functions(svga);
1864a49301eSmrg   svga_init_constbuffer_functions(svga);
1874a49301eSmrg   svga_init_query_functions(svga);
1883464ebd5Sriastradh   svga_init_surface_functions(svga);
18901e04c3fSmrg   svga_init_stream_output_functions(svga);
19001e04c3fSmrg   svga_init_clear_functions(svga);
1917ec681f3Smrg   svga_init_tracked_state(svga);
1924a49301eSmrg
19301e04c3fSmrg   /* init misc state */
19401e04c3fSmrg   svga->curr.sample_mask = ~0;
1954a49301eSmrg
1963464ebd5Sriastradh   /* debug */
1973464ebd5Sriastradh   svga->debug.no_swtnl = debug_get_option_no_swtnl();
1983464ebd5Sriastradh   svga->debug.force_swtnl = debug_get_option_force_swtnl();
1993464ebd5Sriastradh   svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap();
2003464ebd5Sriastradh   svga->debug.no_line_width = debug_get_option_no_line_width();
2013464ebd5Sriastradh   svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple();
2024a49301eSmrg
20301e04c3fSmrg   if (!(svga->blend_object_id_bm = util_bitmask_create()))
20401e04c3fSmrg      goto cleanup;
20501e04c3fSmrg
20601e04c3fSmrg   if (!(svga->ds_object_id_bm = util_bitmask_create()))
20701e04c3fSmrg      goto cleanup;
20801e04c3fSmrg
20901e04c3fSmrg   if (!(svga->input_element_object_id_bm = util_bitmask_create()))
21001e04c3fSmrg      goto cleanup;
21101e04c3fSmrg
21201e04c3fSmrg   if (!(svga->rast_object_id_bm = util_bitmask_create()))
21301e04c3fSmrg      goto cleanup;
21401e04c3fSmrg
21501e04c3fSmrg   if (!(svga->sampler_object_id_bm = util_bitmask_create()))
21601e04c3fSmrg      goto cleanup;
21701e04c3fSmrg
21801e04c3fSmrg   if (!(svga->sampler_view_id_bm = util_bitmask_create()))
21901e04c3fSmrg      goto cleanup;
22001e04c3fSmrg
22101e04c3fSmrg   if (!(svga->shader_id_bm = util_bitmask_create()))
22201e04c3fSmrg      goto cleanup;
22301e04c3fSmrg
22401e04c3fSmrg   if (!(svga->surface_view_id_bm = util_bitmask_create()))
22501e04c3fSmrg      goto cleanup;
22601e04c3fSmrg
22701e04c3fSmrg   if (!(svga->stream_output_id_bm = util_bitmask_create()))
22801e04c3fSmrg      goto cleanup;
22901e04c3fSmrg
23001e04c3fSmrg   if (!(svga->query_id_bm = util_bitmask_create()))
23101e04c3fSmrg      goto cleanup;
232af69d88dSmrg
233af69d88dSmrg   svga->hwtnl = svga_hwtnl_create(svga);
2344a49301eSmrg   if (svga->hwtnl == NULL)
23501e04c3fSmrg      goto cleanup;
2364a49301eSmrg
2373464ebd5Sriastradh   if (!svga_init_swtnl(svga))
23801e04c3fSmrg      goto cleanup;
2394a49301eSmrg
24001e04c3fSmrg   ret = svga_emit_initial_state(svga);
241af69d88dSmrg   if (ret != PIPE_OK)
24201e04c3fSmrg      goto cleanup;
24301e04c3fSmrg
24401e04c3fSmrg   svga->const0_upload = u_upload_create(&svga->pipe,
24501e04c3fSmrg                                         CONST0_UPLOAD_DEFAULT_SIZE,
2469f464c52Smaya                                         PIPE_BIND_CONSTANT_BUFFER |
2479f464c52Smaya                                         PIPE_BIND_CUSTOM,
24801e04c3fSmrg                                         PIPE_USAGE_STREAM, 0);
24901e04c3fSmrg   if (!svga->const0_upload)
25001e04c3fSmrg      goto cleanup;
25101e04c3fSmrg
2527ec681f3Smrg   u_upload_disable_persistent(svga->const0_upload);
2537ec681f3Smrg
25401e04c3fSmrg   if (!svga_texture_transfer_map_upload_create(svga))
25501e04c3fSmrg      goto cleanup;
25601e04c3fSmrg
2574a49301eSmrg   /* Avoid shortcircuiting state with initial value of zero.
2584a49301eSmrg    */
2594a49301eSmrg   memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear));
26001e04c3fSmrg   memset(&svga->state.hw_clear.framebuffer, 0x0,
2614a49301eSmrg          sizeof(svga->state.hw_clear.framebuffer));
2627ec681f3Smrg   memset(&svga->state.hw_clear.rtv, 0, sizeof(svga->state.hw_clear.rtv));
26301e04c3fSmrg   svga->state.hw_clear.num_rendertargets = 0;
26401e04c3fSmrg   svga->state.hw_clear.dsv = NULL;
2654a49301eSmrg
2664a49301eSmrg   memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
2674a49301eSmrg   memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
26801e04c3fSmrg   memset(&svga->state.hw_draw.num_samplers, 0,
26901e04c3fSmrg      sizeof(svga->state.hw_draw.num_samplers));
27001e04c3fSmrg   memset(&svga->state.hw_draw.num_sampler_views, 0,
27101e04c3fSmrg      sizeof(svga->state.hw_draw.num_sampler_views));
27201e04c3fSmrg   memset(svga->state.hw_draw.sampler_views, 0,
27301e04c3fSmrg          sizeof(svga->state.hw_draw.sampler_views));
2744a49301eSmrg   svga->state.hw_draw.num_views = 0;
27501e04c3fSmrg   svga->state.hw_draw.num_backed_views = 0;
27601e04c3fSmrg   svga->state.hw_draw.rasterizer_discard = FALSE;
27701e04c3fSmrg
27801e04c3fSmrg   /* Initialize the shader pointers */
27901e04c3fSmrg   svga->state.hw_draw.vs = NULL;
28001e04c3fSmrg   svga->state.hw_draw.gs = NULL;
28101e04c3fSmrg   svga->state.hw_draw.fs = NULL;
2827ec681f3Smrg   svga->state.hw_draw.tcs = NULL;
2837ec681f3Smrg   svga->state.hw_draw.tes = NULL;
28401e04c3fSmrg
28501e04c3fSmrg   /* Initialize the currently bound buffer resources */
28601e04c3fSmrg   memset(svga->state.hw_draw.constbuf, 0,
28701e04c3fSmrg          sizeof(svga->state.hw_draw.constbuf));
28801e04c3fSmrg   memset(svga->state.hw_draw.default_constbuf_size, 0,
28901e04c3fSmrg          sizeof(svga->state.hw_draw.default_constbuf_size));
29001e04c3fSmrg   memset(svga->state.hw_draw.enabled_constbufs, 0,
29101e04c3fSmrg          sizeof(svga->state.hw_draw.enabled_constbufs));
29201e04c3fSmrg   svga->state.hw_draw.ib = NULL;
29301e04c3fSmrg   svga->state.hw_draw.num_vbuffers = 0;
29401e04c3fSmrg   memset(svga->state.hw_draw.vbuffers, 0,
29501e04c3fSmrg          sizeof(svga->state.hw_draw.vbuffers));
29601e04c3fSmrg   svga->state.hw_draw.const0_buffer = NULL;
29701e04c3fSmrg   svga->state.hw_draw.const0_handle = NULL;
29801e04c3fSmrg
29901e04c3fSmrg   /* Create a no-operation blend state which we will bind whenever the
30001e04c3fSmrg    * requested blend state is impossible (e.g. due to having an integer
30101e04c3fSmrg    * render target attached).
30201e04c3fSmrg    *
30301e04c3fSmrg    * XXX: We will probably actually need 16 of these, one for each possible
30401e04c3fSmrg    * RGBA color mask (4 bits).  Then, we would bind the one with a color mask
30501e04c3fSmrg    * matching the blend state it is replacing.
30601e04c3fSmrg    */
30701e04c3fSmrg   {
30801e04c3fSmrg      struct pipe_blend_state noop_tmpl = {0};
30901e04c3fSmrg      unsigned i;
31001e04c3fSmrg
31101e04c3fSmrg      for (i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
31201e04c3fSmrg         // Set the color mask to all-ones.  Later this may change.
31301e04c3fSmrg         noop_tmpl.rt[i].colormask = PIPE_MASK_RGBA;
31401e04c3fSmrg      }
31501e04c3fSmrg      svga->noop_blend = svga->pipe.create_blend_state(&svga->pipe, &noop_tmpl);
31601e04c3fSmrg   }
3174a49301eSmrg
3187ec681f3Smrg   svga->dirty = SVGA_NEW_ALL;
31901e04c3fSmrg   svga->pred.query_id = SVGA3D_INVALID_ID;
32001e04c3fSmrg   svga->disable_rasterizer = FALSE;
3214a49301eSmrg
3227ec681f3Smrg   /**
3237ec681f3Smrg    * Create stream output statistics queries used in the workaround for auto
3247ec681f3Smrg    * draw with stream instancing.
3257ec681f3Smrg    */
3267ec681f3Smrg   svga_create_stream_output_queries(svga);
3277ec681f3Smrg
32801e04c3fSmrg   goto done;
3294a49301eSmrg
33001e04c3fSmrgcleanup:
3313464ebd5Sriastradh   svga_destroy_swtnl(svga);
33201e04c3fSmrg
33301e04c3fSmrg   if (svga->const0_upload)
33401e04c3fSmrg      u_upload_destroy(svga->const0_upload);
33501e04c3fSmrg   if (svga->pipe.const_uploader)
33601e04c3fSmrg      u_upload_destroy(svga->pipe.const_uploader);
33701e04c3fSmrg   if (svga->pipe.stream_uploader)
33801e04c3fSmrg      u_upload_destroy(svga->pipe.stream_uploader);
33901e04c3fSmrg   svga_texture_transfer_map_upload_destroy(svga);
34001e04c3fSmrg   if (svga->hwtnl)
34101e04c3fSmrg      svga_hwtnl_destroy(svga->hwtnl);
34201e04c3fSmrg   if (svga->swc)
34301e04c3fSmrg      svga->swc->destroy(svga->swc);
34401e04c3fSmrg   util_bitmask_destroy(svga->blend_object_id_bm);
34501e04c3fSmrg   util_bitmask_destroy(svga->ds_object_id_bm);
34601e04c3fSmrg   util_bitmask_destroy(svga->input_element_object_id_bm);
34701e04c3fSmrg   util_bitmask_destroy(svga->rast_object_id_bm);
34801e04c3fSmrg   util_bitmask_destroy(svga->sampler_object_id_bm);
34901e04c3fSmrg   util_bitmask_destroy(svga->sampler_view_id_bm);
35001e04c3fSmrg   util_bitmask_destroy(svga->shader_id_bm);
35101e04c3fSmrg   util_bitmask_destroy(svga->surface_view_id_bm);
35201e04c3fSmrg   util_bitmask_destroy(svga->stream_output_id_bm);
35301e04c3fSmrg   util_bitmask_destroy(svga->query_id_bm);
3544a49301eSmrg   FREE(svga);
35501e04c3fSmrg   svga = NULL;
35601e04c3fSmrg
35701e04c3fSmrgdone:
35801e04c3fSmrg   SVGA_STATS_TIME_POP(svgascreen->sws);
35901e04c3fSmrg   return svga ? &svga->pipe:NULL;
3604a49301eSmrg}
3614a49301eSmrg
3624a49301eSmrg
36301e04c3fSmrgvoid
36401e04c3fSmrgsvga_context_flush(struct svga_context *svga,
36501e04c3fSmrg                   struct pipe_fence_handle **pfence)
3664a49301eSmrg{
3674a49301eSmrg   struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
3683464ebd5Sriastradh   struct pipe_fence_handle *fence = NULL;
36901e04c3fSmrg   uint64_t t0;
37001e04c3fSmrg
37101e04c3fSmrg   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFLUSH);
3724a49301eSmrg
3734a49301eSmrg   svga->curr.nr_fbs = 0;
3744a49301eSmrg
37501e04c3fSmrg   /* Unmap the 0th/default constant buffer.  The u_upload_unmap() function
37601e04c3fSmrg    * will call pipe_context::transfer_flush_region() to indicate the
37701e04c3fSmrg    * region of the buffer which was modified (and needs to be uploaded).
37801e04c3fSmrg    */
37901e04c3fSmrg   if (svga->state.hw_draw.const0_handle) {
38001e04c3fSmrg      assert(svga->state.hw_draw.const0_buffer);
38101e04c3fSmrg      u_upload_unmap(svga->const0_upload);
38201e04c3fSmrg      pipe_resource_reference(&svga->state.hw_draw.const0_buffer, NULL);
38301e04c3fSmrg      svga->state.hw_draw.const0_handle = NULL;
38401e04c3fSmrg   }
38501e04c3fSmrg
3863464ebd5Sriastradh   /* Ensure that texture dma uploads are processed
3874a49301eSmrg    * before submitting commands.
3884a49301eSmrg    */
3894a49301eSmrg   svga_context_flush_buffers(svga);
3904a49301eSmrg
39101e04c3fSmrg   svga->hud.command_buffer_size +=
39201e04c3fSmrg      svga->swc->get_command_buffer_size(svga->swc);
39301e04c3fSmrg
3944a49301eSmrg   /* Flush pending commands to hardware:
3954a49301eSmrg    */
39601e04c3fSmrg   t0 = svga_get_time(svga);
3973464ebd5Sriastradh   svga->swc->flush(svga->swc, &fence);
39801e04c3fSmrg   svga->hud.flush_time += (svga_get_time(svga) - t0);
3993464ebd5Sriastradh
40001e04c3fSmrg   svga->hud.num_flushes++;
40101e04c3fSmrg
40201e04c3fSmrg   svga_screen_cache_flush(svgascreen, svga, fence);
40301e04c3fSmrg
40401e04c3fSmrg   SVGA3D_ResetLastCommand(svga->swc);
4053464ebd5Sriastradh
4063464ebd5Sriastradh   /* To force the re-emission of rendertargets and texture sampler bindings on
4073464ebd5Sriastradh    * the next command buffer.
4083464ebd5Sriastradh    */
40901e04c3fSmrg   svga->rebind.flags.rendertargets = TRUE;
41001e04c3fSmrg   svga->rebind.flags.texture_samplers = TRUE;
41101e04c3fSmrg
412af69d88dSmrg   if (svga_have_gb_objects(svga)) {
41301e04c3fSmrg
41401e04c3fSmrg      svga->rebind.flags.constbufs = TRUE;
41501e04c3fSmrg      svga->rebind.flags.vs = TRUE;
41601e04c3fSmrg      svga->rebind.flags.fs = TRUE;
41701e04c3fSmrg      svga->rebind.flags.gs = TRUE;
41801e04c3fSmrg
4197ec681f3Smrg      if (svga_have_sm5(svga)) {
4207ec681f3Smrg         svga->rebind.flags.tcs = TRUE;
4217ec681f3Smrg         svga->rebind.flags.tes = TRUE;
4227ec681f3Smrg      }
4237ec681f3Smrg
42401e04c3fSmrg      if (svga_need_to_rebind_resources(svga)) {
42501e04c3fSmrg         svga->rebind.flags.query = TRUE;
42601e04c3fSmrg      }
427af69d88dSmrg   }
4284a49301eSmrg
4294a49301eSmrg   if (SVGA_DEBUG & DEBUG_SYNC) {
4303464ebd5Sriastradh      if (fence)
43101e04c3fSmrg         svga->pipe.screen->fence_finish(svga->pipe.screen, NULL, fence,
4323464ebd5Sriastradh                                          PIPE_TIMEOUT_INFINITE);
4334a49301eSmrg   }
4343464ebd5Sriastradh
43501e04c3fSmrg   if (pfence)
436af69d88dSmrg      svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence);
437af69d88dSmrg
438af69d88dSmrg   svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
43901e04c3fSmrg
44001e04c3fSmrg   SVGA_STATS_TIME_POP(svga_sws(svga));
4414a49301eSmrg}
4424a49301eSmrg
4434a49301eSmrg
44401e04c3fSmrg/**
44501e04c3fSmrg * Flush pending commands and wait for completion with a fence.
44601e04c3fSmrg */
44701e04c3fSmrgvoid
44801e04c3fSmrgsvga_context_finish(struct svga_context *svga)
44901e04c3fSmrg{
45001e04c3fSmrg   struct pipe_screen *screen = svga->pipe.screen;
45101e04c3fSmrg   struct pipe_fence_handle *fence = NULL;
45201e04c3fSmrg
45301e04c3fSmrg   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFINISH);
45401e04c3fSmrg
45501e04c3fSmrg   svga_context_flush(svga, &fence);
45601e04c3fSmrg   screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
45701e04c3fSmrg   screen->fence_reference(screen, &fence, NULL);
45801e04c3fSmrg
45901e04c3fSmrg   SVGA_STATS_TIME_POP(svga_sws(svga));
46001e04c3fSmrg}
46101e04c3fSmrg
46201e04c3fSmrg
46301e04c3fSmrg/**
46401e04c3fSmrg * Emit pending drawing commands to the command buffer.
46501e04c3fSmrg * If the command buffer overflows, we flush it and retry.
46601e04c3fSmrg * \sa svga_hwtnl_flush()
46701e04c3fSmrg */
46801e04c3fSmrgvoid
46901e04c3fSmrgsvga_hwtnl_flush_retry(struct svga_context *svga)
4704a49301eSmrg{
4714a49301eSmrg   enum pipe_error ret = PIPE_OK;
4724a49301eSmrg
4737ec681f3Smrg   SVGA_RETRY_OOM(svga, ret, svga_hwtnl_flush(svga->hwtnl));
47401e04c3fSmrg   assert(ret == PIPE_OK);
4754a49301eSmrg}
4764a49301eSmrg
4773464ebd5Sriastradh
478af69d88dSmrg/**
479af69d88dSmrg * Flush the primitive queue if this buffer is referred.
480af69d88dSmrg *
481af69d88dSmrg * Otherwise DMA commands on the referred buffer will be emitted too late.
482af69d88dSmrg */
48301e04c3fSmrgvoid
48401e04c3fSmrgsvga_hwtnl_flush_buffer(struct svga_context *svga,
48501e04c3fSmrg                        struct pipe_resource *buffer)
486af69d88dSmrg{
487af69d88dSmrg   if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) {
488af69d88dSmrg      svga_hwtnl_flush_retry(svga);
489af69d88dSmrg   }
490af69d88dSmrg}
491af69d88dSmrg
492af69d88dSmrg
49301e04c3fSmrg/**
49401e04c3fSmrg * Emit all operations pending on host surfaces.
49501e04c3fSmrg */
49601e04c3fSmrgvoid
49701e04c3fSmrgsvga_surfaces_flush(struct svga_context *svga)
4983464ebd5Sriastradh{
49901e04c3fSmrg   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SURFACEFLUSH);
5003464ebd5Sriastradh
5013464ebd5Sriastradh   /* Emit buffered drawing commands.
5023464ebd5Sriastradh    */
50301e04c3fSmrg   svga_hwtnl_flush_retry(svga);
5043464ebd5Sriastradh
50501e04c3fSmrg   /* Emit back-copy from render target views to textures.
5063464ebd5Sriastradh    */
50701e04c3fSmrg   svga_propagate_rendertargets(svga);
5083464ebd5Sriastradh
50901e04c3fSmrg   SVGA_STATS_TIME_POP(svga_sws(svga));
5103464ebd5Sriastradh}
5113464ebd5Sriastradh
5123464ebd5Sriastradh
5133464ebd5Sriastradhstruct svga_winsys_context *
51401e04c3fSmrgsvga_winsys_context(struct pipe_context *pipe)
5153464ebd5Sriastradh{
51601e04c3fSmrg   return svga_context(pipe)->swc;
5173464ebd5Sriastradh}
518