101e04c3fSmrg/*
201e04c3fSmrg * Copyright 2014, 2015 Red Hat.
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * on the rights to use, copy, modify, merge, publish, distribute, sub
801e04c3fSmrg * license, and/or sell copies of the Software, and to permit persons to whom
901e04c3fSmrg * the Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
1901e04c3fSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2001e04c3fSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2101e04c3fSmrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
249f464c52Smaya#include <libsync.h>
2501e04c3fSmrg#include "pipe/p_shader_tokens.h"
2601e04c3fSmrg
277ec681f3Smrg#include "compiler/nir/nir.h"
2801e04c3fSmrg#include "pipe/p_context.h"
2901e04c3fSmrg#include "pipe/p_defines.h"
3001e04c3fSmrg#include "pipe/p_screen.h"
3101e04c3fSmrg#include "pipe/p_state.h"
327ec681f3Smrg#include "nir/nir_to_tgsi.h"
337ec681f3Smrg#include "util/u_draw.h"
3401e04c3fSmrg#include "util/u_inlines.h"
3501e04c3fSmrg#include "util/u_memory.h"
367ec681f3Smrg#include "util/format/u_format.h"
3701e04c3fSmrg#include "util/u_prim.h"
3801e04c3fSmrg#include "util/u_transfer.h"
3901e04c3fSmrg#include "util/u_helpers.h"
4001e04c3fSmrg#include "util/slab.h"
4101e04c3fSmrg#include "util/u_upload_mgr.h"
4201e04c3fSmrg#include "util/u_blitter.h"
4301e04c3fSmrg#include "tgsi/tgsi_text.h"
4401e04c3fSmrg#include "indices/u_primconvert.h"
4501e04c3fSmrg
4601e04c3fSmrg#include "pipebuffer/pb_buffer.h"
4701e04c3fSmrg
4801e04c3fSmrg#include "virgl_encode.h"
4901e04c3fSmrg#include "virgl_context.h"
507ec681f3Smrg#include "virtio-gpu/virgl_protocol.h"
5101e04c3fSmrg#include "virgl_resource.h"
5201e04c3fSmrg#include "virgl_screen.h"
537ec681f3Smrg#include "virgl_staging_mgr.h"
5401e04c3fSmrg
5501e04c3fSmrgstruct virgl_vertex_elements_state {
5601e04c3fSmrg   uint32_t handle;
5701e04c3fSmrg   uint8_t binding_map[PIPE_MAX_ATTRIBS];
5801e04c3fSmrg   uint8_t num_bindings;
5901e04c3fSmrg};
6001e04c3fSmrg
6101e04c3fSmrgstatic uint32_t next_handle;
6201e04c3fSmrguint32_t virgl_object_assign_handle(void)
6301e04c3fSmrg{
647ec681f3Smrg   return p_atomic_inc_return(&next_handle);
657ec681f3Smrg}
667ec681f3Smrg
677ec681f3Smrgbool
687ec681f3Smrgvirgl_can_rebind_resource(struct virgl_context *vctx,
697ec681f3Smrg                          struct pipe_resource *res)
707ec681f3Smrg{
717ec681f3Smrg   /* We cannot rebind resources that are referenced by host objects, which
727ec681f3Smrg    * are
737ec681f3Smrg    *
747ec681f3Smrg    *  - VIRGL_OBJECT_SURFACE
757ec681f3Smrg    *  - VIRGL_OBJECT_SAMPLER_VIEW
767ec681f3Smrg    *  - VIRGL_OBJECT_STREAMOUT_TARGET
777ec681f3Smrg    *
787ec681f3Smrg    * Because surfaces cannot be created from buffers, we require the resource
797ec681f3Smrg    * to be a buffer instead (and avoid tracking VIRGL_OBJECT_SURFACE binds).
807ec681f3Smrg    */
817ec681f3Smrg   const unsigned unsupported_bind = (PIPE_BIND_SAMPLER_VIEW |
827ec681f3Smrg                                      PIPE_BIND_STREAM_OUTPUT);
837ec681f3Smrg   const unsigned bind_history = virgl_resource(res)->bind_history;
847ec681f3Smrg   return res->target == PIPE_BUFFER && !(bind_history & unsupported_bind);
857ec681f3Smrg}
867ec681f3Smrg
877ec681f3Smrgvoid
887ec681f3Smrgvirgl_rebind_resource(struct virgl_context *vctx,
897ec681f3Smrg                      struct pipe_resource *res)
907ec681f3Smrg{
917ec681f3Smrg   /* Queries use internally created buffers and do not go through transfers.
927ec681f3Smrg    * Index buffers are not bindable.  They are not tracked.
937ec681f3Smrg    */
947ec681f3Smrg   ASSERTED const unsigned tracked_bind = (PIPE_BIND_VERTEX_BUFFER |
957ec681f3Smrg                                               PIPE_BIND_CONSTANT_BUFFER |
967ec681f3Smrg                                               PIPE_BIND_SHADER_BUFFER |
977ec681f3Smrg                                               PIPE_BIND_SHADER_IMAGE);
987ec681f3Smrg   const unsigned bind_history = virgl_resource(res)->bind_history;
997ec681f3Smrg   unsigned i;
1007ec681f3Smrg
1017ec681f3Smrg   assert(virgl_can_rebind_resource(vctx, res) &&
1027ec681f3Smrg          (bind_history & tracked_bind) == bind_history);
1037ec681f3Smrg
1047ec681f3Smrg   if (bind_history & PIPE_BIND_VERTEX_BUFFER) {
1057ec681f3Smrg      for (i = 0; i < vctx->num_vertex_buffers; i++) {
1067ec681f3Smrg         if (vctx->vertex_buffer[i].buffer.resource == res) {
1077ec681f3Smrg            vctx->vertex_array_dirty = true;
1087ec681f3Smrg            break;
1097ec681f3Smrg         }
1107ec681f3Smrg      }
1117ec681f3Smrg   }
1127ec681f3Smrg
1137ec681f3Smrg   if (bind_history & PIPE_BIND_SHADER_BUFFER) {
1147ec681f3Smrg      uint32_t remaining_mask = vctx->atomic_buffer_enabled_mask;
1157ec681f3Smrg      while (remaining_mask) {
1167ec681f3Smrg         int i = u_bit_scan(&remaining_mask);
1177ec681f3Smrg         if (vctx->atomic_buffers[i].buffer == res) {
1187ec681f3Smrg            const struct pipe_shader_buffer *abo = &vctx->atomic_buffers[i];
1197ec681f3Smrg            virgl_encode_set_hw_atomic_buffers(vctx, i, 1, abo);
1207ec681f3Smrg         }
1217ec681f3Smrg      }
1227ec681f3Smrg   }
1237ec681f3Smrg
1247ec681f3Smrg   /* check per-stage shader bindings */
1257ec681f3Smrg   if (bind_history & (PIPE_BIND_CONSTANT_BUFFER |
1267ec681f3Smrg                       PIPE_BIND_SHADER_BUFFER |
1277ec681f3Smrg                       PIPE_BIND_SHADER_IMAGE)) {
1287ec681f3Smrg      enum pipe_shader_type shader_type;
1297ec681f3Smrg      for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) {
1307ec681f3Smrg         const struct virgl_shader_binding_state *binding =
1317ec681f3Smrg            &vctx->shader_bindings[shader_type];
1327ec681f3Smrg
1337ec681f3Smrg         if (bind_history & PIPE_BIND_CONSTANT_BUFFER) {
1347ec681f3Smrg            uint32_t remaining_mask = binding->ubo_enabled_mask;
1357ec681f3Smrg            while (remaining_mask) {
1367ec681f3Smrg               int i = u_bit_scan(&remaining_mask);
1377ec681f3Smrg               if (binding->ubos[i].buffer == res) {
1387ec681f3Smrg                  const struct pipe_constant_buffer *ubo = &binding->ubos[i];
1397ec681f3Smrg                  virgl_encoder_set_uniform_buffer(vctx, shader_type, i,
1407ec681f3Smrg                                                   ubo->buffer_offset,
1417ec681f3Smrg                                                   ubo->buffer_size,
1427ec681f3Smrg                                                   virgl_resource(res));
1437ec681f3Smrg               }
1447ec681f3Smrg            }
1457ec681f3Smrg         }
1467ec681f3Smrg
1477ec681f3Smrg         if (bind_history & PIPE_BIND_SHADER_BUFFER) {
1487ec681f3Smrg            uint32_t remaining_mask = binding->ssbo_enabled_mask;
1497ec681f3Smrg            while (remaining_mask) {
1507ec681f3Smrg               int i = u_bit_scan(&remaining_mask);
1517ec681f3Smrg               if (binding->ssbos[i].buffer == res) {
1527ec681f3Smrg                  const struct pipe_shader_buffer *ssbo = &binding->ssbos[i];
1537ec681f3Smrg                  virgl_encode_set_shader_buffers(vctx, shader_type, i, 1,
1547ec681f3Smrg                                                  ssbo);
1557ec681f3Smrg               }
1567ec681f3Smrg            }
1577ec681f3Smrg         }
1587ec681f3Smrg
1597ec681f3Smrg         if (bind_history & PIPE_BIND_SHADER_IMAGE) {
1607ec681f3Smrg            uint32_t remaining_mask = binding->image_enabled_mask;
1617ec681f3Smrg            while (remaining_mask) {
1627ec681f3Smrg               int i = u_bit_scan(&remaining_mask);
1637ec681f3Smrg               if (binding->images[i].resource == res) {
1647ec681f3Smrg                  const struct pipe_image_view *image = &binding->images[i];
1657ec681f3Smrg                  virgl_encode_set_shader_images(vctx, shader_type, i, 1,
1667ec681f3Smrg                                                 image);
1677ec681f3Smrg               }
1687ec681f3Smrg            }
1697ec681f3Smrg         }
1707ec681f3Smrg      }
1717ec681f3Smrg   }
17201e04c3fSmrg}
17301e04c3fSmrg
17401e04c3fSmrgstatic void virgl_attach_res_framebuffer(struct virgl_context *vctx)
17501e04c3fSmrg{
17601e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
17701e04c3fSmrg   struct pipe_surface *surf;
17801e04c3fSmrg   struct virgl_resource *res;
17901e04c3fSmrg   unsigned i;
18001e04c3fSmrg
18101e04c3fSmrg   surf = vctx->framebuffer.zsbuf;
18201e04c3fSmrg   if (surf) {
18301e04c3fSmrg      res = virgl_resource(surf->texture);
1849f464c52Smaya      if (res) {
18501e04c3fSmrg         vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
1869f464c52Smaya         virgl_resource_dirty(res, surf->u.tex.level);
1879f464c52Smaya      }
18801e04c3fSmrg   }
18901e04c3fSmrg   for (i = 0; i < vctx->framebuffer.nr_cbufs; i++) {
19001e04c3fSmrg      surf = vctx->framebuffer.cbufs[i];
19101e04c3fSmrg      if (surf) {
19201e04c3fSmrg         res = virgl_resource(surf->texture);
1939f464c52Smaya         if (res) {
19401e04c3fSmrg            vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
1959f464c52Smaya            virgl_resource_dirty(res, surf->u.tex.level);
1969f464c52Smaya         }
19701e04c3fSmrg      }
19801e04c3fSmrg   }
19901e04c3fSmrg}
20001e04c3fSmrg
20101e04c3fSmrgstatic void virgl_attach_res_sampler_views(struct virgl_context *vctx,
20201e04c3fSmrg                                           enum pipe_shader_type shader_type)
20301e04c3fSmrg{
20401e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
2057ec681f3Smrg   const struct virgl_shader_binding_state *binding =
2067ec681f3Smrg      &vctx->shader_bindings[shader_type];
2077ec681f3Smrg   uint32_t remaining_mask = binding->view_enabled_mask;
20801e04c3fSmrg   struct virgl_resource *res;
20901e04c3fSmrg
2107ec681f3Smrg   while (remaining_mask) {
2117ec681f3Smrg      int i = u_bit_scan(&remaining_mask);
2127ec681f3Smrg      assert(binding->views[i] && binding->views[i]->texture);
2137ec681f3Smrg      res = virgl_resource(binding->views[i]->texture);
2147ec681f3Smrg      vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
21501e04c3fSmrg   }
21601e04c3fSmrg}
21701e04c3fSmrg
21801e04c3fSmrgstatic void virgl_attach_res_vertex_buffers(struct virgl_context *vctx)
21901e04c3fSmrg{
22001e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
22101e04c3fSmrg   struct virgl_resource *res;
22201e04c3fSmrg   unsigned i;
22301e04c3fSmrg
22401e04c3fSmrg   for (i = 0; i < vctx->num_vertex_buffers; i++) {
22501e04c3fSmrg      res = virgl_resource(vctx->vertex_buffer[i].buffer.resource);
22601e04c3fSmrg      if (res)
22701e04c3fSmrg         vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
22801e04c3fSmrg   }
22901e04c3fSmrg}
23001e04c3fSmrg
23101e04c3fSmrgstatic void virgl_attach_res_index_buffer(struct virgl_context *vctx,
23201e04c3fSmrg					  struct virgl_indexbuf *ib)
23301e04c3fSmrg{
23401e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
23501e04c3fSmrg   struct virgl_resource *res;
23601e04c3fSmrg
23701e04c3fSmrg   res = virgl_resource(ib->buffer);
23801e04c3fSmrg   if (res)
23901e04c3fSmrg      vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
24001e04c3fSmrg}
24101e04c3fSmrg
24201e04c3fSmrgstatic void virgl_attach_res_so_targets(struct virgl_context *vctx)
24301e04c3fSmrg{
24401e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
24501e04c3fSmrg   struct virgl_resource *res;
24601e04c3fSmrg   unsigned i;
24701e04c3fSmrg
24801e04c3fSmrg   for (i = 0; i < vctx->num_so_targets; i++) {
24901e04c3fSmrg      res = virgl_resource(vctx->so_targets[i].base.buffer);
25001e04c3fSmrg      if (res)
25101e04c3fSmrg         vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
25201e04c3fSmrg   }
25301e04c3fSmrg}
25401e04c3fSmrg
25501e04c3fSmrgstatic void virgl_attach_res_uniform_buffers(struct virgl_context *vctx,
25601e04c3fSmrg                                             enum pipe_shader_type shader_type)
25701e04c3fSmrg{
25801e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
2597ec681f3Smrg   const struct virgl_shader_binding_state *binding =
2607ec681f3Smrg      &vctx->shader_bindings[shader_type];
2617ec681f3Smrg   uint32_t remaining_mask = binding->ubo_enabled_mask;
26201e04c3fSmrg   struct virgl_resource *res;
2637ec681f3Smrg
2647ec681f3Smrg   while (remaining_mask) {
2657ec681f3Smrg      int i = u_bit_scan(&remaining_mask);
2667ec681f3Smrg      res = virgl_resource(binding->ubos[i].buffer);
2677ec681f3Smrg      assert(res);
2687ec681f3Smrg      vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
26901e04c3fSmrg   }
27001e04c3fSmrg}
27101e04c3fSmrg
27201e04c3fSmrgstatic void virgl_attach_res_shader_buffers(struct virgl_context *vctx,
27301e04c3fSmrg                                            enum pipe_shader_type shader_type)
27401e04c3fSmrg{
27501e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
2767ec681f3Smrg   const struct virgl_shader_binding_state *binding =
2777ec681f3Smrg      &vctx->shader_bindings[shader_type];
2787ec681f3Smrg   uint32_t remaining_mask = binding->ssbo_enabled_mask;
27901e04c3fSmrg   struct virgl_resource *res;
2807ec681f3Smrg
2817ec681f3Smrg   while (remaining_mask) {
2827ec681f3Smrg      int i = u_bit_scan(&remaining_mask);
2837ec681f3Smrg      res = virgl_resource(binding->ssbos[i].buffer);
2847ec681f3Smrg      assert(res);
2857ec681f3Smrg      vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
28601e04c3fSmrg   }
28701e04c3fSmrg}
28801e04c3fSmrg
28901e04c3fSmrgstatic void virgl_attach_res_shader_images(struct virgl_context *vctx,
29001e04c3fSmrg                                           enum pipe_shader_type shader_type)
29101e04c3fSmrg{
29201e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
2937ec681f3Smrg   const struct virgl_shader_binding_state *binding =
2947ec681f3Smrg      &vctx->shader_bindings[shader_type];
2957ec681f3Smrg   uint32_t remaining_mask = binding->image_enabled_mask;
29601e04c3fSmrg   struct virgl_resource *res;
2977ec681f3Smrg
2987ec681f3Smrg   while (remaining_mask) {
2997ec681f3Smrg      int i = u_bit_scan(&remaining_mask);
3007ec681f3Smrg      res = virgl_resource(binding->images[i].resource);
3017ec681f3Smrg      assert(res);
3027ec681f3Smrg      vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
30301e04c3fSmrg   }
30401e04c3fSmrg}
30501e04c3fSmrg
30601e04c3fSmrgstatic void virgl_attach_res_atomic_buffers(struct virgl_context *vctx)
30701e04c3fSmrg{
30801e04c3fSmrg   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
3097ec681f3Smrg   uint32_t remaining_mask = vctx->atomic_buffer_enabled_mask;
31001e04c3fSmrg   struct virgl_resource *res;
3117ec681f3Smrg
3127ec681f3Smrg   while (remaining_mask) {
3137ec681f3Smrg      int i = u_bit_scan(&remaining_mask);
3147ec681f3Smrg      res = virgl_resource(vctx->atomic_buffers[i].buffer);
3157ec681f3Smrg      assert(res);
3167ec681f3Smrg      vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
31701e04c3fSmrg   }
31801e04c3fSmrg}
31901e04c3fSmrg
32001e04c3fSmrg/*
32101e04c3fSmrg * after flushing, the hw context still has a bunch of
32201e04c3fSmrg * resources bound, so we need to rebind those here.
32301e04c3fSmrg */
3247ec681f3Smrgstatic void virgl_reemit_draw_resources(struct virgl_context *vctx)
32501e04c3fSmrg{
32601e04c3fSmrg   enum pipe_shader_type shader_type;
32701e04c3fSmrg
32801e04c3fSmrg   /* reattach any flushed resources */
32901e04c3fSmrg   /* framebuffer, sampler views, vertex/index/uniform/stream buffers */
33001e04c3fSmrg   virgl_attach_res_framebuffer(vctx);
33101e04c3fSmrg
3327ec681f3Smrg   for (shader_type = 0; shader_type < PIPE_SHADER_COMPUTE; shader_type++) {
33301e04c3fSmrg      virgl_attach_res_sampler_views(vctx, shader_type);
33401e04c3fSmrg      virgl_attach_res_uniform_buffers(vctx, shader_type);
33501e04c3fSmrg      virgl_attach_res_shader_buffers(vctx, shader_type);
33601e04c3fSmrg      virgl_attach_res_shader_images(vctx, shader_type);
33701e04c3fSmrg   }
33801e04c3fSmrg   virgl_attach_res_atomic_buffers(vctx);
33901e04c3fSmrg   virgl_attach_res_vertex_buffers(vctx);
34001e04c3fSmrg   virgl_attach_res_so_targets(vctx);
34101e04c3fSmrg}
34201e04c3fSmrg
3437ec681f3Smrgstatic void virgl_reemit_compute_resources(struct virgl_context *vctx)
3447ec681f3Smrg{
3457ec681f3Smrg   virgl_attach_res_sampler_views(vctx, PIPE_SHADER_COMPUTE);
3467ec681f3Smrg   virgl_attach_res_uniform_buffers(vctx, PIPE_SHADER_COMPUTE);
3477ec681f3Smrg   virgl_attach_res_shader_buffers(vctx, PIPE_SHADER_COMPUTE);
3487ec681f3Smrg   virgl_attach_res_shader_images(vctx, PIPE_SHADER_COMPUTE);
3497ec681f3Smrg
3507ec681f3Smrg   virgl_attach_res_atomic_buffers(vctx);
3517ec681f3Smrg}
3527ec681f3Smrg
35301e04c3fSmrgstatic struct pipe_surface *virgl_create_surface(struct pipe_context *ctx,
35401e04c3fSmrg                                                struct pipe_resource *resource,
35501e04c3fSmrg                                                const struct pipe_surface *templ)
35601e04c3fSmrg{
35701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
35801e04c3fSmrg   struct virgl_surface *surf;
35901e04c3fSmrg   struct virgl_resource *res = virgl_resource(resource);
36001e04c3fSmrg   uint32_t handle;
36101e04c3fSmrg
3627ec681f3Smrg   /* no support for buffer surfaces */
3637ec681f3Smrg   if (resource->target == PIPE_BUFFER)
3647ec681f3Smrg      return NULL;
3657ec681f3Smrg
36601e04c3fSmrg   surf = CALLOC_STRUCT(virgl_surface);
36701e04c3fSmrg   if (!surf)
36801e04c3fSmrg      return NULL;
36901e04c3fSmrg
3709f464c52Smaya   assert(ctx->screen->get_param(ctx->screen,
3719f464c52Smaya                                 PIPE_CAP_DEST_SURFACE_SRGB_CONTROL) ||
3729f464c52Smaya          (util_format_is_srgb(templ->format) ==
3739f464c52Smaya           util_format_is_srgb(resource->format)));
3749f464c52Smaya
3759f464c52Smaya   virgl_resource_dirty(res, 0);
37601e04c3fSmrg   handle = virgl_object_assign_handle();
37701e04c3fSmrg   pipe_reference_init(&surf->base.reference, 1);
37801e04c3fSmrg   pipe_resource_reference(&surf->base.texture, resource);
37901e04c3fSmrg   surf->base.context = ctx;
38001e04c3fSmrg   surf->base.format = templ->format;
3817ec681f3Smrg
3827ec681f3Smrg   surf->base.width = u_minify(resource->width0, templ->u.tex.level);
3837ec681f3Smrg   surf->base.height = u_minify(resource->height0, templ->u.tex.level);
3847ec681f3Smrg   surf->base.u.tex.level = templ->u.tex.level;
3857ec681f3Smrg   surf->base.u.tex.first_layer = templ->u.tex.first_layer;
3867ec681f3Smrg   surf->base.u.tex.last_layer = templ->u.tex.last_layer;
3877ec681f3Smrg   surf->base.nr_samples = templ->nr_samples;
3887ec681f3Smrg
38901e04c3fSmrg   virgl_encoder_create_surface(vctx, handle, res, &surf->base);
39001e04c3fSmrg   surf->handle = handle;
39101e04c3fSmrg   return &surf->base;
39201e04c3fSmrg}
39301e04c3fSmrg
39401e04c3fSmrgstatic void virgl_surface_destroy(struct pipe_context *ctx,
39501e04c3fSmrg                                 struct pipe_surface *psurf)
39601e04c3fSmrg{
39701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
39801e04c3fSmrg   struct virgl_surface *surf = virgl_surface(psurf);
39901e04c3fSmrg
40001e04c3fSmrg   pipe_resource_reference(&surf->base.texture, NULL);
40101e04c3fSmrg   virgl_encode_delete_object(vctx, surf->handle, VIRGL_OBJECT_SURFACE);
40201e04c3fSmrg   FREE(surf);
40301e04c3fSmrg}
40401e04c3fSmrg
40501e04c3fSmrgstatic void *virgl_create_blend_state(struct pipe_context *ctx,
40601e04c3fSmrg                                              const struct pipe_blend_state *blend_state)
40701e04c3fSmrg{
40801e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
40901e04c3fSmrg   uint32_t handle;
41001e04c3fSmrg   handle = virgl_object_assign_handle();
41101e04c3fSmrg
41201e04c3fSmrg   virgl_encode_blend_state(vctx, handle, blend_state);
41301e04c3fSmrg   return (void *)(unsigned long)handle;
41401e04c3fSmrg
41501e04c3fSmrg}
41601e04c3fSmrg
41701e04c3fSmrgstatic void virgl_bind_blend_state(struct pipe_context *ctx,
41801e04c3fSmrg                                           void *blend_state)
41901e04c3fSmrg{
42001e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
42101e04c3fSmrg   uint32_t handle = (unsigned long)blend_state;
42201e04c3fSmrg   virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_BLEND);
42301e04c3fSmrg}
42401e04c3fSmrg
42501e04c3fSmrgstatic void virgl_delete_blend_state(struct pipe_context *ctx,
42601e04c3fSmrg                                     void *blend_state)
42701e04c3fSmrg{
42801e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
42901e04c3fSmrg   uint32_t handle = (unsigned long)blend_state;
43001e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_BLEND);
43101e04c3fSmrg}
43201e04c3fSmrg
43301e04c3fSmrgstatic void *virgl_create_depth_stencil_alpha_state(struct pipe_context *ctx,
43401e04c3fSmrg                                                   const struct pipe_depth_stencil_alpha_state *blend_state)
43501e04c3fSmrg{
43601e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
43701e04c3fSmrg   uint32_t handle;
43801e04c3fSmrg   handle = virgl_object_assign_handle();
43901e04c3fSmrg
44001e04c3fSmrg   virgl_encode_dsa_state(vctx, handle, blend_state);
44101e04c3fSmrg   return (void *)(unsigned long)handle;
44201e04c3fSmrg}
44301e04c3fSmrg
44401e04c3fSmrgstatic void virgl_bind_depth_stencil_alpha_state(struct pipe_context *ctx,
44501e04c3fSmrg                                                void *blend_state)
44601e04c3fSmrg{
44701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
44801e04c3fSmrg   uint32_t handle = (unsigned long)blend_state;
44901e04c3fSmrg   virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_DSA);
45001e04c3fSmrg}
45101e04c3fSmrg
45201e04c3fSmrgstatic void virgl_delete_depth_stencil_alpha_state(struct pipe_context *ctx,
45301e04c3fSmrg                                                  void *dsa_state)
45401e04c3fSmrg{
45501e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
45601e04c3fSmrg   uint32_t handle = (unsigned long)dsa_state;
45701e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_DSA);
45801e04c3fSmrg}
45901e04c3fSmrg
46001e04c3fSmrgstatic void *virgl_create_rasterizer_state(struct pipe_context *ctx,
46101e04c3fSmrg                                                   const struct pipe_rasterizer_state *rs_state)
46201e04c3fSmrg{
46301e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
4649f464c52Smaya   struct virgl_rasterizer_state *vrs = CALLOC_STRUCT(virgl_rasterizer_state);
46501e04c3fSmrg
4669f464c52Smaya   if (!vrs)
4679f464c52Smaya      return NULL;
4689f464c52Smaya   vrs->rs = *rs_state;
4699f464c52Smaya   vrs->handle = virgl_object_assign_handle();
4709f464c52Smaya
4717ec681f3Smrg   assert(rs_state->depth_clip_near ||
4727ec681f3Smrg          virgl_screen(ctx->screen)->caps.caps.v1.bset.depth_clip_disable);
4737ec681f3Smrg
4749f464c52Smaya   virgl_encode_rasterizer_state(vctx, vrs->handle, rs_state);
4759f464c52Smaya   return (void *)vrs;
47601e04c3fSmrg}
47701e04c3fSmrg
47801e04c3fSmrgstatic void virgl_bind_rasterizer_state(struct pipe_context *ctx,
47901e04c3fSmrg                                                void *rs_state)
48001e04c3fSmrg{
48101e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
4829f464c52Smaya   uint32_t handle = 0;
4839f464c52Smaya   if (rs_state) {
4849f464c52Smaya      struct virgl_rasterizer_state *vrs = rs_state;
4859f464c52Smaya      vctx->rs_state = *vrs;
4869f464c52Smaya      handle = vrs->handle;
4879f464c52Smaya   }
48801e04c3fSmrg   virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_RASTERIZER);
48901e04c3fSmrg}
49001e04c3fSmrg
49101e04c3fSmrgstatic void virgl_delete_rasterizer_state(struct pipe_context *ctx,
49201e04c3fSmrg                                         void *rs_state)
49301e04c3fSmrg{
49401e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
4959f464c52Smaya   struct virgl_rasterizer_state *vrs = rs_state;
4969f464c52Smaya   virgl_encode_delete_object(vctx, vrs->handle, VIRGL_OBJECT_RASTERIZER);
4979f464c52Smaya   FREE(vrs);
49801e04c3fSmrg}
49901e04c3fSmrg
50001e04c3fSmrgstatic void virgl_set_framebuffer_state(struct pipe_context *ctx,
50101e04c3fSmrg                                                const struct pipe_framebuffer_state *state)
50201e04c3fSmrg{
50301e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
50401e04c3fSmrg
50501e04c3fSmrg   vctx->framebuffer = *state;
50601e04c3fSmrg   virgl_encoder_set_framebuffer_state(vctx, state);
50701e04c3fSmrg   virgl_attach_res_framebuffer(vctx);
50801e04c3fSmrg}
50901e04c3fSmrg
51001e04c3fSmrgstatic void virgl_set_viewport_states(struct pipe_context *ctx,
51101e04c3fSmrg                                     unsigned start_slot,
51201e04c3fSmrg                                     unsigned num_viewports,
51301e04c3fSmrg                                     const struct pipe_viewport_state *state)
51401e04c3fSmrg{
51501e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
51601e04c3fSmrg   virgl_encoder_set_viewport_states(vctx, start_slot, num_viewports, state);
51701e04c3fSmrg}
51801e04c3fSmrg
51901e04c3fSmrgstatic void *virgl_create_vertex_elements_state(struct pipe_context *ctx,
52001e04c3fSmrg                                                        unsigned num_elements,
52101e04c3fSmrg                                                        const struct pipe_vertex_element *elements)
52201e04c3fSmrg{
52301e04c3fSmrg   struct pipe_vertex_element new_elements[PIPE_MAX_ATTRIBS];
52401e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
52501e04c3fSmrg   struct virgl_vertex_elements_state *state =
52601e04c3fSmrg      CALLOC_STRUCT(virgl_vertex_elements_state);
52701e04c3fSmrg
52801e04c3fSmrg   for (int i = 0; i < num_elements; ++i) {
52901e04c3fSmrg      if (elements[i].instance_divisor) {
53001e04c3fSmrg	 /* Virglrenderer doesn't deal with instance_divisor correctly if
53101e04c3fSmrg	  * there isn't a 1:1 relationship between elements and bindings.
53201e04c3fSmrg	  * So let's make sure there is, by duplicating bindings.
53301e04c3fSmrg	  */
53401e04c3fSmrg	 for (int j = 0; j < num_elements; ++j) {
53501e04c3fSmrg            new_elements[j] = elements[j];
53601e04c3fSmrg            new_elements[j].vertex_buffer_index = j;
53701e04c3fSmrg            state->binding_map[j] = elements[j].vertex_buffer_index;
53801e04c3fSmrg	 }
53901e04c3fSmrg	 elements = new_elements;
54001e04c3fSmrg	 state->num_bindings = num_elements;
54101e04c3fSmrg	 break;
54201e04c3fSmrg      }
54301e04c3fSmrg   }
54401e04c3fSmrg
54501e04c3fSmrg   state->handle = virgl_object_assign_handle();
54601e04c3fSmrg   virgl_encoder_create_vertex_elements(vctx, state->handle,
54701e04c3fSmrg                                       num_elements, elements);
54801e04c3fSmrg   return state;
54901e04c3fSmrg}
55001e04c3fSmrg
55101e04c3fSmrgstatic void virgl_delete_vertex_elements_state(struct pipe_context *ctx,
55201e04c3fSmrg                                              void *ve)
55301e04c3fSmrg{
55401e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
55501e04c3fSmrg   struct virgl_vertex_elements_state *state =
55601e04c3fSmrg      (struct virgl_vertex_elements_state *)ve;
55701e04c3fSmrg   virgl_encode_delete_object(vctx, state->handle, VIRGL_OBJECT_VERTEX_ELEMENTS);
55801e04c3fSmrg   FREE(state);
55901e04c3fSmrg}
56001e04c3fSmrg
56101e04c3fSmrgstatic void virgl_bind_vertex_elements_state(struct pipe_context *ctx,
56201e04c3fSmrg                                                     void *ve)
56301e04c3fSmrg{
56401e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
56501e04c3fSmrg   struct virgl_vertex_elements_state *state =
56601e04c3fSmrg      (struct virgl_vertex_elements_state *)ve;
56701e04c3fSmrg   vctx->vertex_elements = state;
56801e04c3fSmrg   virgl_encode_bind_object(vctx, state ? state->handle : 0,
56901e04c3fSmrg                            VIRGL_OBJECT_VERTEX_ELEMENTS);
57001e04c3fSmrg   vctx->vertex_array_dirty = TRUE;
57101e04c3fSmrg}
57201e04c3fSmrg
57301e04c3fSmrgstatic void virgl_set_vertex_buffers(struct pipe_context *ctx,
57401e04c3fSmrg                                    unsigned start_slot,
57501e04c3fSmrg                                    unsigned num_buffers,
5767ec681f3Smrg                                     unsigned unbind_num_trailing_slots,
5777ec681f3Smrg                                     bool take_ownership,
57801e04c3fSmrg                                    const struct pipe_vertex_buffer *buffers)
57901e04c3fSmrg{
58001e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
58101e04c3fSmrg
58201e04c3fSmrg   util_set_vertex_buffers_count(vctx->vertex_buffer,
58301e04c3fSmrg                                 &vctx->num_vertex_buffers,
5847ec681f3Smrg                                 buffers, start_slot, num_buffers,
5857ec681f3Smrg                                 unbind_num_trailing_slots,
5867ec681f3Smrg                                 take_ownership);
5877ec681f3Smrg
5887ec681f3Smrg   if (buffers) {
5897ec681f3Smrg      for (unsigned i = 0; i < num_buffers; i++) {
5907ec681f3Smrg         struct virgl_resource *res =
5917ec681f3Smrg            virgl_resource(buffers[i].buffer.resource);
5927ec681f3Smrg         if (res && !buffers[i].is_user_buffer)
5937ec681f3Smrg            res->bind_history |= PIPE_BIND_VERTEX_BUFFER;
5947ec681f3Smrg      }
5957ec681f3Smrg   }
59601e04c3fSmrg
59701e04c3fSmrg   vctx->vertex_array_dirty = TRUE;
59801e04c3fSmrg}
59901e04c3fSmrg
6009f464c52Smayastatic void virgl_hw_set_vertex_buffers(struct virgl_context *vctx)
60101e04c3fSmrg{
60201e04c3fSmrg   if (vctx->vertex_array_dirty) {
60301e04c3fSmrg      struct virgl_vertex_elements_state *ve = vctx->vertex_elements;
60401e04c3fSmrg
60501e04c3fSmrg      if (ve->num_bindings) {
60601e04c3fSmrg         struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
60701e04c3fSmrg         for (int i = 0; i < ve->num_bindings; ++i)
60801e04c3fSmrg            vertex_buffers[i] = vctx->vertex_buffer[ve->binding_map[i]];
60901e04c3fSmrg
61001e04c3fSmrg         virgl_encoder_set_vertex_buffers(vctx, ve->num_bindings, vertex_buffers);
61101e04c3fSmrg      } else
61201e04c3fSmrg         virgl_encoder_set_vertex_buffers(vctx, vctx->num_vertex_buffers, vctx->vertex_buffer);
61301e04c3fSmrg
61401e04c3fSmrg      virgl_attach_res_vertex_buffers(vctx);
6159f464c52Smaya
6169f464c52Smaya      vctx->vertex_array_dirty = FALSE;
61701e04c3fSmrg   }
61801e04c3fSmrg}
61901e04c3fSmrg
62001e04c3fSmrgstatic void virgl_set_stencil_ref(struct pipe_context *ctx,
6217ec681f3Smrg                                 const struct pipe_stencil_ref ref)
62201e04c3fSmrg{
62301e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
6247ec681f3Smrg   virgl_encoder_set_stencil_ref(vctx, &ref);
62501e04c3fSmrg}
62601e04c3fSmrg
62701e04c3fSmrgstatic void virgl_set_blend_color(struct pipe_context *ctx,
62801e04c3fSmrg                                 const struct pipe_blend_color *color)
62901e04c3fSmrg{
63001e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
63101e04c3fSmrg   virgl_encoder_set_blend_color(vctx, color);
63201e04c3fSmrg}
63301e04c3fSmrg
6349f464c52Smayastatic void virgl_hw_set_index_buffer(struct virgl_context *vctx,
63501e04c3fSmrg                                     struct virgl_indexbuf *ib)
63601e04c3fSmrg{
63701e04c3fSmrg   virgl_encoder_set_index_buffer(vctx, ib);
63801e04c3fSmrg   virgl_attach_res_index_buffer(vctx, ib);
63901e04c3fSmrg}
64001e04c3fSmrg
64101e04c3fSmrgstatic void virgl_set_constant_buffer(struct pipe_context *ctx,
64201e04c3fSmrg                                     enum pipe_shader_type shader, uint index,
6437ec681f3Smrg                                      bool take_ownership,
64401e04c3fSmrg                                     const struct pipe_constant_buffer *buf)
64501e04c3fSmrg{
64601e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
6477ec681f3Smrg   struct virgl_shader_binding_state *binding =
6487ec681f3Smrg      &vctx->shader_bindings[shader];
64901e04c3fSmrg
6507ec681f3Smrg   if (buf && buf->buffer) {
6517ec681f3Smrg      struct virgl_resource *res = virgl_resource(buf->buffer);
6527ec681f3Smrg      res->bind_history |= PIPE_BIND_CONSTANT_BUFFER;
6537ec681f3Smrg
6547ec681f3Smrg      virgl_encoder_set_uniform_buffer(vctx, shader, index,
6557ec681f3Smrg                                       buf->buffer_offset,
6567ec681f3Smrg                                       buf->buffer_size, res);
6577ec681f3Smrg
6587ec681f3Smrg      if (take_ownership) {
6597ec681f3Smrg         pipe_resource_reference(&binding->ubos[index].buffer, NULL);
6607ec681f3Smrg         binding->ubos[index].buffer = buf->buffer;
6617ec681f3Smrg      } else {
6627ec681f3Smrg         pipe_resource_reference(&binding->ubos[index].buffer, buf->buffer);
66301e04c3fSmrg      }
6647ec681f3Smrg      binding->ubos[index] = *buf;
6657ec681f3Smrg      binding->ubo_enabled_mask |= 1 << index;
66601e04c3fSmrg   } else {
6677ec681f3Smrg      static const struct pipe_constant_buffer dummy_ubo;
6687ec681f3Smrg      if (!buf)
6697ec681f3Smrg         buf = &dummy_ubo;
6707ec681f3Smrg      virgl_encoder_write_constant_buffer(vctx, shader, index,
6717ec681f3Smrg                                          buf->buffer_size / 4,
6727ec681f3Smrg                                          buf->user_buffer);
6737ec681f3Smrg
6747ec681f3Smrg      pipe_resource_reference(&binding->ubos[index].buffer, NULL);
6757ec681f3Smrg      binding->ubo_enabled_mask &= ~(1 << index);
67601e04c3fSmrg   }
67701e04c3fSmrg}
67801e04c3fSmrg
67901e04c3fSmrgstatic void *virgl_shader_encoder(struct pipe_context *ctx,
68001e04c3fSmrg                                  const struct pipe_shader_state *shader,
68101e04c3fSmrg                                  unsigned type)
68201e04c3fSmrg{
68301e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
68401e04c3fSmrg   uint32_t handle;
6857ec681f3Smrg   const struct tgsi_token *tokens;
6867ec681f3Smrg   const struct tgsi_token *ntt_tokens = NULL;
68701e04c3fSmrg   struct tgsi_token *new_tokens;
68801e04c3fSmrg   int ret;
68901e04c3fSmrg
6907ec681f3Smrg   if (shader->type == PIPE_SHADER_IR_NIR) {
6917ec681f3Smrg      nir_shader *s = nir_shader_clone(NULL, shader->ir.nir);
6927ec681f3Smrg      ntt_tokens = tokens = nir_to_tgsi(s, vctx->base.screen); /* takes ownership */
6937ec681f3Smrg   } else {
6947ec681f3Smrg      tokens = shader->tokens;
6957ec681f3Smrg   }
6967ec681f3Smrg
6977ec681f3Smrg   new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, tokens);
69801e04c3fSmrg   if (!new_tokens)
69901e04c3fSmrg      return NULL;
70001e04c3fSmrg
70101e04c3fSmrg   handle = virgl_object_assign_handle();
70201e04c3fSmrg   /* encode VS state */
70301e04c3fSmrg   ret = virgl_encode_shader_state(vctx, handle, type,
70401e04c3fSmrg                                   &shader->stream_output, 0,
70501e04c3fSmrg                                   new_tokens);
70601e04c3fSmrg   if (ret) {
7077ec681f3Smrg      FREE((void *)ntt_tokens);
70801e04c3fSmrg      return NULL;
70901e04c3fSmrg   }
71001e04c3fSmrg
7117ec681f3Smrg   FREE((void *)ntt_tokens);
71201e04c3fSmrg   FREE(new_tokens);
71301e04c3fSmrg   return (void *)(unsigned long)handle;
71401e04c3fSmrg
71501e04c3fSmrg}
71601e04c3fSmrgstatic void *virgl_create_vs_state(struct pipe_context *ctx,
71701e04c3fSmrg                                   const struct pipe_shader_state *shader)
71801e04c3fSmrg{
71901e04c3fSmrg   return virgl_shader_encoder(ctx, shader, PIPE_SHADER_VERTEX);
72001e04c3fSmrg}
72101e04c3fSmrg
72201e04c3fSmrgstatic void *virgl_create_tcs_state(struct pipe_context *ctx,
72301e04c3fSmrg                                   const struct pipe_shader_state *shader)
72401e04c3fSmrg{
72501e04c3fSmrg   return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_CTRL);
72601e04c3fSmrg}
72701e04c3fSmrg
72801e04c3fSmrgstatic void *virgl_create_tes_state(struct pipe_context *ctx,
72901e04c3fSmrg                                   const struct pipe_shader_state *shader)
73001e04c3fSmrg{
73101e04c3fSmrg   return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_EVAL);
73201e04c3fSmrg}
73301e04c3fSmrg
73401e04c3fSmrgstatic void *virgl_create_gs_state(struct pipe_context *ctx,
73501e04c3fSmrg                                   const struct pipe_shader_state *shader)
73601e04c3fSmrg{
73701e04c3fSmrg   return virgl_shader_encoder(ctx, shader, PIPE_SHADER_GEOMETRY);
73801e04c3fSmrg}
73901e04c3fSmrg
74001e04c3fSmrgstatic void *virgl_create_fs_state(struct pipe_context *ctx,
74101e04c3fSmrg                                   const struct pipe_shader_state *shader)
74201e04c3fSmrg{
74301e04c3fSmrg   return virgl_shader_encoder(ctx, shader, PIPE_SHADER_FRAGMENT);
74401e04c3fSmrg}
74501e04c3fSmrg
74601e04c3fSmrgstatic void
74701e04c3fSmrgvirgl_delete_fs_state(struct pipe_context *ctx,
74801e04c3fSmrg                     void *fs)
74901e04c3fSmrg{
75001e04c3fSmrg   uint32_t handle = (unsigned long)fs;
75101e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
75201e04c3fSmrg
75301e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
75401e04c3fSmrg}
75501e04c3fSmrg
75601e04c3fSmrgstatic void
75701e04c3fSmrgvirgl_delete_gs_state(struct pipe_context *ctx,
75801e04c3fSmrg                     void *gs)
75901e04c3fSmrg{
76001e04c3fSmrg   uint32_t handle = (unsigned long)gs;
76101e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
76201e04c3fSmrg
76301e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
76401e04c3fSmrg}
76501e04c3fSmrg
76601e04c3fSmrgstatic void
76701e04c3fSmrgvirgl_delete_vs_state(struct pipe_context *ctx,
76801e04c3fSmrg                     void *vs)
76901e04c3fSmrg{
77001e04c3fSmrg   uint32_t handle = (unsigned long)vs;
77101e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
77201e04c3fSmrg
77301e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
77401e04c3fSmrg}
77501e04c3fSmrg
77601e04c3fSmrgstatic void
77701e04c3fSmrgvirgl_delete_tcs_state(struct pipe_context *ctx,
77801e04c3fSmrg                       void *tcs)
77901e04c3fSmrg{
78001e04c3fSmrg   uint32_t handle = (unsigned long)tcs;
78101e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
78201e04c3fSmrg
78301e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
78401e04c3fSmrg}
78501e04c3fSmrg
78601e04c3fSmrgstatic void
78701e04c3fSmrgvirgl_delete_tes_state(struct pipe_context *ctx,
78801e04c3fSmrg                      void *tes)
78901e04c3fSmrg{
79001e04c3fSmrg   uint32_t handle = (unsigned long)tes;
79101e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
79201e04c3fSmrg
79301e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
79401e04c3fSmrg}
79501e04c3fSmrg
79601e04c3fSmrgstatic void virgl_bind_vs_state(struct pipe_context *ctx,
79701e04c3fSmrg                                        void *vss)
79801e04c3fSmrg{
79901e04c3fSmrg   uint32_t handle = (unsigned long)vss;
80001e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
80101e04c3fSmrg
80201e04c3fSmrg   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_VERTEX);
80301e04c3fSmrg}
80401e04c3fSmrg
80501e04c3fSmrgstatic void virgl_bind_tcs_state(struct pipe_context *ctx,
80601e04c3fSmrg                               void *vss)
80701e04c3fSmrg{
80801e04c3fSmrg   uint32_t handle = (unsigned long)vss;
80901e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
81001e04c3fSmrg
81101e04c3fSmrg   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_CTRL);
81201e04c3fSmrg}
81301e04c3fSmrg
81401e04c3fSmrgstatic void virgl_bind_tes_state(struct pipe_context *ctx,
81501e04c3fSmrg                               void *vss)
81601e04c3fSmrg{
81701e04c3fSmrg   uint32_t handle = (unsigned long)vss;
81801e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
81901e04c3fSmrg
82001e04c3fSmrg   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_EVAL);
82101e04c3fSmrg}
82201e04c3fSmrg
82301e04c3fSmrgstatic void virgl_bind_gs_state(struct pipe_context *ctx,
82401e04c3fSmrg                               void *vss)
82501e04c3fSmrg{
82601e04c3fSmrg   uint32_t handle = (unsigned long)vss;
82701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
82801e04c3fSmrg
82901e04c3fSmrg   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_GEOMETRY);
83001e04c3fSmrg}
83101e04c3fSmrg
83201e04c3fSmrg
83301e04c3fSmrgstatic void virgl_bind_fs_state(struct pipe_context *ctx,
83401e04c3fSmrg                                        void *vss)
83501e04c3fSmrg{
83601e04c3fSmrg   uint32_t handle = (unsigned long)vss;
83701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
83801e04c3fSmrg
83901e04c3fSmrg   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_FRAGMENT);
84001e04c3fSmrg}
84101e04c3fSmrg
84201e04c3fSmrgstatic void virgl_clear(struct pipe_context *ctx,
84301e04c3fSmrg                                unsigned buffers,
8447ec681f3Smrg                                const struct pipe_scissor_state *scissor_state,
84501e04c3fSmrg                                const union pipe_color_union *color,
84601e04c3fSmrg                                double depth, unsigned stencil)
84701e04c3fSmrg{
84801e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
84901e04c3fSmrg
8507ec681f3Smrg   if (!vctx->num_draws)
8517ec681f3Smrg      virgl_reemit_draw_resources(vctx);
8527ec681f3Smrg   vctx->num_draws++;
8537ec681f3Smrg
85401e04c3fSmrg   virgl_encode_clear(vctx, buffers, color, depth, stencil);
85501e04c3fSmrg}
85601e04c3fSmrg
8577ec681f3Smrgstatic void virgl_clear_texture(struct pipe_context *ctx,
8587ec681f3Smrg                                struct pipe_resource *res,
8597ec681f3Smrg                                unsigned int level,
8607ec681f3Smrg                                const struct pipe_box *box,
8617ec681f3Smrg                                const void *data)
86201e04c3fSmrg{
8637ec681f3Smrg   struct virgl_context *vctx = virgl_context(ctx);
8647ec681f3Smrg   struct virgl_resource *vres = virgl_resource(res);
8657ec681f3Smrg
8667ec681f3Smrg   virgl_encode_clear_texture(vctx, vres, level, box, data);
8677ec681f3Smrg
8687ec681f3Smrg   /* Mark as dirty, since we are updating the host side resource
8697ec681f3Smrg    * without going through the corresponding guest side resource, and
8707ec681f3Smrg    * hence the two will diverge.
8717ec681f3Smrg    */
8727ec681f3Smrg   virgl_resource_dirty(vres, level);
8737ec681f3Smrg}
8747ec681f3Smrg
8757ec681f3Smrgstatic void virgl_draw_vbo(struct pipe_context *ctx,
8767ec681f3Smrg                           const struct pipe_draw_info *dinfo,
8777ec681f3Smrg                           unsigned drawid_offset,
8787ec681f3Smrg                           const struct pipe_draw_indirect_info *indirect,
8797ec681f3Smrg                           const struct pipe_draw_start_count_bias *draws,
8807ec681f3Smrg                           unsigned num_draws)
8817ec681f3Smrg{
8827ec681f3Smrg   if (num_draws > 1) {
8837ec681f3Smrg      util_draw_multi(ctx, dinfo, drawid_offset, indirect, draws, num_draws);
8847ec681f3Smrg      return;
8857ec681f3Smrg   }
8867ec681f3Smrg
8877ec681f3Smrg   if (!indirect && (!draws[0].count || !dinfo->instance_count))
8887ec681f3Smrg      return;
8897ec681f3Smrg
89001e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
89101e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->screen);
89201e04c3fSmrg   struct virgl_indexbuf ib = {};
89301e04c3fSmrg   struct pipe_draw_info info = *dinfo;
89401e04c3fSmrg
8957ec681f3Smrg   if (!indirect &&
89601e04c3fSmrg       !dinfo->primitive_restart &&
8977ec681f3Smrg       !u_trim_pipe_prim(dinfo->mode, (unsigned*)&draws[0].count))
89801e04c3fSmrg      return;
89901e04c3fSmrg
90001e04c3fSmrg   if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) {
9019f464c52Smaya      util_primconvert_save_rasterizer_state(vctx->primconvert, &vctx->rs_state.rs);
9027ec681f3Smrg      util_primconvert_draw_vbo(vctx->primconvert, dinfo, drawid_offset, indirect, draws, num_draws);
90301e04c3fSmrg      return;
90401e04c3fSmrg   }
90501e04c3fSmrg   if (info.index_size) {
90601e04c3fSmrg           pipe_resource_reference(&ib.buffer, info.has_user_indices ? NULL : info.index.resource);
90701e04c3fSmrg           ib.user_buffer = info.has_user_indices ? info.index.user : NULL;
90801e04c3fSmrg           ib.index_size = dinfo->index_size;
9097ec681f3Smrg           ib.offset = draws[0].start * ib.index_size;
91001e04c3fSmrg
91101e04c3fSmrg           if (ib.user_buffer) {
9127ec681f3Smrg                   unsigned start_offset = draws[0].start * ib.index_size;
9137ec681f3Smrg                   u_upload_data(vctx->uploader, start_offset,
9147ec681f3Smrg                                 draws[0].count * ib.index_size, 4,
9157ec681f3Smrg                                 (char*)ib.user_buffer + start_offset,
9167ec681f3Smrg                                 &ib.offset, &ib.buffer);
9177ec681f3Smrg                   ib.offset -= start_offset;
91801e04c3fSmrg                   ib.user_buffer = NULL;
91901e04c3fSmrg           }
92001e04c3fSmrg   }
92101e04c3fSmrg
9227ec681f3Smrg   if (!vctx->num_draws)
9237ec681f3Smrg      virgl_reemit_draw_resources(vctx);
92401e04c3fSmrg   vctx->num_draws++;
9257ec681f3Smrg
9269f464c52Smaya   virgl_hw_set_vertex_buffers(vctx);
92701e04c3fSmrg   if (info.index_size)
9289f464c52Smaya      virgl_hw_set_index_buffer(vctx, &ib);
92901e04c3fSmrg
9307ec681f3Smrg   virgl_encoder_draw_vbo(vctx, &info, drawid_offset, indirect, &draws[0]);
93101e04c3fSmrg
93201e04c3fSmrg   pipe_resource_reference(&ib.buffer, NULL);
93301e04c3fSmrg
93401e04c3fSmrg}
93501e04c3fSmrg
9367ec681f3Smrgstatic void virgl_submit_cmd(struct virgl_winsys *vws,
9377ec681f3Smrg                             struct virgl_cmd_buf *cbuf,
9387ec681f3Smrg			     struct pipe_fence_handle **fence)
9397ec681f3Smrg{
9407ec681f3Smrg   if (unlikely(virgl_debug & VIRGL_DEBUG_SYNC)) {
9417ec681f3Smrg      struct pipe_fence_handle *sync_fence = NULL;
9427ec681f3Smrg
9437ec681f3Smrg      vws->submit_cmd(vws, cbuf, &sync_fence);
9447ec681f3Smrg
9457ec681f3Smrg      vws->fence_wait(vws, sync_fence, PIPE_TIMEOUT_INFINITE);
9467ec681f3Smrg      vws->fence_reference(vws, &sync_fence, NULL);
9477ec681f3Smrg   } else {
9487ec681f3Smrg      vws->submit_cmd(vws, cbuf, fence);
9497ec681f3Smrg   }
9507ec681f3Smrg}
9517ec681f3Smrg
9527ec681f3Smrgvoid virgl_flush_eq(struct virgl_context *ctx, void *closure,
9537ec681f3Smrg		    struct pipe_fence_handle **fence)
95401e04c3fSmrg{
95501e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->base.screen);
95601e04c3fSmrg
9579f464c52Smaya   /* skip empty cbuf */
9589f464c52Smaya   if (ctx->cbuf->cdw == ctx->cbuf_initial_cdw &&
9599f464c52Smaya       ctx->queue.num_dwords == 0 &&
9609f464c52Smaya       !fence)
9619f464c52Smaya      return;
9629f464c52Smaya
9639f464c52Smaya   if (ctx->num_draws)
9649f464c52Smaya      u_upload_unmap(ctx->uploader);
9659f464c52Smaya
96601e04c3fSmrg   /* send the buffer to the remote side for decoding */
9679f464c52Smaya   ctx->num_draws = ctx->num_compute = 0;
9689f464c52Smaya
9699f464c52Smaya   virgl_transfer_queue_clear(&ctx->queue, ctx->cbuf);
9707ec681f3Smrg
9717ec681f3Smrg   virgl_submit_cmd(rs->vws, ctx->cbuf, fence);
9729f464c52Smaya
9739f464c52Smaya   /* Reserve some space for transfers. */
9749f464c52Smaya   if (ctx->encoded_transfers)
9759f464c52Smaya      ctx->cbuf->cdw = VIRGL_MAX_TBUF_DWORDS;
97601e04c3fSmrg
97701e04c3fSmrg   virgl_encoder_set_sub_ctx(ctx, ctx->hw_sub_ctx_id);
97801e04c3fSmrg
9799f464c52Smaya   ctx->cbuf_initial_cdw = ctx->cbuf->cdw;
9807ec681f3Smrg
9817ec681f3Smrg   /* We have flushed the command queue, including any pending copy transfers
9827ec681f3Smrg    * involving staging resources.
9837ec681f3Smrg    */
9847ec681f3Smrg   ctx->queued_staging_res_size = 0;
98501e04c3fSmrg}
98601e04c3fSmrg
98701e04c3fSmrgstatic void virgl_flush_from_st(struct pipe_context *ctx,
98801e04c3fSmrg                               struct pipe_fence_handle **fence,
98901e04c3fSmrg                               enum pipe_flush_flags flags)
99001e04c3fSmrg{
99101e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
99201e04c3fSmrg
9939f464c52Smaya   virgl_flush_eq(vctx, vctx, fence);
99401e04c3fSmrg}
99501e04c3fSmrg
99601e04c3fSmrgstatic struct pipe_sampler_view *virgl_create_sampler_view(struct pipe_context *ctx,
99701e04c3fSmrg                                      struct pipe_resource *texture,
99801e04c3fSmrg                                      const struct pipe_sampler_view *state)
99901e04c3fSmrg{
100001e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
100101e04c3fSmrg   struct virgl_sampler_view *grview;
100201e04c3fSmrg   uint32_t handle;
100301e04c3fSmrg   struct virgl_resource *res;
100401e04c3fSmrg
100501e04c3fSmrg   if (!state)
100601e04c3fSmrg      return NULL;
100701e04c3fSmrg
100801e04c3fSmrg   grview = CALLOC_STRUCT(virgl_sampler_view);
100901e04c3fSmrg   if (!grview)
101001e04c3fSmrg      return NULL;
101101e04c3fSmrg
101201e04c3fSmrg   res = virgl_resource(texture);
101301e04c3fSmrg   handle = virgl_object_assign_handle();
101401e04c3fSmrg   virgl_encode_sampler_view(vctx, handle, res, state);
101501e04c3fSmrg
101601e04c3fSmrg   grview->base = *state;
101701e04c3fSmrg   grview->base.reference.count = 1;
101801e04c3fSmrg
101901e04c3fSmrg   grview->base.texture = NULL;
102001e04c3fSmrg   grview->base.context = ctx;
102101e04c3fSmrg   pipe_resource_reference(&grview->base.texture, texture);
102201e04c3fSmrg   grview->handle = handle;
102301e04c3fSmrg   return &grview->base;
102401e04c3fSmrg}
102501e04c3fSmrg
102601e04c3fSmrgstatic void virgl_set_sampler_views(struct pipe_context *ctx,
102701e04c3fSmrg                                   enum pipe_shader_type shader_type,
102801e04c3fSmrg                                   unsigned start_slot,
102901e04c3fSmrg                                   unsigned num_views,
10307ec681f3Smrg                                   unsigned unbind_num_trailing_slots,
10317ec681f3Smrg                                   bool take_ownership,
103201e04c3fSmrg                                   struct pipe_sampler_view **views)
103301e04c3fSmrg{
103401e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
10357ec681f3Smrg   struct virgl_shader_binding_state *binding =
10367ec681f3Smrg      &vctx->shader_bindings[shader_type];
103701e04c3fSmrg
10387ec681f3Smrg   binding->view_enabled_mask &= ~u_bit_consecutive(start_slot, num_views);
10397ec681f3Smrg   for (unsigned i = 0; i < num_views; i++) {
10407ec681f3Smrg      unsigned idx = start_slot + i;
10417ec681f3Smrg      if (views && views[i]) {
10427ec681f3Smrg         struct virgl_resource *res = virgl_resource(views[i]->texture);
10437ec681f3Smrg         res->bind_history |= PIPE_BIND_SAMPLER_VIEW;
10447ec681f3Smrg
10457ec681f3Smrg         if (take_ownership) {
10467ec681f3Smrg            pipe_sampler_view_reference(&binding->views[idx], NULL);
10477ec681f3Smrg            binding->views[idx] = views[i];
10487ec681f3Smrg         } else {
10497ec681f3Smrg            pipe_sampler_view_reference(&binding->views[idx], views[i]);
10507ec681f3Smrg         }
10517ec681f3Smrg         binding->view_enabled_mask |= 1 << idx;
105201e04c3fSmrg      } else {
10537ec681f3Smrg         pipe_sampler_view_reference(&binding->views[idx], NULL);
105401e04c3fSmrg      }
105501e04c3fSmrg   }
105601e04c3fSmrg
10577ec681f3Smrg   virgl_encode_set_sampler_views(vctx, shader_type,
10587ec681f3Smrg         start_slot, num_views, (struct virgl_sampler_view **)binding->views);
105901e04c3fSmrg   virgl_attach_res_sampler_views(vctx, shader_type);
10607ec681f3Smrg
10617ec681f3Smrg   if (unbind_num_trailing_slots) {
10627ec681f3Smrg      virgl_set_sampler_views(ctx, shader_type, start_slot + num_views,
10637ec681f3Smrg                              unbind_num_trailing_slots, 0, false, NULL);
10647ec681f3Smrg   }
106501e04c3fSmrg}
106601e04c3fSmrg
106701e04c3fSmrgstatic void
106801e04c3fSmrgvirgl_texture_barrier(struct pipe_context *ctx, unsigned flags)
106901e04c3fSmrg{
107001e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
107101e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->screen);
107201e04c3fSmrg
10737ec681f3Smrg   if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_TEXTURE_BARRIER) &&
10747ec681f3Smrg       !(rs->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_BLEND_EQUATION))
107501e04c3fSmrg      return;
107601e04c3fSmrg   virgl_encode_texture_barrier(vctx, flags);
107701e04c3fSmrg}
107801e04c3fSmrg
107901e04c3fSmrgstatic void virgl_destroy_sampler_view(struct pipe_context *ctx,
108001e04c3fSmrg                                 struct pipe_sampler_view *view)
108101e04c3fSmrg{
108201e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
108301e04c3fSmrg   struct virgl_sampler_view *grview = virgl_sampler_view(view);
108401e04c3fSmrg
108501e04c3fSmrg   virgl_encode_delete_object(vctx, grview->handle, VIRGL_OBJECT_SAMPLER_VIEW);
108601e04c3fSmrg   pipe_resource_reference(&view->texture, NULL);
108701e04c3fSmrg   FREE(view);
108801e04c3fSmrg}
108901e04c3fSmrg
109001e04c3fSmrgstatic void *virgl_create_sampler_state(struct pipe_context *ctx,
109101e04c3fSmrg                                        const struct pipe_sampler_state *state)
109201e04c3fSmrg{
109301e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
109401e04c3fSmrg   uint32_t handle;
109501e04c3fSmrg
109601e04c3fSmrg   handle = virgl_object_assign_handle();
109701e04c3fSmrg
109801e04c3fSmrg   virgl_encode_sampler_state(vctx, handle, state);
109901e04c3fSmrg   return (void *)(unsigned long)handle;
110001e04c3fSmrg}
110101e04c3fSmrg
110201e04c3fSmrgstatic void virgl_delete_sampler_state(struct pipe_context *ctx,
110301e04c3fSmrg                                      void *ss)
110401e04c3fSmrg{
110501e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
110601e04c3fSmrg   uint32_t handle = (unsigned long)ss;
110701e04c3fSmrg
110801e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SAMPLER_STATE);
110901e04c3fSmrg}
111001e04c3fSmrg
111101e04c3fSmrgstatic void virgl_bind_sampler_states(struct pipe_context *ctx,
111201e04c3fSmrg                                     enum pipe_shader_type shader,
111301e04c3fSmrg                                     unsigned start_slot,
111401e04c3fSmrg                                     unsigned num_samplers,
111501e04c3fSmrg                                     void **samplers)
111601e04c3fSmrg{
111701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
111801e04c3fSmrg   uint32_t handles[32];
111901e04c3fSmrg   int i;
112001e04c3fSmrg   for (i = 0; i < num_samplers; i++) {
112101e04c3fSmrg      handles[i] = (unsigned long)(samplers[i]);
112201e04c3fSmrg   }
112301e04c3fSmrg   virgl_encode_bind_sampler_states(vctx, shader, start_slot, num_samplers, handles);
112401e04c3fSmrg}
112501e04c3fSmrg
112601e04c3fSmrgstatic void virgl_set_polygon_stipple(struct pipe_context *ctx,
112701e04c3fSmrg                                     const struct pipe_poly_stipple *ps)
112801e04c3fSmrg{
112901e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
113001e04c3fSmrg   virgl_encoder_set_polygon_stipple(vctx, ps);
113101e04c3fSmrg}
113201e04c3fSmrg
113301e04c3fSmrgstatic void virgl_set_scissor_states(struct pipe_context *ctx,
113401e04c3fSmrg                                    unsigned start_slot,
113501e04c3fSmrg                                    unsigned num_scissor,
113601e04c3fSmrg                                   const struct pipe_scissor_state *ss)
113701e04c3fSmrg{
113801e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
113901e04c3fSmrg   virgl_encoder_set_scissor_state(vctx, start_slot, num_scissor, ss);
114001e04c3fSmrg}
114101e04c3fSmrg
114201e04c3fSmrgstatic void virgl_set_sample_mask(struct pipe_context *ctx,
114301e04c3fSmrg                                 unsigned sample_mask)
114401e04c3fSmrg{
114501e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
114601e04c3fSmrg   virgl_encoder_set_sample_mask(vctx, sample_mask);
114701e04c3fSmrg}
114801e04c3fSmrg
114901e04c3fSmrgstatic void virgl_set_min_samples(struct pipe_context *ctx,
115001e04c3fSmrg                                 unsigned min_samples)
115101e04c3fSmrg{
115201e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
115301e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->screen);
115401e04c3fSmrg
115501e04c3fSmrg   if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_SET_MIN_SAMPLES))
115601e04c3fSmrg      return;
115701e04c3fSmrg   virgl_encoder_set_min_samples(vctx, min_samples);
115801e04c3fSmrg}
115901e04c3fSmrg
116001e04c3fSmrgstatic void virgl_set_clip_state(struct pipe_context *ctx,
116101e04c3fSmrg                                const struct pipe_clip_state *clip)
116201e04c3fSmrg{
116301e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
116401e04c3fSmrg   virgl_encoder_set_clip_state(vctx, clip);
116501e04c3fSmrg}
116601e04c3fSmrg
116701e04c3fSmrgstatic void virgl_set_tess_state(struct pipe_context *ctx,
116801e04c3fSmrg                                 const float default_outer_level[4],
116901e04c3fSmrg                                 const float default_inner_level[2])
117001e04c3fSmrg{
117101e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
117201e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->screen);
117301e04c3fSmrg
117401e04c3fSmrg   if (!rs->caps.caps.v1.bset.has_tessellation_shaders)
117501e04c3fSmrg      return;
117601e04c3fSmrg   virgl_encode_set_tess_state(vctx, default_outer_level, default_inner_level);
117701e04c3fSmrg}
117801e04c3fSmrg
11797ec681f3Smrgstatic void virgl_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertices)
11807ec681f3Smrg{
11817ec681f3Smrg   struct virgl_context *vctx = virgl_context(ctx);
11827ec681f3Smrg
11837ec681f3Smrg   vctx->patch_vertices = patch_vertices;
11847ec681f3Smrg}
11857ec681f3Smrg
118601e04c3fSmrgstatic void virgl_resource_copy_region(struct pipe_context *ctx,
118701e04c3fSmrg                                      struct pipe_resource *dst,
118801e04c3fSmrg                                      unsigned dst_level,
118901e04c3fSmrg                                      unsigned dstx, unsigned dsty, unsigned dstz,
119001e04c3fSmrg                                      struct pipe_resource *src,
119101e04c3fSmrg                                      unsigned src_level,
119201e04c3fSmrg                                      const struct pipe_box *src_box)
119301e04c3fSmrg{
119401e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
119501e04c3fSmrg   struct virgl_resource *dres = virgl_resource(dst);
119601e04c3fSmrg   struct virgl_resource *sres = virgl_resource(src);
119701e04c3fSmrg
11987ec681f3Smrg   if (dres->b.target == PIPE_BUFFER)
11997ec681f3Smrg      util_range_add(&dres->b, &dres->valid_buffer_range, dstx, dstx + src_box->width);
12009f464c52Smaya   virgl_resource_dirty(dres, dst_level);
12017ec681f3Smrg
120201e04c3fSmrg   virgl_encode_resource_copy_region(vctx, dres,
120301e04c3fSmrg                                    dst_level, dstx, dsty, dstz,
120401e04c3fSmrg                                    sres, src_level,
120501e04c3fSmrg                                    src_box);
120601e04c3fSmrg}
120701e04c3fSmrg
120801e04c3fSmrgstatic void
120901e04c3fSmrgvirgl_flush_resource(struct pipe_context *pipe,
121001e04c3fSmrg                    struct pipe_resource *resource)
121101e04c3fSmrg{
121201e04c3fSmrg}
121301e04c3fSmrg
121401e04c3fSmrgstatic void virgl_blit(struct pipe_context *ctx,
121501e04c3fSmrg                      const struct pipe_blit_info *blit)
121601e04c3fSmrg{
121701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
121801e04c3fSmrg   struct virgl_resource *dres = virgl_resource(blit->dst.resource);
121901e04c3fSmrg   struct virgl_resource *sres = virgl_resource(blit->src.resource);
122001e04c3fSmrg
12219f464c52Smaya   assert(ctx->screen->get_param(ctx->screen,
12229f464c52Smaya                                 PIPE_CAP_DEST_SURFACE_SRGB_CONTROL) ||
12239f464c52Smaya          (util_format_is_srgb(blit->dst.resource->format) ==
12249f464c52Smaya            util_format_is_srgb(blit->dst.format)));
12259f464c52Smaya
12269f464c52Smaya   virgl_resource_dirty(dres, blit->dst.level);
122701e04c3fSmrg   virgl_encode_blit(vctx, dres, sres,
122801e04c3fSmrg                    blit);
122901e04c3fSmrg}
123001e04c3fSmrg
123101e04c3fSmrgstatic void virgl_set_hw_atomic_buffers(struct pipe_context *ctx,
123201e04c3fSmrg                                        unsigned start_slot,
123301e04c3fSmrg                                        unsigned count,
123401e04c3fSmrg                                        const struct pipe_shader_buffer *buffers)
123501e04c3fSmrg{
123601e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
123701e04c3fSmrg
12387ec681f3Smrg   vctx->atomic_buffer_enabled_mask &= ~u_bit_consecutive(start_slot, count);
123901e04c3fSmrg   for (unsigned i = 0; i < count; i++) {
124001e04c3fSmrg      unsigned idx = start_slot + i;
12417ec681f3Smrg      if (buffers && buffers[i].buffer) {
12427ec681f3Smrg         struct virgl_resource *res = virgl_resource(buffers[i].buffer);
12437ec681f3Smrg         res->bind_history |= PIPE_BIND_SHADER_BUFFER;
12447ec681f3Smrg
12457ec681f3Smrg         pipe_resource_reference(&vctx->atomic_buffers[idx].buffer,
12467ec681f3Smrg                                 buffers[i].buffer);
12477ec681f3Smrg         vctx->atomic_buffers[idx] = buffers[i];
12487ec681f3Smrg         vctx->atomic_buffer_enabled_mask |= 1 << idx;
12497ec681f3Smrg      } else {
12507ec681f3Smrg         pipe_resource_reference(&vctx->atomic_buffers[idx].buffer, NULL);
125101e04c3fSmrg      }
125201e04c3fSmrg   }
12537ec681f3Smrg
125401e04c3fSmrg   virgl_encode_set_hw_atomic_buffers(vctx, start_slot, count, buffers);
125501e04c3fSmrg}
125601e04c3fSmrg
125701e04c3fSmrgstatic void virgl_set_shader_buffers(struct pipe_context *ctx,
125801e04c3fSmrg                                     enum pipe_shader_type shader,
125901e04c3fSmrg                                     unsigned start_slot, unsigned count,
12609f464c52Smaya                                     const struct pipe_shader_buffer *buffers,
12619f464c52Smaya                                     unsigned writable_bitmask)
126201e04c3fSmrg{
126301e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
126401e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->screen);
12657ec681f3Smrg   struct virgl_shader_binding_state *binding =
12667ec681f3Smrg      &vctx->shader_bindings[shader];
126701e04c3fSmrg
12687ec681f3Smrg   binding->ssbo_enabled_mask &= ~u_bit_consecutive(start_slot, count);
126901e04c3fSmrg   for (unsigned i = 0; i < count; i++) {
127001e04c3fSmrg      unsigned idx = start_slot + i;
12717ec681f3Smrg      if (buffers && buffers[i].buffer) {
12727ec681f3Smrg         struct virgl_resource *res = virgl_resource(buffers[i].buffer);
12737ec681f3Smrg         res->bind_history |= PIPE_BIND_SHADER_BUFFER;
127401e04c3fSmrg
12757ec681f3Smrg         pipe_resource_reference(&binding->ssbos[idx].buffer, buffers[i].buffer);
12767ec681f3Smrg         binding->ssbos[idx] = buffers[i];
12777ec681f3Smrg         binding->ssbo_enabled_mask |= 1 << idx;
12787ec681f3Smrg      } else {
12797ec681f3Smrg         pipe_resource_reference(&binding->ssbos[idx].buffer, NULL);
128001e04c3fSmrg      }
128101e04c3fSmrg   }
128201e04c3fSmrg
128301e04c3fSmrg   uint32_t max_shader_buffer = (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE) ?
128401e04c3fSmrg      rs->caps.caps.v2.max_shader_buffer_frag_compute :
128501e04c3fSmrg      rs->caps.caps.v2.max_shader_buffer_other_stages;
128601e04c3fSmrg   if (!max_shader_buffer)
128701e04c3fSmrg      return;
128801e04c3fSmrg   virgl_encode_set_shader_buffers(vctx, shader, start_slot, count, buffers);
128901e04c3fSmrg}
129001e04c3fSmrg
12919f464c52Smayastatic void virgl_create_fence_fd(struct pipe_context *ctx,
12929f464c52Smaya                                  struct pipe_fence_handle **fence,
12939f464c52Smaya                                  int fd,
12949f464c52Smaya                                  enum pipe_fd_type type)
12959f464c52Smaya{
12969f464c52Smaya   assert(type == PIPE_FD_TYPE_NATIVE_SYNC);
12979f464c52Smaya   struct virgl_screen *rs = virgl_screen(ctx->screen);
12989f464c52Smaya
12999f464c52Smaya   if (rs->vws->cs_create_fence)
13009f464c52Smaya      *fence = rs->vws->cs_create_fence(rs->vws, fd);
13019f464c52Smaya}
13029f464c52Smaya
13039f464c52Smayastatic void virgl_fence_server_sync(struct pipe_context *ctx,
13049f464c52Smaya			            struct pipe_fence_handle *fence)
13059f464c52Smaya{
13069f464c52Smaya   struct virgl_context *vctx = virgl_context(ctx);
13079f464c52Smaya   struct virgl_screen *rs = virgl_screen(ctx->screen);
13089f464c52Smaya
13099f464c52Smaya   if (rs->vws->fence_server_sync)
13109f464c52Smaya      rs->vws->fence_server_sync(rs->vws, vctx->cbuf, fence);
13119f464c52Smaya}
13129f464c52Smaya
131301e04c3fSmrgstatic void virgl_set_shader_images(struct pipe_context *ctx,
131401e04c3fSmrg                                    enum pipe_shader_type shader,
131501e04c3fSmrg                                    unsigned start_slot, unsigned count,
13167ec681f3Smrg                                    unsigned unbind_num_trailing_slots,
131701e04c3fSmrg                                    const struct pipe_image_view *images)
131801e04c3fSmrg{
131901e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
132001e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->screen);
13217ec681f3Smrg   struct virgl_shader_binding_state *binding =
13227ec681f3Smrg      &vctx->shader_bindings[shader];
132301e04c3fSmrg
13247ec681f3Smrg   binding->image_enabled_mask &= ~u_bit_consecutive(start_slot, count);
132501e04c3fSmrg   for (unsigned i = 0; i < count; i++) {
132601e04c3fSmrg      unsigned idx = start_slot + i;
13277ec681f3Smrg      if (images && images[i].resource) {
13287ec681f3Smrg         struct virgl_resource *res = virgl_resource(images[i].resource);
13297ec681f3Smrg         res->bind_history |= PIPE_BIND_SHADER_IMAGE;
13307ec681f3Smrg
13317ec681f3Smrg         pipe_resource_reference(&binding->images[idx].resource,
13327ec681f3Smrg                                 images[i].resource);
13337ec681f3Smrg         binding->images[idx] = images[i];
13347ec681f3Smrg         binding->image_enabled_mask |= 1 << idx;
13357ec681f3Smrg      } else {
13367ec681f3Smrg         pipe_resource_reference(&binding->images[idx].resource, NULL);
133701e04c3fSmrg      }
133801e04c3fSmrg   }
133901e04c3fSmrg
134001e04c3fSmrg   uint32_t max_shader_images = (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE) ?
134101e04c3fSmrg     rs->caps.caps.v2.max_shader_image_frag_compute :
134201e04c3fSmrg     rs->caps.caps.v2.max_shader_image_other_stages;
134301e04c3fSmrg   if (!max_shader_images)
134401e04c3fSmrg      return;
134501e04c3fSmrg   virgl_encode_set_shader_images(vctx, shader, start_slot, count, images);
13467ec681f3Smrg
13477ec681f3Smrg   if (unbind_num_trailing_slots) {
13487ec681f3Smrg      virgl_set_shader_images(ctx, shader, start_slot + count,
13497ec681f3Smrg                              unbind_num_trailing_slots, 0, NULL);
13507ec681f3Smrg   }
135101e04c3fSmrg}
135201e04c3fSmrg
135301e04c3fSmrgstatic void virgl_memory_barrier(struct pipe_context *ctx,
135401e04c3fSmrg                                 unsigned flags)
135501e04c3fSmrg{
135601e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
135701e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->screen);
135801e04c3fSmrg
135901e04c3fSmrg   if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_MEMORY_BARRIER))
136001e04c3fSmrg      return;
136101e04c3fSmrg   virgl_encode_memory_barrier(vctx, flags);
136201e04c3fSmrg}
136301e04c3fSmrg
136401e04c3fSmrgstatic void *virgl_create_compute_state(struct pipe_context *ctx,
136501e04c3fSmrg                                        const struct pipe_compute_state *state)
136601e04c3fSmrg{
136701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
136801e04c3fSmrg   uint32_t handle;
13697ec681f3Smrg   const struct tgsi_token *ntt_tokens = NULL;
13707ec681f3Smrg   const struct tgsi_token *tokens;
137101e04c3fSmrg   struct pipe_stream_output_info so_info = {};
137201e04c3fSmrg   int ret;
137301e04c3fSmrg
13747ec681f3Smrg   if (state->ir_type == PIPE_SHADER_IR_NIR) {
13757ec681f3Smrg      nir_shader *s = nir_shader_clone(NULL, state->prog);
13767ec681f3Smrg      ntt_tokens = tokens = nir_to_tgsi(s, vctx->base.screen); /* takes ownership */
13777ec681f3Smrg   } else {
13787ec681f3Smrg      tokens = state->prog;
13797ec681f3Smrg   }
13807ec681f3Smrg
138101e04c3fSmrg   handle = virgl_object_assign_handle();
138201e04c3fSmrg   ret = virgl_encode_shader_state(vctx, handle, PIPE_SHADER_COMPUTE,
138301e04c3fSmrg                                   &so_info,
138401e04c3fSmrg                                   state->req_local_mem,
13857ec681f3Smrg                                   tokens);
138601e04c3fSmrg   if (ret) {
13877ec681f3Smrg      FREE((void *)ntt_tokens);
138801e04c3fSmrg      return NULL;
138901e04c3fSmrg   }
139001e04c3fSmrg
13917ec681f3Smrg   FREE((void *)ntt_tokens);
13927ec681f3Smrg
139301e04c3fSmrg   return (void *)(unsigned long)handle;
139401e04c3fSmrg}
139501e04c3fSmrg
139601e04c3fSmrgstatic void virgl_bind_compute_state(struct pipe_context *ctx, void *state)
139701e04c3fSmrg{
139801e04c3fSmrg   uint32_t handle = (unsigned long)state;
139901e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
140001e04c3fSmrg
140101e04c3fSmrg   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_COMPUTE);
140201e04c3fSmrg}
140301e04c3fSmrg
140401e04c3fSmrgstatic void virgl_delete_compute_state(struct pipe_context *ctx, void *state)
140501e04c3fSmrg{
140601e04c3fSmrg   uint32_t handle = (unsigned long)state;
140701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
140801e04c3fSmrg
140901e04c3fSmrg   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
141001e04c3fSmrg}
141101e04c3fSmrg
141201e04c3fSmrgstatic void virgl_launch_grid(struct pipe_context *ctx,
141301e04c3fSmrg                              const struct pipe_grid_info *info)
141401e04c3fSmrg{
141501e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
14167ec681f3Smrg
14177ec681f3Smrg   if (!vctx->num_compute)
14187ec681f3Smrg      virgl_reemit_compute_resources(vctx);
14199f464c52Smaya   vctx->num_compute++;
14207ec681f3Smrg
14217ec681f3Smrg   virgl_encode_launch_grid(vctx, info);
14227ec681f3Smrg}
14237ec681f3Smrg
14247ec681f3Smrgstatic void
14257ec681f3Smrgvirgl_release_shader_binding(struct virgl_context *vctx,
14267ec681f3Smrg                             enum pipe_shader_type shader_type)
14277ec681f3Smrg{
14287ec681f3Smrg   struct virgl_shader_binding_state *binding =
14297ec681f3Smrg      &vctx->shader_bindings[shader_type];
14307ec681f3Smrg
14317ec681f3Smrg   while (binding->view_enabled_mask) {
14327ec681f3Smrg      int i = u_bit_scan(&binding->view_enabled_mask);
14337ec681f3Smrg      pipe_sampler_view_reference(
14347ec681f3Smrg            (struct pipe_sampler_view **)&binding->views[i], NULL);
14357ec681f3Smrg   }
14367ec681f3Smrg
14377ec681f3Smrg   while (binding->ubo_enabled_mask) {
14387ec681f3Smrg      int i = u_bit_scan(&binding->ubo_enabled_mask);
14397ec681f3Smrg      pipe_resource_reference(&binding->ubos[i].buffer, NULL);
14407ec681f3Smrg   }
14417ec681f3Smrg
14427ec681f3Smrg   while (binding->ssbo_enabled_mask) {
14437ec681f3Smrg      int i = u_bit_scan(&binding->ssbo_enabled_mask);
14447ec681f3Smrg      pipe_resource_reference(&binding->ssbos[i].buffer, NULL);
14457ec681f3Smrg   }
14467ec681f3Smrg
14477ec681f3Smrg   while (binding->image_enabled_mask) {
14487ec681f3Smrg      int i = u_bit_scan(&binding->image_enabled_mask);
14497ec681f3Smrg      pipe_resource_reference(&binding->images[i].resource, NULL);
14507ec681f3Smrg   }
14517ec681f3Smrg}
14527ec681f3Smrg
14537ec681f3Smrgstatic void
14547ec681f3Smrgvirgl_emit_string_marker(struct pipe_context *ctx, const char *message,  int len)
14557ec681f3Smrg{
14567ec681f3Smrg    struct virgl_context *vctx = virgl_context(ctx);
14577ec681f3Smrg    virgl_encode_emit_string_marker(vctx, message, len);
145801e04c3fSmrg}
145901e04c3fSmrg
146001e04c3fSmrgstatic void
146101e04c3fSmrgvirgl_context_destroy( struct pipe_context *ctx )
146201e04c3fSmrg{
146301e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
146401e04c3fSmrg   struct virgl_screen *rs = virgl_screen(ctx->screen);
14657ec681f3Smrg   enum pipe_shader_type shader_type;
146601e04c3fSmrg
146701e04c3fSmrg   vctx->framebuffer.zsbuf = NULL;
146801e04c3fSmrg   vctx->framebuffer.nr_cbufs = 0;
146901e04c3fSmrg   virgl_encoder_destroy_sub_ctx(vctx, vctx->hw_sub_ctx_id);
14709f464c52Smaya   virgl_flush_eq(vctx, vctx, NULL);
147101e04c3fSmrg
14727ec681f3Smrg   for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++)
14737ec681f3Smrg      virgl_release_shader_binding(vctx, shader_type);
14747ec681f3Smrg
14757ec681f3Smrg   while (vctx->atomic_buffer_enabled_mask) {
14767ec681f3Smrg      int i = u_bit_scan(&vctx->atomic_buffer_enabled_mask);
14777ec681f3Smrg      pipe_resource_reference(&vctx->atomic_buffers[i].buffer, NULL);
14787ec681f3Smrg   }
14797ec681f3Smrg
148001e04c3fSmrg   rs->vws->cmd_buf_destroy(vctx->cbuf);
148101e04c3fSmrg   if (vctx->uploader)
148201e04c3fSmrg      u_upload_destroy(vctx->uploader);
14837ec681f3Smrg   if (vctx->supports_staging)
14847ec681f3Smrg      virgl_staging_destroy(&vctx->staging);
148501e04c3fSmrg   util_primconvert_destroy(vctx->primconvert);
14869f464c52Smaya   virgl_transfer_queue_fini(&vctx->queue);
148701e04c3fSmrg
14889f464c52Smaya   slab_destroy_child(&vctx->transfer_pool);
148901e04c3fSmrg   FREE(vctx);
149001e04c3fSmrg}
149101e04c3fSmrg
149201e04c3fSmrgstatic void virgl_get_sample_position(struct pipe_context *ctx,
149301e04c3fSmrg				      unsigned sample_count,
149401e04c3fSmrg				      unsigned index,
149501e04c3fSmrg				      float *out_value)
149601e04c3fSmrg{
149701e04c3fSmrg   struct virgl_context *vctx = virgl_context(ctx);
149801e04c3fSmrg   struct virgl_screen *vs = virgl_screen(vctx->base.screen);
149901e04c3fSmrg
150001e04c3fSmrg   if (sample_count > vs->caps.caps.v1.max_samples) {
150101e04c3fSmrg      debug_printf("VIRGL: requested %d MSAA samples, but only %d supported\n",
150201e04c3fSmrg		   sample_count, vs->caps.caps.v1.max_samples);
150301e04c3fSmrg      return;
150401e04c3fSmrg   }
150501e04c3fSmrg
150601e04c3fSmrg   /* The following is basically copied from dri/i965gen6_get_sample_position
150701e04c3fSmrg    * The only addition is that we hold the msaa positions for all sample
150801e04c3fSmrg    * counts in a flat array. */
150901e04c3fSmrg   uint32_t bits = 0;
151001e04c3fSmrg   if (sample_count == 1) {
151101e04c3fSmrg      out_value[0] = out_value[1] = 0.5f;
151201e04c3fSmrg      return;
151301e04c3fSmrg   } else if (sample_count == 2) {
151401e04c3fSmrg      bits = vs->caps.caps.v2.sample_locations[0] >> (8 * index);
151501e04c3fSmrg   } else if (sample_count <= 4) {
151601e04c3fSmrg      bits = vs->caps.caps.v2.sample_locations[1] >> (8 * index);
151701e04c3fSmrg   } else if (sample_count <= 8) {
151801e04c3fSmrg      bits = vs->caps.caps.v2.sample_locations[2 + (index >> 2)] >> (8 * (index & 3));
151901e04c3fSmrg   } else if (sample_count <= 16) {
152001e04c3fSmrg      bits = vs->caps.caps.v2.sample_locations[4 + (index >> 2)] >> (8 * (index & 3));
152101e04c3fSmrg   }
152201e04c3fSmrg   out_value[0] = ((bits >> 4) & 0xf) / 16.0f;
152301e04c3fSmrg   out_value[1] = (bits & 0xf) / 16.0f;
152401e04c3fSmrg
152501e04c3fSmrg   if (virgl_debug & VIRGL_DEBUG_VERBOSE)
152601e04c3fSmrg      debug_printf("VIRGL: sample postion [%2d/%2d] = (%f, %f)\n",
152701e04c3fSmrg                   index, sample_count, out_value[0], out_value[1]);
152801e04c3fSmrg}
152901e04c3fSmrg
15307ec681f3Smrgstatic void virgl_send_tweaks(struct virgl_context *vctx, struct virgl_screen *rs)
15317ec681f3Smrg{
15327ec681f3Smrg   if (rs->tweak_gles_emulate_bgra)
15337ec681f3Smrg      virgl_encode_tweak(vctx, virgl_tweak_gles_brga_emulate, 1);
15347ec681f3Smrg
15357ec681f3Smrg   if (rs->tweak_gles_apply_bgra_dest_swizzle)
15367ec681f3Smrg      virgl_encode_tweak(vctx, virgl_tweak_gles_brga_apply_dest_swizzle, 1);
15377ec681f3Smrg
15387ec681f3Smrg   if (rs->tweak_gles_tf3_value > 0)
15397ec681f3Smrg      virgl_encode_tweak(vctx, virgl_tweak_gles_tf3_samples_passes_multiplier,
15407ec681f3Smrg                         rs->tweak_gles_tf3_value);
15417ec681f3Smrg}
15427ec681f3Smrg
154301e04c3fSmrgstruct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
154401e04c3fSmrg                                          void *priv,
154501e04c3fSmrg                                          unsigned flags)
154601e04c3fSmrg{
154701e04c3fSmrg   struct virgl_context *vctx;
154801e04c3fSmrg   struct virgl_screen *rs = virgl_screen(pscreen);
154901e04c3fSmrg   vctx = CALLOC_STRUCT(virgl_context);
15509f464c52Smaya   const char *host_debug_flagstring;
155101e04c3fSmrg
15529f464c52Smaya   vctx->cbuf = rs->vws->cmd_buf_create(rs->vws, VIRGL_MAX_CMDBUF_DWORDS);
155301e04c3fSmrg   if (!vctx->cbuf) {
155401e04c3fSmrg      FREE(vctx);
155501e04c3fSmrg      return NULL;
155601e04c3fSmrg   }
155701e04c3fSmrg
155801e04c3fSmrg   vctx->base.destroy = virgl_context_destroy;
155901e04c3fSmrg   vctx->base.create_surface = virgl_create_surface;
156001e04c3fSmrg   vctx->base.surface_destroy = virgl_surface_destroy;
156101e04c3fSmrg   vctx->base.set_framebuffer_state = virgl_set_framebuffer_state;
156201e04c3fSmrg   vctx->base.create_blend_state = virgl_create_blend_state;
156301e04c3fSmrg   vctx->base.bind_blend_state = virgl_bind_blend_state;
156401e04c3fSmrg   vctx->base.delete_blend_state = virgl_delete_blend_state;
156501e04c3fSmrg   vctx->base.create_depth_stencil_alpha_state = virgl_create_depth_stencil_alpha_state;
156601e04c3fSmrg   vctx->base.bind_depth_stencil_alpha_state = virgl_bind_depth_stencil_alpha_state;
156701e04c3fSmrg   vctx->base.delete_depth_stencil_alpha_state = virgl_delete_depth_stencil_alpha_state;
156801e04c3fSmrg   vctx->base.create_rasterizer_state = virgl_create_rasterizer_state;
156901e04c3fSmrg   vctx->base.bind_rasterizer_state = virgl_bind_rasterizer_state;
157001e04c3fSmrg   vctx->base.delete_rasterizer_state = virgl_delete_rasterizer_state;
157101e04c3fSmrg
157201e04c3fSmrg   vctx->base.set_viewport_states = virgl_set_viewport_states;
157301e04c3fSmrg   vctx->base.create_vertex_elements_state = virgl_create_vertex_elements_state;
157401e04c3fSmrg   vctx->base.bind_vertex_elements_state = virgl_bind_vertex_elements_state;
157501e04c3fSmrg   vctx->base.delete_vertex_elements_state = virgl_delete_vertex_elements_state;
157601e04c3fSmrg   vctx->base.set_vertex_buffers = virgl_set_vertex_buffers;
157701e04c3fSmrg   vctx->base.set_constant_buffer = virgl_set_constant_buffer;
157801e04c3fSmrg
157901e04c3fSmrg   vctx->base.set_tess_state = virgl_set_tess_state;
15807ec681f3Smrg   vctx->base.set_patch_vertices = virgl_set_patch_vertices;
158101e04c3fSmrg   vctx->base.create_vs_state = virgl_create_vs_state;
158201e04c3fSmrg   vctx->base.create_tcs_state = virgl_create_tcs_state;
158301e04c3fSmrg   vctx->base.create_tes_state = virgl_create_tes_state;
158401e04c3fSmrg   vctx->base.create_gs_state = virgl_create_gs_state;
158501e04c3fSmrg   vctx->base.create_fs_state = virgl_create_fs_state;
158601e04c3fSmrg
158701e04c3fSmrg   vctx->base.bind_vs_state = virgl_bind_vs_state;
158801e04c3fSmrg   vctx->base.bind_tcs_state = virgl_bind_tcs_state;
158901e04c3fSmrg   vctx->base.bind_tes_state = virgl_bind_tes_state;
159001e04c3fSmrg   vctx->base.bind_gs_state = virgl_bind_gs_state;
159101e04c3fSmrg   vctx->base.bind_fs_state = virgl_bind_fs_state;
159201e04c3fSmrg
159301e04c3fSmrg   vctx->base.delete_vs_state = virgl_delete_vs_state;
159401e04c3fSmrg   vctx->base.delete_tcs_state = virgl_delete_tcs_state;
159501e04c3fSmrg   vctx->base.delete_tes_state = virgl_delete_tes_state;
159601e04c3fSmrg   vctx->base.delete_gs_state = virgl_delete_gs_state;
159701e04c3fSmrg   vctx->base.delete_fs_state = virgl_delete_fs_state;
159801e04c3fSmrg
159901e04c3fSmrg   vctx->base.create_compute_state = virgl_create_compute_state;
160001e04c3fSmrg   vctx->base.bind_compute_state = virgl_bind_compute_state;
160101e04c3fSmrg   vctx->base.delete_compute_state = virgl_delete_compute_state;
160201e04c3fSmrg   vctx->base.launch_grid = virgl_launch_grid;
160301e04c3fSmrg
160401e04c3fSmrg   vctx->base.clear = virgl_clear;
16057ec681f3Smrg   vctx->base.clear_texture = virgl_clear_texture;
160601e04c3fSmrg   vctx->base.draw_vbo = virgl_draw_vbo;
160701e04c3fSmrg   vctx->base.flush = virgl_flush_from_st;
160801e04c3fSmrg   vctx->base.screen = pscreen;
160901e04c3fSmrg   vctx->base.create_sampler_view = virgl_create_sampler_view;
161001e04c3fSmrg   vctx->base.sampler_view_destroy = virgl_destroy_sampler_view;
161101e04c3fSmrg   vctx->base.set_sampler_views = virgl_set_sampler_views;
161201e04c3fSmrg   vctx->base.texture_barrier = virgl_texture_barrier;
161301e04c3fSmrg
161401e04c3fSmrg   vctx->base.create_sampler_state = virgl_create_sampler_state;
161501e04c3fSmrg   vctx->base.delete_sampler_state = virgl_delete_sampler_state;
161601e04c3fSmrg   vctx->base.bind_sampler_states = virgl_bind_sampler_states;
161701e04c3fSmrg
161801e04c3fSmrg   vctx->base.set_polygon_stipple = virgl_set_polygon_stipple;
161901e04c3fSmrg   vctx->base.set_scissor_states = virgl_set_scissor_states;
162001e04c3fSmrg   vctx->base.set_sample_mask = virgl_set_sample_mask;
162101e04c3fSmrg   vctx->base.set_min_samples = virgl_set_min_samples;
162201e04c3fSmrg   vctx->base.set_stencil_ref = virgl_set_stencil_ref;
162301e04c3fSmrg   vctx->base.set_clip_state = virgl_set_clip_state;
162401e04c3fSmrg
162501e04c3fSmrg   vctx->base.set_blend_color = virgl_set_blend_color;
162601e04c3fSmrg
162701e04c3fSmrg   vctx->base.get_sample_position = virgl_get_sample_position;
162801e04c3fSmrg
162901e04c3fSmrg   vctx->base.resource_copy_region = virgl_resource_copy_region;
163001e04c3fSmrg   vctx->base.flush_resource = virgl_flush_resource;
163101e04c3fSmrg   vctx->base.blit =  virgl_blit;
16329f464c52Smaya   vctx->base.create_fence_fd = virgl_create_fence_fd;
16339f464c52Smaya   vctx->base.fence_server_sync = virgl_fence_server_sync;
163401e04c3fSmrg
163501e04c3fSmrg   vctx->base.set_shader_buffers = virgl_set_shader_buffers;
163601e04c3fSmrg   vctx->base.set_hw_atomic_buffers = virgl_set_hw_atomic_buffers;
163701e04c3fSmrg   vctx->base.set_shader_images = virgl_set_shader_images;
163801e04c3fSmrg   vctx->base.memory_barrier = virgl_memory_barrier;
16397ec681f3Smrg   vctx->base.emit_string_marker = virgl_emit_string_marker;
164001e04c3fSmrg
164101e04c3fSmrg   virgl_init_context_resource_functions(&vctx->base);
164201e04c3fSmrg   virgl_init_query_functions(vctx);
164301e04c3fSmrg   virgl_init_so_functions(vctx);
164401e04c3fSmrg
16459f464c52Smaya   slab_create_child(&vctx->transfer_pool, &rs->transfer_pool);
16467ec681f3Smrg   virgl_transfer_queue_init(&vctx->queue, vctx);
16479f464c52Smaya   vctx->encoded_transfers = (rs->vws->supports_encoded_transfers &&
16489f464c52Smaya                       (rs->caps.caps.v2.capability_bits & VIRGL_CAP_TRANSFER));
16499f464c52Smaya
16509f464c52Smaya   /* Reserve some space for transfers. */
16519f464c52Smaya   if (vctx->encoded_transfers)
16529f464c52Smaya      vctx->cbuf->cdw = VIRGL_MAX_TBUF_DWORDS;
165301e04c3fSmrg
165401e04c3fSmrg   vctx->primconvert = util_primconvert_create(&vctx->base, rs->caps.caps.v1.prim_mask);
165501e04c3fSmrg   vctx->uploader = u_upload_create(&vctx->base, 1024 * 1024,
165601e04c3fSmrg                                     PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_STREAM, 0);
165701e04c3fSmrg   if (!vctx->uploader)
165801e04c3fSmrg           goto fail;
165901e04c3fSmrg   vctx->base.stream_uploader = vctx->uploader;
166001e04c3fSmrg   vctx->base.const_uploader = vctx->uploader;
166101e04c3fSmrg
16627ec681f3Smrg   /* We use a special staging buffer as the source of copy transfers. */
16637ec681f3Smrg   if ((rs->caps.caps.v2.capability_bits & VIRGL_CAP_COPY_TRANSFER) &&
16647ec681f3Smrg       vctx->encoded_transfers) {
16657ec681f3Smrg      virgl_staging_init(&vctx->staging, &vctx->base, 1024 * 1024);
16667ec681f3Smrg      vctx->supports_staging = true;
16677ec681f3Smrg   }
16687ec681f3Smrg
16697ec681f3Smrg   vctx->hw_sub_ctx_id = p_atomic_inc_return(&rs->sub_ctx_id);
167001e04c3fSmrg   virgl_encoder_create_sub_ctx(vctx, vctx->hw_sub_ctx_id);
167101e04c3fSmrg
167201e04c3fSmrg   virgl_encoder_set_sub_ctx(vctx, vctx->hw_sub_ctx_id);
16739f464c52Smaya
16749f464c52Smaya   if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_GUEST_MAY_INIT_LOG) {
16759f464c52Smaya      host_debug_flagstring = getenv("VIRGL_HOST_DEBUG");
16769f464c52Smaya      if (host_debug_flagstring)
16779f464c52Smaya         virgl_encode_host_debug_flagstring(vctx, host_debug_flagstring);
16789f464c52Smaya   }
16799f464c52Smaya
16807ec681f3Smrg   if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_APP_TWEAK_SUPPORT)
16817ec681f3Smrg      virgl_send_tweaks(vctx, rs);
16827ec681f3Smrg
168301e04c3fSmrg   return &vctx->base;
168401e04c3fSmrgfail:
16857ec681f3Smrg   virgl_context_destroy(&vctx->base);
168601e04c3fSmrg   return NULL;
168701e04c3fSmrg}
1688