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