1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2014, 2015 Red Hat. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <libsync.h> 25bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "compiler/nir/nir.h" 28bf215546Sopenharmony_ci#include "pipe/p_context.h" 29bf215546Sopenharmony_ci#include "pipe/p_defines.h" 30bf215546Sopenharmony_ci#include "pipe/p_screen.h" 31bf215546Sopenharmony_ci#include "pipe/p_state.h" 32bf215546Sopenharmony_ci#include "nir/nir_to_tgsi.h" 33bf215546Sopenharmony_ci#include "util/u_draw.h" 34bf215546Sopenharmony_ci#include "util/u_inlines.h" 35bf215546Sopenharmony_ci#include "util/u_memory.h" 36bf215546Sopenharmony_ci#include "util/format/u_format.h" 37bf215546Sopenharmony_ci#include "util/u_prim.h" 38bf215546Sopenharmony_ci#include "util/u_transfer.h" 39bf215546Sopenharmony_ci#include "util/u_helpers.h" 40bf215546Sopenharmony_ci#include "util/slab.h" 41bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 42bf215546Sopenharmony_ci#include "util/u_blitter.h" 43bf215546Sopenharmony_ci#include "tgsi/tgsi_text.h" 44bf215546Sopenharmony_ci#include "indices/u_primconvert.h" 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci#include "virgl_encode.h" 47bf215546Sopenharmony_ci#include "virgl_context.h" 48bf215546Sopenharmony_ci#include "virtio-gpu/virgl_protocol.h" 49bf215546Sopenharmony_ci#include "virgl_resource.h" 50bf215546Sopenharmony_ci#include "virgl_screen.h" 51bf215546Sopenharmony_ci#include "virgl_staging_mgr.h" 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cistruct virgl_vertex_elements_state { 54bf215546Sopenharmony_ci uint32_t handle; 55bf215546Sopenharmony_ci uint8_t binding_map[PIPE_MAX_ATTRIBS]; 56bf215546Sopenharmony_ci uint8_t num_bindings; 57bf215546Sopenharmony_ci}; 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_cistatic uint32_t next_handle; 60bf215546Sopenharmony_ciuint32_t virgl_object_assign_handle(void) 61bf215546Sopenharmony_ci{ 62bf215546Sopenharmony_ci return p_atomic_inc_return(&next_handle); 63bf215546Sopenharmony_ci} 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_cibool 66bf215546Sopenharmony_civirgl_can_rebind_resource(struct virgl_context *vctx, 67bf215546Sopenharmony_ci struct pipe_resource *res) 68bf215546Sopenharmony_ci{ 69bf215546Sopenharmony_ci /* We cannot rebind resources that are referenced by host objects, which 70bf215546Sopenharmony_ci * are 71bf215546Sopenharmony_ci * 72bf215546Sopenharmony_ci * - VIRGL_OBJECT_SURFACE 73bf215546Sopenharmony_ci * - VIRGL_OBJECT_SAMPLER_VIEW 74bf215546Sopenharmony_ci * - VIRGL_OBJECT_STREAMOUT_TARGET 75bf215546Sopenharmony_ci * 76bf215546Sopenharmony_ci * Because surfaces cannot be created from buffers, we require the resource 77bf215546Sopenharmony_ci * to be a buffer instead (and avoid tracking VIRGL_OBJECT_SURFACE binds). 78bf215546Sopenharmony_ci */ 79bf215546Sopenharmony_ci const unsigned unsupported_bind = (PIPE_BIND_SAMPLER_VIEW | 80bf215546Sopenharmony_ci PIPE_BIND_STREAM_OUTPUT); 81bf215546Sopenharmony_ci const unsigned bind_history = virgl_resource(res)->bind_history; 82bf215546Sopenharmony_ci return res->target == PIPE_BUFFER && !(bind_history & unsupported_bind); 83bf215546Sopenharmony_ci} 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_civoid 86bf215546Sopenharmony_civirgl_rebind_resource(struct virgl_context *vctx, 87bf215546Sopenharmony_ci struct pipe_resource *res) 88bf215546Sopenharmony_ci{ 89bf215546Sopenharmony_ci /* Queries use internally created buffers and do not go through transfers. 90bf215546Sopenharmony_ci * Index buffers are not bindable. They are not tracked. 91bf215546Sopenharmony_ci */ 92bf215546Sopenharmony_ci ASSERTED const unsigned tracked_bind = (PIPE_BIND_VERTEX_BUFFER | 93bf215546Sopenharmony_ci PIPE_BIND_CONSTANT_BUFFER | 94bf215546Sopenharmony_ci PIPE_BIND_SHADER_BUFFER | 95bf215546Sopenharmony_ci PIPE_BIND_SHADER_IMAGE); 96bf215546Sopenharmony_ci const unsigned bind_history = virgl_resource(res)->bind_history; 97bf215546Sopenharmony_ci unsigned i; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci assert(virgl_can_rebind_resource(vctx, res) && 100bf215546Sopenharmony_ci (bind_history & tracked_bind) == bind_history); 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci if (bind_history & PIPE_BIND_VERTEX_BUFFER) { 103bf215546Sopenharmony_ci for (i = 0; i < vctx->num_vertex_buffers; i++) { 104bf215546Sopenharmony_ci if (vctx->vertex_buffer[i].buffer.resource == res) { 105bf215546Sopenharmony_ci vctx->vertex_array_dirty = true; 106bf215546Sopenharmony_ci break; 107bf215546Sopenharmony_ci } 108bf215546Sopenharmony_ci } 109bf215546Sopenharmony_ci } 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci if (bind_history & PIPE_BIND_SHADER_BUFFER) { 112bf215546Sopenharmony_ci uint32_t remaining_mask = vctx->atomic_buffer_enabled_mask; 113bf215546Sopenharmony_ci while (remaining_mask) { 114bf215546Sopenharmony_ci int i = u_bit_scan(&remaining_mask); 115bf215546Sopenharmony_ci if (vctx->atomic_buffers[i].buffer == res) { 116bf215546Sopenharmony_ci const struct pipe_shader_buffer *abo = &vctx->atomic_buffers[i]; 117bf215546Sopenharmony_ci virgl_encode_set_hw_atomic_buffers(vctx, i, 1, abo); 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci } 120bf215546Sopenharmony_ci } 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci /* check per-stage shader bindings */ 123bf215546Sopenharmony_ci if (bind_history & (PIPE_BIND_CONSTANT_BUFFER | 124bf215546Sopenharmony_ci PIPE_BIND_SHADER_BUFFER | 125bf215546Sopenharmony_ci PIPE_BIND_SHADER_IMAGE)) { 126bf215546Sopenharmony_ci enum pipe_shader_type shader_type; 127bf215546Sopenharmony_ci for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) { 128bf215546Sopenharmony_ci const struct virgl_shader_binding_state *binding = 129bf215546Sopenharmony_ci &vctx->shader_bindings[shader_type]; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci if (bind_history & PIPE_BIND_CONSTANT_BUFFER) { 132bf215546Sopenharmony_ci uint32_t remaining_mask = binding->ubo_enabled_mask; 133bf215546Sopenharmony_ci while (remaining_mask) { 134bf215546Sopenharmony_ci int i = u_bit_scan(&remaining_mask); 135bf215546Sopenharmony_ci if (binding->ubos[i].buffer == res) { 136bf215546Sopenharmony_ci const struct pipe_constant_buffer *ubo = &binding->ubos[i]; 137bf215546Sopenharmony_ci virgl_encoder_set_uniform_buffer(vctx, shader_type, i, 138bf215546Sopenharmony_ci ubo->buffer_offset, 139bf215546Sopenharmony_ci ubo->buffer_size, 140bf215546Sopenharmony_ci virgl_resource(res)); 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci } 143bf215546Sopenharmony_ci } 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci if (bind_history & PIPE_BIND_SHADER_BUFFER) { 146bf215546Sopenharmony_ci uint32_t remaining_mask = binding->ssbo_enabled_mask; 147bf215546Sopenharmony_ci while (remaining_mask) { 148bf215546Sopenharmony_ci int i = u_bit_scan(&remaining_mask); 149bf215546Sopenharmony_ci if (binding->ssbos[i].buffer == res) { 150bf215546Sopenharmony_ci const struct pipe_shader_buffer *ssbo = &binding->ssbos[i]; 151bf215546Sopenharmony_ci virgl_encode_set_shader_buffers(vctx, shader_type, i, 1, 152bf215546Sopenharmony_ci ssbo); 153bf215546Sopenharmony_ci } 154bf215546Sopenharmony_ci } 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci if (bind_history & PIPE_BIND_SHADER_IMAGE) { 158bf215546Sopenharmony_ci uint32_t remaining_mask = binding->image_enabled_mask; 159bf215546Sopenharmony_ci while (remaining_mask) { 160bf215546Sopenharmony_ci int i = u_bit_scan(&remaining_mask); 161bf215546Sopenharmony_ci if (binding->images[i].resource == res) { 162bf215546Sopenharmony_ci const struct pipe_image_view *image = &binding->images[i]; 163bf215546Sopenharmony_ci virgl_encode_set_shader_images(vctx, shader_type, i, 1, 164bf215546Sopenharmony_ci image); 165bf215546Sopenharmony_ci } 166bf215546Sopenharmony_ci } 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci } 170bf215546Sopenharmony_ci} 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_cistatic void virgl_attach_res_framebuffer(struct virgl_context *vctx) 173bf215546Sopenharmony_ci{ 174bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 175bf215546Sopenharmony_ci struct pipe_surface *surf; 176bf215546Sopenharmony_ci struct virgl_resource *res; 177bf215546Sopenharmony_ci unsigned i; 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci surf = vctx->framebuffer.zsbuf; 180bf215546Sopenharmony_ci if (surf) { 181bf215546Sopenharmony_ci res = virgl_resource(surf->texture); 182bf215546Sopenharmony_ci if (res) { 183bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 184bf215546Sopenharmony_ci virgl_resource_dirty(res, surf->u.tex.level); 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci } 187bf215546Sopenharmony_ci for (i = 0; i < vctx->framebuffer.nr_cbufs; i++) { 188bf215546Sopenharmony_ci surf = vctx->framebuffer.cbufs[i]; 189bf215546Sopenharmony_ci if (surf) { 190bf215546Sopenharmony_ci res = virgl_resource(surf->texture); 191bf215546Sopenharmony_ci if (res) { 192bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 193bf215546Sopenharmony_ci virgl_resource_dirty(res, surf->u.tex.level); 194bf215546Sopenharmony_ci } 195bf215546Sopenharmony_ci } 196bf215546Sopenharmony_ci } 197bf215546Sopenharmony_ci} 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_cistatic void virgl_attach_res_sampler_views(struct virgl_context *vctx, 200bf215546Sopenharmony_ci enum pipe_shader_type shader_type) 201bf215546Sopenharmony_ci{ 202bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 203bf215546Sopenharmony_ci const struct virgl_shader_binding_state *binding = 204bf215546Sopenharmony_ci &vctx->shader_bindings[shader_type]; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci for (int i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; ++i) { 207bf215546Sopenharmony_ci if (binding->views[i] && binding->views[i]->texture) { 208bf215546Sopenharmony_ci struct virgl_resource *res = virgl_resource(binding->views[i]->texture); 209bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci } 212bf215546Sopenharmony_ci} 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_cistatic void virgl_attach_res_vertex_buffers(struct virgl_context *vctx) 215bf215546Sopenharmony_ci{ 216bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 217bf215546Sopenharmony_ci struct virgl_resource *res; 218bf215546Sopenharmony_ci unsigned i; 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci for (i = 0; i < vctx->num_vertex_buffers; i++) { 221bf215546Sopenharmony_ci res = virgl_resource(vctx->vertex_buffer[i].buffer.resource); 222bf215546Sopenharmony_ci if (res) 223bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci} 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_cistatic void virgl_attach_res_index_buffer(struct virgl_context *vctx, 228bf215546Sopenharmony_ci struct virgl_indexbuf *ib) 229bf215546Sopenharmony_ci{ 230bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 231bf215546Sopenharmony_ci struct virgl_resource *res; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci res = virgl_resource(ib->buffer); 234bf215546Sopenharmony_ci if (res) 235bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 236bf215546Sopenharmony_ci} 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_cistatic void virgl_attach_res_so_targets(struct virgl_context *vctx) 239bf215546Sopenharmony_ci{ 240bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 241bf215546Sopenharmony_ci struct virgl_resource *res; 242bf215546Sopenharmony_ci unsigned i; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci for (i = 0; i < vctx->num_so_targets; i++) { 245bf215546Sopenharmony_ci res = virgl_resource(vctx->so_targets[i].base.buffer); 246bf215546Sopenharmony_ci if (res) 247bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 248bf215546Sopenharmony_ci } 249bf215546Sopenharmony_ci} 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_cistatic void virgl_attach_res_uniform_buffers(struct virgl_context *vctx, 252bf215546Sopenharmony_ci enum pipe_shader_type shader_type) 253bf215546Sopenharmony_ci{ 254bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 255bf215546Sopenharmony_ci const struct virgl_shader_binding_state *binding = 256bf215546Sopenharmony_ci &vctx->shader_bindings[shader_type]; 257bf215546Sopenharmony_ci uint32_t remaining_mask = binding->ubo_enabled_mask; 258bf215546Sopenharmony_ci struct virgl_resource *res; 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci while (remaining_mask) { 261bf215546Sopenharmony_ci int i = u_bit_scan(&remaining_mask); 262bf215546Sopenharmony_ci res = virgl_resource(binding->ubos[i].buffer); 263bf215546Sopenharmony_ci assert(res); 264bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 265bf215546Sopenharmony_ci } 266bf215546Sopenharmony_ci} 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_cistatic void virgl_attach_res_shader_buffers(struct virgl_context *vctx, 269bf215546Sopenharmony_ci enum pipe_shader_type shader_type) 270bf215546Sopenharmony_ci{ 271bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 272bf215546Sopenharmony_ci const struct virgl_shader_binding_state *binding = 273bf215546Sopenharmony_ci &vctx->shader_bindings[shader_type]; 274bf215546Sopenharmony_ci uint32_t remaining_mask = binding->ssbo_enabled_mask; 275bf215546Sopenharmony_ci struct virgl_resource *res; 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci while (remaining_mask) { 278bf215546Sopenharmony_ci int i = u_bit_scan(&remaining_mask); 279bf215546Sopenharmony_ci res = virgl_resource(binding->ssbos[i].buffer); 280bf215546Sopenharmony_ci assert(res); 281bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci} 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_cistatic void virgl_attach_res_shader_images(struct virgl_context *vctx, 286bf215546Sopenharmony_ci enum pipe_shader_type shader_type) 287bf215546Sopenharmony_ci{ 288bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 289bf215546Sopenharmony_ci const struct virgl_shader_binding_state *binding = 290bf215546Sopenharmony_ci &vctx->shader_bindings[shader_type]; 291bf215546Sopenharmony_ci uint32_t remaining_mask = binding->image_enabled_mask; 292bf215546Sopenharmony_ci struct virgl_resource *res; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci while (remaining_mask) { 295bf215546Sopenharmony_ci int i = u_bit_scan(&remaining_mask); 296bf215546Sopenharmony_ci res = virgl_resource(binding->images[i].resource); 297bf215546Sopenharmony_ci assert(res); 298bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci} 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_cistatic void virgl_attach_res_atomic_buffers(struct virgl_context *vctx) 303bf215546Sopenharmony_ci{ 304bf215546Sopenharmony_ci struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; 305bf215546Sopenharmony_ci uint32_t remaining_mask = vctx->atomic_buffer_enabled_mask; 306bf215546Sopenharmony_ci struct virgl_resource *res; 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci while (remaining_mask) { 309bf215546Sopenharmony_ci int i = u_bit_scan(&remaining_mask); 310bf215546Sopenharmony_ci res = virgl_resource(vctx->atomic_buffers[i].buffer); 311bf215546Sopenharmony_ci assert(res); 312bf215546Sopenharmony_ci vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci} 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci/* 317bf215546Sopenharmony_ci * after flushing, the hw context still has a bunch of 318bf215546Sopenharmony_ci * resources bound, so we need to rebind those here. 319bf215546Sopenharmony_ci */ 320bf215546Sopenharmony_cistatic void virgl_reemit_draw_resources(struct virgl_context *vctx) 321bf215546Sopenharmony_ci{ 322bf215546Sopenharmony_ci enum pipe_shader_type shader_type; 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci /* reattach any flushed resources */ 325bf215546Sopenharmony_ci /* framebuffer, sampler views, vertex/index/uniform/stream buffers */ 326bf215546Sopenharmony_ci virgl_attach_res_framebuffer(vctx); 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci for (shader_type = 0; shader_type < PIPE_SHADER_COMPUTE; shader_type++) { 329bf215546Sopenharmony_ci virgl_attach_res_sampler_views(vctx, shader_type); 330bf215546Sopenharmony_ci virgl_attach_res_uniform_buffers(vctx, shader_type); 331bf215546Sopenharmony_ci virgl_attach_res_shader_buffers(vctx, shader_type); 332bf215546Sopenharmony_ci virgl_attach_res_shader_images(vctx, shader_type); 333bf215546Sopenharmony_ci } 334bf215546Sopenharmony_ci virgl_attach_res_atomic_buffers(vctx); 335bf215546Sopenharmony_ci virgl_attach_res_vertex_buffers(vctx); 336bf215546Sopenharmony_ci virgl_attach_res_so_targets(vctx); 337bf215546Sopenharmony_ci} 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_cistatic void virgl_reemit_compute_resources(struct virgl_context *vctx) 340bf215546Sopenharmony_ci{ 341bf215546Sopenharmony_ci virgl_attach_res_sampler_views(vctx, PIPE_SHADER_COMPUTE); 342bf215546Sopenharmony_ci virgl_attach_res_uniform_buffers(vctx, PIPE_SHADER_COMPUTE); 343bf215546Sopenharmony_ci virgl_attach_res_shader_buffers(vctx, PIPE_SHADER_COMPUTE); 344bf215546Sopenharmony_ci virgl_attach_res_shader_images(vctx, PIPE_SHADER_COMPUTE); 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci virgl_attach_res_atomic_buffers(vctx); 347bf215546Sopenharmony_ci} 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_cistatic struct pipe_surface *virgl_create_surface(struct pipe_context *ctx, 350bf215546Sopenharmony_ci struct pipe_resource *resource, 351bf215546Sopenharmony_ci const struct pipe_surface *templ) 352bf215546Sopenharmony_ci{ 353bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 354bf215546Sopenharmony_ci struct virgl_surface *surf; 355bf215546Sopenharmony_ci struct virgl_resource *res = virgl_resource(resource); 356bf215546Sopenharmony_ci uint32_t handle; 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci /* no support for buffer surfaces */ 359bf215546Sopenharmony_ci if (resource->target == PIPE_BUFFER) 360bf215546Sopenharmony_ci return NULL; 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci surf = CALLOC_STRUCT(virgl_surface); 363bf215546Sopenharmony_ci if (!surf) 364bf215546Sopenharmony_ci return NULL; 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci assert(ctx->screen->get_param(ctx->screen, 367bf215546Sopenharmony_ci PIPE_CAP_DEST_SURFACE_SRGB_CONTROL) || 368bf215546Sopenharmony_ci (util_format_is_srgb(templ->format) == 369bf215546Sopenharmony_ci util_format_is_srgb(resource->format))); 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci virgl_resource_dirty(res, 0); 372bf215546Sopenharmony_ci handle = virgl_object_assign_handle(); 373bf215546Sopenharmony_ci pipe_reference_init(&surf->base.reference, 1); 374bf215546Sopenharmony_ci pipe_resource_reference(&surf->base.texture, resource); 375bf215546Sopenharmony_ci surf->base.context = ctx; 376bf215546Sopenharmony_ci surf->base.format = templ->format; 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci surf->base.width = u_minify(resource->width0, templ->u.tex.level); 379bf215546Sopenharmony_ci surf->base.height = u_minify(resource->height0, templ->u.tex.level); 380bf215546Sopenharmony_ci surf->base.u.tex.level = templ->u.tex.level; 381bf215546Sopenharmony_ci surf->base.u.tex.first_layer = templ->u.tex.first_layer; 382bf215546Sopenharmony_ci surf->base.u.tex.last_layer = templ->u.tex.last_layer; 383bf215546Sopenharmony_ci surf->base.nr_samples = templ->nr_samples; 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci virgl_encoder_create_surface(vctx, handle, res, &surf->base); 386bf215546Sopenharmony_ci surf->handle = handle; 387bf215546Sopenharmony_ci return &surf->base; 388bf215546Sopenharmony_ci} 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_cistatic void virgl_surface_destroy(struct pipe_context *ctx, 391bf215546Sopenharmony_ci struct pipe_surface *psurf) 392bf215546Sopenharmony_ci{ 393bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 394bf215546Sopenharmony_ci struct virgl_surface *surf = virgl_surface(psurf); 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci pipe_resource_reference(&surf->base.texture, NULL); 397bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, surf->handle, VIRGL_OBJECT_SURFACE); 398bf215546Sopenharmony_ci FREE(surf); 399bf215546Sopenharmony_ci} 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_cistatic void *virgl_create_blend_state(struct pipe_context *ctx, 402bf215546Sopenharmony_ci const struct pipe_blend_state *blend_state) 403bf215546Sopenharmony_ci{ 404bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 405bf215546Sopenharmony_ci uint32_t handle; 406bf215546Sopenharmony_ci handle = virgl_object_assign_handle(); 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci virgl_encode_blend_state(vctx, handle, blend_state); 409bf215546Sopenharmony_ci return (void *)(unsigned long)handle; 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci} 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_cistatic void virgl_bind_blend_state(struct pipe_context *ctx, 414bf215546Sopenharmony_ci void *blend_state) 415bf215546Sopenharmony_ci{ 416bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 417bf215546Sopenharmony_ci uint32_t handle = (unsigned long)blend_state; 418bf215546Sopenharmony_ci virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_BLEND); 419bf215546Sopenharmony_ci} 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_cistatic void virgl_delete_blend_state(struct pipe_context *ctx, 422bf215546Sopenharmony_ci void *blend_state) 423bf215546Sopenharmony_ci{ 424bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 425bf215546Sopenharmony_ci uint32_t handle = (unsigned long)blend_state; 426bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_BLEND); 427bf215546Sopenharmony_ci} 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_cistatic void *virgl_create_depth_stencil_alpha_state(struct pipe_context *ctx, 430bf215546Sopenharmony_ci const struct pipe_depth_stencil_alpha_state *blend_state) 431bf215546Sopenharmony_ci{ 432bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 433bf215546Sopenharmony_ci uint32_t handle; 434bf215546Sopenharmony_ci handle = virgl_object_assign_handle(); 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci virgl_encode_dsa_state(vctx, handle, blend_state); 437bf215546Sopenharmony_ci return (void *)(unsigned long)handle; 438bf215546Sopenharmony_ci} 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_cistatic void virgl_bind_depth_stencil_alpha_state(struct pipe_context *ctx, 441bf215546Sopenharmony_ci void *blend_state) 442bf215546Sopenharmony_ci{ 443bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 444bf215546Sopenharmony_ci uint32_t handle = (unsigned long)blend_state; 445bf215546Sopenharmony_ci virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_DSA); 446bf215546Sopenharmony_ci} 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_cistatic void virgl_delete_depth_stencil_alpha_state(struct pipe_context *ctx, 449bf215546Sopenharmony_ci void *dsa_state) 450bf215546Sopenharmony_ci{ 451bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 452bf215546Sopenharmony_ci uint32_t handle = (unsigned long)dsa_state; 453bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_DSA); 454bf215546Sopenharmony_ci} 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_cistatic void *virgl_create_rasterizer_state(struct pipe_context *ctx, 457bf215546Sopenharmony_ci const struct pipe_rasterizer_state *rs_state) 458bf215546Sopenharmony_ci{ 459bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 460bf215546Sopenharmony_ci struct virgl_rasterizer_state *vrs = CALLOC_STRUCT(virgl_rasterizer_state); 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci if (!vrs) 463bf215546Sopenharmony_ci return NULL; 464bf215546Sopenharmony_ci vrs->rs = *rs_state; 465bf215546Sopenharmony_ci vrs->handle = virgl_object_assign_handle(); 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci assert(rs_state->depth_clip_near || 468bf215546Sopenharmony_ci virgl_screen(ctx->screen)->caps.caps.v1.bset.depth_clip_disable); 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci virgl_encode_rasterizer_state(vctx, vrs->handle, rs_state); 471bf215546Sopenharmony_ci return (void *)vrs; 472bf215546Sopenharmony_ci} 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_cistatic void virgl_bind_rasterizer_state(struct pipe_context *ctx, 475bf215546Sopenharmony_ci void *rs_state) 476bf215546Sopenharmony_ci{ 477bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 478bf215546Sopenharmony_ci uint32_t handle = 0; 479bf215546Sopenharmony_ci if (rs_state) { 480bf215546Sopenharmony_ci struct virgl_rasterizer_state *vrs = rs_state; 481bf215546Sopenharmony_ci vctx->rs_state = *vrs; 482bf215546Sopenharmony_ci handle = vrs->handle; 483bf215546Sopenharmony_ci } 484bf215546Sopenharmony_ci virgl_encode_bind_object(vctx, handle, VIRGL_OBJECT_RASTERIZER); 485bf215546Sopenharmony_ci} 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_cistatic void virgl_delete_rasterizer_state(struct pipe_context *ctx, 488bf215546Sopenharmony_ci void *rs_state) 489bf215546Sopenharmony_ci{ 490bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 491bf215546Sopenharmony_ci struct virgl_rasterizer_state *vrs = rs_state; 492bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, vrs->handle, VIRGL_OBJECT_RASTERIZER); 493bf215546Sopenharmony_ci FREE(vrs); 494bf215546Sopenharmony_ci} 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_cistatic void virgl_set_framebuffer_state(struct pipe_context *ctx, 497bf215546Sopenharmony_ci const struct pipe_framebuffer_state *state) 498bf215546Sopenharmony_ci{ 499bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci vctx->framebuffer = *state; 502bf215546Sopenharmony_ci virgl_encoder_set_framebuffer_state(vctx, state); 503bf215546Sopenharmony_ci virgl_attach_res_framebuffer(vctx); 504bf215546Sopenharmony_ci} 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_cistatic void virgl_set_viewport_states(struct pipe_context *ctx, 507bf215546Sopenharmony_ci unsigned start_slot, 508bf215546Sopenharmony_ci unsigned num_viewports, 509bf215546Sopenharmony_ci const struct pipe_viewport_state *state) 510bf215546Sopenharmony_ci{ 511bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 512bf215546Sopenharmony_ci virgl_encoder_set_viewport_states(vctx, start_slot, num_viewports, state); 513bf215546Sopenharmony_ci} 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_cistatic void *virgl_create_vertex_elements_state(struct pipe_context *ctx, 516bf215546Sopenharmony_ci unsigned num_elements, 517bf215546Sopenharmony_ci const struct pipe_vertex_element *elements) 518bf215546Sopenharmony_ci{ 519bf215546Sopenharmony_ci struct pipe_vertex_element new_elements[PIPE_MAX_ATTRIBS]; 520bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 521bf215546Sopenharmony_ci struct virgl_vertex_elements_state *state = 522bf215546Sopenharmony_ci CALLOC_STRUCT(virgl_vertex_elements_state); 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci for (int i = 0; i < num_elements; ++i) { 525bf215546Sopenharmony_ci if (elements[i].instance_divisor) { 526bf215546Sopenharmony_ci /* Virglrenderer doesn't deal with instance_divisor correctly if 527bf215546Sopenharmony_ci * there isn't a 1:1 relationship between elements and bindings. 528bf215546Sopenharmony_ci * So let's make sure there is, by duplicating bindings. 529bf215546Sopenharmony_ci */ 530bf215546Sopenharmony_ci for (int j = 0; j < num_elements; ++j) { 531bf215546Sopenharmony_ci new_elements[j] = elements[j]; 532bf215546Sopenharmony_ci new_elements[j].vertex_buffer_index = j; 533bf215546Sopenharmony_ci state->binding_map[j] = elements[j].vertex_buffer_index; 534bf215546Sopenharmony_ci } 535bf215546Sopenharmony_ci elements = new_elements; 536bf215546Sopenharmony_ci state->num_bindings = num_elements; 537bf215546Sopenharmony_ci break; 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci } 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci state->handle = virgl_object_assign_handle(); 542bf215546Sopenharmony_ci virgl_encoder_create_vertex_elements(vctx, state->handle, 543bf215546Sopenharmony_ci num_elements, elements); 544bf215546Sopenharmony_ci return state; 545bf215546Sopenharmony_ci} 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_cistatic void virgl_delete_vertex_elements_state(struct pipe_context *ctx, 548bf215546Sopenharmony_ci void *ve) 549bf215546Sopenharmony_ci{ 550bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 551bf215546Sopenharmony_ci struct virgl_vertex_elements_state *state = 552bf215546Sopenharmony_ci (struct virgl_vertex_elements_state *)ve; 553bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, state->handle, VIRGL_OBJECT_VERTEX_ELEMENTS); 554bf215546Sopenharmony_ci FREE(state); 555bf215546Sopenharmony_ci} 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_cistatic void virgl_bind_vertex_elements_state(struct pipe_context *ctx, 558bf215546Sopenharmony_ci void *ve) 559bf215546Sopenharmony_ci{ 560bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 561bf215546Sopenharmony_ci struct virgl_vertex_elements_state *state = 562bf215546Sopenharmony_ci (struct virgl_vertex_elements_state *)ve; 563bf215546Sopenharmony_ci vctx->vertex_elements = state; 564bf215546Sopenharmony_ci virgl_encode_bind_object(vctx, state ? state->handle : 0, 565bf215546Sopenharmony_ci VIRGL_OBJECT_VERTEX_ELEMENTS); 566bf215546Sopenharmony_ci vctx->vertex_array_dirty = TRUE; 567bf215546Sopenharmony_ci} 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_cistatic void virgl_set_vertex_buffers(struct pipe_context *ctx, 570bf215546Sopenharmony_ci unsigned start_slot, 571bf215546Sopenharmony_ci unsigned num_buffers, 572bf215546Sopenharmony_ci unsigned unbind_num_trailing_slots, 573bf215546Sopenharmony_ci bool take_ownership, 574bf215546Sopenharmony_ci const struct pipe_vertex_buffer *buffers) 575bf215546Sopenharmony_ci{ 576bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci util_set_vertex_buffers_count(vctx->vertex_buffer, 579bf215546Sopenharmony_ci &vctx->num_vertex_buffers, 580bf215546Sopenharmony_ci buffers, start_slot, num_buffers, 581bf215546Sopenharmony_ci unbind_num_trailing_slots, 582bf215546Sopenharmony_ci take_ownership); 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_ci if (buffers) { 585bf215546Sopenharmony_ci for (unsigned i = 0; i < num_buffers; i++) { 586bf215546Sopenharmony_ci struct virgl_resource *res = 587bf215546Sopenharmony_ci virgl_resource(buffers[i].buffer.resource); 588bf215546Sopenharmony_ci if (res && !buffers[i].is_user_buffer) 589bf215546Sopenharmony_ci res->bind_history |= PIPE_BIND_VERTEX_BUFFER; 590bf215546Sopenharmony_ci } 591bf215546Sopenharmony_ci } 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci vctx->vertex_array_dirty = TRUE; 594bf215546Sopenharmony_ci} 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_cistatic void virgl_hw_set_vertex_buffers(struct virgl_context *vctx) 597bf215546Sopenharmony_ci{ 598bf215546Sopenharmony_ci if (vctx->vertex_array_dirty) { 599bf215546Sopenharmony_ci struct virgl_vertex_elements_state *ve = vctx->vertex_elements; 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci if (ve->num_bindings) { 602bf215546Sopenharmony_ci struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; 603bf215546Sopenharmony_ci for (int i = 0; i < ve->num_bindings; ++i) 604bf215546Sopenharmony_ci vertex_buffers[i] = vctx->vertex_buffer[ve->binding_map[i]]; 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci virgl_encoder_set_vertex_buffers(vctx, ve->num_bindings, vertex_buffers); 607bf215546Sopenharmony_ci } else 608bf215546Sopenharmony_ci virgl_encoder_set_vertex_buffers(vctx, vctx->num_vertex_buffers, vctx->vertex_buffer); 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci virgl_attach_res_vertex_buffers(vctx); 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci vctx->vertex_array_dirty = FALSE; 613bf215546Sopenharmony_ci } 614bf215546Sopenharmony_ci} 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_cistatic void virgl_set_stencil_ref(struct pipe_context *ctx, 617bf215546Sopenharmony_ci const struct pipe_stencil_ref ref) 618bf215546Sopenharmony_ci{ 619bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 620bf215546Sopenharmony_ci virgl_encoder_set_stencil_ref(vctx, &ref); 621bf215546Sopenharmony_ci} 622bf215546Sopenharmony_ci 623bf215546Sopenharmony_cistatic void virgl_set_blend_color(struct pipe_context *ctx, 624bf215546Sopenharmony_ci const struct pipe_blend_color *color) 625bf215546Sopenharmony_ci{ 626bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 627bf215546Sopenharmony_ci virgl_encoder_set_blend_color(vctx, color); 628bf215546Sopenharmony_ci} 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_cistatic void virgl_hw_set_index_buffer(struct virgl_context *vctx, 631bf215546Sopenharmony_ci struct virgl_indexbuf *ib) 632bf215546Sopenharmony_ci{ 633bf215546Sopenharmony_ci virgl_encoder_set_index_buffer(vctx, ib); 634bf215546Sopenharmony_ci virgl_attach_res_index_buffer(vctx, ib); 635bf215546Sopenharmony_ci} 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_cistatic void virgl_set_constant_buffer(struct pipe_context *ctx, 638bf215546Sopenharmony_ci enum pipe_shader_type shader, uint index, 639bf215546Sopenharmony_ci bool take_ownership, 640bf215546Sopenharmony_ci const struct pipe_constant_buffer *buf) 641bf215546Sopenharmony_ci{ 642bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 643bf215546Sopenharmony_ci struct virgl_shader_binding_state *binding = 644bf215546Sopenharmony_ci &vctx->shader_bindings[shader]; 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci if (buf && buf->buffer) { 647bf215546Sopenharmony_ci struct virgl_resource *res = virgl_resource(buf->buffer); 648bf215546Sopenharmony_ci res->bind_history |= PIPE_BIND_CONSTANT_BUFFER; 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ci virgl_encoder_set_uniform_buffer(vctx, shader, index, 651bf215546Sopenharmony_ci buf->buffer_offset, 652bf215546Sopenharmony_ci buf->buffer_size, res); 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci if (take_ownership) { 655bf215546Sopenharmony_ci pipe_resource_reference(&binding->ubos[index].buffer, NULL); 656bf215546Sopenharmony_ci binding->ubos[index].buffer = buf->buffer; 657bf215546Sopenharmony_ci } else { 658bf215546Sopenharmony_ci pipe_resource_reference(&binding->ubos[index].buffer, buf->buffer); 659bf215546Sopenharmony_ci } 660bf215546Sopenharmony_ci binding->ubos[index] = *buf; 661bf215546Sopenharmony_ci binding->ubo_enabled_mask |= 1 << index; 662bf215546Sopenharmony_ci } else { 663bf215546Sopenharmony_ci static const struct pipe_constant_buffer dummy_ubo; 664bf215546Sopenharmony_ci if (!buf) 665bf215546Sopenharmony_ci buf = &dummy_ubo; 666bf215546Sopenharmony_ci virgl_encoder_write_constant_buffer(vctx, shader, index, 667bf215546Sopenharmony_ci buf->buffer_size / 4, 668bf215546Sopenharmony_ci buf->user_buffer); 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_ci pipe_resource_reference(&binding->ubos[index].buffer, NULL); 671bf215546Sopenharmony_ci binding->ubo_enabled_mask &= ~(1 << index); 672bf215546Sopenharmony_ci } 673bf215546Sopenharmony_ci} 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_cistatic void *virgl_shader_encoder(struct pipe_context *ctx, 676bf215546Sopenharmony_ci const struct pipe_shader_state *shader, 677bf215546Sopenharmony_ci unsigned type) 678bf215546Sopenharmony_ci{ 679bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 680bf215546Sopenharmony_ci uint32_t handle; 681bf215546Sopenharmony_ci const struct tgsi_token *tokens; 682bf215546Sopenharmony_ci const struct tgsi_token *ntt_tokens = NULL; 683bf215546Sopenharmony_ci struct tgsi_token *new_tokens; 684bf215546Sopenharmony_ci int ret; 685bf215546Sopenharmony_ci bool is_separable = false; 686bf215546Sopenharmony_ci 687bf215546Sopenharmony_ci if (shader->type == PIPE_SHADER_IR_NIR) { 688bf215546Sopenharmony_ci struct nir_to_tgsi_options options = { 689bf215546Sopenharmony_ci .unoptimized_ra = true, 690bf215546Sopenharmony_ci .lower_fabs = true 691bf215546Sopenharmony_ci }; 692bf215546Sopenharmony_ci nir_shader *s = nir_shader_clone(NULL, shader->ir.nir); 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci /* Propagare the separable shader property to the host, unless 695bf215546Sopenharmony_ci * it is an internal shader - these are marked separable even though they are not. */ 696bf215546Sopenharmony_ci is_separable = s->info.separate_shader && !s->info.internal; 697bf215546Sopenharmony_ci ntt_tokens = tokens = nir_to_tgsi_options(s, vctx->base.screen, &options); /* takes ownership */ 698bf215546Sopenharmony_ci } else { 699bf215546Sopenharmony_ci tokens = shader->tokens; 700bf215546Sopenharmony_ci } 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ci new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, tokens, is_separable); 703bf215546Sopenharmony_ci if (!new_tokens) 704bf215546Sopenharmony_ci return NULL; 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci handle = virgl_object_assign_handle(); 707bf215546Sopenharmony_ci /* encode VS state */ 708bf215546Sopenharmony_ci ret = virgl_encode_shader_state(vctx, handle, type, 709bf215546Sopenharmony_ci &shader->stream_output, 0, 710bf215546Sopenharmony_ci new_tokens); 711bf215546Sopenharmony_ci if (ret) { 712bf215546Sopenharmony_ci FREE((void *)ntt_tokens); 713bf215546Sopenharmony_ci return NULL; 714bf215546Sopenharmony_ci } 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci FREE((void *)ntt_tokens); 717bf215546Sopenharmony_ci FREE(new_tokens); 718bf215546Sopenharmony_ci return (void *)(unsigned long)handle; 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci} 721bf215546Sopenharmony_cistatic void *virgl_create_vs_state(struct pipe_context *ctx, 722bf215546Sopenharmony_ci const struct pipe_shader_state *shader) 723bf215546Sopenharmony_ci{ 724bf215546Sopenharmony_ci return virgl_shader_encoder(ctx, shader, PIPE_SHADER_VERTEX); 725bf215546Sopenharmony_ci} 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_cistatic void *virgl_create_tcs_state(struct pipe_context *ctx, 728bf215546Sopenharmony_ci const struct pipe_shader_state *shader) 729bf215546Sopenharmony_ci{ 730bf215546Sopenharmony_ci return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_CTRL); 731bf215546Sopenharmony_ci} 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_cistatic void *virgl_create_tes_state(struct pipe_context *ctx, 734bf215546Sopenharmony_ci const struct pipe_shader_state *shader) 735bf215546Sopenharmony_ci{ 736bf215546Sopenharmony_ci return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_EVAL); 737bf215546Sopenharmony_ci} 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_cistatic void *virgl_create_gs_state(struct pipe_context *ctx, 740bf215546Sopenharmony_ci const struct pipe_shader_state *shader) 741bf215546Sopenharmony_ci{ 742bf215546Sopenharmony_ci return virgl_shader_encoder(ctx, shader, PIPE_SHADER_GEOMETRY); 743bf215546Sopenharmony_ci} 744bf215546Sopenharmony_ci 745bf215546Sopenharmony_cistatic void *virgl_create_fs_state(struct pipe_context *ctx, 746bf215546Sopenharmony_ci const struct pipe_shader_state *shader) 747bf215546Sopenharmony_ci{ 748bf215546Sopenharmony_ci return virgl_shader_encoder(ctx, shader, PIPE_SHADER_FRAGMENT); 749bf215546Sopenharmony_ci} 750bf215546Sopenharmony_ci 751bf215546Sopenharmony_cistatic void 752bf215546Sopenharmony_civirgl_delete_fs_state(struct pipe_context *ctx, 753bf215546Sopenharmony_ci void *fs) 754bf215546Sopenharmony_ci{ 755bf215546Sopenharmony_ci uint32_t handle = (unsigned long)fs; 756bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER); 759bf215546Sopenharmony_ci} 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_cistatic void 762bf215546Sopenharmony_civirgl_delete_gs_state(struct pipe_context *ctx, 763bf215546Sopenharmony_ci void *gs) 764bf215546Sopenharmony_ci{ 765bf215546Sopenharmony_ci uint32_t handle = (unsigned long)gs; 766bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER); 769bf215546Sopenharmony_ci} 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_cistatic void 772bf215546Sopenharmony_civirgl_delete_vs_state(struct pipe_context *ctx, 773bf215546Sopenharmony_ci void *vs) 774bf215546Sopenharmony_ci{ 775bf215546Sopenharmony_ci uint32_t handle = (unsigned long)vs; 776bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER); 779bf215546Sopenharmony_ci} 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_cistatic void 782bf215546Sopenharmony_civirgl_delete_tcs_state(struct pipe_context *ctx, 783bf215546Sopenharmony_ci void *tcs) 784bf215546Sopenharmony_ci{ 785bf215546Sopenharmony_ci uint32_t handle = (unsigned long)tcs; 786bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 787bf215546Sopenharmony_ci 788bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER); 789bf215546Sopenharmony_ci} 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_cistatic void 792bf215546Sopenharmony_civirgl_delete_tes_state(struct pipe_context *ctx, 793bf215546Sopenharmony_ci void *tes) 794bf215546Sopenharmony_ci{ 795bf215546Sopenharmony_ci uint32_t handle = (unsigned long)tes; 796bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER); 799bf215546Sopenharmony_ci} 800bf215546Sopenharmony_ci 801bf215546Sopenharmony_cistatic void virgl_bind_vs_state(struct pipe_context *ctx, 802bf215546Sopenharmony_ci void *vss) 803bf215546Sopenharmony_ci{ 804bf215546Sopenharmony_ci uint32_t handle = (unsigned long)vss; 805bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_VERTEX); 808bf215546Sopenharmony_ci} 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_cistatic void virgl_bind_tcs_state(struct pipe_context *ctx, 811bf215546Sopenharmony_ci void *vss) 812bf215546Sopenharmony_ci{ 813bf215546Sopenharmony_ci uint32_t handle = (unsigned long)vss; 814bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_CTRL); 817bf215546Sopenharmony_ci} 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_cistatic void virgl_bind_tes_state(struct pipe_context *ctx, 820bf215546Sopenharmony_ci void *vss) 821bf215546Sopenharmony_ci{ 822bf215546Sopenharmony_ci uint32_t handle = (unsigned long)vss; 823bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 824bf215546Sopenharmony_ci 825bf215546Sopenharmony_ci virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_EVAL); 826bf215546Sopenharmony_ci} 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_cistatic void virgl_bind_gs_state(struct pipe_context *ctx, 829bf215546Sopenharmony_ci void *vss) 830bf215546Sopenharmony_ci{ 831bf215546Sopenharmony_ci uint32_t handle = (unsigned long)vss; 832bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_GEOMETRY); 835bf215546Sopenharmony_ci} 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_cistatic void virgl_bind_fs_state(struct pipe_context *ctx, 839bf215546Sopenharmony_ci void *vss) 840bf215546Sopenharmony_ci{ 841bf215546Sopenharmony_ci uint32_t handle = (unsigned long)vss; 842bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_ci virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_FRAGMENT); 845bf215546Sopenharmony_ci} 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_cistatic void virgl_clear(struct pipe_context *ctx, 848bf215546Sopenharmony_ci unsigned buffers, 849bf215546Sopenharmony_ci const struct pipe_scissor_state *scissor_state, 850bf215546Sopenharmony_ci const union pipe_color_union *color, 851bf215546Sopenharmony_ci double depth, unsigned stencil) 852bf215546Sopenharmony_ci{ 853bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci if (!vctx->num_draws) 856bf215546Sopenharmony_ci virgl_reemit_draw_resources(vctx); 857bf215546Sopenharmony_ci vctx->num_draws++; 858bf215546Sopenharmony_ci 859bf215546Sopenharmony_ci virgl_encode_clear(vctx, buffers, color, depth, stencil); 860bf215546Sopenharmony_ci} 861bf215546Sopenharmony_ci 862bf215546Sopenharmony_cistatic void virgl_clear_texture(struct pipe_context *ctx, 863bf215546Sopenharmony_ci struct pipe_resource *res, 864bf215546Sopenharmony_ci unsigned int level, 865bf215546Sopenharmony_ci const struct pipe_box *box, 866bf215546Sopenharmony_ci const void *data) 867bf215546Sopenharmony_ci{ 868bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 869bf215546Sopenharmony_ci struct virgl_resource *vres = virgl_resource(res); 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ci virgl_encode_clear_texture(vctx, vres, level, box, data); 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_ci /* Mark as dirty, since we are updating the host side resource 874bf215546Sopenharmony_ci * without going through the corresponding guest side resource, and 875bf215546Sopenharmony_ci * hence the two will diverge. 876bf215546Sopenharmony_ci */ 877bf215546Sopenharmony_ci virgl_resource_dirty(vres, level); 878bf215546Sopenharmony_ci} 879bf215546Sopenharmony_ci 880bf215546Sopenharmony_cistatic void virgl_draw_vbo(struct pipe_context *ctx, 881bf215546Sopenharmony_ci const struct pipe_draw_info *dinfo, 882bf215546Sopenharmony_ci unsigned drawid_offset, 883bf215546Sopenharmony_ci const struct pipe_draw_indirect_info *indirect, 884bf215546Sopenharmony_ci const struct pipe_draw_start_count_bias *draws, 885bf215546Sopenharmony_ci unsigned num_draws) 886bf215546Sopenharmony_ci{ 887bf215546Sopenharmony_ci if (num_draws > 1) { 888bf215546Sopenharmony_ci util_draw_multi(ctx, dinfo, drawid_offset, indirect, draws, num_draws); 889bf215546Sopenharmony_ci return; 890bf215546Sopenharmony_ci } 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci if (!indirect && (!draws[0].count || !dinfo->instance_count)) 893bf215546Sopenharmony_ci return; 894bf215546Sopenharmony_ci 895bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 896bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 897bf215546Sopenharmony_ci struct virgl_indexbuf ib = {}; 898bf215546Sopenharmony_ci struct pipe_draw_info info = *dinfo; 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_ci if (!indirect && 901bf215546Sopenharmony_ci !dinfo->primitive_restart && 902bf215546Sopenharmony_ci !u_trim_pipe_prim(dinfo->mode, (unsigned*)&draws[0].count)) 903bf215546Sopenharmony_ci return; 904bf215546Sopenharmony_ci 905bf215546Sopenharmony_ci if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) { 906bf215546Sopenharmony_ci util_primconvert_save_rasterizer_state(vctx->primconvert, &vctx->rs_state.rs); 907bf215546Sopenharmony_ci util_primconvert_draw_vbo(vctx->primconvert, dinfo, drawid_offset, indirect, draws, num_draws); 908bf215546Sopenharmony_ci return; 909bf215546Sopenharmony_ci } 910bf215546Sopenharmony_ci if (info.index_size) { 911bf215546Sopenharmony_ci pipe_resource_reference(&ib.buffer, info.has_user_indices ? NULL : info.index.resource); 912bf215546Sopenharmony_ci ib.user_buffer = info.has_user_indices ? info.index.user : NULL; 913bf215546Sopenharmony_ci ib.index_size = dinfo->index_size; 914bf215546Sopenharmony_ci ib.offset = draws[0].start * ib.index_size; 915bf215546Sopenharmony_ci 916bf215546Sopenharmony_ci if (ib.user_buffer) { 917bf215546Sopenharmony_ci unsigned start_offset = draws[0].start * ib.index_size; 918bf215546Sopenharmony_ci u_upload_data(vctx->uploader, start_offset, 919bf215546Sopenharmony_ci draws[0].count * ib.index_size, 4, 920bf215546Sopenharmony_ci (char*)ib.user_buffer + start_offset, 921bf215546Sopenharmony_ci &ib.offset, &ib.buffer); 922bf215546Sopenharmony_ci ib.offset -= start_offset; 923bf215546Sopenharmony_ci ib.user_buffer = NULL; 924bf215546Sopenharmony_ci } 925bf215546Sopenharmony_ci } 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_ci if (!vctx->num_draws) 928bf215546Sopenharmony_ci virgl_reemit_draw_resources(vctx); 929bf215546Sopenharmony_ci vctx->num_draws++; 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci virgl_hw_set_vertex_buffers(vctx); 932bf215546Sopenharmony_ci if (info.index_size) 933bf215546Sopenharmony_ci virgl_hw_set_index_buffer(vctx, &ib); 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci virgl_encoder_draw_vbo(vctx, &info, drawid_offset, indirect, &draws[0]); 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci pipe_resource_reference(&ib.buffer, NULL); 938bf215546Sopenharmony_ci 939bf215546Sopenharmony_ci} 940bf215546Sopenharmony_ci 941bf215546Sopenharmony_cistatic void virgl_submit_cmd(struct virgl_winsys *vws, 942bf215546Sopenharmony_ci struct virgl_cmd_buf *cbuf, 943bf215546Sopenharmony_ci struct pipe_fence_handle **fence) 944bf215546Sopenharmony_ci{ 945bf215546Sopenharmony_ci if (unlikely(virgl_debug & VIRGL_DEBUG_SYNC)) { 946bf215546Sopenharmony_ci struct pipe_fence_handle *sync_fence = NULL; 947bf215546Sopenharmony_ci 948bf215546Sopenharmony_ci vws->submit_cmd(vws, cbuf, &sync_fence); 949bf215546Sopenharmony_ci 950bf215546Sopenharmony_ci vws->fence_wait(vws, sync_fence, PIPE_TIMEOUT_INFINITE); 951bf215546Sopenharmony_ci vws->fence_reference(vws, &sync_fence, NULL); 952bf215546Sopenharmony_ci } else { 953bf215546Sopenharmony_ci vws->submit_cmd(vws, cbuf, fence); 954bf215546Sopenharmony_ci } 955bf215546Sopenharmony_ci} 956bf215546Sopenharmony_ci 957bf215546Sopenharmony_civoid virgl_flush_eq(struct virgl_context *ctx, void *closure, 958bf215546Sopenharmony_ci struct pipe_fence_handle **fence) 959bf215546Sopenharmony_ci{ 960bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->base.screen); 961bf215546Sopenharmony_ci 962bf215546Sopenharmony_ci /* skip empty cbuf */ 963bf215546Sopenharmony_ci if (ctx->cbuf->cdw == ctx->cbuf_initial_cdw && 964bf215546Sopenharmony_ci ctx->queue.num_dwords == 0 && 965bf215546Sopenharmony_ci !fence) 966bf215546Sopenharmony_ci return; 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_ci if (ctx->num_draws) 969bf215546Sopenharmony_ci u_upload_unmap(ctx->uploader); 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ci /* send the buffer to the remote side for decoding */ 972bf215546Sopenharmony_ci ctx->num_draws = ctx->num_compute = 0; 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_ci virgl_transfer_queue_clear(&ctx->queue, ctx->cbuf); 975bf215546Sopenharmony_ci 976bf215546Sopenharmony_ci virgl_submit_cmd(rs->vws, ctx->cbuf, fence); 977bf215546Sopenharmony_ci 978bf215546Sopenharmony_ci /* Reserve some space for transfers. */ 979bf215546Sopenharmony_ci if (ctx->encoded_transfers) 980bf215546Sopenharmony_ci ctx->cbuf->cdw = VIRGL_MAX_TBUF_DWORDS; 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci virgl_encoder_set_sub_ctx(ctx, ctx->hw_sub_ctx_id); 983bf215546Sopenharmony_ci 984bf215546Sopenharmony_ci ctx->cbuf_initial_cdw = ctx->cbuf->cdw; 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_ci /* We have flushed the command queue, including any pending copy transfers 987bf215546Sopenharmony_ci * involving staging resources. 988bf215546Sopenharmony_ci */ 989bf215546Sopenharmony_ci ctx->queued_staging_res_size = 0; 990bf215546Sopenharmony_ci} 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_cistatic void virgl_flush_from_st(struct pipe_context *ctx, 993bf215546Sopenharmony_ci struct pipe_fence_handle **fence, 994bf215546Sopenharmony_ci enum pipe_flush_flags flags) 995bf215546Sopenharmony_ci{ 996bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci virgl_flush_eq(vctx, vctx, fence); 999bf215546Sopenharmony_ci} 1000bf215546Sopenharmony_ci 1001bf215546Sopenharmony_cistatic struct pipe_sampler_view *virgl_create_sampler_view(struct pipe_context *ctx, 1002bf215546Sopenharmony_ci struct pipe_resource *texture, 1003bf215546Sopenharmony_ci const struct pipe_sampler_view *state) 1004bf215546Sopenharmony_ci{ 1005bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1006bf215546Sopenharmony_ci struct virgl_sampler_view *grview; 1007bf215546Sopenharmony_ci uint32_t handle; 1008bf215546Sopenharmony_ci struct virgl_resource *res; 1009bf215546Sopenharmony_ci 1010bf215546Sopenharmony_ci if (!state) 1011bf215546Sopenharmony_ci return NULL; 1012bf215546Sopenharmony_ci 1013bf215546Sopenharmony_ci grview = CALLOC_STRUCT(virgl_sampler_view); 1014bf215546Sopenharmony_ci if (!grview) 1015bf215546Sopenharmony_ci return NULL; 1016bf215546Sopenharmony_ci 1017bf215546Sopenharmony_ci res = virgl_resource(texture); 1018bf215546Sopenharmony_ci handle = virgl_object_assign_handle(); 1019bf215546Sopenharmony_ci virgl_encode_sampler_view(vctx, handle, res, state); 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci grview->base = *state; 1022bf215546Sopenharmony_ci grview->base.reference.count = 1; 1023bf215546Sopenharmony_ci 1024bf215546Sopenharmony_ci grview->base.texture = NULL; 1025bf215546Sopenharmony_ci grview->base.context = ctx; 1026bf215546Sopenharmony_ci pipe_resource_reference(&grview->base.texture, texture); 1027bf215546Sopenharmony_ci grview->handle = handle; 1028bf215546Sopenharmony_ci return &grview->base; 1029bf215546Sopenharmony_ci} 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_cistatic void virgl_set_sampler_views(struct pipe_context *ctx, 1032bf215546Sopenharmony_ci enum pipe_shader_type shader_type, 1033bf215546Sopenharmony_ci unsigned start_slot, 1034bf215546Sopenharmony_ci unsigned num_views, 1035bf215546Sopenharmony_ci unsigned unbind_num_trailing_slots, 1036bf215546Sopenharmony_ci bool take_ownership, 1037bf215546Sopenharmony_ci struct pipe_sampler_view **views) 1038bf215546Sopenharmony_ci{ 1039bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1040bf215546Sopenharmony_ci struct virgl_shader_binding_state *binding = 1041bf215546Sopenharmony_ci &vctx->shader_bindings[shader_type]; 1042bf215546Sopenharmony_ci 1043bf215546Sopenharmony_ci for (unsigned i = 0; i < num_views; i++) { 1044bf215546Sopenharmony_ci unsigned idx = start_slot + i; 1045bf215546Sopenharmony_ci if (views && views[i]) { 1046bf215546Sopenharmony_ci struct virgl_resource *res = virgl_resource(views[i]->texture); 1047bf215546Sopenharmony_ci res->bind_history |= PIPE_BIND_SAMPLER_VIEW; 1048bf215546Sopenharmony_ci 1049bf215546Sopenharmony_ci if (take_ownership) { 1050bf215546Sopenharmony_ci pipe_sampler_view_reference(&binding->views[idx], NULL); 1051bf215546Sopenharmony_ci binding->views[idx] = views[i]; 1052bf215546Sopenharmony_ci } else { 1053bf215546Sopenharmony_ci pipe_sampler_view_reference(&binding->views[idx], views[i]); 1054bf215546Sopenharmony_ci } 1055bf215546Sopenharmony_ci } else { 1056bf215546Sopenharmony_ci pipe_sampler_view_reference(&binding->views[idx], NULL); 1057bf215546Sopenharmony_ci } 1058bf215546Sopenharmony_ci } 1059bf215546Sopenharmony_ci 1060bf215546Sopenharmony_ci virgl_encode_set_sampler_views(vctx, shader_type, 1061bf215546Sopenharmony_ci start_slot, num_views, (struct virgl_sampler_view **)binding->views); 1062bf215546Sopenharmony_ci virgl_attach_res_sampler_views(vctx, shader_type); 1063bf215546Sopenharmony_ci 1064bf215546Sopenharmony_ci if (unbind_num_trailing_slots) { 1065bf215546Sopenharmony_ci virgl_set_sampler_views(ctx, shader_type, start_slot + num_views, 1066bf215546Sopenharmony_ci unbind_num_trailing_slots, 0, false, NULL); 1067bf215546Sopenharmony_ci } 1068bf215546Sopenharmony_ci} 1069bf215546Sopenharmony_ci 1070bf215546Sopenharmony_cistatic void 1071bf215546Sopenharmony_civirgl_texture_barrier(struct pipe_context *ctx, unsigned flags) 1072bf215546Sopenharmony_ci{ 1073bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1074bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1075bf215546Sopenharmony_ci 1076bf215546Sopenharmony_ci if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_TEXTURE_BARRIER) && 1077bf215546Sopenharmony_ci !(rs->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_BLEND_EQUATION)) 1078bf215546Sopenharmony_ci return; 1079bf215546Sopenharmony_ci virgl_encode_texture_barrier(vctx, flags); 1080bf215546Sopenharmony_ci} 1081bf215546Sopenharmony_ci 1082bf215546Sopenharmony_cistatic void virgl_destroy_sampler_view(struct pipe_context *ctx, 1083bf215546Sopenharmony_ci struct pipe_sampler_view *view) 1084bf215546Sopenharmony_ci{ 1085bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1086bf215546Sopenharmony_ci struct virgl_sampler_view *grview = virgl_sampler_view(view); 1087bf215546Sopenharmony_ci 1088bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, grview->handle, VIRGL_OBJECT_SAMPLER_VIEW); 1089bf215546Sopenharmony_ci pipe_resource_reference(&view->texture, NULL); 1090bf215546Sopenharmony_ci FREE(view); 1091bf215546Sopenharmony_ci} 1092bf215546Sopenharmony_ci 1093bf215546Sopenharmony_cistatic void *virgl_create_sampler_state(struct pipe_context *ctx, 1094bf215546Sopenharmony_ci const struct pipe_sampler_state *state) 1095bf215546Sopenharmony_ci{ 1096bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1097bf215546Sopenharmony_ci uint32_t handle; 1098bf215546Sopenharmony_ci 1099bf215546Sopenharmony_ci handle = virgl_object_assign_handle(); 1100bf215546Sopenharmony_ci 1101bf215546Sopenharmony_ci virgl_encode_sampler_state(vctx, handle, state); 1102bf215546Sopenharmony_ci return (void *)(unsigned long)handle; 1103bf215546Sopenharmony_ci} 1104bf215546Sopenharmony_ci 1105bf215546Sopenharmony_cistatic void virgl_delete_sampler_state(struct pipe_context *ctx, 1106bf215546Sopenharmony_ci void *ss) 1107bf215546Sopenharmony_ci{ 1108bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1109bf215546Sopenharmony_ci uint32_t handle = (unsigned long)ss; 1110bf215546Sopenharmony_ci 1111bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SAMPLER_STATE); 1112bf215546Sopenharmony_ci} 1113bf215546Sopenharmony_ci 1114bf215546Sopenharmony_cistatic void virgl_bind_sampler_states(struct pipe_context *ctx, 1115bf215546Sopenharmony_ci enum pipe_shader_type shader, 1116bf215546Sopenharmony_ci unsigned start_slot, 1117bf215546Sopenharmony_ci unsigned num_samplers, 1118bf215546Sopenharmony_ci void **samplers) 1119bf215546Sopenharmony_ci{ 1120bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1121bf215546Sopenharmony_ci uint32_t handles[32]; 1122bf215546Sopenharmony_ci int i; 1123bf215546Sopenharmony_ci for (i = 0; i < num_samplers; i++) { 1124bf215546Sopenharmony_ci handles[i] = (unsigned long)(samplers[i]); 1125bf215546Sopenharmony_ci } 1126bf215546Sopenharmony_ci virgl_encode_bind_sampler_states(vctx, shader, start_slot, num_samplers, handles); 1127bf215546Sopenharmony_ci} 1128bf215546Sopenharmony_ci 1129bf215546Sopenharmony_cistatic void virgl_set_polygon_stipple(struct pipe_context *ctx, 1130bf215546Sopenharmony_ci const struct pipe_poly_stipple *ps) 1131bf215546Sopenharmony_ci{ 1132bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1133bf215546Sopenharmony_ci virgl_encoder_set_polygon_stipple(vctx, ps); 1134bf215546Sopenharmony_ci} 1135bf215546Sopenharmony_ci 1136bf215546Sopenharmony_cistatic void virgl_set_scissor_states(struct pipe_context *ctx, 1137bf215546Sopenharmony_ci unsigned start_slot, 1138bf215546Sopenharmony_ci unsigned num_scissor, 1139bf215546Sopenharmony_ci const struct pipe_scissor_state *ss) 1140bf215546Sopenharmony_ci{ 1141bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1142bf215546Sopenharmony_ci virgl_encoder_set_scissor_state(vctx, start_slot, num_scissor, ss); 1143bf215546Sopenharmony_ci} 1144bf215546Sopenharmony_ci 1145bf215546Sopenharmony_cistatic void virgl_set_sample_mask(struct pipe_context *ctx, 1146bf215546Sopenharmony_ci unsigned sample_mask) 1147bf215546Sopenharmony_ci{ 1148bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1149bf215546Sopenharmony_ci virgl_encoder_set_sample_mask(vctx, sample_mask); 1150bf215546Sopenharmony_ci} 1151bf215546Sopenharmony_ci 1152bf215546Sopenharmony_cistatic void virgl_set_min_samples(struct pipe_context *ctx, 1153bf215546Sopenharmony_ci unsigned min_samples) 1154bf215546Sopenharmony_ci{ 1155bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1156bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1157bf215546Sopenharmony_ci 1158bf215546Sopenharmony_ci if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_SET_MIN_SAMPLES)) 1159bf215546Sopenharmony_ci return; 1160bf215546Sopenharmony_ci virgl_encoder_set_min_samples(vctx, min_samples); 1161bf215546Sopenharmony_ci} 1162bf215546Sopenharmony_ci 1163bf215546Sopenharmony_cistatic void virgl_set_clip_state(struct pipe_context *ctx, 1164bf215546Sopenharmony_ci const struct pipe_clip_state *clip) 1165bf215546Sopenharmony_ci{ 1166bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1167bf215546Sopenharmony_ci virgl_encoder_set_clip_state(vctx, clip); 1168bf215546Sopenharmony_ci} 1169bf215546Sopenharmony_ci 1170bf215546Sopenharmony_cistatic void virgl_set_tess_state(struct pipe_context *ctx, 1171bf215546Sopenharmony_ci const float default_outer_level[4], 1172bf215546Sopenharmony_ci const float default_inner_level[2]) 1173bf215546Sopenharmony_ci{ 1174bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1175bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1176bf215546Sopenharmony_ci 1177bf215546Sopenharmony_ci if (!rs->caps.caps.v1.bset.has_tessellation_shaders) 1178bf215546Sopenharmony_ci return; 1179bf215546Sopenharmony_ci virgl_encode_set_tess_state(vctx, default_outer_level, default_inner_level); 1180bf215546Sopenharmony_ci} 1181bf215546Sopenharmony_ci 1182bf215546Sopenharmony_cistatic void virgl_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertices) 1183bf215546Sopenharmony_ci{ 1184bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci vctx->patch_vertices = patch_vertices; 1187bf215546Sopenharmony_ci} 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_cistatic void virgl_resource_copy_region(struct pipe_context *ctx, 1190bf215546Sopenharmony_ci struct pipe_resource *dst, 1191bf215546Sopenharmony_ci unsigned dst_level, 1192bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned dstz, 1193bf215546Sopenharmony_ci struct pipe_resource *src, 1194bf215546Sopenharmony_ci unsigned src_level, 1195bf215546Sopenharmony_ci const struct pipe_box *src_box) 1196bf215546Sopenharmony_ci{ 1197bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1198bf215546Sopenharmony_ci struct virgl_resource *dres = virgl_resource(dst); 1199bf215546Sopenharmony_ci struct virgl_resource *sres = virgl_resource(src); 1200bf215546Sopenharmony_ci 1201bf215546Sopenharmony_ci if (dres->b.target == PIPE_BUFFER) 1202bf215546Sopenharmony_ci util_range_add(&dres->b, &dres->valid_buffer_range, dstx, dstx + src_box->width); 1203bf215546Sopenharmony_ci virgl_resource_dirty(dres, dst_level); 1204bf215546Sopenharmony_ci 1205bf215546Sopenharmony_ci virgl_encode_resource_copy_region(vctx, dres, 1206bf215546Sopenharmony_ci dst_level, dstx, dsty, dstz, 1207bf215546Sopenharmony_ci sres, src_level, 1208bf215546Sopenharmony_ci src_box); 1209bf215546Sopenharmony_ci} 1210bf215546Sopenharmony_ci 1211bf215546Sopenharmony_cistatic void 1212bf215546Sopenharmony_civirgl_flush_resource(struct pipe_context *pipe, 1213bf215546Sopenharmony_ci struct pipe_resource *resource) 1214bf215546Sopenharmony_ci{ 1215bf215546Sopenharmony_ci} 1216bf215546Sopenharmony_ci 1217bf215546Sopenharmony_cistatic void virgl_blit(struct pipe_context *ctx, 1218bf215546Sopenharmony_ci const struct pipe_blit_info *blit) 1219bf215546Sopenharmony_ci{ 1220bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1221bf215546Sopenharmony_ci struct virgl_resource *dres = virgl_resource(blit->dst.resource); 1222bf215546Sopenharmony_ci struct virgl_resource *sres = virgl_resource(blit->src.resource); 1223bf215546Sopenharmony_ci 1224bf215546Sopenharmony_ci assert(ctx->screen->get_param(ctx->screen, 1225bf215546Sopenharmony_ci PIPE_CAP_DEST_SURFACE_SRGB_CONTROL) || 1226bf215546Sopenharmony_ci (util_format_is_srgb(blit->dst.resource->format) == 1227bf215546Sopenharmony_ci util_format_is_srgb(blit->dst.format))); 1228bf215546Sopenharmony_ci 1229bf215546Sopenharmony_ci virgl_resource_dirty(dres, blit->dst.level); 1230bf215546Sopenharmony_ci virgl_encode_blit(vctx, dres, sres, 1231bf215546Sopenharmony_ci blit); 1232bf215546Sopenharmony_ci} 1233bf215546Sopenharmony_ci 1234bf215546Sopenharmony_cistatic void virgl_set_hw_atomic_buffers(struct pipe_context *ctx, 1235bf215546Sopenharmony_ci unsigned start_slot, 1236bf215546Sopenharmony_ci unsigned count, 1237bf215546Sopenharmony_ci const struct pipe_shader_buffer *buffers) 1238bf215546Sopenharmony_ci{ 1239bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1240bf215546Sopenharmony_ci 1241bf215546Sopenharmony_ci vctx->atomic_buffer_enabled_mask &= ~u_bit_consecutive(start_slot, count); 1242bf215546Sopenharmony_ci for (unsigned i = 0; i < count; i++) { 1243bf215546Sopenharmony_ci unsigned idx = start_slot + i; 1244bf215546Sopenharmony_ci if (buffers && buffers[i].buffer) { 1245bf215546Sopenharmony_ci struct virgl_resource *res = virgl_resource(buffers[i].buffer); 1246bf215546Sopenharmony_ci res->bind_history |= PIPE_BIND_SHADER_BUFFER; 1247bf215546Sopenharmony_ci 1248bf215546Sopenharmony_ci pipe_resource_reference(&vctx->atomic_buffers[idx].buffer, 1249bf215546Sopenharmony_ci buffers[i].buffer); 1250bf215546Sopenharmony_ci vctx->atomic_buffers[idx] = buffers[i]; 1251bf215546Sopenharmony_ci vctx->atomic_buffer_enabled_mask |= 1 << idx; 1252bf215546Sopenharmony_ci } else { 1253bf215546Sopenharmony_ci pipe_resource_reference(&vctx->atomic_buffers[idx].buffer, NULL); 1254bf215546Sopenharmony_ci } 1255bf215546Sopenharmony_ci } 1256bf215546Sopenharmony_ci 1257bf215546Sopenharmony_ci virgl_encode_set_hw_atomic_buffers(vctx, start_slot, count, buffers); 1258bf215546Sopenharmony_ci} 1259bf215546Sopenharmony_ci 1260bf215546Sopenharmony_cistatic void virgl_set_shader_buffers(struct pipe_context *ctx, 1261bf215546Sopenharmony_ci enum pipe_shader_type shader, 1262bf215546Sopenharmony_ci unsigned start_slot, unsigned count, 1263bf215546Sopenharmony_ci const struct pipe_shader_buffer *buffers, 1264bf215546Sopenharmony_ci unsigned writable_bitmask) 1265bf215546Sopenharmony_ci{ 1266bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1267bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1268bf215546Sopenharmony_ci struct virgl_shader_binding_state *binding = 1269bf215546Sopenharmony_ci &vctx->shader_bindings[shader]; 1270bf215546Sopenharmony_ci 1271bf215546Sopenharmony_ci binding->ssbo_enabled_mask &= ~u_bit_consecutive(start_slot, count); 1272bf215546Sopenharmony_ci for (unsigned i = 0; i < count; i++) { 1273bf215546Sopenharmony_ci unsigned idx = start_slot + i; 1274bf215546Sopenharmony_ci if (buffers && buffers[i].buffer) { 1275bf215546Sopenharmony_ci struct virgl_resource *res = virgl_resource(buffers[i].buffer); 1276bf215546Sopenharmony_ci res->bind_history |= PIPE_BIND_SHADER_BUFFER; 1277bf215546Sopenharmony_ci 1278bf215546Sopenharmony_ci pipe_resource_reference(&binding->ssbos[idx].buffer, buffers[i].buffer); 1279bf215546Sopenharmony_ci binding->ssbos[idx] = buffers[i]; 1280bf215546Sopenharmony_ci binding->ssbo_enabled_mask |= 1 << idx; 1281bf215546Sopenharmony_ci } else { 1282bf215546Sopenharmony_ci pipe_resource_reference(&binding->ssbos[idx].buffer, NULL); 1283bf215546Sopenharmony_ci } 1284bf215546Sopenharmony_ci } 1285bf215546Sopenharmony_ci 1286bf215546Sopenharmony_ci uint32_t max_shader_buffer = (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE) ? 1287bf215546Sopenharmony_ci rs->caps.caps.v2.max_shader_buffer_frag_compute : 1288bf215546Sopenharmony_ci rs->caps.caps.v2.max_shader_buffer_other_stages; 1289bf215546Sopenharmony_ci if (!max_shader_buffer) 1290bf215546Sopenharmony_ci return; 1291bf215546Sopenharmony_ci virgl_encode_set_shader_buffers(vctx, shader, start_slot, count, buffers); 1292bf215546Sopenharmony_ci} 1293bf215546Sopenharmony_ci 1294bf215546Sopenharmony_cistatic void virgl_create_fence_fd(struct pipe_context *ctx, 1295bf215546Sopenharmony_ci struct pipe_fence_handle **fence, 1296bf215546Sopenharmony_ci int fd, 1297bf215546Sopenharmony_ci enum pipe_fd_type type) 1298bf215546Sopenharmony_ci{ 1299bf215546Sopenharmony_ci assert(type == PIPE_FD_TYPE_NATIVE_SYNC); 1300bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1301bf215546Sopenharmony_ci 1302bf215546Sopenharmony_ci if (rs->vws->cs_create_fence) 1303bf215546Sopenharmony_ci *fence = rs->vws->cs_create_fence(rs->vws, fd); 1304bf215546Sopenharmony_ci} 1305bf215546Sopenharmony_ci 1306bf215546Sopenharmony_cistatic void virgl_fence_server_sync(struct pipe_context *ctx, 1307bf215546Sopenharmony_ci struct pipe_fence_handle *fence) 1308bf215546Sopenharmony_ci{ 1309bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1310bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1311bf215546Sopenharmony_ci 1312bf215546Sopenharmony_ci if (rs->vws->fence_server_sync) 1313bf215546Sopenharmony_ci rs->vws->fence_server_sync(rs->vws, vctx->cbuf, fence); 1314bf215546Sopenharmony_ci} 1315bf215546Sopenharmony_ci 1316bf215546Sopenharmony_cistatic void virgl_set_shader_images(struct pipe_context *ctx, 1317bf215546Sopenharmony_ci enum pipe_shader_type shader, 1318bf215546Sopenharmony_ci unsigned start_slot, unsigned count, 1319bf215546Sopenharmony_ci unsigned unbind_num_trailing_slots, 1320bf215546Sopenharmony_ci const struct pipe_image_view *images) 1321bf215546Sopenharmony_ci{ 1322bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1323bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1324bf215546Sopenharmony_ci struct virgl_shader_binding_state *binding = 1325bf215546Sopenharmony_ci &vctx->shader_bindings[shader]; 1326bf215546Sopenharmony_ci 1327bf215546Sopenharmony_ci binding->image_enabled_mask &= ~u_bit_consecutive(start_slot, count); 1328bf215546Sopenharmony_ci for (unsigned i = 0; i < count; i++) { 1329bf215546Sopenharmony_ci unsigned idx = start_slot + i; 1330bf215546Sopenharmony_ci if (images && images[i].resource) { 1331bf215546Sopenharmony_ci struct virgl_resource *res = virgl_resource(images[i].resource); 1332bf215546Sopenharmony_ci res->bind_history |= PIPE_BIND_SHADER_IMAGE; 1333bf215546Sopenharmony_ci 1334bf215546Sopenharmony_ci pipe_resource_reference(&binding->images[idx].resource, 1335bf215546Sopenharmony_ci images[i].resource); 1336bf215546Sopenharmony_ci binding->images[idx] = images[i]; 1337bf215546Sopenharmony_ci binding->image_enabled_mask |= 1 << idx; 1338bf215546Sopenharmony_ci } else { 1339bf215546Sopenharmony_ci pipe_resource_reference(&binding->images[idx].resource, NULL); 1340bf215546Sopenharmony_ci } 1341bf215546Sopenharmony_ci } 1342bf215546Sopenharmony_ci 1343bf215546Sopenharmony_ci uint32_t max_shader_images = (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE) ? 1344bf215546Sopenharmony_ci rs->caps.caps.v2.max_shader_image_frag_compute : 1345bf215546Sopenharmony_ci rs->caps.caps.v2.max_shader_image_other_stages; 1346bf215546Sopenharmony_ci if (!max_shader_images) 1347bf215546Sopenharmony_ci return; 1348bf215546Sopenharmony_ci virgl_encode_set_shader_images(vctx, shader, start_slot, count, images); 1349bf215546Sopenharmony_ci 1350bf215546Sopenharmony_ci if (unbind_num_trailing_slots) { 1351bf215546Sopenharmony_ci virgl_set_shader_images(ctx, shader, start_slot + count, 1352bf215546Sopenharmony_ci unbind_num_trailing_slots, 0, NULL); 1353bf215546Sopenharmony_ci } 1354bf215546Sopenharmony_ci} 1355bf215546Sopenharmony_ci 1356bf215546Sopenharmony_cistatic void virgl_memory_barrier(struct pipe_context *ctx, 1357bf215546Sopenharmony_ci unsigned flags) 1358bf215546Sopenharmony_ci{ 1359bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1360bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1361bf215546Sopenharmony_ci 1362bf215546Sopenharmony_ci if (!(rs->caps.caps.v2.capability_bits & VIRGL_CAP_MEMORY_BARRIER)) 1363bf215546Sopenharmony_ci return; 1364bf215546Sopenharmony_ci virgl_encode_memory_barrier(vctx, flags); 1365bf215546Sopenharmony_ci} 1366bf215546Sopenharmony_ci 1367bf215546Sopenharmony_cistatic void *virgl_create_compute_state(struct pipe_context *ctx, 1368bf215546Sopenharmony_ci const struct pipe_compute_state *state) 1369bf215546Sopenharmony_ci{ 1370bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1371bf215546Sopenharmony_ci uint32_t handle; 1372bf215546Sopenharmony_ci const struct tgsi_token *ntt_tokens = NULL; 1373bf215546Sopenharmony_ci const struct tgsi_token *tokens; 1374bf215546Sopenharmony_ci struct pipe_stream_output_info so_info = {}; 1375bf215546Sopenharmony_ci int ret; 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci if (state->ir_type == PIPE_SHADER_IR_NIR) { 1378bf215546Sopenharmony_ci struct nir_to_tgsi_options options = { 1379bf215546Sopenharmony_ci .unoptimized_ra = true, 1380bf215546Sopenharmony_ci .lower_fabs = true 1381bf215546Sopenharmony_ci }; 1382bf215546Sopenharmony_ci nir_shader *s = nir_shader_clone(NULL, state->prog); 1383bf215546Sopenharmony_ci ntt_tokens = tokens = nir_to_tgsi_options(s, vctx->base.screen, &options); /* takes ownership */ 1384bf215546Sopenharmony_ci } else { 1385bf215546Sopenharmony_ci tokens = state->prog; 1386bf215546Sopenharmony_ci } 1387bf215546Sopenharmony_ci 1388bf215546Sopenharmony_ci void *new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, tokens, false); 1389bf215546Sopenharmony_ci if (!new_tokens) 1390bf215546Sopenharmony_ci return NULL; 1391bf215546Sopenharmony_ci 1392bf215546Sopenharmony_ci handle = virgl_object_assign_handle(); 1393bf215546Sopenharmony_ci ret = virgl_encode_shader_state(vctx, handle, PIPE_SHADER_COMPUTE, 1394bf215546Sopenharmony_ci &so_info, 1395bf215546Sopenharmony_ci state->req_local_mem, 1396bf215546Sopenharmony_ci new_tokens); 1397bf215546Sopenharmony_ci if (ret) { 1398bf215546Sopenharmony_ci FREE((void *)ntt_tokens); 1399bf215546Sopenharmony_ci return NULL; 1400bf215546Sopenharmony_ci } 1401bf215546Sopenharmony_ci 1402bf215546Sopenharmony_ci FREE((void *)ntt_tokens); 1403bf215546Sopenharmony_ci FREE(new_tokens); 1404bf215546Sopenharmony_ci 1405bf215546Sopenharmony_ci return (void *)(unsigned long)handle; 1406bf215546Sopenharmony_ci} 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_cistatic void virgl_bind_compute_state(struct pipe_context *ctx, void *state) 1409bf215546Sopenharmony_ci{ 1410bf215546Sopenharmony_ci uint32_t handle = (unsigned long)state; 1411bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1412bf215546Sopenharmony_ci 1413bf215546Sopenharmony_ci virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_COMPUTE); 1414bf215546Sopenharmony_ci} 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_cistatic void virgl_delete_compute_state(struct pipe_context *ctx, void *state) 1417bf215546Sopenharmony_ci{ 1418bf215546Sopenharmony_ci uint32_t handle = (unsigned long)state; 1419bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1420bf215546Sopenharmony_ci 1421bf215546Sopenharmony_ci virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER); 1422bf215546Sopenharmony_ci} 1423bf215546Sopenharmony_ci 1424bf215546Sopenharmony_cistatic void virgl_launch_grid(struct pipe_context *ctx, 1425bf215546Sopenharmony_ci const struct pipe_grid_info *info) 1426bf215546Sopenharmony_ci{ 1427bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci if (!vctx->num_compute) 1430bf215546Sopenharmony_ci virgl_reemit_compute_resources(vctx); 1431bf215546Sopenharmony_ci vctx->num_compute++; 1432bf215546Sopenharmony_ci 1433bf215546Sopenharmony_ci virgl_encode_launch_grid(vctx, info); 1434bf215546Sopenharmony_ci} 1435bf215546Sopenharmony_ci 1436bf215546Sopenharmony_cistatic void 1437bf215546Sopenharmony_civirgl_release_shader_binding(struct virgl_context *vctx, 1438bf215546Sopenharmony_ci enum pipe_shader_type shader_type) 1439bf215546Sopenharmony_ci{ 1440bf215546Sopenharmony_ci struct virgl_shader_binding_state *binding = 1441bf215546Sopenharmony_ci &vctx->shader_bindings[shader_type]; 1442bf215546Sopenharmony_ci 1443bf215546Sopenharmony_ci for (int i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; ++i) { 1444bf215546Sopenharmony_ci if (binding->views[i]) { 1445bf215546Sopenharmony_ci pipe_sampler_view_reference( 1446bf215546Sopenharmony_ci (struct pipe_sampler_view **)&binding->views[i], NULL); 1447bf215546Sopenharmony_ci } 1448bf215546Sopenharmony_ci } 1449bf215546Sopenharmony_ci 1450bf215546Sopenharmony_ci while (binding->ubo_enabled_mask) { 1451bf215546Sopenharmony_ci int i = u_bit_scan(&binding->ubo_enabled_mask); 1452bf215546Sopenharmony_ci pipe_resource_reference(&binding->ubos[i].buffer, NULL); 1453bf215546Sopenharmony_ci } 1454bf215546Sopenharmony_ci 1455bf215546Sopenharmony_ci while (binding->ssbo_enabled_mask) { 1456bf215546Sopenharmony_ci int i = u_bit_scan(&binding->ssbo_enabled_mask); 1457bf215546Sopenharmony_ci pipe_resource_reference(&binding->ssbos[i].buffer, NULL); 1458bf215546Sopenharmony_ci } 1459bf215546Sopenharmony_ci 1460bf215546Sopenharmony_ci while (binding->image_enabled_mask) { 1461bf215546Sopenharmony_ci int i = u_bit_scan(&binding->image_enabled_mask); 1462bf215546Sopenharmony_ci pipe_resource_reference(&binding->images[i].resource, NULL); 1463bf215546Sopenharmony_ci } 1464bf215546Sopenharmony_ci} 1465bf215546Sopenharmony_ci 1466bf215546Sopenharmony_cistatic void 1467bf215546Sopenharmony_civirgl_emit_string_marker(struct pipe_context *ctx, const char *message, int len) 1468bf215546Sopenharmony_ci{ 1469bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1470bf215546Sopenharmony_ci virgl_encode_emit_string_marker(vctx, message, len); 1471bf215546Sopenharmony_ci} 1472bf215546Sopenharmony_ci 1473bf215546Sopenharmony_cistatic void 1474bf215546Sopenharmony_civirgl_context_destroy( struct pipe_context *ctx ) 1475bf215546Sopenharmony_ci{ 1476bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1477bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(ctx->screen); 1478bf215546Sopenharmony_ci enum pipe_shader_type shader_type; 1479bf215546Sopenharmony_ci 1480bf215546Sopenharmony_ci vctx->framebuffer.zsbuf = NULL; 1481bf215546Sopenharmony_ci vctx->framebuffer.nr_cbufs = 0; 1482bf215546Sopenharmony_ci virgl_encoder_destroy_sub_ctx(vctx, vctx->hw_sub_ctx_id); 1483bf215546Sopenharmony_ci virgl_flush_eq(vctx, vctx, NULL); 1484bf215546Sopenharmony_ci 1485bf215546Sopenharmony_ci for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) 1486bf215546Sopenharmony_ci virgl_release_shader_binding(vctx, shader_type); 1487bf215546Sopenharmony_ci 1488bf215546Sopenharmony_ci while (vctx->atomic_buffer_enabled_mask) { 1489bf215546Sopenharmony_ci int i = u_bit_scan(&vctx->atomic_buffer_enabled_mask); 1490bf215546Sopenharmony_ci pipe_resource_reference(&vctx->atomic_buffers[i].buffer, NULL); 1491bf215546Sopenharmony_ci } 1492bf215546Sopenharmony_ci 1493bf215546Sopenharmony_ci rs->vws->cmd_buf_destroy(vctx->cbuf); 1494bf215546Sopenharmony_ci if (vctx->uploader) 1495bf215546Sopenharmony_ci u_upload_destroy(vctx->uploader); 1496bf215546Sopenharmony_ci if (vctx->supports_staging) 1497bf215546Sopenharmony_ci virgl_staging_destroy(&vctx->staging); 1498bf215546Sopenharmony_ci util_primconvert_destroy(vctx->primconvert); 1499bf215546Sopenharmony_ci virgl_transfer_queue_fini(&vctx->queue); 1500bf215546Sopenharmony_ci 1501bf215546Sopenharmony_ci slab_destroy_child(&vctx->transfer_pool); 1502bf215546Sopenharmony_ci FREE(vctx); 1503bf215546Sopenharmony_ci} 1504bf215546Sopenharmony_ci 1505bf215546Sopenharmony_cistatic void virgl_get_sample_position(struct pipe_context *ctx, 1506bf215546Sopenharmony_ci unsigned sample_count, 1507bf215546Sopenharmony_ci unsigned index, 1508bf215546Sopenharmony_ci float *out_value) 1509bf215546Sopenharmony_ci{ 1510bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1511bf215546Sopenharmony_ci struct virgl_screen *vs = virgl_screen(vctx->base.screen); 1512bf215546Sopenharmony_ci 1513bf215546Sopenharmony_ci if (sample_count > vs->caps.caps.v1.max_samples) { 1514bf215546Sopenharmony_ci debug_printf("VIRGL: requested %d MSAA samples, but only %d supported\n", 1515bf215546Sopenharmony_ci sample_count, vs->caps.caps.v1.max_samples); 1516bf215546Sopenharmony_ci return; 1517bf215546Sopenharmony_ci } 1518bf215546Sopenharmony_ci 1519bf215546Sopenharmony_ci /* The following is basically copied from dri/i965gen6_get_sample_position 1520bf215546Sopenharmony_ci * The only addition is that we hold the msaa positions for all sample 1521bf215546Sopenharmony_ci * counts in a flat array. */ 1522bf215546Sopenharmony_ci uint32_t bits = 0; 1523bf215546Sopenharmony_ci if (sample_count == 1) { 1524bf215546Sopenharmony_ci out_value[0] = out_value[1] = 0.5f; 1525bf215546Sopenharmony_ci return; 1526bf215546Sopenharmony_ci } else if (sample_count == 2) { 1527bf215546Sopenharmony_ci bits = vs->caps.caps.v2.sample_locations[0] >> (8 * index); 1528bf215546Sopenharmony_ci } else if (sample_count <= 4) { 1529bf215546Sopenharmony_ci bits = vs->caps.caps.v2.sample_locations[1] >> (8 * index); 1530bf215546Sopenharmony_ci } else if (sample_count <= 8) { 1531bf215546Sopenharmony_ci bits = vs->caps.caps.v2.sample_locations[2 + (index >> 2)] >> (8 * (index & 3)); 1532bf215546Sopenharmony_ci } else if (sample_count <= 16) { 1533bf215546Sopenharmony_ci bits = vs->caps.caps.v2.sample_locations[4 + (index >> 2)] >> (8 * (index & 3)); 1534bf215546Sopenharmony_ci } 1535bf215546Sopenharmony_ci out_value[0] = ((bits >> 4) & 0xf) / 16.0f; 1536bf215546Sopenharmony_ci out_value[1] = (bits & 0xf) / 16.0f; 1537bf215546Sopenharmony_ci 1538bf215546Sopenharmony_ci if (virgl_debug & VIRGL_DEBUG_VERBOSE) 1539bf215546Sopenharmony_ci debug_printf("VIRGL: sample postion [%2d/%2d] = (%f, %f)\n", 1540bf215546Sopenharmony_ci index, sample_count, out_value[0], out_value[1]); 1541bf215546Sopenharmony_ci} 1542bf215546Sopenharmony_ci 1543bf215546Sopenharmony_cistatic void virgl_send_tweaks(struct virgl_context *vctx, struct virgl_screen *rs) 1544bf215546Sopenharmony_ci{ 1545bf215546Sopenharmony_ci if (rs->tweak_gles_emulate_bgra) 1546bf215546Sopenharmony_ci virgl_encode_tweak(vctx, virgl_tweak_gles_brga_emulate, 1); 1547bf215546Sopenharmony_ci 1548bf215546Sopenharmony_ci if (rs->tweak_gles_apply_bgra_dest_swizzle) 1549bf215546Sopenharmony_ci virgl_encode_tweak(vctx, virgl_tweak_gles_brga_apply_dest_swizzle, 1); 1550bf215546Sopenharmony_ci 1551bf215546Sopenharmony_ci if (rs->tweak_gles_tf3_value > 0) 1552bf215546Sopenharmony_ci virgl_encode_tweak(vctx, virgl_tweak_gles_tf3_samples_passes_multiplier, 1553bf215546Sopenharmony_ci rs->tweak_gles_tf3_value); 1554bf215546Sopenharmony_ci} 1555bf215546Sopenharmony_ci 1556bf215546Sopenharmony_cistatic void virgl_link_shader(struct pipe_context *ctx, void **handles) 1557bf215546Sopenharmony_ci{ 1558bf215546Sopenharmony_ci struct virgl_context *vctx = virgl_context(ctx); 1559bf215546Sopenharmony_ci uint32_t shader_handles[PIPE_SHADER_TYPES]; 1560bf215546Sopenharmony_ci for (uint32_t i = 0; i < PIPE_SHADER_TYPES; ++i) 1561bf215546Sopenharmony_ci shader_handles[i] = (uintptr_t)handles[i]; 1562bf215546Sopenharmony_ci virgl_encode_link_shader(vctx, shader_handles); 1563bf215546Sopenharmony_ci} 1564bf215546Sopenharmony_ci 1565bf215546Sopenharmony_cistruct pipe_context *virgl_context_create(struct pipe_screen *pscreen, 1566bf215546Sopenharmony_ci void *priv, 1567bf215546Sopenharmony_ci unsigned flags) 1568bf215546Sopenharmony_ci{ 1569bf215546Sopenharmony_ci struct virgl_context *vctx; 1570bf215546Sopenharmony_ci struct virgl_screen *rs = virgl_screen(pscreen); 1571bf215546Sopenharmony_ci vctx = CALLOC_STRUCT(virgl_context); 1572bf215546Sopenharmony_ci const char *host_debug_flagstring; 1573bf215546Sopenharmony_ci 1574bf215546Sopenharmony_ci vctx->cbuf = rs->vws->cmd_buf_create(rs->vws, VIRGL_MAX_CMDBUF_DWORDS); 1575bf215546Sopenharmony_ci if (!vctx->cbuf) { 1576bf215546Sopenharmony_ci FREE(vctx); 1577bf215546Sopenharmony_ci return NULL; 1578bf215546Sopenharmony_ci } 1579bf215546Sopenharmony_ci 1580bf215546Sopenharmony_ci vctx->base.destroy = virgl_context_destroy; 1581bf215546Sopenharmony_ci vctx->base.create_surface = virgl_create_surface; 1582bf215546Sopenharmony_ci vctx->base.surface_destroy = virgl_surface_destroy; 1583bf215546Sopenharmony_ci vctx->base.set_framebuffer_state = virgl_set_framebuffer_state; 1584bf215546Sopenharmony_ci vctx->base.create_blend_state = virgl_create_blend_state; 1585bf215546Sopenharmony_ci vctx->base.bind_blend_state = virgl_bind_blend_state; 1586bf215546Sopenharmony_ci vctx->base.delete_blend_state = virgl_delete_blend_state; 1587bf215546Sopenharmony_ci vctx->base.create_depth_stencil_alpha_state = virgl_create_depth_stencil_alpha_state; 1588bf215546Sopenharmony_ci vctx->base.bind_depth_stencil_alpha_state = virgl_bind_depth_stencil_alpha_state; 1589bf215546Sopenharmony_ci vctx->base.delete_depth_stencil_alpha_state = virgl_delete_depth_stencil_alpha_state; 1590bf215546Sopenharmony_ci vctx->base.create_rasterizer_state = virgl_create_rasterizer_state; 1591bf215546Sopenharmony_ci vctx->base.bind_rasterizer_state = virgl_bind_rasterizer_state; 1592bf215546Sopenharmony_ci vctx->base.delete_rasterizer_state = virgl_delete_rasterizer_state; 1593bf215546Sopenharmony_ci 1594bf215546Sopenharmony_ci vctx->base.set_viewport_states = virgl_set_viewport_states; 1595bf215546Sopenharmony_ci vctx->base.create_vertex_elements_state = virgl_create_vertex_elements_state; 1596bf215546Sopenharmony_ci vctx->base.bind_vertex_elements_state = virgl_bind_vertex_elements_state; 1597bf215546Sopenharmony_ci vctx->base.delete_vertex_elements_state = virgl_delete_vertex_elements_state; 1598bf215546Sopenharmony_ci vctx->base.set_vertex_buffers = virgl_set_vertex_buffers; 1599bf215546Sopenharmony_ci vctx->base.set_constant_buffer = virgl_set_constant_buffer; 1600bf215546Sopenharmony_ci 1601bf215546Sopenharmony_ci vctx->base.set_tess_state = virgl_set_tess_state; 1602bf215546Sopenharmony_ci vctx->base.set_patch_vertices = virgl_set_patch_vertices; 1603bf215546Sopenharmony_ci vctx->base.create_vs_state = virgl_create_vs_state; 1604bf215546Sopenharmony_ci vctx->base.create_tcs_state = virgl_create_tcs_state; 1605bf215546Sopenharmony_ci vctx->base.create_tes_state = virgl_create_tes_state; 1606bf215546Sopenharmony_ci vctx->base.create_gs_state = virgl_create_gs_state; 1607bf215546Sopenharmony_ci vctx->base.create_fs_state = virgl_create_fs_state; 1608bf215546Sopenharmony_ci 1609bf215546Sopenharmony_ci vctx->base.bind_vs_state = virgl_bind_vs_state; 1610bf215546Sopenharmony_ci vctx->base.bind_tcs_state = virgl_bind_tcs_state; 1611bf215546Sopenharmony_ci vctx->base.bind_tes_state = virgl_bind_tes_state; 1612bf215546Sopenharmony_ci vctx->base.bind_gs_state = virgl_bind_gs_state; 1613bf215546Sopenharmony_ci vctx->base.bind_fs_state = virgl_bind_fs_state; 1614bf215546Sopenharmony_ci 1615bf215546Sopenharmony_ci vctx->base.delete_vs_state = virgl_delete_vs_state; 1616bf215546Sopenharmony_ci vctx->base.delete_tcs_state = virgl_delete_tcs_state; 1617bf215546Sopenharmony_ci vctx->base.delete_tes_state = virgl_delete_tes_state; 1618bf215546Sopenharmony_ci vctx->base.delete_gs_state = virgl_delete_gs_state; 1619bf215546Sopenharmony_ci vctx->base.delete_fs_state = virgl_delete_fs_state; 1620bf215546Sopenharmony_ci 1621bf215546Sopenharmony_ci vctx->base.create_compute_state = virgl_create_compute_state; 1622bf215546Sopenharmony_ci vctx->base.bind_compute_state = virgl_bind_compute_state; 1623bf215546Sopenharmony_ci vctx->base.delete_compute_state = virgl_delete_compute_state; 1624bf215546Sopenharmony_ci vctx->base.launch_grid = virgl_launch_grid; 1625bf215546Sopenharmony_ci 1626bf215546Sopenharmony_ci vctx->base.clear = virgl_clear; 1627bf215546Sopenharmony_ci vctx->base.clear_texture = virgl_clear_texture; 1628bf215546Sopenharmony_ci vctx->base.draw_vbo = virgl_draw_vbo; 1629bf215546Sopenharmony_ci vctx->base.flush = virgl_flush_from_st; 1630bf215546Sopenharmony_ci vctx->base.screen = pscreen; 1631bf215546Sopenharmony_ci vctx->base.create_sampler_view = virgl_create_sampler_view; 1632bf215546Sopenharmony_ci vctx->base.sampler_view_destroy = virgl_destroy_sampler_view; 1633bf215546Sopenharmony_ci vctx->base.set_sampler_views = virgl_set_sampler_views; 1634bf215546Sopenharmony_ci vctx->base.texture_barrier = virgl_texture_barrier; 1635bf215546Sopenharmony_ci 1636bf215546Sopenharmony_ci vctx->base.create_sampler_state = virgl_create_sampler_state; 1637bf215546Sopenharmony_ci vctx->base.delete_sampler_state = virgl_delete_sampler_state; 1638bf215546Sopenharmony_ci vctx->base.bind_sampler_states = virgl_bind_sampler_states; 1639bf215546Sopenharmony_ci 1640bf215546Sopenharmony_ci vctx->base.set_polygon_stipple = virgl_set_polygon_stipple; 1641bf215546Sopenharmony_ci vctx->base.set_scissor_states = virgl_set_scissor_states; 1642bf215546Sopenharmony_ci vctx->base.set_sample_mask = virgl_set_sample_mask; 1643bf215546Sopenharmony_ci vctx->base.set_min_samples = virgl_set_min_samples; 1644bf215546Sopenharmony_ci vctx->base.set_stencil_ref = virgl_set_stencil_ref; 1645bf215546Sopenharmony_ci vctx->base.set_clip_state = virgl_set_clip_state; 1646bf215546Sopenharmony_ci 1647bf215546Sopenharmony_ci vctx->base.set_blend_color = virgl_set_blend_color; 1648bf215546Sopenharmony_ci 1649bf215546Sopenharmony_ci vctx->base.get_sample_position = virgl_get_sample_position; 1650bf215546Sopenharmony_ci 1651bf215546Sopenharmony_ci vctx->base.resource_copy_region = virgl_resource_copy_region; 1652bf215546Sopenharmony_ci vctx->base.flush_resource = virgl_flush_resource; 1653bf215546Sopenharmony_ci vctx->base.blit = virgl_blit; 1654bf215546Sopenharmony_ci vctx->base.create_fence_fd = virgl_create_fence_fd; 1655bf215546Sopenharmony_ci vctx->base.fence_server_sync = virgl_fence_server_sync; 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci vctx->base.set_shader_buffers = virgl_set_shader_buffers; 1658bf215546Sopenharmony_ci vctx->base.set_hw_atomic_buffers = virgl_set_hw_atomic_buffers; 1659bf215546Sopenharmony_ci vctx->base.set_shader_images = virgl_set_shader_images; 1660bf215546Sopenharmony_ci vctx->base.memory_barrier = virgl_memory_barrier; 1661bf215546Sopenharmony_ci vctx->base.emit_string_marker = virgl_emit_string_marker; 1662bf215546Sopenharmony_ci 1663bf215546Sopenharmony_ci if (rs->caps.caps.v2.host_feature_check_version >= 7) 1664bf215546Sopenharmony_ci vctx->base.link_shader = virgl_link_shader; 1665bf215546Sopenharmony_ci 1666bf215546Sopenharmony_ci virgl_init_context_resource_functions(&vctx->base); 1667bf215546Sopenharmony_ci virgl_init_query_functions(vctx); 1668bf215546Sopenharmony_ci virgl_init_so_functions(vctx); 1669bf215546Sopenharmony_ci 1670bf215546Sopenharmony_ci slab_create_child(&vctx->transfer_pool, &rs->transfer_pool); 1671bf215546Sopenharmony_ci virgl_transfer_queue_init(&vctx->queue, vctx); 1672bf215546Sopenharmony_ci vctx->encoded_transfers = (rs->vws->supports_encoded_transfers && 1673bf215546Sopenharmony_ci (rs->caps.caps.v2.capability_bits & VIRGL_CAP_TRANSFER)); 1674bf215546Sopenharmony_ci 1675bf215546Sopenharmony_ci /* Reserve some space for transfers. */ 1676bf215546Sopenharmony_ci if (vctx->encoded_transfers) 1677bf215546Sopenharmony_ci vctx->cbuf->cdw = VIRGL_MAX_TBUF_DWORDS; 1678bf215546Sopenharmony_ci 1679bf215546Sopenharmony_ci vctx->primconvert = util_primconvert_create(&vctx->base, rs->caps.caps.v1.prim_mask); 1680bf215546Sopenharmony_ci vctx->uploader = u_upload_create(&vctx->base, 1024 * 1024, 1681bf215546Sopenharmony_ci PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_STREAM, 0); 1682bf215546Sopenharmony_ci if (!vctx->uploader) 1683bf215546Sopenharmony_ci goto fail; 1684bf215546Sopenharmony_ci vctx->base.stream_uploader = vctx->uploader; 1685bf215546Sopenharmony_ci vctx->base.const_uploader = vctx->uploader; 1686bf215546Sopenharmony_ci 1687bf215546Sopenharmony_ci /* We use a special staging buffer as the source of copy transfers. */ 1688bf215546Sopenharmony_ci if ((rs->caps.caps.v2.capability_bits & VIRGL_CAP_COPY_TRANSFER) && 1689bf215546Sopenharmony_ci vctx->encoded_transfers) { 1690bf215546Sopenharmony_ci virgl_staging_init(&vctx->staging, &vctx->base, 1024 * 1024); 1691bf215546Sopenharmony_ci vctx->supports_staging = true; 1692bf215546Sopenharmony_ci } 1693bf215546Sopenharmony_ci 1694bf215546Sopenharmony_ci vctx->hw_sub_ctx_id = p_atomic_inc_return(&rs->sub_ctx_id); 1695bf215546Sopenharmony_ci virgl_encoder_create_sub_ctx(vctx, vctx->hw_sub_ctx_id); 1696bf215546Sopenharmony_ci 1697bf215546Sopenharmony_ci virgl_encoder_set_sub_ctx(vctx, vctx->hw_sub_ctx_id); 1698bf215546Sopenharmony_ci 1699bf215546Sopenharmony_ci if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_GUEST_MAY_INIT_LOG) { 1700bf215546Sopenharmony_ci host_debug_flagstring = getenv("VIRGL_HOST_DEBUG"); 1701bf215546Sopenharmony_ci if (host_debug_flagstring) 1702bf215546Sopenharmony_ci virgl_encode_host_debug_flagstring(vctx, host_debug_flagstring); 1703bf215546Sopenharmony_ci } 1704bf215546Sopenharmony_ci 1705bf215546Sopenharmony_ci if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_APP_TWEAK_SUPPORT) 1706bf215546Sopenharmony_ci virgl_send_tweaks(vctx, rs); 1707bf215546Sopenharmony_ci 1708bf215546Sopenharmony_ci return &vctx->base; 1709bf215546Sopenharmony_cifail: 1710bf215546Sopenharmony_ci virgl_context_destroy(&vctx->base); 1711bf215546Sopenharmony_ci return NULL; 1712bf215546Sopenharmony_ci} 1713