svga_context.c revision b8e80941
11.403Snakayama/**********************************************************
21.1Scgd * Copyright 2008-2009 VMware, Inc.  All rights reserved.
31.25Spk *
41.1Scgd * Permission is hereby granted, free of charge, to any person
51.1Scgd * obtaining a copy of this software and associated documentation
61.28Senami * files (the "Software"), to deal in the Software without
71.145Slukem * restriction, including without limitation the rights to use, copy,
81.148Ssimonb * modify, merge, publish, distribute, sublicense, and/or sell copies
91.1Scgd * of the Software, and to permit persons to whom the Software is
101.149Swiz * furnished to do so, subject to the following conditions:
111.149Swiz *
121.149Swiz * The above copyright notice and this permission notice shall be
131.90Swiz * included in all copies or substantial portions of the Software.
141.101Sbouyer *
151.145Slukem * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
161.230Srearnsha * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
171.199Smatt * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
181.33Sthorpej * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
191.13Sthorpej * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
201.123Slukem * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
211.26Smycroft * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
221.38Scgd * SOFTWARE.
231.11Scgd *
241.346Sdyoung **********************************************************/
251.139Sthorpej
261.165Sthorpej#include "svga_cmd.h"
271.1Scgd
281.219Sdrochner#include "pipe/p_defines.h"
291.219Sdrochner#include "util/u_inlines.h"
301.329Spgoyette#include "pipe/p_screen.h"
311.329Spgoyette#include "util/u_memory.h"
321.336Scegger#include "util/u_bitmask.h"
331.336Scegger#include "util/u_upload_mgr.h"
341.96Sthorpej
351.96Sthorpej#include "svga_context.h"
361.96Sthorpej#include "svga_screen.h"
371.96Sthorpej#include "svga_surface.h"
381.96Sthorpej#include "svga_resource_texture.h"
391.96Sthorpej#include "svga_resource_buffer.h"
401.96Sthorpej#include "svga_resource.h"
411.96Sthorpej#include "svga_winsys.h"
421.96Sthorpej#include "svga_swtnl.h"
431.96Sthorpej#include "svga_draw.h"
441.96Sthorpej#include "svga_debug.h"
451.16Smycroft#include "svga_state.h"
461.16Smycroft#include "svga_winsys.h"
471.75Sthorpej
481.16Smycroft#define CONST0_UPLOAD_DEFAULT_SIZE 65536
491.186Sfvdl
501.186SfvdlDEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", FALSE)
511.186SfvdlDEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", FALSE);
521.103SadDEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", FALSE);
531.108SadDEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", FALSE);
541.108SadDEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", FALSE);
551.108Sad
561.108Sad
571.103Sadstatic void
581.103Sadsvga_destroy(struct pipe_context *pipe)
591.103Sad{
601.103Sad   struct svga_context *svga = svga_context(pipe);
611.103Sad   unsigned shader, i;
621.110Sad
631.110Sad   /* free any alternate rasterizer states used for point sprite */
641.161Sad   for (i = 0; i < ARRAY_SIZE(svga->rasterizer_no_cull); i++) {
651.254Swrstuden      if (svga->rasterizer_no_cull[i]) {
661.254Swrstuden         pipe->delete_rasterizer_state(pipe, svga->rasterizer_no_cull[i]);
671.254Swrstuden      }
681.254Swrstuden   }
691.254Swrstuden
701.254Swrstuden   /* free depthstencil_disable state */
711.254Swrstuden   if (svga->depthstencil_disable) {
721.161Sad      pipe->delete_depth_stencil_alpha_state(pipe, svga->depthstencil_disable);
731.161Sad   }
741.161Sad
751.161Sad   /* free HW constant buffers */
761.161Sad   for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) {
771.161Sad      pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], NULL);
781.161Sad   }
791.78Sad
801.297Sxtraeme   pipe->delete_blend_state(pipe, svga->noop_blend);
811.335Smatt
821.298Sxtraeme   /* free query gb object */
831.298Sxtraeme   if (svga->gb_query) {
841.297Sxtraeme      pipe->destroy_query(pipe, NULL);
851.78Sad      svga->gb_query = NULL;
861.78Sad   }
871.78Sad
881.119Sad   util_blitter_destroy(svga->blitter);
891.134Sad
901.119Sad   svga_cleanup_sampler_state(svga);
911.119Sad   svga_cleanup_framebuffer(svga);
921.134Sad   svga_cleanup_tss_binding(svga);
931.134Sad   svga_cleanup_vertex_state(svga);
941.134Sad
951.134Sad   svga_destroy_swtnl(svga);
961.135Sad   svga_hwtnl_destroy(svga->hwtnl);
971.184Smartin
981.184Smartin   svga->swc->destroy(svga->swc);
991.184Smartin
1001.184Smartin   util_bitmask_destroy(svga->blend_object_id_bm);
1011.170Sad   util_bitmask_destroy(svga->ds_object_id_bm);
1021.170Sad   util_bitmask_destroy(svga->input_element_object_id_bm);
1031.170Sad   util_bitmask_destroy(svga->rast_object_id_bm);
1041.170Sad   util_bitmask_destroy(svga->sampler_object_id_bm);
1051.172Sad   util_bitmask_destroy(svga->sampler_view_id_bm);
1061.172Sad   util_bitmask_destroy(svga->shader_id_bm);
1071.172Sad   util_bitmask_destroy(svga->surface_view_id_bm);
1081.172Sad   util_bitmask_destroy(svga->stream_output_id_bm);
1091.63Sad   util_bitmask_destroy(svga->query_id_bm);
1101.392Sjdolecek   u_upload_destroy(svga->const0_upload);
1111.392Sjdolecek   u_upload_destroy(svga->pipe.stream_uploader);
1121.392Sjdolecek   u_upload_destroy(svga->pipe.const_uploader);
1131.392Sjdolecek   svga_texture_transfer_map_upload_destroy(svga);
1141.392Sjdolecek
1151.63Sad   /* free user's constant buffers */
1161.63Sad   for (shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
1171.63Sad      for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[shader]); ++i) {
1181.45Sdante         pipe_resource_reference(&svga->curr.constbufs[shader][i].buffer, NULL);
1191.45Sdante      }
1201.45Sdante   }
1211.45Sdante
1221.45Sdante   FREE(svga);
1231.46Sdante}
1241.46Sdante
1251.46Sdante
1261.123Slukemstruct pipe_context *
1271.123Slukemsvga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
1281.123Slukem{
1291.123Slukem   struct svga_screen *svgascreen = svga_screen(screen);
1301.51Sthorpej   struct svga_context *svga = NULL;
1311.51Sthorpej   enum pipe_error ret;
1321.51Sthorpej
1331.51Sthorpej   SVGA_STATS_TIME_PUSH(svgascreen->sws, SVGA_STATS_TIME_CREATECONTEXT);
1341.51Sthorpej
1351.19Smycroft   svga = CALLOC_STRUCT(svga_context);
1361.245She   if (!svga)
1371.245She      goto done;
1381.245She
1391.245She   LIST_INITHEAD(&svga->dirty_buffers);
1401.19Smycroft
1411.27Smycroft   svga->pipe.screen = screen;
1421.19Smycroft   svga->pipe.priv = priv;
1431.19Smycroft   svga->pipe.destroy = svga_destroy;
1441.22Scgd   svga->pipe.stream_uploader = u_upload_create(&svga->pipe, 1024 * 1024,
1451.22Scgd                                                PIPE_BIND_VERTEX_BUFFER |
1461.22Scgd                                                PIPE_BIND_INDEX_BUFFER,
1471.22Scgd                                                PIPE_USAGE_STREAM, 0);
1481.22Scgd   if (!svga->pipe.stream_uploader)
1491.173Smatt      goto cleanup;
1501.274Sbouyer
1511.274Sbouyer   svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024,
1521.274Sbouyer                                               PIPE_BIND_CONSTANT_BUFFER,
1531.274Sbouyer                                               PIPE_USAGE_STREAM, 0);
1541.274Sbouyer   if (!svga->pipe.const_uploader)
1551.173Smatt      goto cleanup;
1561.173Smatt
1571.185Sthorpej   svga->swc = svgascreen->sws->context_create(svgascreen->sws);
1581.185Sthorpej   if (!svga->swc)
1591.10Scgd      goto cleanup;
1601.357Sbouyer
1611.357Sbouyer   svga_init_resource_functions(svga);
1621.357Sbouyer   svga_init_blend_functions(svga);
1631.357Sbouyer   svga_init_blit_functions(svga);
1641.357Sbouyer   svga_init_depth_stencil_functions(svga);
1651.3Scgd   svga_init_draw_functions(svga);
1661.33Sthorpej   svga_init_flush_functions(svga);
1671.13Sthorpej   svga_init_misc_functions(svga);
1681.3Scgd   svga_init_rasterizer_functions(svga);
1691.7Scgd   svga_init_sampler_functions(svga);
1701.18Scgd   svga_init_fs_functions(svga);
1711.18Scgd   svga_init_vs_functions(svga);
1721.18Scgd   svga_init_gs_functions(svga);
1731.18Scgd   svga_init_vertex_functions(svga);
1741.49Sfvdl   svga_init_constbuffer_functions(svga);
1751.49Sfvdl   svga_init_query_functions(svga);
1761.49Sfvdl   svga_init_surface_functions(svga);
1771.49Sfvdl   svga_init_stream_output_functions(svga);
1781.49Sfvdl   svga_init_clear_functions(svga);
1791.18Scgd
1801.7Scgd   /* init misc state */
1811.33Sthorpej   svga->curr.sample_mask = ~0;
1821.13Sthorpej
1831.7Scgd   /* debug */
1841.7Scgd   svga->debug.no_swtnl = debug_get_option_no_swtnl();
1851.18Scgd   svga->debug.force_swtnl = debug_get_option_force_swtnl();
1861.18Scgd   svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap();
1871.42Sdrochner   svga->debug.no_line_width = debug_get_option_no_line_width();
1881.18Scgd   svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple();
1891.137Sthorpej
1901.137Sthorpej   if (!(svga->blend_object_id_bm = util_bitmask_create()))
1911.137Sthorpej      goto cleanup;
1921.137Sthorpej
1931.137Sthorpej   if (!(svga->ds_object_id_bm = util_bitmask_create()))
1941.137Sthorpej      goto cleanup;
1951.88Sbouyer
1961.93Sbouyer   if (!(svga->input_element_object_id_bm = util_bitmask_create()))
1971.123Slukem      goto cleanup;
1981.93Sbouyer
1991.93Sbouyer   if (!(svga->rast_object_id_bm = util_bitmask_create()))
2001.88Sbouyer      goto cleanup;
2011.88Sbouyer
2021.93Sbouyer   if (!(svga->sampler_object_id_bm = util_bitmask_create()))
2031.123Slukem      goto cleanup;
2041.169Sbouyer
2051.169Sbouyer   if (!(svga->sampler_view_id_bm = util_bitmask_create()))
2061.130Stsutsui      goto cleanup;
2071.130Stsutsui
2081.130Stsutsui   if (!(svga->shader_id_bm = util_bitmask_create()))
2091.130Stsutsui      goto cleanup;
2101.143Stsutsui
2111.143Stsutsui   if (!(svga->surface_view_id_bm = util_bitmask_create()))
2121.143Stsutsui      goto cleanup;
2131.143Stsutsui
2141.143Stsutsui   if (!(svga->stream_output_id_bm = util_bitmask_create()))
2151.153Saugustss      goto cleanup;
2161.153Saugustss
2171.177Saugustss   if (!(svga->query_id_bm = util_bitmask_create()))
2181.177Saugustss      goto cleanup;
2191.177Saugustss
2201.153Saugustss   svga->hwtnl = svga_hwtnl_create(svga);
2211.153Saugustss   if (svga->hwtnl == NULL)
2221.158Sdrochner      goto cleanup;
2231.153Saugustss
2241.153Saugustss   if (!svga_init_swtnl(svga))
2251.34Scgd      goto cleanup;
2261.47Sbouyer
2271.197Sbouyer   ret = svga_emit_initial_state(svga);
2281.197Sbouyer   if (ret != PIPE_OK)
2291.197Sbouyer      goto cleanup;
2301.237Sdrochner
2311.47Sbouyer   svga->const0_upload = u_upload_create(&svga->pipe,
2321.47Sbouyer                                         CONST0_UPLOAD_DEFAULT_SIZE,
2331.197Sbouyer                                         PIPE_BIND_CONSTANT_BUFFER |
2341.273Sbouyer                                         PIPE_BIND_CUSTOM,
2351.287Sbouyer                                         PIPE_USAGE_STREAM, 0);
2361.287Sbouyer   if (!svga->const0_upload)
2371.273Sbouyer      goto cleanup;
2381.197Sbouyer
2391.267Sitohy   if (!svga_texture_transfer_map_upload_create(svga))
2401.197Sbouyer      goto cleanup;
2411.197Sbouyer
2421.197Sbouyer   /* Avoid shortcircuiting state with initial value of zero.
2431.197Sbouyer    */
2441.267Sitohy   memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear));
2451.197Sbouyer   memset(&svga->state.hw_clear.framebuffer, 0x0,
2461.197Sbouyer          sizeof(svga->state.hw_clear.framebuffer));
2471.204Sthorpej   svga->state.hw_clear.num_rendertargets = 0;
2481.204Sthorpej   svga->state.hw_clear.dsv = NULL;
2491.267Sitohy
2501.204Sthorpej   memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
2511.204Sthorpej   memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
2521.197Sbouyer   memset(&svga->state.hw_draw.num_samplers, 0,
2531.197Sbouyer      sizeof(svga->state.hw_draw.num_samplers));
2541.267Sitohy   memset(&svga->state.hw_draw.num_sampler_views, 0,
2551.197Sbouyer      sizeof(svga->state.hw_draw.num_sampler_views));
2561.197Sbouyer   memset(svga->state.hw_draw.sampler_views, 0,
2571.197Sbouyer          sizeof(svga->state.hw_draw.sampler_views));
2581.197Sbouyer   svga->state.hw_draw.num_views = 0;
2591.267Sitohy   svga->state.hw_draw.num_backed_views = 0;
2601.197Sbouyer   svga->state.hw_draw.rasterizer_discard = FALSE;
2611.197Sbouyer
2621.197Sbouyer   /* Initialize the shader pointers */
2631.214Sbouyer   svga->state.hw_draw.vs = NULL;
2641.267Sitohy   svga->state.hw_draw.gs = NULL;
2651.214Sbouyer   svga->state.hw_draw.fs = NULL;
2661.214Sbouyer
2671.214Sbouyer   /* Initialize the currently bound buffer resources */
2681.197Sbouyer   memset(svga->state.hw_draw.constbuf, 0,
2691.267Sitohy          sizeof(svga->state.hw_draw.constbuf));
2701.197Sbouyer   memset(svga->state.hw_draw.default_constbuf_size, 0,
2711.197Sbouyer          sizeof(svga->state.hw_draw.default_constbuf_size));
2721.197Sbouyer   memset(svga->state.hw_draw.enabled_constbufs, 0,
2731.225Sgrant          sizeof(svga->state.hw_draw.enabled_constbufs));
2741.267Sitohy   svga->state.hw_draw.ib = NULL;
2751.225Sgrant   svga->state.hw_draw.num_vbuffers = 0;
2761.225Sgrant   memset(svga->state.hw_draw.vbuffers, 0,
2771.225Sgrant          sizeof(svga->state.hw_draw.vbuffers));
2781.288Sbouyer   svga->state.hw_draw.const0_buffer = NULL;
2791.288Sbouyer   svga->state.hw_draw.const0_handle = NULL;
2801.288Sbouyer
2811.288Sbouyer   /* Create a no-operation blend state which we will bind whenever the
2821.288Sbouyer    * requested blend state is impossible (e.g. due to having an integer
2831.288Sbouyer    * render target attached).
2841.288Sbouyer    *
2851.333Sskrll    * XXX: We will probably actually need 16 of these, one for each possible
2861.333Sskrll    * RGBA color mask (4 bits).  Then, we would bind the one with a color mask
2871.333Sskrll    * matching the blend state it is replacing.
2881.333Sskrll    */
2891.333Sskrll   {
2901.197Sbouyer      struct pipe_blend_state noop_tmpl = {0};
2911.267Sitohy      unsigned i;
2921.197Sbouyer
2931.197Sbouyer      for (i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
2941.197Sbouyer         // Set the color mask to all-ones.  Later this may change.
2951.197Sbouyer         noop_tmpl.rt[i].colormask = PIPE_MASK_RGBA;
2961.267Sitohy      }
2971.197Sbouyer      svga->noop_blend = svga->pipe.create_blend_state(&svga->pipe, &noop_tmpl);
2981.197Sbouyer   }
2991.197Sbouyer
3001.224Sbouyer   svga->dirty = ~0;
3011.270Sbouyer   svga->pred.query_id = SVGA3D_INVALID_ID;
3021.224Sbouyer   svga->disable_rasterizer = FALSE;
3031.224Sbouyer
3041.224Sbouyer   goto done;
3051.197Sbouyer
3061.267Sitohycleanup:
3071.197Sbouyer   svga_destroy_swtnl(svga);
3081.197Sbouyer
3091.201Smycroft   if (svga->const0_upload)
3101.201Smycroft      u_upload_destroy(svga->const0_upload);
3111.267Sitohy   if (svga->pipe.const_uploader)
3121.201Smycroft      u_upload_destroy(svga->pipe.const_uploader);
3131.201Smycroft   if (svga->pipe.stream_uploader)
3141.203Sthorpej      u_upload_destroy(svga->pipe.stream_uploader);
3151.340Sbouyer   svga_texture_transfer_map_upload_destroy(svga);
3161.340Sbouyer   if (svga->hwtnl)
3171.340Sbouyer      svga_hwtnl_destroy(svga->hwtnl);
3181.340Sbouyer   if (svga->swc)
3191.340Sbouyer      svga->swc->destroy(svga->swc);
3201.243Sbouyer   util_bitmask_destroy(svga->blend_object_id_bm);
3211.267Sitohy   util_bitmask_destroy(svga->ds_object_id_bm);
3221.243Sbouyer   util_bitmask_destroy(svga->input_element_object_id_bm);
3231.243Sbouyer   util_bitmask_destroy(svga->rast_object_id_bm);
3241.243Sbouyer   util_bitmask_destroy(svga->sampler_object_id_bm);
3251.203Sthorpej   util_bitmask_destroy(svga->sampler_view_id_bm);
3261.267Sitohy   util_bitmask_destroy(svga->shader_id_bm);
3271.203Sthorpej   util_bitmask_destroy(svga->surface_view_id_bm);
3281.203Sthorpej   util_bitmask_destroy(svga->stream_output_id_bm);
3291.197Sbouyer   util_bitmask_destroy(svga->query_id_bm);
3301.331Sjakllsch   FREE(svga);
3311.331Sjakllsch   svga = NULL;
3321.331Sjakllsch
3331.331Sjakllschdone:
3341.331Sjakllsch   SVGA_STATS_TIME_POP(svgascreen->sws);
3351.197Sbouyer   return svga ? &svga->pipe:NULL;
3361.267Sitohy}
3371.197Sbouyer
3381.197Sbouyer
3391.197Sbouyervoid
3401.197Sbouyersvga_context_flush(struct svga_context *svga,
3411.267Sitohy                   struct pipe_fence_handle **pfence)
3421.197Sbouyer{
3431.197Sbouyer   struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
3441.197Sbouyer   struct pipe_fence_handle *fence = NULL;
3451.197Sbouyer   uint64_t t0;
3461.267Sitohy
3471.197Sbouyer   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFLUSH);
3481.197Sbouyer
3491.197Sbouyer   svga->curr.nr_fbs = 0;
3501.197Sbouyer
3511.271Sbouyer   /* Unmap the 0th/default constant buffer.  The u_upload_unmap() function
3521.197Sbouyer    * will call pipe_context::transfer_flush_region() to indicate the
3531.197Sbouyer    * region of the buffer which was modified (and needs to be uploaded).
3541.200Snisimura    */
3551.200Snisimura   if (svga->state.hw_draw.const0_handle) {
3561.267Sitohy      assert(svga->state.hw_draw.const0_buffer);
3571.200Snisimura      u_upload_unmap(svga->const0_upload);
3581.200Snisimura      pipe_resource_reference(&svga->state.hw_draw.const0_buffer, NULL);
3591.11Scgd      svga->state.hw_draw.const0_handle = NULL;
3601.226Scube   }
3611.267Sitohy
3621.226Scube   /* Ensure that texture dma uploads are processed
3631.226Scube    * before submitting commands.
3641.226Scube    */
3651.320Schristos   svga_context_flush_buffers(svga);
3661.320Schristos
3671.320Schristos   svga->hud.command_buffer_size +=
3681.320Schristos      svga->swc->get_command_buffer_size(svga->swc);
3691.320Schristos
3701.11Scgd   /* Flush pending commands to hardware:
3711.33Sthorpej    */
3721.13Sthorpej   t0 = svga_get_time(svga);
3731.11Scgd   svga->swc->flush(svga->swc, &fence);
3741.20Schristos   svga->hud.flush_time += (svga_get_time(svga) - t0);
3751.232Sperry
3761.20Schristos   svga->hud.num_flushes++;
3771.20Schristos
3781.94Sthorpej   svga_screen_cache_flush(svgascreen, svga, fence);
3791.94Sthorpej
3801.94Sthorpej   SVGA3D_ResetLastCommand(svga->swc);
3811.94Sthorpej
3821.123Slukem   /* To force the re-emission of rendertargets and texture sampler bindings on
3831.24Sthorpej    * the next command buffer.
3841.24Sthorpej    */
3851.56Sthorpej   svga->rebind.flags.rendertargets = TRUE;
3861.56Sthorpej   svga->rebind.flags.texture_samplers = TRUE;
3871.84Smrg
3881.84Smrg   if (svga_have_gb_objects(svga)) {
3891.84Smrg
3901.84Smrg      svga->rebind.flags.constbufs = TRUE;
3911.140Seeh      svga->rebind.flags.vs = TRUE;
3921.140Seeh      svga->rebind.flags.fs = TRUE;
3931.140Seeh      svga->rebind.flags.gs = TRUE;
3941.140Seeh
3951.29Sthorpej      if (svga_need_to_rebind_resources(svga)) {
3961.324Sjdc         svga->rebind.flags.query = TRUE;
3971.324Sjdc      }
3981.324Sjdc   }
3991.324Sjdc
4001.324Sjdc   if (SVGA_DEBUG & DEBUG_SYNC) {
4011.306Sbouyer      if (fence)
4021.306Sbouyer         svga->pipe.screen->fence_finish(svga->pipe.screen, NULL, fence,
4031.306Sbouyer                                          PIPE_TIMEOUT_INFINITE);
4041.306Sbouyer   }
4051.306Sbouyer
4061.29Sthorpej   if (pfence)
4071.48Sthorpej      svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence);
4081.398Smaxv
4091.30Sbouyer   svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
4101.31Sbouyer
4111.195Sthorpej   SVGA_STATS_TIME_POP(svga_sws(svga));
4121.195Sthorpej}
4131.123Slukem
4141.123Slukem
4151.43Sexplorer/**
4161.43Sexplorer * Flush pending commands and wait for completion with a fence.
4171.74Schopps */
4181.43Sexplorervoid
4191.43Sexplorersvga_context_finish(struct svga_context *svga)
4201.37Skml{
4211.54Sexplorer   struct pipe_screen *screen = svga->pipe.screen;
4221.54Sexplorer   struct pipe_fence_handle *fence = NULL;
4231.54Sexplorer
4241.54Sexplorer   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFINISH);
4251.54Sexplorer
4261.37Skml   svga_context_flush(svga, &fence);
4271.37Skml   screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
4281.123Slukem   screen->fence_reference(screen, &fence, NULL);
4291.123Slukem
4301.35Sdrochner   SVGA_STATS_TIME_POP(svga_sws(svga));
4311.35Sdrochner}
4321.305Sjoerg
4331.35Sdrochner
4341.123Slukem/**
4351.35Sdrochner * Emit pending drawing commands to the command buffer.
4361.35Sdrochner * If the command buffer overflows, we flush it and retry.
4371.87Snathanw * \sa svga_hwtnl_flush()
4381.35Sdrochner */
4391.123Slukemvoid
4401.54Sexplorersvga_hwtnl_flush_retry(struct svga_context *svga)
4411.77Selric{
4421.83Snathanw   enum pipe_error ret = PIPE_OK;
4431.154Sthorpej
4441.166Suwe   ret = svga_hwtnl_flush(svga->hwtnl);
4451.332Sskrll   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
4461.332Sskrll      svga_context_flush(svga, NULL);
4471.332Sskrll      ret = svga_hwtnl_flush(svga->hwtnl);
4481.332Sskrll   }
4491.166Suwe
4501.166Suwe   assert(ret == PIPE_OK);
4511.166Suwe}
4521.166Suwe
4531.90Swiz
4541.90Swiz/**
4551.218Sdrochner * Flush the primitive queue if this buffer is referred.
4561.123Slukem *
4571.123Slukem * Otherwise DMA commands on the referred buffer will be emitted too late.
4581.123Slukem */
4591.123Slukemvoid
4601.123Slukemsvga_hwtnl_flush_buffer(struct svga_context *svga,
4611.123Slukem                        struct pipe_resource *buffer)
4621.73Saugustss{
4631.73Saugustss   if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) {
4641.168Saugustss      svga_hwtnl_flush_retry(svga);
4651.123Slukem   }
4661.123Slukem}
4671.117Saugustss
4681.117Saugustss
4691.168Saugustss/**
4701.123Slukem * Emit all operations pending on host surfaces.
4711.123Slukem */
4721.120Stachavoid
4731.120Stachasvga_surfaces_flush(struct svga_context *svga)
4741.123Slukem{
4751.69Saugustss   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SURFACEFLUSH);
4761.69Saugustss
4771.168Saugustss   /* Emit buffered drawing commands.
4781.123Slukem    */
4791.123Slukem   svga_hwtnl_flush_retry(svga);
4801.69Saugustss
4811.69Saugustss   /* Emit back-copy from render target views to textures.
4821.70Sthorpej    */
4831.69Saugustss   svga_propagate_rendertargets(svga);
4841.69Saugustss
4851.70Sthorpej   SVGA_STATS_TIME_POP(svga_sws(svga));
4861.36Saugustss}
4871.36Saugustss
4881.213Sdrochner
4891.36Saugustssstruct svga_winsys_context *
4901.36Saugustsssvga_winsys_context(struct pipe_context *pipe)
4911.111Sthorpej{
4921.213Sdrochner   return svga_context(pipe)->swc;
4931.213Sdrochner}
4941.213Sdrochner