Path: blob/21.2-virgl/src/gallium/drivers/virgl/virgl_context.c
4570 views
/*1* Copyright 2014, 2015 Red Hat.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE.21*/2223#include <libsync.h>24#include "pipe/p_shader_tokens.h"2526#include "pipe/p_context.h"27#include "pipe/p_defines.h"28#include "pipe/p_screen.h"29#include "pipe/p_state.h"30#include "util/u_draw.h"31#include "util/u_inlines.h"32#include "util/u_memory.h"33#include "util/format/u_format.h"34#include "util/u_prim.h"35#include "util/u_transfer.h"36#include "util/u_helpers.h"37#include "util/slab.h"38#include "util/u_upload_mgr.h"39#include "util/u_blitter.h"40#include "tgsi/tgsi_text.h"41#include "indices/u_primconvert.h"4243#include "pipebuffer/pb_buffer.h"4445#include "virgl_encode.h"46#include "virgl_context.h"47#include "virtio-gpu/virgl_protocol.h"48#include "virgl_resource.h"49#include "virgl_screen.h"50#include "virgl_staging_mgr.h"5152struct virgl_vertex_elements_state {53uint32_t handle;54uint8_t binding_map[PIPE_MAX_ATTRIBS];55uint8_t num_bindings;56};5758static uint32_t next_handle;59uint32_t virgl_object_assign_handle(void)60{61return p_atomic_inc_return(&next_handle);62}6364bool65virgl_can_rebind_resource(struct virgl_context *vctx,66struct pipe_resource *res)67{68/* We cannot rebind resources that are referenced by host objects, which69* are70*71* - VIRGL_OBJECT_SURFACE72* - VIRGL_OBJECT_SAMPLER_VIEW73* - VIRGL_OBJECT_STREAMOUT_TARGET74*75* Because surfaces cannot be created from buffers, we require the resource76* to be a buffer instead (and avoid tracking VIRGL_OBJECT_SURFACE binds).77*/78const unsigned unsupported_bind = (PIPE_BIND_SAMPLER_VIEW |79PIPE_BIND_STREAM_OUTPUT);80const unsigned bind_history = virgl_resource(res)->bind_history;81return res->target == PIPE_BUFFER && !(bind_history & unsupported_bind);82}8384void85virgl_rebind_resource(struct virgl_context *vctx,86struct pipe_resource *res)87{88/* Queries use internally created buffers and do not go through transfers.89* Index buffers are not bindable. They are not tracked.90*/91ASSERTED const unsigned tracked_bind = (PIPE_BIND_VERTEX_BUFFER |92PIPE_BIND_CONSTANT_BUFFER |93PIPE_BIND_SHADER_BUFFER |94PIPE_BIND_SHADER_IMAGE);95const unsigned bind_history = virgl_resource(res)->bind_history;96unsigned i;9798assert(virgl_can_rebind_resource(vctx, res) &&99(bind_history & tracked_bind) == bind_history);100101if (bind_history & PIPE_BIND_VERTEX_BUFFER) {102for (i = 0; i < vctx->num_vertex_buffers; i++) {103if (vctx->vertex_buffer[i].buffer.resource == res) {104vctx->vertex_array_dirty = true;105break;106}107}108}109110if (bind_history & PIPE_BIND_SHADER_BUFFER) {111uint32_t remaining_mask = vctx->atomic_buffer_enabled_mask;112while (remaining_mask) {113int i = u_bit_scan(&remaining_mask);114if (vctx->atomic_buffers[i].buffer == res) {115const struct pipe_shader_buffer *abo = &vctx->atomic_buffers[i];116virgl_encode_set_hw_atomic_buffers(vctx, i, 1, abo);117}118}119}120121/* check per-stage shader bindings */122if (bind_history & (PIPE_BIND_CONSTANT_BUFFER |123PIPE_BIND_SHADER_BUFFER |124PIPE_BIND_SHADER_IMAGE)) {125enum pipe_shader_type shader_type;126for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) {127const struct virgl_shader_binding_state *binding =128&vctx->shader_bindings[shader_type];129130if (bind_history & PIPE_BIND_CONSTANT_BUFFER) {131uint32_t remaining_mask = binding->ubo_enabled_mask;132while (remaining_mask) {133int i = u_bit_scan(&remaining_mask);134if (binding->ubos[i].buffer == res) {135const struct pipe_constant_buffer *ubo = &binding->ubos[i];136virgl_encoder_set_uniform_buffer(vctx, shader_type, i,137ubo->buffer_offset,138ubo->buffer_size,139virgl_resource(res));140}141}142}143144if (bind_history & PIPE_BIND_SHADER_BUFFER) {145uint32_t remaining_mask = binding->ssbo_enabled_mask;146while (remaining_mask) {147int i = u_bit_scan(&remaining_mask);148if (binding->ssbos[i].buffer == res) {149const struct pipe_shader_buffer *ssbo = &binding->ssbos[i];150virgl_encode_set_shader_buffers(vctx, shader_type, i, 1,151ssbo);152}153}154}155156if (bind_history & PIPE_BIND_SHADER_IMAGE) {157uint32_t remaining_mask = binding->image_enabled_mask;158while (remaining_mask) {159int i = u_bit_scan(&remaining_mask);160if (binding->images[i].resource == res) {161const struct pipe_image_view *image = &binding->images[i];162virgl_encode_set_shader_images(vctx, shader_type, i, 1,163image);164}165}166}167}168}169}170171static void virgl_attach_res_framebuffer(struct virgl_context *vctx)172{173struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;174struct pipe_surface *surf;175struct virgl_resource *res;176unsigned i;177178surf = vctx->framebuffer.zsbuf;179if (surf) {180res = virgl_resource(surf->texture);181if (res) {182vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);183virgl_resource_dirty(res, surf->u.tex.level);184}185}186for (i = 0; i < vctx->framebuffer.nr_cbufs; i++) {187surf = vctx->framebuffer.cbufs[i];188if (surf) {189res = virgl_resource(surf->texture);190if (res) {191vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);192virgl_resource_dirty(res, surf->u.tex.level);193}194}195}196}197198static void virgl_attach_res_sampler_views(struct virgl_context *vctx,199enum pipe_shader_type shader_type)200{201struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;202const struct virgl_shader_binding_state *binding =203&vctx->shader_bindings[shader_type];204uint32_t remaining_mask = binding->view_enabled_mask;205struct virgl_resource *res;206207while (remaining_mask) {208int i = u_bit_scan(&remaining_mask);209assert(binding->views[i] && binding->views[i]->texture);210res = virgl_resource(binding->views[i]->texture);211vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);212}213}214215static void virgl_attach_res_vertex_buffers(struct virgl_context *vctx)216{217struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;218struct virgl_resource *res;219unsigned i;220221for (i = 0; i < vctx->num_vertex_buffers; i++) {222res = virgl_resource(vctx->vertex_buffer[i].buffer.resource);223if (res)224vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);225}226}227228static void virgl_attach_res_index_buffer(struct virgl_context *vctx,229struct virgl_indexbuf *ib)230{231struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;232struct virgl_resource *res;233234res = virgl_resource(ib->buffer);235if (res)236vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);237}238239static void virgl_attach_res_so_targets(struct virgl_context *vctx)240{241struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;242struct virgl_resource *res;243unsigned i;244245for (i = 0; i < vctx->num_so_targets; i++) {246res = virgl_resource(vctx->so_targets[i].base.buffer);247if (res)248vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);249}250}251252static void virgl_attach_res_uniform_buffers(struct virgl_context *vctx,253enum pipe_shader_type shader_type)254{255struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;256const struct virgl_shader_binding_state *binding =257&vctx->shader_bindings[shader_type];258uint32_t remaining_mask = binding->ubo_enabled_mask;259struct virgl_resource *res;260261while (remaining_mask) {262int i = u_bit_scan(&remaining_mask);263res = virgl_resource(binding->ubos[i].buffer);264assert(res);265vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);266}267}268269static void virgl_attach_res_shader_buffers(struct virgl_context *vctx,270enum pipe_shader_type shader_type)271{272struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;273const struct virgl_shader_binding_state *binding =274&vctx->shader_bindings[shader_type];275uint32_t remaining_mask = binding->ssbo_enabled_mask;276struct virgl_resource *res;277278while (remaining_mask) {279int i = u_bit_scan(&remaining_mask);280res = virgl_resource(binding->ssbos[i].buffer);281assert(res);282vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);283}284}285286static void virgl_attach_res_shader_images(struct virgl_context *vctx,287enum pipe_shader_type shader_type)288{289struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;290const struct virgl_shader_binding_state *binding =291&vctx->shader_bindings[shader_type];292uint32_t remaining_mask = binding->image_enabled_mask;293struct virgl_resource *res;294295while (remaining_mask) {296int i = u_bit_scan(&remaining_mask);297res = virgl_resource(binding->images[i].resource);298assert(res);299vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);300}301}302303static void virgl_attach_res_atomic_buffers(struct virgl_context *vctx)304{305struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;306uint32_t remaining_mask = vctx->atomic_buffer_enabled_mask;307struct virgl_resource *res;308309while (remaining_mask) {310int i = u_bit_scan(&remaining_mask);311res = virgl_resource(vctx->atomic_buffers[i].buffer);312assert(res);313vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);314}315}316317/*318* after flushing, the hw context still has a bunch of319* resources bound, so we need to rebind those here.320*/321static void virgl_reemit_draw_resources(struct virgl_context *vctx)322{323enum pipe_shader_type shader_type;324325/* reattach any flushed resources */326/* framebuffer, sampler views, vertex/index/uniform/stream buffers */327virgl_attach_res_framebuffer(vctx);328329for (shader_type = 0; shader_type < PIPE_SHADER_COMPUTE; shader_type++) {330virgl_attach_res_sampler_views(vctx, shader_type);331virgl_attach_res_uniform_buffers(vctx, shader_type);332virgl_attach_res_shader_buffers(vctx, shader_type);333virgl_attach_res_shader_images(vctx, shader_type);334}335virgl_attach_res_atomic_buffers(vctx);336virgl_attach_res_vertex_buffers(vctx);337virgl_attach_res_so_targets(vctx);338}339340static void virgl_reemit_compute_resources(struct virgl_context *vctx)341{342virgl_attach_res_sampler_views(vctx, PIPE_SHADER_COMPUTE);343virgl_attach_res_uniform_buffers(vctx, PIPE_SHADER_COMPUTE);344virgl_attach_res_shader_buffers(vctx, PIPE_SHADER_COMPUTE);345virgl_attach_res_shader_images(vctx, PIPE_SHADER_COMPUTE);346347virgl_attach_res_atomic_buffers(vctx);348}349350static struct pipe_surface *virgl_create_surface(struct pipe_context *ctx,351struct pipe_resource *resource,352const struct pipe_surface *templ)353{354struct virgl_context *vctx = virgl_context(ctx);355struct virgl_surface *surf;356struct virgl_resource *res = virgl_resource(resource);357uint32_t handle;358359/* no support for buffer surfaces */360if (resource->target == PIPE_BUFFER)361return NULL;362363surf = CALLOC_STRUCT(virgl_surface);364if (!surf)365return NULL;366367assert(ctx->screen->get_param(ctx->screen,368PIPE_CAP_DEST_SURFACE_SRGB_CONTROL) ||369(util_format_is_srgb(templ->format) ==370util_format_is_srgb(resource->format)));371372virgl_resource_dirty(res, 0);373handle = virgl_object_assign_handle();374pipe_reference_init(&surf->base.reference, 1);375pipe_resource_reference(&surf->base.texture, resource);376surf->base.context = ctx;377surf->base.format = templ->format;378379surf->base.width = u_minify(resource->width0, templ->u.tex.level);380surf->base.height = u_minify(resource->height0, templ->u.tex.level);381surf->base.u.tex.level = templ->u.tex.level;382surf->base.u.tex.first_layer = templ->u.tex.first_layer;383surf->base.u.tex.last_layer = templ->u.tex.last_layer;384surf->base.nr_samples = templ->nr_samples;385386virgl_encoder_create_surface(vctx, handle, res, &surf->base);387surf->handle = handle;388return &surf->base;389}390391static void virgl_surface_destroy(struct pipe_context *ctx,392struct pipe_surface *psurf)393{394struct virgl_context *vctx = virgl_context(ctx);395struct virgl_surface *surf = virgl_surface(psurf);396397pipe_resource_reference(&surf->base.texture, NULL);398virgl_encode_delete_object(vctx, surf->handle, VIRGL_OBJECT_SURFACE);399FREE(surf);400}401402static void *virgl_create_blend_state(struct pipe_context *ctx,403const struct pipe_blend_state *blend_state)404{405struct virgl_context *vctx = virgl_context(ctx);406uint32_t handle;407handle = virgl_object_assign_handle();408409virgl_encode_blend_state(vctx, handle, blend_state);410return (void *)(unsigned long)handle;411412}413414static void virgl_bind_blend_state(struct pipe_context *ctx,415void *blend_state)416{417struct virgl_context *vctx = virgl_context(ctx);418uint32_t handle = (unsigned long)blend_state;419virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_BLEND);420}421422static void virgl_delete_blend_state(struct pipe_context *ctx,423void *blend_state)424{425struct virgl_context *vctx = virgl_context(ctx);426uint32_t handle = (unsigned long)blend_state;427virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_BLEND);428}429430static void *virgl_create_depth_stencil_alpha_state(struct pipe_context *ctx,431const struct pipe_depth_stencil_alpha_state *blend_state)432{433struct virgl_context *vctx = virgl_context(ctx);434uint32_t handle;435handle = virgl_object_assign_handle();436437virgl_encode_dsa_state(vctx, handle, blend_state);438return (void *)(unsigned long)handle;439}440441static void virgl_bind_depth_stencil_alpha_state(struct pipe_context *ctx,442void *blend_state)443{444struct virgl_context *vctx = virgl_context(ctx);445uint32_t handle = (unsigned long)blend_state;446virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_DSA);447}448449static void virgl_delete_depth_stencil_alpha_state(struct pipe_context *ctx,450void *dsa_state)451{452struct virgl_context *vctx = virgl_context(ctx);453uint32_t handle = (unsigned long)dsa_state;454virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_DSA);455}456457static void *virgl_create_rasterizer_state(struct pipe_context *ctx,458const struct pipe_rasterizer_state *rs_state)459{460struct virgl_context *vctx = virgl_context(ctx);461struct virgl_rasterizer_state *vrs = CALLOC_STRUCT(virgl_rasterizer_state);462463if (!vrs)464return NULL;465vrs->rs = *rs_state;466vrs->handle = virgl_object_assign_handle();467468assert(rs_state->depth_clip_near ||469virgl_screen(ctx->screen)->caps.caps.v1.bset.depth_clip_disable);470471virgl_encode_rasterizer_state(vctx, vrs->handle, rs_state);472return (void *)vrs;473}474475static void virgl_bind_rasterizer_state(struct pipe_context *ctx,476void *rs_state)477{478struct virgl_context *vctx = virgl_context(ctx);479uint32_t handle = 0;480if (rs_state) {481struct virgl_rasterizer_state *vrs = rs_state;482vctx->rs_state = *vrs;483handle = vrs->handle;484}485virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_RASTERIZER);486}487488static void virgl_delete_rasterizer_state(struct pipe_context *ctx,489void *rs_state)490{491struct virgl_context *vctx = virgl_context(ctx);492struct virgl_rasterizer_state *vrs = rs_state;493virgl_encode_delete_object(vctx, vrs->handle, VIRGL_OBJECT_RASTERIZER);494FREE(vrs);495}496497static void virgl_set_framebuffer_state(struct pipe_context *ctx,498const struct pipe_framebuffer_state *state)499{500struct virgl_context *vctx = virgl_context(ctx);501502vctx->framebuffer = *state;503virgl_encoder_set_framebuffer_state(vctx, state);504virgl_attach_res_framebuffer(vctx);505}506507static void virgl_set_viewport_states(struct pipe_context *ctx,508unsigned start_slot,509unsigned num_viewports,510const struct pipe_viewport_state *state)511{512struct virgl_context *vctx = virgl_context(ctx);513virgl_encoder_set_viewport_states(vctx, start_slot, num_viewports, state);514}515516static void *virgl_create_vertex_elements_state(struct pipe_context *ctx,517unsigned num_elements,518const struct pipe_vertex_element *elements)519{520struct pipe_vertex_element new_elements[PIPE_MAX_ATTRIBS];521struct virgl_context *vctx = virgl_context(ctx);522struct virgl_vertex_elements_state *state =523CALLOC_STRUCT(virgl_vertex_elements_state);524525for (int i = 0; i < num_elements; ++i) {526if (elements[i].instance_divisor) {527/* Virglrenderer doesn't deal with instance_divisor correctly if528* there isn't a 1:1 relationship between elements and bindings.529* So let's make sure there is, by duplicating bindings.530*/531for (int j = 0; j < num_elements; ++j) {532new_elements[j] = elements[j];533new_elements[j].vertex_buffer_index = j;534state->binding_map[j] = elements[j].vertex_buffer_index;535}536elements = new_elements;537state->num_bindings = num_elements;538break;539}540}541542state->handle = virgl_object_assign_handle();543virgl_encoder_create_vertex_elements(vctx, state->handle,544num_elements, elements);545return state;546}547548static void virgl_delete_vertex_elements_state(struct pipe_context *ctx,549void *ve)550{551struct virgl_context *vctx = virgl_context(ctx);552struct virgl_vertex_elements_state *state =553(struct virgl_vertex_elements_state *)ve;554virgl_encode_delete_object(vctx, state->handle, VIRGL_OBJECT_VERTEX_ELEMENTS);555FREE(state);556}557558static void virgl_bind_vertex_elements_state(struct pipe_context *ctx,559void *ve)560{561struct virgl_context *vctx = virgl_context(ctx);562struct virgl_vertex_elements_state *state =563(struct virgl_vertex_elements_state *)ve;564vctx->vertex_elements = state;565virgl_encode_bind_object(vctx, state ? state->handle : 0,566VIRGL_OBJECT_VERTEX_ELEMENTS);567vctx->vertex_array_dirty = TRUE;568}569570static void virgl_set_vertex_buffers(struct pipe_context *ctx,571unsigned start_slot,572unsigned num_buffers,573unsigned unbind_num_trailing_slots,574bool take_ownership,575const struct pipe_vertex_buffer *buffers)576{577struct virgl_context *vctx = virgl_context(ctx);578579util_set_vertex_buffers_count(vctx->vertex_buffer,580&vctx->num_vertex_buffers,581buffers, start_slot, num_buffers,582unbind_num_trailing_slots,583take_ownership);584585if (buffers) {586for (unsigned i = 0; i < num_buffers; i++) {587struct virgl_resource *res =588virgl_resource(buffers[i].buffer.resource);589if (res && !buffers[i].is_user_buffer)590res->bind_history |= PIPE_BIND_VERTEX_BUFFER;591}592}593594vctx->vertex_array_dirty = TRUE;595}596597static void virgl_hw_set_vertex_buffers(struct virgl_context *vctx)598{599if (vctx->vertex_array_dirty) {600struct virgl_vertex_elements_state *ve = vctx->vertex_elements;601602if (ve->num_bindings) {603struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];604for (int i = 0; i < ve->num_bindings; ++i)605vertex_buffers[i] = vctx->vertex_buffer[ve->binding_map[i]];606607virgl_encoder_set_vertex_buffers(vctx, ve->num_bindings, vertex_buffers);608} else609virgl_encoder_set_vertex_buffers(vctx, vctx->num_vertex_buffers, vctx->vertex_buffer);610611virgl_attach_res_vertex_buffers(vctx);612613vctx->vertex_array_dirty = FALSE;614}615}616617static void virgl_set_stencil_ref(struct pipe_context *ctx,618const struct pipe_stencil_ref ref)619{620struct virgl_context *vctx = virgl_context(ctx);621virgl_encoder_set_stencil_ref(vctx, &ref);622}623624static void virgl_set_blend_color(struct pipe_context *ctx,625const struct pipe_blend_color *color)626{627struct virgl_context *vctx = virgl_context(ctx);628virgl_encoder_set_blend_color(vctx, color);629}630631static void virgl_hw_set_index_buffer(struct virgl_context *vctx,632struct virgl_indexbuf *ib)633{634virgl_encoder_set_index_buffer(vctx, ib);635virgl_attach_res_index_buffer(vctx, ib);636}637638static void virgl_set_constant_buffer(struct pipe_context *ctx,639enum pipe_shader_type shader, uint index,640bool take_ownership,641const struct pipe_constant_buffer *buf)642{643struct virgl_context *vctx = virgl_context(ctx);644struct virgl_shader_binding_state *binding =645&vctx->shader_bindings[shader];646647if (buf && buf->buffer) {648struct virgl_resource *res = virgl_resource(buf->buffer);649res->bind_history |= PIPE_BIND_CONSTANT_BUFFER;650651virgl_encoder_set_uniform_buffer(vctx, shader, index,652buf->buffer_offset,653buf->buffer_size, res);654655if (take_ownership) {656pipe_resource_reference(&binding->ubos[index].buffer, NULL);657binding->ubos[index].buffer = buf->buffer;658} else {659pipe_resource_reference(&binding->ubos[index].buffer, buf->buffer);660}661binding->ubos[index] = *buf;662binding->ubo_enabled_mask |= 1 << index;663} else {664static const struct pipe_constant_buffer dummy_ubo;665if (!buf)666buf = &dummy_ubo;667virgl_encoder_write_constant_buffer(vctx, shader, index,668buf->buffer_size / 4,669buf->user_buffer);670671pipe_resource_reference(&binding->ubos[index].buffer, NULL);672binding->ubo_enabled_mask &= ~(1 << index);673}674}675676static void *virgl_shader_encoder(struct pipe_context *ctx,677const struct pipe_shader_state *shader,678unsigned type)679{680struct virgl_context *vctx = virgl_context(ctx);681uint32_t handle;682struct tgsi_token *new_tokens;683int ret;684685new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, shader->tokens);686if (!new_tokens)687return NULL;688689handle = virgl_object_assign_handle();690/* encode VS state */691ret = virgl_encode_shader_state(vctx, handle, type,692&shader->stream_output, 0,693new_tokens);694if (ret) {695return NULL;696}697698FREE(new_tokens);699return (void *)(unsigned long)handle;700701}702static void *virgl_create_vs_state(struct pipe_context *ctx,703const struct pipe_shader_state *shader)704{705return virgl_shader_encoder(ctx, shader, PIPE_SHADER_VERTEX);706}707708static void *virgl_create_tcs_state(struct pipe_context *ctx,709const struct pipe_shader_state *shader)710{711return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_CTRL);712}713714static void *virgl_create_tes_state(struct pipe_context *ctx,715const struct pipe_shader_state *shader)716{717return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_EVAL);718}719720static void *virgl_create_gs_state(struct pipe_context *ctx,721const struct pipe_shader_state *shader)722{723return virgl_shader_encoder(ctx, shader, PIPE_SHADER_GEOMETRY);724}725726static void *virgl_create_fs_state(struct pipe_context *ctx,727const struct pipe_shader_state *shader)728{729return virgl_shader_encoder(ctx, shader, PIPE_SHADER_FRAGMENT);730}731732static void733virgl_delete_fs_state(struct pipe_context *ctx,734void *fs)735{736uint32_t handle = (unsigned long)fs;737struct virgl_context *vctx = virgl_context(ctx);738739virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);740}741742static void743virgl_delete_gs_state(struct pipe_context *ctx,744void *gs)745{746uint32_t handle = (unsigned long)gs;747struct virgl_context *vctx = virgl_context(ctx);748749virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);750}751752static void753virgl_delete_vs_state(struct pipe_context *ctx,754void *vs)755{756uint32_t handle = (unsigned long)vs;757struct virgl_context *vctx = virgl_context(ctx);758759virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);760}761762static void763virgl_delete_tcs_state(struct pipe_context *ctx,764void *tcs)765{766uint32_t handle = (unsigned long)tcs;767struct virgl_context *vctx = virgl_context(ctx);768769virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);770}771772static void773virgl_delete_tes_state(struct pipe_context *ctx,774void *tes)775{776uint32_t handle = (unsigned long)tes;777struct virgl_context *vctx = virgl_context(ctx);778779virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);780}781782static void virgl_bind_vs_state(struct pipe_context *ctx,783void *vss)784{785uint32_t handle = (unsigned long)vss;786struct virgl_context *vctx = virgl_context(ctx);787788virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_VERTEX);789}790791static void virgl_bind_tcs_state(struct pipe_context *ctx,792void *vss)793{794uint32_t handle = (unsigned long)vss;795struct virgl_context *vctx = virgl_context(ctx);796797virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_CTRL);798}799800static void virgl_bind_tes_state(struct pipe_context *ctx,801void *vss)802{803uint32_t handle = (unsigned long)vss;804struct virgl_context *vctx = virgl_context(ctx);805806virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_EVAL);807}808809static void virgl_bind_gs_state(struct pipe_context *ctx,810void *vss)811{812uint32_t handle = (unsigned long)vss;813struct virgl_context *vctx = virgl_context(ctx);814815virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_GEOMETRY);816}817818819static void virgl_bind_fs_state(struct pipe_context *ctx,820void *vss)821{822uint32_t handle = (unsigned long)vss;823struct virgl_context *vctx = virgl_context(ctx);824825virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_FRAGMENT);826}827828static void virgl_clear(struct pipe_context *ctx,829unsigned buffers,830const struct pipe_scissor_state *scissor_state,831const union pipe_color_union *color,832double depth, unsigned stencil)833{834struct virgl_context *vctx = virgl_context(ctx);835836if (!vctx->num_draws)837virgl_reemit_draw_resources(vctx);838vctx->num_draws++;839840virgl_encode_clear(vctx, buffers, color, depth, stencil);841}842843static void virgl_clear_texture(struct pipe_context *ctx,844struct pipe_resource *res,845unsigned int level,846const struct pipe_box *box,847const void *data)848{849struct virgl_context *vctx = virgl_context(ctx);850struct virgl_resource *vres = virgl_resource(res);851852virgl_encode_clear_texture(vctx, vres, level, box, data);853854/* Mark as dirty, since we are updating the host side resource855* without going through the corresponding guest side resource, and856* hence the two will diverge.857*/858virgl_resource_dirty(vres, level);859}860861static void virgl_draw_vbo(struct pipe_context *ctx,862const struct pipe_draw_info *dinfo,863unsigned drawid_offset,864const struct pipe_draw_indirect_info *indirect,865const struct pipe_draw_start_count_bias *draws,866unsigned num_draws)867{868if (num_draws > 1) {869util_draw_multi(ctx, dinfo, drawid_offset, indirect, draws, num_draws);870return;871}872873if (!indirect && (!draws[0].count || !dinfo->instance_count))874return;875876struct virgl_context *vctx = virgl_context(ctx);877struct virgl_screen *rs = virgl_screen(ctx->screen);878struct virgl_indexbuf ib = {};879struct pipe_draw_info info = *dinfo;880881if (!indirect &&882!dinfo->primitive_restart &&883!u_trim_pipe_prim(dinfo->mode, (unsigned*)&draws[0].count))884return;885886if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) {887util_primconvert_save_rasterizer_state(vctx->primconvert, &vctx->rs_state.rs);888util_primconvert_draw_vbo(vctx->primconvert, dinfo, drawid_offset, indirect, draws, num_draws);889return;890}891if (info.index_size) {892pipe_resource_reference(&ib.buffer, info.has_user_indices ? NULL : info.index.resource);893ib.user_buffer = info.has_user_indices ? info.index.user : NULL;894ib.index_size = dinfo->index_size;895ib.offset = draws[0].start * ib.index_size;896897if (ib.user_buffer) {898unsigned start_offset = draws[0].start * ib.index_size;899u_upload_data(vctx->uploader, start_offset,900draws[0].count * ib.index_size, 4,901(char*)ib.user_buffer + start_offset,902&ib.offset, &ib.buffer);903ib.offset -= start_offset;904ib.user_buffer = NULL;905}906}907908if (!vctx->num_draws)909virgl_reemit_draw_resources(vctx);910vctx->num_draws++;911912virgl_hw_set_vertex_buffers(vctx);913if (info.index_size)914virgl_hw_set_index_buffer(vctx, &ib);915916virgl_encoder_draw_vbo(vctx, &info, drawid_offset, indirect, &draws[0]);917918pipe_resource_reference(&ib.buffer, NULL);919920}921922static void virgl_submit_cmd(struct virgl_winsys *vws,923struct virgl_cmd_buf *cbuf,924struct pipe_fence_handle **fence)925{926if (unlikely(virgl_debug & VIRGL_DEBUG_SYNC)) {927struct pipe_fence_handle *sync_fence = NULL;928929vws->submit_cmd(vws, cbuf, &sync_fence);930931vws->fence_wait(vws, sync_fence, PIPE_TIMEOUT_INFINITE);932vws->fence_reference(vws, &sync_fence, NULL);933} else {934vws->submit_cmd(vws, cbuf, fence);935}936}937938static void virgl_flush_eq(struct virgl_context *ctx, void *closure,939struct pipe_fence_handle **fence)940{941struct virgl_screen *rs = virgl_screen(ctx->base.screen);942943/* skip empty cbuf */944if (ctx->cbuf->cdw == ctx->cbuf_initial_cdw &&945ctx->queue.num_dwords == 0 &&946!fence)947return;948949if (ctx->num_draws)950u_upload_unmap(ctx->uploader);951952/* send the buffer to the remote side for decoding */953ctx->num_draws = ctx->num_compute = 0;954955virgl_transfer_queue_clear(&ctx->queue, ctx->cbuf);956957virgl_submit_cmd(rs->vws, ctx->cbuf, fence);958959/* Reserve some space for transfers. */960if (ctx->encoded_transfers)961ctx->cbuf->cdw = VIRGL_MAX_TBUF_DWORDS;962963virgl_encoder_set_sub_ctx(ctx, ctx->hw_sub_ctx_id);964965ctx->cbuf_initial_cdw = ctx->cbuf->cdw;966967/* We have flushed the command queue, including any pending copy transfers968* involving staging resources.969*/970ctx->queued_staging_res_size = 0;971}972973static void virgl_flush_from_st(struct pipe_context *ctx,974struct pipe_fence_handle **fence,975enum pipe_flush_flags flags)976{977struct virgl_context *vctx = virgl_context(ctx);978979virgl_flush_eq(vctx, vctx, fence);980}981982static struct pipe_sampler_view *virgl_create_sampler_view(struct pipe_context *ctx,983struct pipe_resource *texture,984const struct pipe_sampler_view *state)985{986struct virgl_context *vctx = virgl_context(ctx);987struct virgl_sampler_view *grview;988uint32_t handle;989struct virgl_resource *res;990991if (!state)992return NULL;993994grview = CALLOC_STRUCT(virgl_sampler_view);995if (!grview)996return NULL;997998res = virgl_resource(texture);999handle = virgl_object_assign_handle();1000virgl_encode_sampler_view(vctx, handle, res, state);10011002grview->base = *state;1003grview->base.reference.count = 1;10041005grview->base.texture = NULL;1006grview->base.context = ctx;1007pipe_resource_reference(&grview->base.texture, texture);1008grview->handle = handle;1009return &grview->base;1010}10111012static void virgl_set_sampler_views(struct pipe_context *ctx,1013enum pipe_shader_type shader_type,1014unsigned start_slot,1015unsigned num_views,1016unsigned unbind_num_trailing_slots,1017struct pipe_sampler_view **views)1018{1019struct virgl_context *vctx = virgl_context(ctx);1020struct virgl_shader_binding_state *binding =1021&vctx->shader_bindings[shader_type];10221023binding->view_enabled_mask &= ~u_bit_consecutive(start_slot, num_views);1024for (unsigned i = 0; i < num_views; i++) {1025unsigned idx = start_slot + i;1026if (views && views[i]) {1027struct virgl_resource *res = virgl_resource(views[i]->texture);1028res->bind_history |= PIPE_BIND_SAMPLER_VIEW;10291030pipe_sampler_view_reference(&binding->views[idx], views[i]);1031binding->view_enabled_mask |= 1 << idx;1032} else {1033pipe_sampler_view_reference(&binding->views[idx], NULL);1034}1035}10361037virgl_encode_set_sampler_views(vctx, shader_type,1038start_slot, num_views, (struct virgl_sampler_view **)binding->views);1039virgl_attach_res_sampler_views(vctx, shader_type);10401041if (unbind_num_trailing_slots) {1042virgl_set_sampler_views(ctx, shader_type, start_slot + num_views,1043unbind_num_trailing_slots, 0, NULL);1044}1045}10461047static void1048virgl_texture_barrier(struct pipe_context *ctx, unsigned flags)1049{1050struct virgl_context *vctx = virgl_context(ctx);1051struct virgl_screen *rs = virgl_screen(ctx->screen);10521053if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_TEXTURE_BARRIER) &&1054!(rs->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_BLEND_EQUATION))1055return;1056virgl_encode_texture_barrier(vctx, flags);1057}10581059static void virgl_destroy_sampler_view(struct pipe_context *ctx,1060struct pipe_sampler_view *view)1061{1062struct virgl_context *vctx = virgl_context(ctx);1063struct virgl_sampler_view *grview = virgl_sampler_view(view);10641065virgl_encode_delete_object(vctx, grview->handle, VIRGL_OBJECT_SAMPLER_VIEW);1066pipe_resource_reference(&view->texture, NULL);1067FREE(view);1068}10691070static void *virgl_create_sampler_state(struct pipe_context *ctx,1071const struct pipe_sampler_state *state)1072{1073struct virgl_context *vctx = virgl_context(ctx);1074uint32_t handle;10751076handle = virgl_object_assign_handle();10771078virgl_encode_sampler_state(vctx, handle, state);1079return (void *)(unsigned long)handle;1080}10811082static void virgl_delete_sampler_state(struct pipe_context *ctx,1083void *ss)1084{1085struct virgl_context *vctx = virgl_context(ctx);1086uint32_t handle = (unsigned long)ss;10871088virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SAMPLER_STATE);1089}10901091static void virgl_bind_sampler_states(struct pipe_context *ctx,1092enum pipe_shader_type shader,1093unsigned start_slot,1094unsigned num_samplers,1095void **samplers)1096{1097struct virgl_context *vctx = virgl_context(ctx);1098uint32_t handles[32];1099int i;1100for (i = 0; i < num_samplers; i++) {1101handles[i] = (unsigned long)(samplers[i]);1102}1103virgl_encode_bind_sampler_states(vctx, shader, start_slot, num_samplers, handles);1104}11051106static void virgl_set_polygon_stipple(struct pipe_context *ctx,1107const struct pipe_poly_stipple *ps)1108{1109struct virgl_context *vctx = virgl_context(ctx);1110virgl_encoder_set_polygon_stipple(vctx, ps);1111}11121113static void virgl_set_scissor_states(struct pipe_context *ctx,1114unsigned start_slot,1115unsigned num_scissor,1116const struct pipe_scissor_state *ss)1117{1118struct virgl_context *vctx = virgl_context(ctx);1119virgl_encoder_set_scissor_state(vctx, start_slot, num_scissor, ss);1120}11211122static void virgl_set_sample_mask(struct pipe_context *ctx,1123unsigned sample_mask)1124{1125struct virgl_context *vctx = virgl_context(ctx);1126virgl_encoder_set_sample_mask(vctx, sample_mask);1127}11281129static void virgl_set_min_samples(struct pipe_context *ctx,1130unsigned min_samples)1131{1132struct virgl_context *vctx = virgl_context(ctx);1133struct virgl_screen *rs = virgl_screen(ctx->screen);11341135if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_SET_MIN_SAMPLES))1136return;1137virgl_encoder_set_min_samples(vctx, min_samples);1138}11391140static void virgl_set_clip_state(struct pipe_context *ctx,1141const struct pipe_clip_state *clip)1142{1143struct virgl_context *vctx = virgl_context(ctx);1144virgl_encoder_set_clip_state(vctx, clip);1145}11461147static void virgl_set_tess_state(struct pipe_context *ctx,1148const float default_outer_level[4],1149const float default_inner_level[2])1150{1151struct virgl_context *vctx = virgl_context(ctx);1152struct virgl_screen *rs = virgl_screen(ctx->screen);11531154if (!rs->caps.caps.v1.bset.has_tessellation_shaders)1155return;1156virgl_encode_set_tess_state(vctx, default_outer_level, default_inner_level);1157}11581159static void virgl_resource_copy_region(struct pipe_context *ctx,1160struct pipe_resource *dst,1161unsigned dst_level,1162unsigned dstx, unsigned dsty, unsigned dstz,1163struct pipe_resource *src,1164unsigned src_level,1165const struct pipe_box *src_box)1166{1167struct virgl_context *vctx = virgl_context(ctx);1168struct virgl_resource *dres = virgl_resource(dst);1169struct virgl_resource *sres = virgl_resource(src);11701171if (dres->b.target == PIPE_BUFFER)1172util_range_add(&dres->b, &dres->valid_buffer_range, dstx, dstx + src_box->width);1173virgl_resource_dirty(dres, dst_level);11741175virgl_encode_resource_copy_region(vctx, dres,1176dst_level, dstx, dsty, dstz,1177sres, src_level,1178src_box);1179}11801181static void1182virgl_flush_resource(struct pipe_context *pipe,1183struct pipe_resource *resource)1184{1185}11861187static void virgl_blit(struct pipe_context *ctx,1188const struct pipe_blit_info *blit)1189{1190struct virgl_context *vctx = virgl_context(ctx);1191struct virgl_resource *dres = virgl_resource(blit->dst.resource);1192struct virgl_resource *sres = virgl_resource(blit->src.resource);11931194assert(ctx->screen->get_param(ctx->screen,1195PIPE_CAP_DEST_SURFACE_SRGB_CONTROL) ||1196(util_format_is_srgb(blit->dst.resource->format) ==1197util_format_is_srgb(blit->dst.format)));11981199virgl_resource_dirty(dres, blit->dst.level);1200virgl_encode_blit(vctx, dres, sres,1201blit);1202}12031204static void virgl_set_hw_atomic_buffers(struct pipe_context *ctx,1205unsigned start_slot,1206unsigned count,1207const struct pipe_shader_buffer *buffers)1208{1209struct virgl_context *vctx = virgl_context(ctx);12101211vctx->atomic_buffer_enabled_mask &= ~u_bit_consecutive(start_slot, count);1212for (unsigned i = 0; i < count; i++) {1213unsigned idx = start_slot + i;1214if (buffers && buffers[i].buffer) {1215struct virgl_resource *res = virgl_resource(buffers[i].buffer);1216res->bind_history |= PIPE_BIND_SHADER_BUFFER;12171218pipe_resource_reference(&vctx->atomic_buffers[idx].buffer,1219buffers[i].buffer);1220vctx->atomic_buffers[idx] = buffers[i];1221vctx->atomic_buffer_enabled_mask |= 1 << idx;1222} else {1223pipe_resource_reference(&vctx->atomic_buffers[idx].buffer, NULL);1224}1225}12261227virgl_encode_set_hw_atomic_buffers(vctx, start_slot, count, buffers);1228}12291230static void virgl_set_shader_buffers(struct pipe_context *ctx,1231enum pipe_shader_type shader,1232unsigned start_slot, unsigned count,1233const struct pipe_shader_buffer *buffers,1234unsigned writable_bitmask)1235{1236struct virgl_context *vctx = virgl_context(ctx);1237struct virgl_screen *rs = virgl_screen(ctx->screen);1238struct virgl_shader_binding_state *binding =1239&vctx->shader_bindings[shader];12401241binding->ssbo_enabled_mask &= ~u_bit_consecutive(start_slot, count);1242for (unsigned i = 0; i < count; i++) {1243unsigned idx = start_slot + i;1244if (buffers && buffers[i].buffer) {1245struct virgl_resource *res = virgl_resource(buffers[i].buffer);1246res->bind_history |= PIPE_BIND_SHADER_BUFFER;12471248pipe_resource_reference(&binding->ssbos[idx].buffer, buffers[i].buffer);1249binding->ssbos[idx] = buffers[i];1250binding->ssbo_enabled_mask |= 1 << idx;1251} else {1252pipe_resource_reference(&binding->ssbos[idx].buffer, NULL);1253}1254}12551256uint32_t max_shader_buffer = (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE) ?1257rs->caps.caps.v2.max_shader_buffer_frag_compute :1258rs->caps.caps.v2.max_shader_buffer_other_stages;1259if (!max_shader_buffer)1260return;1261virgl_encode_set_shader_buffers(vctx, shader, start_slot, count, buffers);1262}12631264static void virgl_create_fence_fd(struct pipe_context *ctx,1265struct pipe_fence_handle **fence,1266int fd,1267enum pipe_fd_type type)1268{1269assert(type == PIPE_FD_TYPE_NATIVE_SYNC);1270struct virgl_screen *rs = virgl_screen(ctx->screen);12711272if (rs->vws->cs_create_fence)1273*fence = rs->vws->cs_create_fence(rs->vws, fd);1274}12751276static void virgl_fence_server_sync(struct pipe_context *ctx,1277struct pipe_fence_handle *fence)1278{1279struct virgl_context *vctx = virgl_context(ctx);1280struct virgl_screen *rs = virgl_screen(ctx->screen);12811282if (rs->vws->fence_server_sync)1283rs->vws->fence_server_sync(rs->vws, vctx->cbuf, fence);1284}12851286static void virgl_set_shader_images(struct pipe_context *ctx,1287enum pipe_shader_type shader,1288unsigned start_slot, unsigned count,1289unsigned unbind_num_trailing_slots,1290const struct pipe_image_view *images)1291{1292struct virgl_context *vctx = virgl_context(ctx);1293struct virgl_screen *rs = virgl_screen(ctx->screen);1294struct virgl_shader_binding_state *binding =1295&vctx->shader_bindings[shader];12961297binding->image_enabled_mask &= ~u_bit_consecutive(start_slot, count);1298for (unsigned i = 0; i < count; i++) {1299unsigned idx = start_slot + i;1300if (images && images[i].resource) {1301struct virgl_resource *res = virgl_resource(images[i].resource);1302res->bind_history |= PIPE_BIND_SHADER_IMAGE;13031304pipe_resource_reference(&binding->images[idx].resource,1305images[i].resource);1306binding->images[idx] = images[i];1307binding->image_enabled_mask |= 1 << idx;1308} else {1309pipe_resource_reference(&binding->images[idx].resource, NULL);1310}1311}13121313uint32_t max_shader_images = (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE) ?1314rs->caps.caps.v2.max_shader_image_frag_compute :1315rs->caps.caps.v2.max_shader_image_other_stages;1316if (!max_shader_images)1317return;1318virgl_encode_set_shader_images(vctx, shader, start_slot, count, images);13191320if (unbind_num_trailing_slots) {1321virgl_set_shader_images(ctx, shader, start_slot + count,1322unbind_num_trailing_slots, 0, NULL);1323}1324}13251326static void virgl_memory_barrier(struct pipe_context *ctx,1327unsigned flags)1328{1329struct virgl_context *vctx = virgl_context(ctx);1330struct virgl_screen *rs = virgl_screen(ctx->screen);13311332if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_MEMORY_BARRIER))1333return;1334virgl_encode_memory_barrier(vctx, flags);1335}13361337static void *virgl_create_compute_state(struct pipe_context *ctx,1338const struct pipe_compute_state *state)1339{1340struct virgl_context *vctx = virgl_context(ctx);1341uint32_t handle;1342const struct tgsi_token *new_tokens = state->prog;1343struct pipe_stream_output_info so_info = {};1344int ret;13451346handle = virgl_object_assign_handle();1347ret = virgl_encode_shader_state(vctx, handle, PIPE_SHADER_COMPUTE,1348&so_info,1349state->req_local_mem,1350new_tokens);1351if (ret) {1352return NULL;1353}13541355return (void *)(unsigned long)handle;1356}13571358static void virgl_bind_compute_state(struct pipe_context *ctx, void *state)1359{1360uint32_t handle = (unsigned long)state;1361struct virgl_context *vctx = virgl_context(ctx);13621363virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_COMPUTE);1364}13651366static void virgl_delete_compute_state(struct pipe_context *ctx, void *state)1367{1368uint32_t handle = (unsigned long)state;1369struct virgl_context *vctx = virgl_context(ctx);13701371virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);1372}13731374static void virgl_launch_grid(struct pipe_context *ctx,1375const struct pipe_grid_info *info)1376{1377struct virgl_context *vctx = virgl_context(ctx);13781379if (!vctx->num_compute)1380virgl_reemit_compute_resources(vctx);1381vctx->num_compute++;13821383virgl_encode_launch_grid(vctx, info);1384}13851386static void1387virgl_release_shader_binding(struct virgl_context *vctx,1388enum pipe_shader_type shader_type)1389{1390struct virgl_shader_binding_state *binding =1391&vctx->shader_bindings[shader_type];13921393while (binding->view_enabled_mask) {1394int i = u_bit_scan(&binding->view_enabled_mask);1395pipe_sampler_view_reference(1396(struct pipe_sampler_view **)&binding->views[i], NULL);1397}13981399while (binding->ubo_enabled_mask) {1400int i = u_bit_scan(&binding->ubo_enabled_mask);1401pipe_resource_reference(&binding->ubos[i].buffer, NULL);1402}14031404while (binding->ssbo_enabled_mask) {1405int i = u_bit_scan(&binding->ssbo_enabled_mask);1406pipe_resource_reference(&binding->ssbos[i].buffer, NULL);1407}14081409while (binding->image_enabled_mask) {1410int i = u_bit_scan(&binding->image_enabled_mask);1411pipe_resource_reference(&binding->images[i].resource, NULL);1412}1413}14141415static void1416virgl_emit_string_marker(struct pipe_context *ctx, const char *message, int len)1417{1418struct virgl_context *vctx = virgl_context(ctx);1419virgl_encode_emit_string_marker(vctx, message, len);1420}14211422static void1423virgl_context_destroy( struct pipe_context *ctx )1424{1425struct virgl_context *vctx = virgl_context(ctx);1426struct virgl_screen *rs = virgl_screen(ctx->screen);1427enum pipe_shader_type shader_type;14281429vctx->framebuffer.zsbuf = NULL;1430vctx->framebuffer.nr_cbufs = 0;1431virgl_encoder_destroy_sub_ctx(vctx, vctx->hw_sub_ctx_id);1432virgl_flush_eq(vctx, vctx, NULL);14331434for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++)1435virgl_release_shader_binding(vctx, shader_type);14361437while (vctx->atomic_buffer_enabled_mask) {1438int i = u_bit_scan(&vctx->atomic_buffer_enabled_mask);1439pipe_resource_reference(&vctx->atomic_buffers[i].buffer, NULL);1440}14411442rs->vws->cmd_buf_destroy(vctx->cbuf);1443if (vctx->uploader)1444u_upload_destroy(vctx->uploader);1445if (vctx->supports_staging)1446virgl_staging_destroy(&vctx->staging);1447util_primconvert_destroy(vctx->primconvert);1448virgl_transfer_queue_fini(&vctx->queue);14491450slab_destroy_child(&vctx->transfer_pool);1451FREE(vctx);1452}14531454static void virgl_get_sample_position(struct pipe_context *ctx,1455unsigned sample_count,1456unsigned index,1457float *out_value)1458{1459struct virgl_context *vctx = virgl_context(ctx);1460struct virgl_screen *vs = virgl_screen(vctx->base.screen);14611462if (sample_count > vs->caps.caps.v1.max_samples) {1463debug_printf("VIRGL: requested %d MSAA samples, but only %d supported\n",1464sample_count, vs->caps.caps.v1.max_samples);1465return;1466}14671468/* The following is basically copied from dri/i965gen6_get_sample_position1469* The only addition is that we hold the msaa positions for all sample1470* counts in a flat array. */1471uint32_t bits = 0;1472if (sample_count == 1) {1473out_value[0] = out_value[1] = 0.5f;1474return;1475} else if (sample_count == 2) {1476bits = vs->caps.caps.v2.sample_locations[0] >> (8 * index);1477} else if (sample_count <= 4) {1478bits = vs->caps.caps.v2.sample_locations[1] >> (8 * index);1479} else if (sample_count <= 8) {1480bits = vs->caps.caps.v2.sample_locations[2 + (index >> 2)] >> (8 * (index & 3));1481} else if (sample_count <= 16) {1482bits = vs->caps.caps.v2.sample_locations[4 + (index >> 2)] >> (8 * (index & 3));1483}1484out_value[0] = ((bits >> 4) & 0xf) / 16.0f;1485out_value[1] = (bits & 0xf) / 16.0f;14861487if (virgl_debug & VIRGL_DEBUG_VERBOSE)1488debug_printf("VIRGL: sample postion [%2d/%2d] = (%f, %f)\n",1489index, sample_count, out_value[0], out_value[1]);1490}14911492static void virgl_send_tweaks(struct virgl_context *vctx, struct virgl_screen *rs)1493{1494if (rs->tweak_gles_emulate_bgra)1495virgl_encode_tweak(vctx, virgl_tweak_gles_brga_emulate, 1);14961497if (rs->tweak_gles_apply_bgra_dest_swizzle)1498virgl_encode_tweak(vctx, virgl_tweak_gles_brga_apply_dest_swizzle, 1);14991500if (rs->tweak_gles_tf3_value > 0)1501virgl_encode_tweak(vctx, virgl_tweak_gles_tf3_samples_passes_multiplier,1502rs->tweak_gles_tf3_value);1503}15041505struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,1506void *priv,1507unsigned flags)1508{1509struct virgl_context *vctx;1510struct virgl_screen *rs = virgl_screen(pscreen);1511vctx = CALLOC_STRUCT(virgl_context);1512const char *host_debug_flagstring;15131514vctx->cbuf = rs->vws->cmd_buf_create(rs->vws, VIRGL_MAX_CMDBUF_DWORDS);1515if (!vctx->cbuf) {1516FREE(vctx);1517return NULL;1518}15191520vctx->base.destroy = virgl_context_destroy;1521vctx->base.create_surface = virgl_create_surface;1522vctx->base.surface_destroy = virgl_surface_destroy;1523vctx->base.set_framebuffer_state = virgl_set_framebuffer_state;1524vctx->base.create_blend_state = virgl_create_blend_state;1525vctx->base.bind_blend_state = virgl_bind_blend_state;1526vctx->base.delete_blend_state = virgl_delete_blend_state;1527vctx->base.create_depth_stencil_alpha_state = virgl_create_depth_stencil_alpha_state;1528vctx->base.bind_depth_stencil_alpha_state = virgl_bind_depth_stencil_alpha_state;1529vctx->base.delete_depth_stencil_alpha_state = virgl_delete_depth_stencil_alpha_state;1530vctx->base.create_rasterizer_state = virgl_create_rasterizer_state;1531vctx->base.bind_rasterizer_state = virgl_bind_rasterizer_state;1532vctx->base.delete_rasterizer_state = virgl_delete_rasterizer_state;15331534vctx->base.set_viewport_states = virgl_set_viewport_states;1535vctx->base.create_vertex_elements_state = virgl_create_vertex_elements_state;1536vctx->base.bind_vertex_elements_state = virgl_bind_vertex_elements_state;1537vctx->base.delete_vertex_elements_state = virgl_delete_vertex_elements_state;1538vctx->base.set_vertex_buffers = virgl_set_vertex_buffers;1539vctx->base.set_constant_buffer = virgl_set_constant_buffer;15401541vctx->base.set_tess_state = virgl_set_tess_state;1542vctx->base.create_vs_state = virgl_create_vs_state;1543vctx->base.create_tcs_state = virgl_create_tcs_state;1544vctx->base.create_tes_state = virgl_create_tes_state;1545vctx->base.create_gs_state = virgl_create_gs_state;1546vctx->base.create_fs_state = virgl_create_fs_state;15471548vctx->base.bind_vs_state = virgl_bind_vs_state;1549vctx->base.bind_tcs_state = virgl_bind_tcs_state;1550vctx->base.bind_tes_state = virgl_bind_tes_state;1551vctx->base.bind_gs_state = virgl_bind_gs_state;1552vctx->base.bind_fs_state = virgl_bind_fs_state;15531554vctx->base.delete_vs_state = virgl_delete_vs_state;1555vctx->base.delete_tcs_state = virgl_delete_tcs_state;1556vctx->base.delete_tes_state = virgl_delete_tes_state;1557vctx->base.delete_gs_state = virgl_delete_gs_state;1558vctx->base.delete_fs_state = virgl_delete_fs_state;15591560vctx->base.create_compute_state = virgl_create_compute_state;1561vctx->base.bind_compute_state = virgl_bind_compute_state;1562vctx->base.delete_compute_state = virgl_delete_compute_state;1563vctx->base.launch_grid = virgl_launch_grid;15641565vctx->base.clear = virgl_clear;1566vctx->base.clear_texture = virgl_clear_texture;1567vctx->base.draw_vbo = virgl_draw_vbo;1568vctx->base.flush = virgl_flush_from_st;1569vctx->base.screen = pscreen;1570vctx->base.create_sampler_view = virgl_create_sampler_view;1571vctx->base.sampler_view_destroy = virgl_destroy_sampler_view;1572vctx->base.set_sampler_views = virgl_set_sampler_views;1573vctx->base.texture_barrier = virgl_texture_barrier;15741575vctx->base.create_sampler_state = virgl_create_sampler_state;1576vctx->base.delete_sampler_state = virgl_delete_sampler_state;1577vctx->base.bind_sampler_states = virgl_bind_sampler_states;15781579vctx->base.set_polygon_stipple = virgl_set_polygon_stipple;1580vctx->base.set_scissor_states = virgl_set_scissor_states;1581vctx->base.set_sample_mask = virgl_set_sample_mask;1582vctx->base.set_min_samples = virgl_set_min_samples;1583vctx->base.set_stencil_ref = virgl_set_stencil_ref;1584vctx->base.set_clip_state = virgl_set_clip_state;15851586vctx->base.set_blend_color = virgl_set_blend_color;15871588vctx->base.get_sample_position = virgl_get_sample_position;15891590vctx->base.resource_copy_region = virgl_resource_copy_region;1591vctx->base.flush_resource = virgl_flush_resource;1592vctx->base.blit = virgl_blit;1593vctx->base.create_fence_fd = virgl_create_fence_fd;1594vctx->base.fence_server_sync = virgl_fence_server_sync;15951596vctx->base.set_shader_buffers = virgl_set_shader_buffers;1597vctx->base.set_hw_atomic_buffers = virgl_set_hw_atomic_buffers;1598vctx->base.set_shader_images = virgl_set_shader_images;1599vctx->base.memory_barrier = virgl_memory_barrier;1600vctx->base.emit_string_marker = virgl_emit_string_marker;16011602virgl_init_context_resource_functions(&vctx->base);1603virgl_init_query_functions(vctx);1604virgl_init_so_functions(vctx);16051606slab_create_child(&vctx->transfer_pool, &rs->transfer_pool);1607virgl_transfer_queue_init(&vctx->queue, vctx);1608vctx->encoded_transfers = (rs->vws->supports_encoded_transfers &&1609(rs->caps.caps.v2.capability_bits & VIRGL_CAP_TRANSFER));16101611/* Reserve some space for transfers. */1612if (vctx->encoded_transfers)1613vctx->cbuf->cdw = VIRGL_MAX_TBUF_DWORDS;16141615vctx->primconvert = util_primconvert_create(&vctx->base, rs->caps.caps.v1.prim_mask);1616vctx->uploader = u_upload_create(&vctx->base, 1024 * 1024,1617PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_STREAM, 0);1618if (!vctx->uploader)1619goto fail;1620vctx->base.stream_uploader = vctx->uploader;1621vctx->base.const_uploader = vctx->uploader;16221623/* We use a special staging buffer as the source of copy transfers. */1624if ((rs->caps.caps.v2.capability_bits & VIRGL_CAP_COPY_TRANSFER) &&1625vctx->encoded_transfers) {1626virgl_staging_init(&vctx->staging, &vctx->base, 1024 * 1024);1627vctx->supports_staging = true;1628}16291630vctx->hw_sub_ctx_id = p_atomic_inc_return(&rs->sub_ctx_id);1631virgl_encoder_create_sub_ctx(vctx, vctx->hw_sub_ctx_id);16321633virgl_encoder_set_sub_ctx(vctx, vctx->hw_sub_ctx_id);16341635if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_GUEST_MAY_INIT_LOG) {1636host_debug_flagstring = getenv("VIRGL_HOST_DEBUG");1637if (host_debug_flagstring)1638virgl_encode_host_debug_flagstring(vctx, host_debug_flagstring);1639}16401641if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_APP_TWEAK_SUPPORT)1642virgl_send_tweaks(vctx, rs);16431644return &vctx->base;1645fail:1646virgl_context_destroy(&vctx->base);1647return NULL;1648}164916501651