• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014, 2015 Red Hat.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "pipe/p_shader_tokens.h"
25 
26 #include "pipe/p_context.h"
27 #include "pipe/p_defines.h"
28 #include "pipe/p_screen.h"
29 #include "pipe/p_state.h"
30 #include "util/u_inlines.h"
31 #include "util/u_memory.h"
32 #include "util/u_format.h"
33 #include "util/u_prim.h"
34 #include "util/u_transfer.h"
35 #include "util/u_helpers.h"
36 #include "util/slab.h"
37 #include "util/u_upload_mgr.h"
38 #include "util/u_blitter.h"
39 #include "tgsi/tgsi_text.h"
40 #include "indices/u_primconvert.h"
41 
42 #include "pipebuffer/pb_buffer.h"
43 
44 #include "virgl_encode.h"
45 #include "virgl_context.h"
46 #include "virgl_protocol.h"
47 #include "virgl_resource.h"
48 #include "virgl_screen.h"
49 
50 static uint32_t next_handle;
virgl_object_assign_handle(void)51 uint32_t virgl_object_assign_handle(void)
52 {
53    return ++next_handle;
54 }
55 
virgl_buffer_flush(struct virgl_context * vctx,struct virgl_buffer * vbuf)56 static void virgl_buffer_flush(struct virgl_context *vctx,
57                               struct virgl_buffer *vbuf)
58 {
59    struct virgl_screen *rs = virgl_screen(vctx->base.screen);
60    struct pipe_box box;
61 
62    assert(vbuf->on_list);
63 
64    box.height = 1;
65    box.depth = 1;
66    box.y = 0;
67    box.z = 0;
68 
69    box.x = vbuf->valid_buffer_range.start;
70    box.width = MIN2(vbuf->valid_buffer_range.end - vbuf->valid_buffer_range.start, vbuf->base.u.b.width0);
71 
72    vctx->num_transfers++;
73    rs->vws->transfer_put(rs->vws, vbuf->base.hw_res,
74                          &box, 0, 0, box.x, 0);
75 
76    util_range_set_empty(&vbuf->valid_buffer_range);
77 }
78 
virgl_attach_res_framebuffer(struct virgl_context * vctx)79 static void virgl_attach_res_framebuffer(struct virgl_context *vctx)
80 {
81    struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
82    struct pipe_surface *surf;
83    struct virgl_resource *res;
84    unsigned i;
85 
86    surf = vctx->framebuffer.zsbuf;
87    if (surf) {
88       res = virgl_resource(surf->texture);
89       if (res)
90          vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
91    }
92    for (i = 0; i < vctx->framebuffer.nr_cbufs; i++) {
93       surf = vctx->framebuffer.cbufs[i];
94       if (surf) {
95          res = virgl_resource(surf->texture);
96          if (res)
97             vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
98       }
99    }
100 }
101 
virgl_attach_res_sampler_views(struct virgl_context * vctx,enum pipe_shader_type shader_type)102 static void virgl_attach_res_sampler_views(struct virgl_context *vctx,
103                                            enum pipe_shader_type shader_type)
104 {
105    struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
106    struct virgl_textures_info *tinfo = &vctx->samplers[shader_type];
107    struct virgl_resource *res;
108    uint32_t remaining_mask = tinfo->enabled_mask;
109    unsigned i;
110    while (remaining_mask) {
111       i = u_bit_scan(&remaining_mask);
112       assert(tinfo->views[i]);
113 
114       res = virgl_resource(tinfo->views[i]->base.texture);
115       if (res)
116          vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
117    }
118 }
119 
virgl_attach_res_vertex_buffers(struct virgl_context * vctx)120 static void virgl_attach_res_vertex_buffers(struct virgl_context *vctx)
121 {
122    struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
123    struct virgl_resource *res;
124    unsigned i;
125 
126    for (i = 0; i < vctx->num_vertex_buffers; i++) {
127       res = virgl_resource(vctx->vertex_buffer[i].buffer.resource);
128       if (res)
129          vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
130    }
131 }
132 
virgl_attach_res_index_buffer(struct virgl_context * vctx,struct virgl_indexbuf * ib)133 static void virgl_attach_res_index_buffer(struct virgl_context *vctx,
134 					  struct virgl_indexbuf *ib)
135 {
136    struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
137    struct virgl_resource *res;
138 
139    res = virgl_resource(ib->buffer);
140    if (res)
141       vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
142 }
143 
virgl_attach_res_so_targets(struct virgl_context * vctx)144 static void virgl_attach_res_so_targets(struct virgl_context *vctx)
145 {
146    struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
147    struct virgl_resource *res;
148    unsigned i;
149 
150    for (i = 0; i < vctx->num_so_targets; i++) {
151       res = virgl_resource(vctx->so_targets[i].base.buffer);
152       if (res)
153          vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
154    }
155 }
156 
virgl_attach_res_uniform_buffers(struct virgl_context * vctx,enum pipe_shader_type shader_type)157 static void virgl_attach_res_uniform_buffers(struct virgl_context *vctx,
158                                              enum pipe_shader_type shader_type)
159 {
160    struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
161    struct virgl_resource *res;
162    unsigned i;
163    for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
164       res = virgl_resource(vctx->ubos[shader_type][i]);
165       if (res) {
166          vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
167       }
168    }
169 }
170 
171 /*
172  * after flushing, the hw context still has a bunch of
173  * resources bound, so we need to rebind those here.
174  */
virgl_reemit_res(struct virgl_context * vctx)175 static void virgl_reemit_res(struct virgl_context *vctx)
176 {
177    enum pipe_shader_type shader_type;
178 
179    /* reattach any flushed resources */
180    /* framebuffer, sampler views, vertex/index/uniform/stream buffers */
181    virgl_attach_res_framebuffer(vctx);
182 
183    for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) {
184       virgl_attach_res_sampler_views(vctx, shader_type);
185       virgl_attach_res_uniform_buffers(vctx, shader_type);
186    }
187    virgl_attach_res_vertex_buffers(vctx);
188    virgl_attach_res_so_targets(vctx);
189 }
190 
virgl_create_surface(struct pipe_context * ctx,struct pipe_resource * resource,const struct pipe_surface * templ)191 static struct pipe_surface *virgl_create_surface(struct pipe_context *ctx,
192                                                 struct pipe_resource *resource,
193                                                 const struct pipe_surface *templ)
194 {
195    struct virgl_context *vctx = virgl_context(ctx);
196    struct virgl_surface *surf;
197    struct virgl_resource *res = virgl_resource(resource);
198    uint32_t handle;
199 
200    surf = CALLOC_STRUCT(virgl_surface);
201    if (!surf)
202       return NULL;
203 
204    res->clean = FALSE;
205    handle = virgl_object_assign_handle();
206    pipe_reference_init(&surf->base.reference, 1);
207    pipe_resource_reference(&surf->base.texture, resource);
208    surf->base.context = ctx;
209    surf->base.format = templ->format;
210    if (resource->target != PIPE_BUFFER) {
211       surf->base.width = u_minify(resource->width0, templ->u.tex.level);
212       surf->base.height = u_minify(resource->height0, templ->u.tex.level);
213       surf->base.u.tex.level = templ->u.tex.level;
214       surf->base.u.tex.first_layer = templ->u.tex.first_layer;
215       surf->base.u.tex.last_layer = templ->u.tex.last_layer;
216    } else {
217       surf->base.width = templ->u.buf.last_element - templ->u.buf.first_element + 1;
218       surf->base.height = resource->height0;
219       surf->base.u.buf.first_element = templ->u.buf.first_element;
220       surf->base.u.buf.last_element = templ->u.buf.last_element;
221    }
222    virgl_encoder_create_surface(vctx, handle, res, &surf->base);
223    surf->handle = handle;
224    return &surf->base;
225 }
226 
virgl_surface_destroy(struct pipe_context * ctx,struct pipe_surface * psurf)227 static void virgl_surface_destroy(struct pipe_context *ctx,
228                                  struct pipe_surface *psurf)
229 {
230    struct virgl_context *vctx = virgl_context(ctx);
231    struct virgl_surface *surf = virgl_surface(psurf);
232 
233    pipe_resource_reference(&surf->base.texture, NULL);
234    virgl_encode_delete_object(vctx, surf->handle, VIRGL_OBJECT_SURFACE);
235    FREE(surf);
236 }
237 
virgl_create_blend_state(struct pipe_context * ctx,const struct pipe_blend_state * blend_state)238 static void *virgl_create_blend_state(struct pipe_context *ctx,
239                                               const struct pipe_blend_state *blend_state)
240 {
241    struct virgl_context *vctx = virgl_context(ctx);
242    uint32_t handle;
243    handle = virgl_object_assign_handle();
244 
245    virgl_encode_blend_state(vctx, handle, blend_state);
246    return (void *)(unsigned long)handle;
247 
248 }
249 
virgl_bind_blend_state(struct pipe_context * ctx,void * blend_state)250 static void virgl_bind_blend_state(struct pipe_context *ctx,
251                                            void *blend_state)
252 {
253    struct virgl_context *vctx = virgl_context(ctx);
254    uint32_t handle = (unsigned long)blend_state;
255    virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_BLEND);
256 }
257 
virgl_delete_blend_state(struct pipe_context * ctx,void * blend_state)258 static void virgl_delete_blend_state(struct pipe_context *ctx,
259                                      void *blend_state)
260 {
261    struct virgl_context *vctx = virgl_context(ctx);
262    uint32_t handle = (unsigned long)blend_state;
263    virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_BLEND);
264 }
265 
virgl_create_depth_stencil_alpha_state(struct pipe_context * ctx,const struct pipe_depth_stencil_alpha_state * blend_state)266 static void *virgl_create_depth_stencil_alpha_state(struct pipe_context *ctx,
267                                                    const struct pipe_depth_stencil_alpha_state *blend_state)
268 {
269    struct virgl_context *vctx = virgl_context(ctx);
270    uint32_t handle;
271    handle = virgl_object_assign_handle();
272 
273    virgl_encode_dsa_state(vctx, handle, blend_state);
274    return (void *)(unsigned long)handle;
275 }
276 
virgl_bind_depth_stencil_alpha_state(struct pipe_context * ctx,void * blend_state)277 static void virgl_bind_depth_stencil_alpha_state(struct pipe_context *ctx,
278                                                 void *blend_state)
279 {
280    struct virgl_context *vctx = virgl_context(ctx);
281    uint32_t handle = (unsigned long)blend_state;
282    virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_DSA);
283 }
284 
virgl_delete_depth_stencil_alpha_state(struct pipe_context * ctx,void * dsa_state)285 static void virgl_delete_depth_stencil_alpha_state(struct pipe_context *ctx,
286                                                   void *dsa_state)
287 {
288    struct virgl_context *vctx = virgl_context(ctx);
289    uint32_t handle = (unsigned long)dsa_state;
290    virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_DSA);
291 }
292 
virgl_create_rasterizer_state(struct pipe_context * ctx,const struct pipe_rasterizer_state * rs_state)293 static void *virgl_create_rasterizer_state(struct pipe_context *ctx,
294                                                    const struct pipe_rasterizer_state *rs_state)
295 {
296    struct virgl_context *vctx = virgl_context(ctx);
297    uint32_t handle;
298    handle = virgl_object_assign_handle();
299 
300    virgl_encode_rasterizer_state(vctx, handle, rs_state);
301    return (void *)(unsigned long)handle;
302 }
303 
virgl_bind_rasterizer_state(struct pipe_context * ctx,void * rs_state)304 static void virgl_bind_rasterizer_state(struct pipe_context *ctx,
305                                                 void *rs_state)
306 {
307    struct virgl_context *vctx = virgl_context(ctx);
308    uint32_t handle = (unsigned long)rs_state;
309 
310    virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_RASTERIZER);
311 }
312 
virgl_delete_rasterizer_state(struct pipe_context * ctx,void * rs_state)313 static void virgl_delete_rasterizer_state(struct pipe_context *ctx,
314                                          void *rs_state)
315 {
316    struct virgl_context *vctx = virgl_context(ctx);
317    uint32_t handle = (unsigned long)rs_state;
318    virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_RASTERIZER);
319 }
320 
virgl_set_framebuffer_state(struct pipe_context * ctx,const struct pipe_framebuffer_state * state)321 static void virgl_set_framebuffer_state(struct pipe_context *ctx,
322                                                 const struct pipe_framebuffer_state *state)
323 {
324    struct virgl_context *vctx = virgl_context(ctx);
325 
326    vctx->framebuffer = *state;
327    virgl_encoder_set_framebuffer_state(vctx, state);
328    virgl_attach_res_framebuffer(vctx);
329 }
330 
virgl_set_viewport_states(struct pipe_context * ctx,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * state)331 static void virgl_set_viewport_states(struct pipe_context *ctx,
332                                      unsigned start_slot,
333                                      unsigned num_viewports,
334                                      const struct pipe_viewport_state *state)
335 {
336    struct virgl_context *vctx = virgl_context(ctx);
337    virgl_encoder_set_viewport_states(vctx, start_slot, num_viewports, state);
338 }
339 
virgl_create_vertex_elements_state(struct pipe_context * ctx,unsigned num_elements,const struct pipe_vertex_element * elements)340 static void *virgl_create_vertex_elements_state(struct pipe_context *ctx,
341                                                         unsigned num_elements,
342                                                         const struct pipe_vertex_element *elements)
343 {
344    struct virgl_context *vctx = virgl_context(ctx);
345    uint32_t handle = virgl_object_assign_handle();
346    virgl_encoder_create_vertex_elements(vctx, handle,
347                                        num_elements, elements);
348    return (void*)(unsigned long)handle;
349 
350 }
351 
virgl_delete_vertex_elements_state(struct pipe_context * ctx,void * ve)352 static void virgl_delete_vertex_elements_state(struct pipe_context *ctx,
353                                               void *ve)
354 {
355    struct virgl_context *vctx = virgl_context(ctx);
356    uint32_t handle = (unsigned long)ve;
357 
358    virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_VERTEX_ELEMENTS);
359 }
360 
virgl_bind_vertex_elements_state(struct pipe_context * ctx,void * ve)361 static void virgl_bind_vertex_elements_state(struct pipe_context *ctx,
362                                                      void *ve)
363 {
364    struct virgl_context *vctx = virgl_context(ctx);
365    uint32_t handle = (unsigned long)ve;
366    virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_VERTEX_ELEMENTS);
367 }
368 
virgl_set_vertex_buffers(struct pipe_context * ctx,unsigned start_slot,unsigned num_buffers,const struct pipe_vertex_buffer * buffers)369 static void virgl_set_vertex_buffers(struct pipe_context *ctx,
370                                     unsigned start_slot,
371                                     unsigned num_buffers,
372                                     const struct pipe_vertex_buffer *buffers)
373 {
374    struct virgl_context *vctx = virgl_context(ctx);
375 
376    util_set_vertex_buffers_count(vctx->vertex_buffer,
377                                  &vctx->num_vertex_buffers,
378                                  buffers, start_slot, num_buffers);
379 
380    vctx->vertex_array_dirty = TRUE;
381 }
382 
virgl_hw_set_vertex_buffers(struct pipe_context * ctx)383 static void virgl_hw_set_vertex_buffers(struct pipe_context *ctx)
384 {
385    struct virgl_context *vctx = virgl_context(ctx);
386 
387    if (vctx->vertex_array_dirty) {
388       virgl_encoder_set_vertex_buffers(vctx, vctx->num_vertex_buffers, vctx->vertex_buffer);
389       virgl_attach_res_vertex_buffers(vctx);
390    }
391 }
392 
virgl_set_stencil_ref(struct pipe_context * ctx,const struct pipe_stencil_ref * ref)393 static void virgl_set_stencil_ref(struct pipe_context *ctx,
394                                  const struct pipe_stencil_ref *ref)
395 {
396    struct virgl_context *vctx = virgl_context(ctx);
397    virgl_encoder_set_stencil_ref(vctx, ref);
398 }
399 
virgl_set_blend_color(struct pipe_context * ctx,const struct pipe_blend_color * color)400 static void virgl_set_blend_color(struct pipe_context *ctx,
401                                  const struct pipe_blend_color *color)
402 {
403    struct virgl_context *vctx = virgl_context(ctx);
404    virgl_encoder_set_blend_color(vctx, color);
405 }
406 
virgl_hw_set_index_buffer(struct pipe_context * ctx,struct virgl_indexbuf * ib)407 static void virgl_hw_set_index_buffer(struct pipe_context *ctx,
408                                      struct virgl_indexbuf *ib)
409 {
410    struct virgl_context *vctx = virgl_context(ctx);
411    virgl_encoder_set_index_buffer(vctx, ib);
412    virgl_attach_res_index_buffer(vctx, ib);
413 }
414 
virgl_set_constant_buffer(struct pipe_context * ctx,enum pipe_shader_type shader,uint index,const struct pipe_constant_buffer * buf)415 static void virgl_set_constant_buffer(struct pipe_context *ctx,
416                                      enum pipe_shader_type shader, uint index,
417                                      const struct pipe_constant_buffer *buf)
418 {
419    struct virgl_context *vctx = virgl_context(ctx);
420 
421    if (buf) {
422       if (!buf->user_buffer){
423          struct virgl_resource *res = virgl_resource(buf->buffer);
424          virgl_encoder_set_uniform_buffer(vctx, shader, index, buf->buffer_offset,
425                                           buf->buffer_size, res);
426          pipe_resource_reference(&vctx->ubos[shader][index], buf->buffer);
427          return;
428       }
429       pipe_resource_reference(&vctx->ubos[shader][index], NULL);
430       virgl_encoder_write_constant_buffer(vctx, shader, index, buf->buffer_size / 4, buf->user_buffer);
431    } else {
432       virgl_encoder_write_constant_buffer(vctx, shader, index, 0, NULL);
433       pipe_resource_reference(&vctx->ubos[shader][index], NULL);
434    }
435 }
436 
virgl_transfer_inline_write(struct pipe_context * ctx,struct pipe_resource * res,unsigned level,unsigned usage,const struct pipe_box * box,const void * data,unsigned stride,unsigned layer_stride)437 void virgl_transfer_inline_write(struct pipe_context *ctx,
438                                 struct pipe_resource *res,
439                                 unsigned level,
440                                 unsigned usage,
441                                 const struct pipe_box *box,
442                                 const void *data,
443                                 unsigned stride,
444                                 unsigned layer_stride)
445 {
446    struct virgl_context *vctx = virgl_context(ctx);
447    struct virgl_screen *vs = virgl_screen(ctx->screen);
448    struct virgl_resource *grres = virgl_resource(res);
449    struct virgl_buffer *vbuf = virgl_buffer(res);
450 
451    grres->clean = FALSE;
452 
453    if (virgl_res_needs_flush_wait(vctx, &vbuf->base, usage)) {
454       ctx->flush(ctx, NULL, 0);
455 
456       vs->vws->resource_wait(vs->vws, vbuf->base.hw_res);
457    }
458 
459    virgl_encoder_inline_write(vctx, grres, level, usage,
460                               box, data, stride, layer_stride);
461 }
462 
virgl_shader_encoder(struct pipe_context * ctx,const struct pipe_shader_state * shader,unsigned type)463 static void *virgl_shader_encoder(struct pipe_context *ctx,
464                                   const struct pipe_shader_state *shader,
465                                   unsigned type)
466 {
467    struct virgl_context *vctx = virgl_context(ctx);
468    uint32_t handle;
469    struct tgsi_token *new_tokens;
470    int ret;
471 
472    new_tokens = virgl_tgsi_transform(shader->tokens);
473    if (!new_tokens)
474       return NULL;
475 
476    handle = virgl_object_assign_handle();
477    /* encode VS state */
478    ret = virgl_encode_shader_state(vctx, handle, type,
479                                    &shader->stream_output,
480                                    new_tokens);
481    if (ret) {
482       return NULL;
483    }
484 
485    FREE(new_tokens);
486    return (void *)(unsigned long)handle;
487 
488 }
virgl_create_vs_state(struct pipe_context * ctx,const struct pipe_shader_state * shader)489 static void *virgl_create_vs_state(struct pipe_context *ctx,
490                                    const struct pipe_shader_state *shader)
491 {
492    return virgl_shader_encoder(ctx, shader, PIPE_SHADER_VERTEX);
493 }
494 
virgl_create_gs_state(struct pipe_context * ctx,const struct pipe_shader_state * shader)495 static void *virgl_create_gs_state(struct pipe_context *ctx,
496                                    const struct pipe_shader_state *shader)
497 {
498    return virgl_shader_encoder(ctx, shader, PIPE_SHADER_GEOMETRY);
499 }
500 
virgl_create_fs_state(struct pipe_context * ctx,const struct pipe_shader_state * shader)501 static void *virgl_create_fs_state(struct pipe_context *ctx,
502                                    const struct pipe_shader_state *shader)
503 {
504    return virgl_shader_encoder(ctx, shader, PIPE_SHADER_FRAGMENT);
505 }
506 
507 static void
virgl_delete_fs_state(struct pipe_context * ctx,void * fs)508 virgl_delete_fs_state(struct pipe_context *ctx,
509                      void *fs)
510 {
511    uint32_t handle = (unsigned long)fs;
512    struct virgl_context *vctx = virgl_context(ctx);
513 
514    virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
515 }
516 
517 static void
virgl_delete_gs_state(struct pipe_context * ctx,void * gs)518 virgl_delete_gs_state(struct pipe_context *ctx,
519                      void *gs)
520 {
521    uint32_t handle = (unsigned long)gs;
522    struct virgl_context *vctx = virgl_context(ctx);
523 
524    virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
525 }
526 
527 static void
virgl_delete_vs_state(struct pipe_context * ctx,void * vs)528 virgl_delete_vs_state(struct pipe_context *ctx,
529                      void *vs)
530 {
531    uint32_t handle = (unsigned long)vs;
532    struct virgl_context *vctx = virgl_context(ctx);
533 
534    virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
535 }
536 
virgl_bind_vs_state(struct pipe_context * ctx,void * vss)537 static void virgl_bind_vs_state(struct pipe_context *ctx,
538                                         void *vss)
539 {
540    uint32_t handle = (unsigned long)vss;
541    struct virgl_context *vctx = virgl_context(ctx);
542 
543    virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_VERTEX);
544 }
545 
virgl_bind_gs_state(struct pipe_context * ctx,void * vss)546 static void virgl_bind_gs_state(struct pipe_context *ctx,
547                                void *vss)
548 {
549    uint32_t handle = (unsigned long)vss;
550    struct virgl_context *vctx = virgl_context(ctx);
551 
552    virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_GEOMETRY);
553 }
554 
555 
virgl_bind_fs_state(struct pipe_context * ctx,void * vss)556 static void virgl_bind_fs_state(struct pipe_context *ctx,
557                                         void *vss)
558 {
559    uint32_t handle = (unsigned long)vss;
560    struct virgl_context *vctx = virgl_context(ctx);
561 
562    virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_FRAGMENT);
563 }
564 
virgl_clear(struct pipe_context * ctx,unsigned buffers,const union pipe_color_union * color,double depth,unsigned stencil)565 static void virgl_clear(struct pipe_context *ctx,
566                                 unsigned buffers,
567                                 const union pipe_color_union *color,
568                                 double depth, unsigned stencil)
569 {
570    struct virgl_context *vctx = virgl_context(ctx);
571 
572    virgl_encode_clear(vctx, buffers, color, depth, stencil);
573 }
574 
virgl_draw_vbo(struct pipe_context * ctx,const struct pipe_draw_info * dinfo)575 static void virgl_draw_vbo(struct pipe_context *ctx,
576                                    const struct pipe_draw_info *dinfo)
577 {
578    struct virgl_context *vctx = virgl_context(ctx);
579    struct virgl_screen *rs = virgl_screen(ctx->screen);
580    struct virgl_indexbuf ib = {};
581    struct pipe_draw_info info = *dinfo;
582 
583    if (!dinfo->count_from_stream_output && !dinfo->indirect &&
584        !dinfo->primitive_restart &&
585        !u_trim_pipe_prim(dinfo->mode, (unsigned*)&dinfo->count))
586       return;
587 
588    if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) {
589       util_primconvert_draw_vbo(vctx->primconvert, dinfo);
590       return;
591    }
592    if (info.index_size) {
593            pipe_resource_reference(&ib.buffer, info.has_user_indices ? NULL : info.index.resource);
594            ib.user_buffer = info.has_user_indices ? info.index.user : NULL;
595            ib.index_size = dinfo->index_size;
596            ib.offset = info.start * ib.index_size;
597 
598            if (ib.user_buffer) {
599                    u_upload_data(vctx->uploader, 0, info.count * ib.index_size, 256,
600                                  ib.user_buffer, &ib.offset, &ib.buffer);
601                    ib.user_buffer = NULL;
602            }
603    }
604 
605    u_upload_unmap(vctx->uploader);
606 
607    vctx->num_draws++;
608    virgl_hw_set_vertex_buffers(ctx);
609    if (info.index_size)
610       virgl_hw_set_index_buffer(ctx, &ib);
611 
612    virgl_encoder_draw_vbo(vctx, &info);
613 
614    pipe_resource_reference(&ib.buffer, NULL);
615 
616 }
617 
virgl_flush_eq(struct virgl_context * ctx,void * closure)618 static void virgl_flush_eq(struct virgl_context *ctx, void *closure)
619 {
620    struct virgl_screen *rs = virgl_screen(ctx->base.screen);
621 
622    /* send the buffer to the remote side for decoding */
623    ctx->num_transfers = ctx->num_draws = 0;
624    rs->vws->submit_cmd(rs->vws, ctx->cbuf);
625 
626    virgl_encoder_set_sub_ctx(ctx, ctx->hw_sub_ctx_id);
627 
628    /* add back current framebuffer resources to reference list? */
629    virgl_reemit_res(ctx);
630 }
631 
virgl_flush_from_st(struct pipe_context * ctx,struct pipe_fence_handle ** fence,enum pipe_flush_flags flags)632 static void virgl_flush_from_st(struct pipe_context *ctx,
633                                struct pipe_fence_handle **fence,
634                                enum pipe_flush_flags flags)
635 {
636    struct virgl_context *vctx = virgl_context(ctx);
637    struct virgl_screen *rs = virgl_screen(ctx->screen);
638    struct virgl_buffer *buf, *tmp;
639 
640    if (fence)
641       *fence = rs->vws->cs_create_fence(rs->vws);
642 
643    LIST_FOR_EACH_ENTRY_SAFE(buf, tmp, &vctx->to_flush_bufs, flush_list) {
644       struct pipe_resource *res = &buf->base.u.b;
645       virgl_buffer_flush(vctx, buf);
646       list_del(&buf->flush_list);
647       buf->on_list = FALSE;
648       pipe_resource_reference(&res, NULL);
649 
650    }
651    virgl_flush_eq(vctx, vctx);
652 }
653 
virgl_create_sampler_view(struct pipe_context * ctx,struct pipe_resource * texture,const struct pipe_sampler_view * state)654 static struct pipe_sampler_view *virgl_create_sampler_view(struct pipe_context *ctx,
655                                       struct pipe_resource *texture,
656                                       const struct pipe_sampler_view *state)
657 {
658    struct virgl_context *vctx = virgl_context(ctx);
659    struct virgl_sampler_view *grview;
660    uint32_t handle;
661    struct virgl_resource *res;
662 
663    if (!state)
664       return NULL;
665 
666    grview = CALLOC_STRUCT(virgl_sampler_view);
667    if (!grview)
668       return NULL;
669 
670    res = virgl_resource(texture);
671    handle = virgl_object_assign_handle();
672    virgl_encode_sampler_view(vctx, handle, res, state);
673 
674    grview->base = *state;
675    grview->base.reference.count = 1;
676 
677    grview->base.texture = NULL;
678    grview->base.context = ctx;
679    pipe_resource_reference(&grview->base.texture, texture);
680    grview->handle = handle;
681    return &grview->base;
682 }
683 
virgl_set_sampler_views(struct pipe_context * ctx,enum pipe_shader_type shader_type,unsigned start_slot,unsigned num_views,struct pipe_sampler_view ** views)684 static void virgl_set_sampler_views(struct pipe_context *ctx,
685                                    enum pipe_shader_type shader_type,
686                                    unsigned start_slot,
687                                    unsigned num_views,
688                                    struct pipe_sampler_view **views)
689 {
690    struct virgl_context *vctx = virgl_context(ctx);
691    int i;
692    uint32_t disable_mask = ~((1ull << num_views) - 1);
693    struct virgl_textures_info *tinfo = &vctx->samplers[shader_type];
694    uint32_t new_mask = 0;
695    uint32_t remaining_mask;
696 
697    remaining_mask = tinfo->enabled_mask & disable_mask;
698 
699    while (remaining_mask) {
700       i = u_bit_scan(&remaining_mask);
701       assert(tinfo->views[i]);
702 
703       pipe_sampler_view_reference((struct pipe_sampler_view **)&tinfo->views[i], NULL);
704    }
705 
706    for (i = 0; i < num_views; i++) {
707       struct virgl_sampler_view *grview = virgl_sampler_view(views[i]);
708 
709       if (views[i] == (struct pipe_sampler_view *)tinfo->views[i])
710          continue;
711 
712       if (grview) {
713          new_mask |= 1 << i;
714          pipe_sampler_view_reference((struct pipe_sampler_view **)&tinfo->views[i], views[i]);
715       } else {
716          pipe_sampler_view_reference((struct pipe_sampler_view **)&tinfo->views[i], NULL);
717          disable_mask |= 1 << i;
718       }
719    }
720 
721    tinfo->enabled_mask &= ~disable_mask;
722    tinfo->enabled_mask |= new_mask;
723    virgl_encode_set_sampler_views(vctx, shader_type, start_slot, num_views, tinfo->views);
724    virgl_attach_res_sampler_views(vctx, shader_type);
725 }
726 
virgl_destroy_sampler_view(struct pipe_context * ctx,struct pipe_sampler_view * view)727 static void virgl_destroy_sampler_view(struct pipe_context *ctx,
728                                  struct pipe_sampler_view *view)
729 {
730    struct virgl_context *vctx = virgl_context(ctx);
731    struct virgl_sampler_view *grview = virgl_sampler_view(view);
732 
733    virgl_encode_delete_object(vctx, grview->handle, VIRGL_OBJECT_SAMPLER_VIEW);
734    pipe_resource_reference(&view->texture, NULL);
735    FREE(view);
736 }
737 
virgl_create_sampler_state(struct pipe_context * ctx,const struct pipe_sampler_state * state)738 static void *virgl_create_sampler_state(struct pipe_context *ctx,
739                                         const struct pipe_sampler_state *state)
740 {
741    struct virgl_context *vctx = virgl_context(ctx);
742    uint32_t handle;
743 
744    handle = virgl_object_assign_handle();
745 
746    virgl_encode_sampler_state(vctx, handle, state);
747    return (void *)(unsigned long)handle;
748 }
749 
virgl_delete_sampler_state(struct pipe_context * ctx,void * ss)750 static void virgl_delete_sampler_state(struct pipe_context *ctx,
751                                       void *ss)
752 {
753    struct virgl_context *vctx = virgl_context(ctx);
754    uint32_t handle = (unsigned long)ss;
755 
756    virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SAMPLER_STATE);
757 }
758 
virgl_bind_sampler_states(struct pipe_context * ctx,enum pipe_shader_type shader,unsigned start_slot,unsigned num_samplers,void ** samplers)759 static void virgl_bind_sampler_states(struct pipe_context *ctx,
760                                      enum pipe_shader_type shader,
761                                      unsigned start_slot,
762                                      unsigned num_samplers,
763                                      void **samplers)
764 {
765    struct virgl_context *vctx = virgl_context(ctx);
766    uint32_t handles[32];
767    int i;
768    for (i = 0; i < num_samplers; i++) {
769       handles[i] = (unsigned long)(samplers[i]);
770    }
771    virgl_encode_bind_sampler_states(vctx, shader, start_slot, num_samplers, handles);
772 }
773 
virgl_set_polygon_stipple(struct pipe_context * ctx,const struct pipe_poly_stipple * ps)774 static void virgl_set_polygon_stipple(struct pipe_context *ctx,
775                                      const struct pipe_poly_stipple *ps)
776 {
777    struct virgl_context *vctx = virgl_context(ctx);
778    virgl_encoder_set_polygon_stipple(vctx, ps);
779 }
780 
virgl_set_scissor_states(struct pipe_context * ctx,unsigned start_slot,unsigned num_scissor,const struct pipe_scissor_state * ss)781 static void virgl_set_scissor_states(struct pipe_context *ctx,
782                                     unsigned start_slot,
783                                     unsigned num_scissor,
784                                    const struct pipe_scissor_state *ss)
785 {
786    struct virgl_context *vctx = virgl_context(ctx);
787    virgl_encoder_set_scissor_state(vctx, start_slot, num_scissor, ss);
788 }
789 
virgl_set_sample_mask(struct pipe_context * ctx,unsigned sample_mask)790 static void virgl_set_sample_mask(struct pipe_context *ctx,
791                                  unsigned sample_mask)
792 {
793    struct virgl_context *vctx = virgl_context(ctx);
794    virgl_encoder_set_sample_mask(vctx, sample_mask);
795 }
796 
virgl_set_clip_state(struct pipe_context * ctx,const struct pipe_clip_state * clip)797 static void virgl_set_clip_state(struct pipe_context *ctx,
798                                 const struct pipe_clip_state *clip)
799 {
800    struct virgl_context *vctx = virgl_context(ctx);
801    virgl_encoder_set_clip_state(vctx, clip);
802 }
803 
virgl_resource_copy_region(struct pipe_context * ctx,struct pipe_resource * dst,unsigned dst_level,unsigned dstx,unsigned dsty,unsigned dstz,struct pipe_resource * src,unsigned src_level,const struct pipe_box * src_box)804 static void virgl_resource_copy_region(struct pipe_context *ctx,
805                                       struct pipe_resource *dst,
806                                       unsigned dst_level,
807                                       unsigned dstx, unsigned dsty, unsigned dstz,
808                                       struct pipe_resource *src,
809                                       unsigned src_level,
810                                       const struct pipe_box *src_box)
811 {
812    struct virgl_context *vctx = virgl_context(ctx);
813    struct virgl_resource *dres = virgl_resource(dst);
814    struct virgl_resource *sres = virgl_resource(src);
815 
816    dres->clean = FALSE;
817    virgl_encode_resource_copy_region(vctx, dres,
818                                     dst_level, dstx, dsty, dstz,
819                                     sres, src_level,
820                                     src_box);
821 }
822 
823 static void
virgl_flush_resource(struct pipe_context * pipe,struct pipe_resource * resource)824 virgl_flush_resource(struct pipe_context *pipe,
825                     struct pipe_resource *resource)
826 {
827 }
828 
virgl_blit(struct pipe_context * ctx,const struct pipe_blit_info * blit)829 static void virgl_blit(struct pipe_context *ctx,
830                       const struct pipe_blit_info *blit)
831 {
832    struct virgl_context *vctx = virgl_context(ctx);
833    struct virgl_resource *dres = virgl_resource(blit->dst.resource);
834    struct virgl_resource *sres = virgl_resource(blit->src.resource);
835 
836    dres->clean = FALSE;
837    virgl_encode_blit(vctx, dres, sres,
838                     blit);
839 }
840 
841 static void
virgl_context_destroy(struct pipe_context * ctx)842 virgl_context_destroy( struct pipe_context *ctx )
843 {
844    struct virgl_context *vctx = virgl_context(ctx);
845    struct virgl_screen *rs = virgl_screen(ctx->screen);
846 
847    vctx->framebuffer.zsbuf = NULL;
848    vctx->framebuffer.nr_cbufs = 0;
849    virgl_encoder_destroy_sub_ctx(vctx, vctx->hw_sub_ctx_id);
850    virgl_flush_eq(vctx, vctx);
851 
852    rs->vws->cmd_buf_destroy(vctx->cbuf);
853    if (vctx->uploader)
854       u_upload_destroy(vctx->uploader);
855    util_primconvert_destroy(vctx->primconvert);
856 
857    slab_destroy_child(&vctx->texture_transfer_pool);
858    FREE(vctx);
859 }
860 
virgl_context_create(struct pipe_screen * pscreen,void * priv,unsigned flags)861 struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
862                                           void *priv,
863                                           unsigned flags)
864 {
865    struct virgl_context *vctx;
866    struct virgl_screen *rs = virgl_screen(pscreen);
867    vctx = CALLOC_STRUCT(virgl_context);
868 
869    vctx->cbuf = rs->vws->cmd_buf_create(rs->vws);
870    if (!vctx->cbuf) {
871       FREE(vctx);
872       return NULL;
873    }
874 
875    vctx->base.destroy = virgl_context_destroy;
876    vctx->base.create_surface = virgl_create_surface;
877    vctx->base.surface_destroy = virgl_surface_destroy;
878    vctx->base.set_framebuffer_state = virgl_set_framebuffer_state;
879    vctx->base.create_blend_state = virgl_create_blend_state;
880    vctx->base.bind_blend_state = virgl_bind_blend_state;
881    vctx->base.delete_blend_state = virgl_delete_blend_state;
882    vctx->base.create_depth_stencil_alpha_state = virgl_create_depth_stencil_alpha_state;
883    vctx->base.bind_depth_stencil_alpha_state = virgl_bind_depth_stencil_alpha_state;
884    vctx->base.delete_depth_stencil_alpha_state = virgl_delete_depth_stencil_alpha_state;
885    vctx->base.create_rasterizer_state = virgl_create_rasterizer_state;
886    vctx->base.bind_rasterizer_state = virgl_bind_rasterizer_state;
887    vctx->base.delete_rasterizer_state = virgl_delete_rasterizer_state;
888 
889    vctx->base.set_viewport_states = virgl_set_viewport_states;
890    vctx->base.create_vertex_elements_state = virgl_create_vertex_elements_state;
891    vctx->base.bind_vertex_elements_state = virgl_bind_vertex_elements_state;
892    vctx->base.delete_vertex_elements_state = virgl_delete_vertex_elements_state;
893    vctx->base.set_vertex_buffers = virgl_set_vertex_buffers;
894    vctx->base.set_constant_buffer = virgl_set_constant_buffer;
895 
896    vctx->base.create_vs_state = virgl_create_vs_state;
897    vctx->base.create_gs_state = virgl_create_gs_state;
898    vctx->base.create_fs_state = virgl_create_fs_state;
899 
900    vctx->base.bind_vs_state = virgl_bind_vs_state;
901    vctx->base.bind_gs_state = virgl_bind_gs_state;
902    vctx->base.bind_fs_state = virgl_bind_fs_state;
903 
904    vctx->base.delete_vs_state = virgl_delete_vs_state;
905    vctx->base.delete_gs_state = virgl_delete_gs_state;
906    vctx->base.delete_fs_state = virgl_delete_fs_state;
907 
908    vctx->base.clear = virgl_clear;
909    vctx->base.draw_vbo = virgl_draw_vbo;
910    vctx->base.flush = virgl_flush_from_st;
911    vctx->base.screen = pscreen;
912    vctx->base.create_sampler_view = virgl_create_sampler_view;
913    vctx->base.sampler_view_destroy = virgl_destroy_sampler_view;
914    vctx->base.set_sampler_views = virgl_set_sampler_views;
915 
916    vctx->base.create_sampler_state = virgl_create_sampler_state;
917    vctx->base.delete_sampler_state = virgl_delete_sampler_state;
918    vctx->base.bind_sampler_states = virgl_bind_sampler_states;
919 
920    vctx->base.set_polygon_stipple = virgl_set_polygon_stipple;
921    vctx->base.set_scissor_states = virgl_set_scissor_states;
922    vctx->base.set_sample_mask = virgl_set_sample_mask;
923    vctx->base.set_stencil_ref = virgl_set_stencil_ref;
924    vctx->base.set_clip_state = virgl_set_clip_state;
925 
926    vctx->base.set_blend_color = virgl_set_blend_color;
927 
928    vctx->base.resource_copy_region = virgl_resource_copy_region;
929    vctx->base.flush_resource = virgl_flush_resource;
930    vctx->base.blit =  virgl_blit;
931 
932    virgl_init_context_resource_functions(&vctx->base);
933    virgl_init_query_functions(vctx);
934    virgl_init_so_functions(vctx);
935 
936    list_inithead(&vctx->to_flush_bufs);
937    slab_create_child(&vctx->texture_transfer_pool, &rs->texture_transfer_pool);
938 
939    vctx->primconvert = util_primconvert_create(&vctx->base, rs->caps.caps.v1.prim_mask);
940    vctx->uploader = u_upload_create(&vctx->base, 1024 * 1024,
941                                      PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_STREAM, 0);
942    if (!vctx->uploader)
943            goto fail;
944    vctx->base.stream_uploader = vctx->uploader;
945    vctx->base.const_uploader = vctx->uploader;
946 
947    vctx->hw_sub_ctx_id = rs->sub_ctx_id++;
948    virgl_encoder_create_sub_ctx(vctx, vctx->hw_sub_ctx_id);
949 
950    virgl_encoder_set_sub_ctx(vctx, vctx->hw_sub_ctx_id);
951    return &vctx->base;
952 fail:
953    return NULL;
954 }
955