1bf215546Sopenharmony_ci/**********************************************************
2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person
5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation
6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without
7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy,
8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies
9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is
10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be
13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22bf215546Sopenharmony_ci * SOFTWARE.
23bf215546Sopenharmony_ci *
24bf215546Sopenharmony_ci **********************************************************/
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "svga_cmd.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "pipe/p_defines.h"
29bf215546Sopenharmony_ci#include "util/u_inlines.h"
30bf215546Sopenharmony_ci#include "pipe/p_screen.h"
31bf215546Sopenharmony_ci#include "util/u_memory.h"
32bf215546Sopenharmony_ci#include "util/u_bitmask.h"
33bf215546Sopenharmony_ci#include "util/u_upload_mgr.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci#include "svga_context.h"
36bf215546Sopenharmony_ci#include "svga_screen.h"
37bf215546Sopenharmony_ci#include "svga_surface.h"
38bf215546Sopenharmony_ci#include "svga_resource_texture.h"
39bf215546Sopenharmony_ci#include "svga_resource_buffer.h"
40bf215546Sopenharmony_ci#include "svga_resource.h"
41bf215546Sopenharmony_ci#include "svga_winsys.h"
42bf215546Sopenharmony_ci#include "svga_swtnl.h"
43bf215546Sopenharmony_ci#include "svga_draw.h"
44bf215546Sopenharmony_ci#include "svga_debug.h"
45bf215546Sopenharmony_ci#include "svga_state.h"
46bf215546Sopenharmony_ci#include "svga_winsys.h"
47bf215546Sopenharmony_ci#include "svga_streamout.h"
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci#define CONST0_UPLOAD_DEFAULT_SIZE 65536
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ciDEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", FALSE)
52bf215546Sopenharmony_ciDEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", FALSE);
53bf215546Sopenharmony_ciDEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", FALSE);
54bf215546Sopenharmony_ciDEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", FALSE);
55bf215546Sopenharmony_ciDEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", FALSE);
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_cistatic void
59bf215546Sopenharmony_cisvga_destroy(struct pipe_context *pipe)
60bf215546Sopenharmony_ci{
61bf215546Sopenharmony_ci   struct svga_context *svga = svga_context(pipe);
62bf215546Sopenharmony_ci   unsigned shader, i;
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci   /* free depthstencil_disable state */
65bf215546Sopenharmony_ci   if (svga->depthstencil_disable) {
66bf215546Sopenharmony_ci      pipe->delete_depth_stencil_alpha_state(pipe, svga->depthstencil_disable);
67bf215546Sopenharmony_ci   }
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci   /* free HW constant buffers */
70bf215546Sopenharmony_ci   for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) {
71bf215546Sopenharmony_ci      for (i = 0; i < ARRAY_SIZE(svga->state.hw_draw.constbuf[0]); i++) {
72bf215546Sopenharmony_ci         pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][i], NULL);
73bf215546Sopenharmony_ci      }
74bf215546Sopenharmony_ci   }
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   pipe->delete_blend_state(pipe, svga->noop_blend);
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   /* destroy stream output statistics queries */
79bf215546Sopenharmony_ci   svga_destroy_stream_output_queries(svga);
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   /* free query gb object */
82bf215546Sopenharmony_ci   if (svga->gb_query) {
83bf215546Sopenharmony_ci      pipe->destroy_query(pipe, NULL);
84bf215546Sopenharmony_ci      svga->gb_query = NULL;
85bf215546Sopenharmony_ci   }
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   util_blitter_destroy(svga->blitter);
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   svga_cleanup_sampler_state(svga);
90bf215546Sopenharmony_ci   svga_cleanup_framebuffer(svga);
91bf215546Sopenharmony_ci   svga_cleanup_tss_binding(svga);
92bf215546Sopenharmony_ci   svga_cleanup_vertex_state(svga);
93bf215546Sopenharmony_ci   svga_cleanup_tcs_state(svga);
94bf215546Sopenharmony_ci   svga_cleanup_shader_image_state(svga);
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci   svga_destroy_swtnl(svga);
97bf215546Sopenharmony_ci   svga_hwtnl_destroy(svga->hwtnl);
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   svga->swc->destroy(svga->swc);
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci   util_bitmask_destroy(svga->blend_object_id_bm);
102bf215546Sopenharmony_ci   util_bitmask_destroy(svga->ds_object_id_bm);
103bf215546Sopenharmony_ci   util_bitmask_destroy(svga->input_element_object_id_bm);
104bf215546Sopenharmony_ci   util_bitmask_destroy(svga->rast_object_id_bm);
105bf215546Sopenharmony_ci   util_bitmask_destroy(svga->sampler_object_id_bm);
106bf215546Sopenharmony_ci   util_bitmask_destroy(svga->sampler_view_id_bm);
107bf215546Sopenharmony_ci   util_bitmask_destroy(svga->shader_id_bm);
108bf215546Sopenharmony_ci   util_bitmask_destroy(svga->surface_view_id_bm);
109bf215546Sopenharmony_ci   util_bitmask_destroy(svga->stream_output_id_bm);
110bf215546Sopenharmony_ci   util_bitmask_destroy(svga->query_id_bm);
111bf215546Sopenharmony_ci   util_bitmask_destroy(svga->uav_id_bm);
112bf215546Sopenharmony_ci   util_bitmask_destroy(svga->uav_to_free_id_bm);
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci   u_upload_destroy(svga->const0_upload);
115bf215546Sopenharmony_ci   u_upload_destroy(svga->pipe.stream_uploader);
116bf215546Sopenharmony_ci   u_upload_destroy(svga->pipe.const_uploader);
117bf215546Sopenharmony_ci   svga_texture_transfer_map_upload_destroy(svga);
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci   /* free user's constant buffers */
120bf215546Sopenharmony_ci   for (shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
121bf215546Sopenharmony_ci      for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[shader]); ++i) {
122bf215546Sopenharmony_ci         pipe_resource_reference(&svga->curr.constbufs[shader][i].buffer, NULL);
123bf215546Sopenharmony_ci      }
124bf215546Sopenharmony_ci   }
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   /* free any pending srvs that were created for rawbuf sr view for
127bf215546Sopenharmony_ci    * constant buf.
128bf215546Sopenharmony_ci    */
129bf215546Sopenharmony_ci   if (svga_have_gl43(svga)) {
130bf215546Sopenharmony_ci      svga_destroy_rawbuf_srv(svga);
131bf215546Sopenharmony_ci      util_bitmask_destroy(svga->sampler_view_to_free_id_bm);
132bf215546Sopenharmony_ci      pipe_resource_reference(&svga->dummy_resource, NULL);
133bf215546Sopenharmony_ci   }
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   FREE(svga);
136bf215546Sopenharmony_ci}
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_cistruct pipe_context *
140bf215546Sopenharmony_cisvga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
141bf215546Sopenharmony_ci{
142bf215546Sopenharmony_ci   struct svga_screen *svgascreen = svga_screen(screen);
143bf215546Sopenharmony_ci   struct svga_context *svga = NULL;
144bf215546Sopenharmony_ci   enum pipe_error ret;
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci   SVGA_STATS_TIME_PUSH(svgascreen->sws, SVGA_STATS_TIME_CREATECONTEXT);
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci   svga = CALLOC_STRUCT(svga_context);
149bf215546Sopenharmony_ci   if (!svga)
150bf215546Sopenharmony_ci      goto done;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci   list_inithead(&svga->dirty_buffers);
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci   svga->pipe.screen = screen;
155bf215546Sopenharmony_ci   svga->pipe.priv = priv;
156bf215546Sopenharmony_ci   svga->pipe.destroy = svga_destroy;
157bf215546Sopenharmony_ci   svga->pipe.stream_uploader = u_upload_create(&svga->pipe, 1024 * 1024,
158bf215546Sopenharmony_ci                                                PIPE_BIND_VERTEX_BUFFER |
159bf215546Sopenharmony_ci                                                PIPE_BIND_INDEX_BUFFER,
160bf215546Sopenharmony_ci                                                PIPE_USAGE_STREAM, 0);
161bf215546Sopenharmony_ci   if (!svga->pipe.stream_uploader)
162bf215546Sopenharmony_ci      goto cleanup;
163bf215546Sopenharmony_ci
164bf215546Sopenharmony_ci   u_upload_disable_persistent(svga->pipe.stream_uploader);
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci   svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024,
167bf215546Sopenharmony_ci                                               PIPE_BIND_CONSTANT_BUFFER,
168bf215546Sopenharmony_ci                                               PIPE_USAGE_STREAM, 0);
169bf215546Sopenharmony_ci   if (!svga->pipe.const_uploader)
170bf215546Sopenharmony_ci      goto cleanup;
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci   u_upload_disable_persistent(svga->pipe.const_uploader);
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci   svga->swc = svgascreen->sws->context_create(svgascreen->sws);
175bf215546Sopenharmony_ci   if (!svga->swc)
176bf215546Sopenharmony_ci      goto cleanup;
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   svga_init_resource_functions(svga);
179bf215546Sopenharmony_ci   svga_init_blend_functions(svga);
180bf215546Sopenharmony_ci   svga_init_blit_functions(svga);
181bf215546Sopenharmony_ci   svga_init_depth_stencil_functions(svga);
182bf215546Sopenharmony_ci   svga_init_draw_functions(svga);
183bf215546Sopenharmony_ci   svga_init_flush_functions(svga);
184bf215546Sopenharmony_ci   svga_init_misc_functions(svga);
185bf215546Sopenharmony_ci   svga_init_rasterizer_functions(svga);
186bf215546Sopenharmony_ci   svga_init_sampler_functions(svga);
187bf215546Sopenharmony_ci   svga_init_fs_functions(svga);
188bf215546Sopenharmony_ci   svga_init_vs_functions(svga);
189bf215546Sopenharmony_ci   svga_init_gs_functions(svga);
190bf215546Sopenharmony_ci   svga_init_ts_functions(svga);
191bf215546Sopenharmony_ci   svga_init_vertex_functions(svga);
192bf215546Sopenharmony_ci   svga_init_constbuffer_functions(svga);
193bf215546Sopenharmony_ci   svga_init_query_functions(svga);
194bf215546Sopenharmony_ci   svga_init_surface_functions(svga);
195bf215546Sopenharmony_ci   svga_init_stream_output_functions(svga);
196bf215546Sopenharmony_ci   svga_init_clear_functions(svga);
197bf215546Sopenharmony_ci   svga_init_tracked_state(svga);
198bf215546Sopenharmony_ci   svga_init_shader_image_functions(svga);
199bf215546Sopenharmony_ci   svga_init_shader_buffer_functions(svga);
200bf215546Sopenharmony_ci   svga_init_cs_functions(svga);
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci   /* init misc state */
203bf215546Sopenharmony_ci   svga->curr.sample_mask = ~0;
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   /* debug */
206bf215546Sopenharmony_ci   svga->debug.no_swtnl = debug_get_option_no_swtnl();
207bf215546Sopenharmony_ci   svga->debug.force_swtnl = debug_get_option_force_swtnl();
208bf215546Sopenharmony_ci   svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap();
209bf215546Sopenharmony_ci   svga->debug.no_line_width = debug_get_option_no_line_width();
210bf215546Sopenharmony_ci   svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple();
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_ci   if (!(svga->blend_object_id_bm = util_bitmask_create()))
213bf215546Sopenharmony_ci      goto cleanup;
214bf215546Sopenharmony_ci
215bf215546Sopenharmony_ci   if (!(svga->ds_object_id_bm = util_bitmask_create()))
216bf215546Sopenharmony_ci      goto cleanup;
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ci   if (!(svga->input_element_object_id_bm = util_bitmask_create()))
219bf215546Sopenharmony_ci      goto cleanup;
220bf215546Sopenharmony_ci
221bf215546Sopenharmony_ci   if (!(svga->rast_object_id_bm = util_bitmask_create()))
222bf215546Sopenharmony_ci      goto cleanup;
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci   if (!(svga->sampler_object_id_bm = util_bitmask_create()))
225bf215546Sopenharmony_ci      goto cleanup;
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_ci   if (!(svga->sampler_view_id_bm = util_bitmask_create()))
228bf215546Sopenharmony_ci      goto cleanup;
229bf215546Sopenharmony_ci
230bf215546Sopenharmony_ci   if (!(svga->shader_id_bm = util_bitmask_create()))
231bf215546Sopenharmony_ci      goto cleanup;
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ci   if (!(svga->surface_view_id_bm = util_bitmask_create()))
234bf215546Sopenharmony_ci      goto cleanup;
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_ci   if (!(svga->stream_output_id_bm = util_bitmask_create()))
237bf215546Sopenharmony_ci      goto cleanup;
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci   if (!(svga->query_id_bm = util_bitmask_create()))
240bf215546Sopenharmony_ci      goto cleanup;
241bf215546Sopenharmony_ci
242bf215546Sopenharmony_ci   if (!(svga->uav_id_bm = util_bitmask_create()))
243bf215546Sopenharmony_ci      goto cleanup;
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ci   if (!(svga->uav_to_free_id_bm = util_bitmask_create()))
246bf215546Sopenharmony_ci      goto cleanup;
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci   if (!(svga->sampler_view_to_free_id_bm = util_bitmask_create()))
249bf215546Sopenharmony_ci      goto cleanup;
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci   svga->hwtnl = svga_hwtnl_create(svga);
252bf215546Sopenharmony_ci   if (svga->hwtnl == NULL)
253bf215546Sopenharmony_ci      goto cleanup;
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci   if (!svga_init_swtnl(svga))
256bf215546Sopenharmony_ci      goto cleanup;
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_ci   ret = svga_emit_initial_state(svga);
259bf215546Sopenharmony_ci   if (ret != PIPE_OK)
260bf215546Sopenharmony_ci      goto cleanup;
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci   svga->const0_upload = u_upload_create(&svga->pipe,
263bf215546Sopenharmony_ci                                         CONST0_UPLOAD_DEFAULT_SIZE,
264bf215546Sopenharmony_ci                                         PIPE_BIND_CONSTANT_BUFFER |
265bf215546Sopenharmony_ci                                         PIPE_BIND_CUSTOM,
266bf215546Sopenharmony_ci                                         PIPE_USAGE_STREAM, 0);
267bf215546Sopenharmony_ci   if (!svga->const0_upload)
268bf215546Sopenharmony_ci      goto cleanup;
269bf215546Sopenharmony_ci
270bf215546Sopenharmony_ci   u_upload_disable_persistent(svga->const0_upload);
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_ci   if (!svga_texture_transfer_map_upload_create(svga))
273bf215546Sopenharmony_ci      goto cleanup;
274bf215546Sopenharmony_ci
275bf215546Sopenharmony_ci   /* Avoid shortcircuiting state with initial value of zero.
276bf215546Sopenharmony_ci    */
277bf215546Sopenharmony_ci   memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear));
278bf215546Sopenharmony_ci   memset(&svga->state.hw_clear.framebuffer, 0x0,
279bf215546Sopenharmony_ci          sizeof(svga->state.hw_clear.framebuffer));
280bf215546Sopenharmony_ci   memset(&svga->state.hw_clear.rtv, 0, sizeof(svga->state.hw_clear.rtv));
281bf215546Sopenharmony_ci   svga->state.hw_clear.num_rendertargets = 0;
282bf215546Sopenharmony_ci   svga->state.hw_clear.dsv = NULL;
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
285bf215546Sopenharmony_ci   memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
286bf215546Sopenharmony_ci   memset(&svga->state.hw_draw.num_samplers, 0,
287bf215546Sopenharmony_ci      sizeof(svga->state.hw_draw.num_samplers));
288bf215546Sopenharmony_ci   memset(&svga->state.hw_draw.num_sampler_views, 0,
289bf215546Sopenharmony_ci      sizeof(svga->state.hw_draw.num_sampler_views));
290bf215546Sopenharmony_ci   memset(svga->state.hw_draw.sampler_views, 0,
291bf215546Sopenharmony_ci          sizeof(svga->state.hw_draw.sampler_views));
292bf215546Sopenharmony_ci   svga->state.hw_draw.num_views = 0;
293bf215546Sopenharmony_ci   svga->state.hw_draw.num_backed_views = 0;
294bf215546Sopenharmony_ci   svga->state.hw_draw.rasterizer_discard = FALSE;
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ci   /* Initialize uavs */
297bf215546Sopenharmony_ci   svga->state.hw_draw.uavSpliceIndex = -1;
298bf215546Sopenharmony_ci   svga->state.hw_draw.num_uavs = 0;
299bf215546Sopenharmony_ci   svga->state.hw_draw.num_cs_uavs = 0;
300bf215546Sopenharmony_ci
301bf215546Sopenharmony_ci   /* Initialize the shader pointers */
302bf215546Sopenharmony_ci   svga->state.hw_draw.vs = NULL;
303bf215546Sopenharmony_ci   svga->state.hw_draw.gs = NULL;
304bf215546Sopenharmony_ci   svga->state.hw_draw.fs = NULL;
305bf215546Sopenharmony_ci   svga->state.hw_draw.tcs = NULL;
306bf215546Sopenharmony_ci   svga->state.hw_draw.tes = NULL;
307bf215546Sopenharmony_ci
308bf215546Sopenharmony_ci   /* Initialize the currently bound buffer resources */
309bf215546Sopenharmony_ci   memset(svga->state.hw_draw.constbuf, 0,
310bf215546Sopenharmony_ci          sizeof(svga->state.hw_draw.constbuf));
311bf215546Sopenharmony_ci   memset(svga->state.hw_draw.default_constbuf_size, 0,
312bf215546Sopenharmony_ci          sizeof(svga->state.hw_draw.default_constbuf_size));
313bf215546Sopenharmony_ci   memset(svga->state.hw_draw.enabled_constbufs, 0,
314bf215546Sopenharmony_ci          sizeof(svga->state.hw_draw.enabled_constbufs));
315bf215546Sopenharmony_ci   memset(svga->state.hw_draw.enabled_rawbufs, 0,
316bf215546Sopenharmony_ci          sizeof(svga->state.hw_draw.enabled_rawbufs));
317bf215546Sopenharmony_ci   memset(svga->state.hw_draw.rawbufs, 0,
318bf215546Sopenharmony_ci          sizeof(svga->state.hw_draw.rawbufs));
319bf215546Sopenharmony_ci   svga->state.hw_draw.ib = NULL;
320bf215546Sopenharmony_ci   svga->state.hw_draw.num_vbuffers = 0;
321bf215546Sopenharmony_ci   memset(svga->state.hw_draw.vbuffers, 0,
322bf215546Sopenharmony_ci          sizeof(svga->state.hw_draw.vbuffers));
323bf215546Sopenharmony_ci   svga->state.hw_draw.const0_buffer = NULL;
324bf215546Sopenharmony_ci   svga->state.hw_draw.const0_handle = NULL;
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_ci   if (svga_have_gl43(svga)) {
327bf215546Sopenharmony_ci      for (unsigned shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
328bf215546Sopenharmony_ci         for (unsigned i = 0;
329bf215546Sopenharmony_ci              i < ARRAY_SIZE(svga->state.hw_draw.rawbufs[shader]); i++) {
330bf215546Sopenharmony_ci            svga->state.hw_draw.rawbufs[shader][i].srvid = SVGA3D_INVALID_ID;
331bf215546Sopenharmony_ci         }
332bf215546Sopenharmony_ci      }
333bf215546Sopenharmony_ci      svga_uav_cache_init(svga);
334bf215546Sopenharmony_ci      svga->dummy_resource = NULL;
335bf215546Sopenharmony_ci   }
336bf215546Sopenharmony_ci
337bf215546Sopenharmony_ci   /* Create a no-operation blend state which we will bind whenever the
338bf215546Sopenharmony_ci    * requested blend state is impossible (e.g. due to having an integer
339bf215546Sopenharmony_ci    * render target attached).
340bf215546Sopenharmony_ci    *
341bf215546Sopenharmony_ci    * XXX: We will probably actually need 16 of these, one for each possible
342bf215546Sopenharmony_ci    * RGBA color mask (4 bits).  Then, we would bind the one with a color mask
343bf215546Sopenharmony_ci    * matching the blend state it is replacing.
344bf215546Sopenharmony_ci    */
345bf215546Sopenharmony_ci   {
346bf215546Sopenharmony_ci      struct pipe_blend_state noop_tmpl = {0};
347bf215546Sopenharmony_ci      unsigned i;
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ci      for (i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
350bf215546Sopenharmony_ci         // Set the color mask to all-ones.  Later this may change.
351bf215546Sopenharmony_ci         noop_tmpl.rt[i].colormask = PIPE_MASK_RGBA;
352bf215546Sopenharmony_ci      }
353bf215546Sopenharmony_ci      svga->noop_blend = svga->pipe.create_blend_state(&svga->pipe, &noop_tmpl);
354bf215546Sopenharmony_ci   }
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ci   svga->dirty = SVGA_NEW_ALL;
357bf215546Sopenharmony_ci   svga->pred.query_id = SVGA3D_INVALID_ID;
358bf215546Sopenharmony_ci   svga->disable_rasterizer = FALSE;
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci   /**
361bf215546Sopenharmony_ci    * Create stream output statistics queries used in the workaround for auto
362bf215546Sopenharmony_ci    * draw with stream instancing.
363bf215546Sopenharmony_ci    */
364bf215546Sopenharmony_ci   svga_create_stream_output_queries(svga);
365bf215546Sopenharmony_ci
366bf215546Sopenharmony_ci   goto done;
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_cicleanup:
369bf215546Sopenharmony_ci   svga_destroy_swtnl(svga);
370bf215546Sopenharmony_ci
371bf215546Sopenharmony_ci   if (svga->const0_upload)
372bf215546Sopenharmony_ci      u_upload_destroy(svga->const0_upload);
373bf215546Sopenharmony_ci   if (svga->pipe.const_uploader)
374bf215546Sopenharmony_ci      u_upload_destroy(svga->pipe.const_uploader);
375bf215546Sopenharmony_ci   if (svga->pipe.stream_uploader)
376bf215546Sopenharmony_ci      u_upload_destroy(svga->pipe.stream_uploader);
377bf215546Sopenharmony_ci   svga_texture_transfer_map_upload_destroy(svga);
378bf215546Sopenharmony_ci   if (svga->hwtnl)
379bf215546Sopenharmony_ci      svga_hwtnl_destroy(svga->hwtnl);
380bf215546Sopenharmony_ci   if (svga->swc)
381bf215546Sopenharmony_ci      svga->swc->destroy(svga->swc);
382bf215546Sopenharmony_ci   util_bitmask_destroy(svga->blend_object_id_bm);
383bf215546Sopenharmony_ci   util_bitmask_destroy(svga->ds_object_id_bm);
384bf215546Sopenharmony_ci   util_bitmask_destroy(svga->input_element_object_id_bm);
385bf215546Sopenharmony_ci   util_bitmask_destroy(svga->rast_object_id_bm);
386bf215546Sopenharmony_ci   util_bitmask_destroy(svga->sampler_object_id_bm);
387bf215546Sopenharmony_ci   util_bitmask_destroy(svga->shader_id_bm);
388bf215546Sopenharmony_ci   util_bitmask_destroy(svga->surface_view_id_bm);
389bf215546Sopenharmony_ci   util_bitmask_destroy(svga->stream_output_id_bm);
390bf215546Sopenharmony_ci   util_bitmask_destroy(svga->query_id_bm);
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci   util_bitmask_destroy(svga->uav_id_bm);
393bf215546Sopenharmony_ci   util_bitmask_destroy(svga->uav_to_free_id_bm);
394bf215546Sopenharmony_ci   util_bitmask_destroy(svga->sampler_view_id_bm);
395bf215546Sopenharmony_ci
396bf215546Sopenharmony_ci   FREE(svga);
397bf215546Sopenharmony_ci   svga = NULL;
398bf215546Sopenharmony_ci
399bf215546Sopenharmony_cidone:
400bf215546Sopenharmony_ci   SVGA_STATS_TIME_POP(svgascreen->sws);
401bf215546Sopenharmony_ci   return svga ? &svga->pipe:NULL;
402bf215546Sopenharmony_ci}
403bf215546Sopenharmony_ci
404bf215546Sopenharmony_ci
405bf215546Sopenharmony_civoid
406bf215546Sopenharmony_cisvga_context_flush(struct svga_context *svga,
407bf215546Sopenharmony_ci                   struct pipe_fence_handle **pfence)
408bf215546Sopenharmony_ci{
409bf215546Sopenharmony_ci   struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
410bf215546Sopenharmony_ci   struct pipe_fence_handle *fence = NULL;
411bf215546Sopenharmony_ci   uint64_t t0;
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFLUSH);
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci   svga->curr.nr_fbs = 0;
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci   /* Unmap the 0th/default constant buffer.  The u_upload_unmap() function
418bf215546Sopenharmony_ci    * will call pipe_context::transfer_flush_region() to indicate the
419bf215546Sopenharmony_ci    * region of the buffer which was modified (and needs to be uploaded).
420bf215546Sopenharmony_ci    */
421bf215546Sopenharmony_ci   if (svga->state.hw_draw.const0_handle) {
422bf215546Sopenharmony_ci      assert(svga->state.hw_draw.const0_buffer);
423bf215546Sopenharmony_ci      u_upload_unmap(svga->const0_upload);
424bf215546Sopenharmony_ci      pipe_resource_reference(&svga->state.hw_draw.const0_buffer, NULL);
425bf215546Sopenharmony_ci      svga->state.hw_draw.const0_handle = NULL;
426bf215546Sopenharmony_ci   }
427bf215546Sopenharmony_ci
428bf215546Sopenharmony_ci   /* Ensure that texture dma uploads are processed
429bf215546Sopenharmony_ci    * before submitting commands.
430bf215546Sopenharmony_ci    */
431bf215546Sopenharmony_ci   svga_context_flush_buffers(svga);
432bf215546Sopenharmony_ci
433bf215546Sopenharmony_ci   svga->hud.command_buffer_size +=
434bf215546Sopenharmony_ci      svga->swc->get_command_buffer_size(svga->swc);
435bf215546Sopenharmony_ci
436bf215546Sopenharmony_ci   /* Flush pending commands to hardware:
437bf215546Sopenharmony_ci    */
438bf215546Sopenharmony_ci   t0 = svga_get_time(svga);
439bf215546Sopenharmony_ci   svga->swc->flush(svga->swc, &fence);
440bf215546Sopenharmony_ci   svga->hud.flush_time += (svga_get_time(svga) - t0);
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci   svga->hud.num_flushes++;
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci   svga_screen_cache_flush(svgascreen, svga, fence);
445bf215546Sopenharmony_ci
446bf215546Sopenharmony_ci   SVGA3D_ResetLastCommand(svga->swc);
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_ci   /* To force the re-emission of rendertargets and texture sampler bindings on
449bf215546Sopenharmony_ci    * the next command buffer.
450bf215546Sopenharmony_ci    */
451bf215546Sopenharmony_ci   svga->rebind.flags.rendertargets = TRUE;
452bf215546Sopenharmony_ci   svga->rebind.flags.texture_samplers = TRUE;
453bf215546Sopenharmony_ci
454bf215546Sopenharmony_ci   if (svga_have_gb_objects(svga)) {
455bf215546Sopenharmony_ci
456bf215546Sopenharmony_ci      svga->rebind.flags.constbufs = TRUE;
457bf215546Sopenharmony_ci      svga->rebind.flags.vs = TRUE;
458bf215546Sopenharmony_ci      svga->rebind.flags.fs = TRUE;
459bf215546Sopenharmony_ci      svga->rebind.flags.gs = TRUE;
460bf215546Sopenharmony_ci
461bf215546Sopenharmony_ci      if (svga_have_sm5(svga)) {
462bf215546Sopenharmony_ci         svga->rebind.flags.tcs = TRUE;
463bf215546Sopenharmony_ci         svga->rebind.flags.tes = TRUE;
464bf215546Sopenharmony_ci      }
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_ci      if (svga_need_to_rebind_resources(svga)) {
467bf215546Sopenharmony_ci         svga->rebind.flags.query = TRUE;
468bf215546Sopenharmony_ci      }
469bf215546Sopenharmony_ci
470bf215546Sopenharmony_ci      if (svga_sws(svga)->have_index_vertex_buffer_offset_cmd) {
471bf215546Sopenharmony_ci         svga->rebind.flags.vertexbufs = TRUE;
472bf215546Sopenharmony_ci         svga->rebind.flags.indexbuf = TRUE;
473bf215546Sopenharmony_ci      }
474bf215546Sopenharmony_ci   }
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ci   if (SVGA_DEBUG & DEBUG_SYNC) {
477bf215546Sopenharmony_ci      if (fence)
478bf215546Sopenharmony_ci         svga->pipe.screen->fence_finish(svga->pipe.screen, NULL, fence,
479bf215546Sopenharmony_ci                                          PIPE_TIMEOUT_INFINITE);
480bf215546Sopenharmony_ci   }
481bf215546Sopenharmony_ci
482bf215546Sopenharmony_ci   if (pfence)
483bf215546Sopenharmony_ci      svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence);
484bf215546Sopenharmony_ci
485bf215546Sopenharmony_ci   svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_ci   SVGA_STATS_TIME_POP(svga_sws(svga));
488bf215546Sopenharmony_ci}
489bf215546Sopenharmony_ci
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_ci/**
492bf215546Sopenharmony_ci * Flush pending commands and wait for completion with a fence.
493bf215546Sopenharmony_ci */
494bf215546Sopenharmony_civoid
495bf215546Sopenharmony_cisvga_context_finish(struct svga_context *svga)
496bf215546Sopenharmony_ci{
497bf215546Sopenharmony_ci   struct pipe_screen *screen = svga->pipe.screen;
498bf215546Sopenharmony_ci   struct pipe_fence_handle *fence = NULL;
499bf215546Sopenharmony_ci
500bf215546Sopenharmony_ci   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFINISH);
501bf215546Sopenharmony_ci
502bf215546Sopenharmony_ci   svga_context_flush(svga, &fence);
503bf215546Sopenharmony_ci   screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
504bf215546Sopenharmony_ci   screen->fence_reference(screen, &fence, NULL);
505bf215546Sopenharmony_ci
506bf215546Sopenharmony_ci   SVGA_STATS_TIME_POP(svga_sws(svga));
507bf215546Sopenharmony_ci}
508bf215546Sopenharmony_ci
509bf215546Sopenharmony_ci
510bf215546Sopenharmony_ci/**
511bf215546Sopenharmony_ci * Emit pending drawing commands to the command buffer.
512bf215546Sopenharmony_ci * If the command buffer overflows, we flush it and retry.
513bf215546Sopenharmony_ci * \sa svga_hwtnl_flush()
514bf215546Sopenharmony_ci */
515bf215546Sopenharmony_civoid
516bf215546Sopenharmony_cisvga_hwtnl_flush_retry(struct svga_context *svga)
517bf215546Sopenharmony_ci{
518bf215546Sopenharmony_ci   enum pipe_error ret = PIPE_OK;
519bf215546Sopenharmony_ci
520bf215546Sopenharmony_ci   SVGA_RETRY_OOM(svga, ret, svga_hwtnl_flush(svga->hwtnl));
521bf215546Sopenharmony_ci   assert(ret == PIPE_OK);
522bf215546Sopenharmony_ci}
523bf215546Sopenharmony_ci
524bf215546Sopenharmony_ci
525bf215546Sopenharmony_ci/**
526bf215546Sopenharmony_ci * Flush the primitive queue if this buffer is referred.
527bf215546Sopenharmony_ci *
528bf215546Sopenharmony_ci * Otherwise DMA commands on the referred buffer will be emitted too late.
529bf215546Sopenharmony_ci */
530bf215546Sopenharmony_civoid
531bf215546Sopenharmony_cisvga_hwtnl_flush_buffer(struct svga_context *svga,
532bf215546Sopenharmony_ci                        struct pipe_resource *buffer)
533bf215546Sopenharmony_ci{
534bf215546Sopenharmony_ci   if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) {
535bf215546Sopenharmony_ci      svga_hwtnl_flush_retry(svga);
536bf215546Sopenharmony_ci   }
537bf215546Sopenharmony_ci}
538bf215546Sopenharmony_ci
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci/**
541bf215546Sopenharmony_ci * Emit all operations pending on host surfaces.
542bf215546Sopenharmony_ci */
543bf215546Sopenharmony_civoid
544bf215546Sopenharmony_cisvga_surfaces_flush(struct svga_context *svga)
545bf215546Sopenharmony_ci{
546bf215546Sopenharmony_ci   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SURFACEFLUSH);
547bf215546Sopenharmony_ci
548bf215546Sopenharmony_ci   /* Emit buffered drawing commands.
549bf215546Sopenharmony_ci    */
550bf215546Sopenharmony_ci   svga_hwtnl_flush_retry(svga);
551bf215546Sopenharmony_ci
552bf215546Sopenharmony_ci   /* Emit back-copy from render target views to textures.
553bf215546Sopenharmony_ci    */
554bf215546Sopenharmony_ci   svga_propagate_rendertargets(svga);
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci   SVGA_STATS_TIME_POP(svga_sws(svga));
557bf215546Sopenharmony_ci}
558bf215546Sopenharmony_ci
559bf215546Sopenharmony_ci
560bf215546Sopenharmony_cistruct svga_winsys_context *
561bf215546Sopenharmony_cisvga_winsys_context(struct pipe_context *pipe)
562bf215546Sopenharmony_ci{
563bf215546Sopenharmony_ci   return svga_context(pipe)->swc;
564bf215546Sopenharmony_ci}
565