virgl_encode.c revision 9f464c52
1/* 2 * Copyright 2014, 2015 Red Hat. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23#include <stdint.h> 24#include <assert.h> 25#include <string.h> 26 27#include "util/u_format.h" 28#include "util/u_memory.h" 29#include "util/u_math.h" 30#include "pipe/p_state.h" 31#include "tgsi/tgsi_dump.h" 32#include "tgsi/tgsi_parse.h" 33 34#include "virgl_context.h" 35#include "virgl_encode.h" 36#include "virgl_protocol.h" 37#include "virgl_resource.h" 38#include "virgl_screen.h" 39 40#define VIRGL_ENCODE_MAX_DWORDS MIN2(VIRGL_MAX_CMDBUF_DWORDS, VIRGL_CMD0_MAX_DWORDS) 41 42static int virgl_encoder_write_cmd_dword(struct virgl_context *ctx, 43 uint32_t dword) 44{ 45 int len = (dword >> 16); 46 47 if ((ctx->cbuf->cdw + len + 1) > VIRGL_MAX_CMDBUF_DWORDS) 48 ctx->base.flush(&ctx->base, NULL, 0); 49 50 virgl_encoder_write_dword(ctx->cbuf, dword); 51 return 0; 52} 53 54static void virgl_encoder_emit_resource(struct virgl_screen *vs, 55 struct virgl_cmd_buf *buf, 56 struct virgl_resource *res) 57{ 58 struct virgl_winsys *vws = vs->vws; 59 if (res && res->hw_res) 60 vws->emit_res(vws, buf, res->hw_res, TRUE); 61 else { 62 virgl_encoder_write_dword(buf, 0); 63 } 64} 65 66static void virgl_encoder_write_res(struct virgl_context *ctx, 67 struct virgl_resource *res) 68{ 69 struct virgl_screen *vs = virgl_screen(ctx->base.screen); 70 virgl_encoder_emit_resource(vs, ctx->cbuf, res); 71} 72 73int virgl_encode_bind_object(struct virgl_context *ctx, 74 uint32_t handle, uint32_t object) 75{ 76 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_BIND_OBJECT, object, 1)); 77 virgl_encoder_write_dword(ctx->cbuf, handle); 78 return 0; 79} 80 81int virgl_encode_delete_object(struct virgl_context *ctx, 82 uint32_t handle, uint32_t object) 83{ 84 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DESTROY_OBJECT, object, 1)); 85 virgl_encoder_write_dword(ctx->cbuf, handle); 86 return 0; 87} 88 89int virgl_encode_blend_state(struct virgl_context *ctx, 90 uint32_t handle, 91 const struct pipe_blend_state *blend_state) 92{ 93 uint32_t tmp; 94 int i; 95 96 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_BLEND, VIRGL_OBJ_BLEND_SIZE)); 97 virgl_encoder_write_dword(ctx->cbuf, handle); 98 99 tmp = 100 VIRGL_OBJ_BLEND_S0_INDEPENDENT_BLEND_ENABLE(blend_state->independent_blend_enable) | 101 VIRGL_OBJ_BLEND_S0_LOGICOP_ENABLE(blend_state->logicop_enable) | 102 VIRGL_OBJ_BLEND_S0_DITHER(blend_state->dither) | 103 VIRGL_OBJ_BLEND_S0_ALPHA_TO_COVERAGE(blend_state->alpha_to_coverage) | 104 VIRGL_OBJ_BLEND_S0_ALPHA_TO_ONE(blend_state->alpha_to_one); 105 106 virgl_encoder_write_dword(ctx->cbuf, tmp); 107 108 tmp = VIRGL_OBJ_BLEND_S1_LOGICOP_FUNC(blend_state->logicop_func); 109 virgl_encoder_write_dword(ctx->cbuf, tmp); 110 111 for (i = 0; i < VIRGL_MAX_COLOR_BUFS; i++) { 112 tmp = 113 VIRGL_OBJ_BLEND_S2_RT_BLEND_ENABLE(blend_state->rt[i].blend_enable) | 114 VIRGL_OBJ_BLEND_S2_RT_RGB_FUNC(blend_state->rt[i].rgb_func) | 115 VIRGL_OBJ_BLEND_S2_RT_RGB_SRC_FACTOR(blend_state->rt[i].rgb_src_factor) | 116 VIRGL_OBJ_BLEND_S2_RT_RGB_DST_FACTOR(blend_state->rt[i].rgb_dst_factor)| 117 VIRGL_OBJ_BLEND_S2_RT_ALPHA_FUNC(blend_state->rt[i].alpha_func) | 118 VIRGL_OBJ_BLEND_S2_RT_ALPHA_SRC_FACTOR(blend_state->rt[i].alpha_src_factor) | 119 VIRGL_OBJ_BLEND_S2_RT_ALPHA_DST_FACTOR(blend_state->rt[i].alpha_dst_factor) | 120 VIRGL_OBJ_BLEND_S2_RT_COLORMASK(blend_state->rt[i].colormask); 121 virgl_encoder_write_dword(ctx->cbuf, tmp); 122 } 123 return 0; 124} 125 126int virgl_encode_dsa_state(struct virgl_context *ctx, 127 uint32_t handle, 128 const struct pipe_depth_stencil_alpha_state *dsa_state) 129{ 130 uint32_t tmp; 131 int i; 132 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_DSA, VIRGL_OBJ_DSA_SIZE)); 133 virgl_encoder_write_dword(ctx->cbuf, handle); 134 135 tmp = VIRGL_OBJ_DSA_S0_DEPTH_ENABLE(dsa_state->depth.enabled) | 136 VIRGL_OBJ_DSA_S0_DEPTH_WRITEMASK(dsa_state->depth.writemask) | 137 VIRGL_OBJ_DSA_S0_DEPTH_FUNC(dsa_state->depth.func) | 138 VIRGL_OBJ_DSA_S0_ALPHA_ENABLED(dsa_state->alpha.enabled) | 139 VIRGL_OBJ_DSA_S0_ALPHA_FUNC(dsa_state->alpha.func); 140 virgl_encoder_write_dword(ctx->cbuf, tmp); 141 142 for (i = 0; i < 2; i++) { 143 tmp = VIRGL_OBJ_DSA_S1_STENCIL_ENABLED(dsa_state->stencil[i].enabled) | 144 VIRGL_OBJ_DSA_S1_STENCIL_FUNC(dsa_state->stencil[i].func) | 145 VIRGL_OBJ_DSA_S1_STENCIL_FAIL_OP(dsa_state->stencil[i].fail_op) | 146 VIRGL_OBJ_DSA_S1_STENCIL_ZPASS_OP(dsa_state->stencil[i].zpass_op) | 147 VIRGL_OBJ_DSA_S1_STENCIL_ZFAIL_OP(dsa_state->stencil[i].zfail_op) | 148 VIRGL_OBJ_DSA_S1_STENCIL_VALUEMASK(dsa_state->stencil[i].valuemask) | 149 VIRGL_OBJ_DSA_S1_STENCIL_WRITEMASK(dsa_state->stencil[i].writemask); 150 virgl_encoder_write_dword(ctx->cbuf, tmp); 151 } 152 153 virgl_encoder_write_dword(ctx->cbuf, fui(dsa_state->alpha.ref_value)); 154 return 0; 155} 156int virgl_encode_rasterizer_state(struct virgl_context *ctx, 157 uint32_t handle, 158 const struct pipe_rasterizer_state *state) 159{ 160 uint32_t tmp; 161 162 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_RASTERIZER, VIRGL_OBJ_RS_SIZE)); 163 virgl_encoder_write_dword(ctx->cbuf, handle); 164 165 tmp = VIRGL_OBJ_RS_S0_FLATSHADE(state->flatshade) | 166 VIRGL_OBJ_RS_S0_DEPTH_CLIP(state->depth_clip_near) | 167 VIRGL_OBJ_RS_S0_CLIP_HALFZ(state->clip_halfz) | 168 VIRGL_OBJ_RS_S0_RASTERIZER_DISCARD(state->rasterizer_discard) | 169 VIRGL_OBJ_RS_S0_FLATSHADE_FIRST(state->flatshade_first) | 170 VIRGL_OBJ_RS_S0_LIGHT_TWOSIZE(state->light_twoside) | 171 VIRGL_OBJ_RS_S0_SPRITE_COORD_MODE(state->sprite_coord_mode) | 172 VIRGL_OBJ_RS_S0_POINT_QUAD_RASTERIZATION(state->point_quad_rasterization) | 173 VIRGL_OBJ_RS_S0_CULL_FACE(state->cull_face) | 174 VIRGL_OBJ_RS_S0_FILL_FRONT(state->fill_front) | 175 VIRGL_OBJ_RS_S0_FILL_BACK(state->fill_back) | 176 VIRGL_OBJ_RS_S0_SCISSOR(state->scissor) | 177 VIRGL_OBJ_RS_S0_FRONT_CCW(state->front_ccw) | 178 VIRGL_OBJ_RS_S0_CLAMP_VERTEX_COLOR(state->clamp_vertex_color) | 179 VIRGL_OBJ_RS_S0_CLAMP_FRAGMENT_COLOR(state->clamp_fragment_color) | 180 VIRGL_OBJ_RS_S0_OFFSET_LINE(state->offset_line) | 181 VIRGL_OBJ_RS_S0_OFFSET_POINT(state->offset_point) | 182 VIRGL_OBJ_RS_S0_OFFSET_TRI(state->offset_tri) | 183 VIRGL_OBJ_RS_S0_POLY_SMOOTH(state->poly_smooth) | 184 VIRGL_OBJ_RS_S0_POLY_STIPPLE_ENABLE(state->poly_stipple_enable) | 185 VIRGL_OBJ_RS_S0_POINT_SMOOTH(state->point_smooth) | 186 VIRGL_OBJ_RS_S0_POINT_SIZE_PER_VERTEX(state->point_size_per_vertex) | 187 VIRGL_OBJ_RS_S0_MULTISAMPLE(state->multisample) | 188 VIRGL_OBJ_RS_S0_LINE_SMOOTH(state->line_smooth) | 189 VIRGL_OBJ_RS_S0_LINE_STIPPLE_ENABLE(state->line_stipple_enable) | 190 VIRGL_OBJ_RS_S0_LINE_LAST_PIXEL(state->line_last_pixel) | 191 VIRGL_OBJ_RS_S0_HALF_PIXEL_CENTER(state->half_pixel_center) | 192 VIRGL_OBJ_RS_S0_BOTTOM_EDGE_RULE(state->bottom_edge_rule) | 193 VIRGL_OBJ_RS_S0_FORCE_PERSAMPLE_INTERP(state->force_persample_interp); 194 195 virgl_encoder_write_dword(ctx->cbuf, tmp); /* S0 */ 196 virgl_encoder_write_dword(ctx->cbuf, fui(state->point_size)); /* S1 */ 197 virgl_encoder_write_dword(ctx->cbuf, state->sprite_coord_enable); /* S2 */ 198 tmp = VIRGL_OBJ_RS_S3_LINE_STIPPLE_PATTERN(state->line_stipple_pattern) | 199 VIRGL_OBJ_RS_S3_LINE_STIPPLE_FACTOR(state->line_stipple_factor) | 200 VIRGL_OBJ_RS_S3_CLIP_PLANE_ENABLE(state->clip_plane_enable); 201 virgl_encoder_write_dword(ctx->cbuf, tmp); /* S3 */ 202 virgl_encoder_write_dword(ctx->cbuf, fui(state->line_width)); /* S4 */ 203 virgl_encoder_write_dword(ctx->cbuf, fui(state->offset_units)); /* S5 */ 204 virgl_encoder_write_dword(ctx->cbuf, fui(state->offset_scale)); /* S6 */ 205 virgl_encoder_write_dword(ctx->cbuf, fui(state->offset_clamp)); /* S7 */ 206 return 0; 207} 208 209static void virgl_emit_shader_header(struct virgl_context *ctx, 210 uint32_t handle, uint32_t len, 211 uint32_t type, uint32_t offlen, 212 uint32_t num_tokens) 213{ 214 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_SHADER, len)); 215 virgl_encoder_write_dword(ctx->cbuf, handle); 216 virgl_encoder_write_dword(ctx->cbuf, type); 217 virgl_encoder_write_dword(ctx->cbuf, offlen); 218 virgl_encoder_write_dword(ctx->cbuf, num_tokens); 219} 220 221static void virgl_emit_shader_streamout(struct virgl_context *ctx, 222 const struct pipe_stream_output_info *so_info) 223{ 224 int num_outputs = 0; 225 int i; 226 uint32_t tmp; 227 228 if (so_info) 229 num_outputs = so_info->num_outputs; 230 231 virgl_encoder_write_dword(ctx->cbuf, num_outputs); 232 if (num_outputs) { 233 for (i = 0; i < 4; i++) 234 virgl_encoder_write_dword(ctx->cbuf, so_info->stride[i]); 235 236 for (i = 0; i < so_info->num_outputs; i++) { 237 tmp = 238 VIRGL_OBJ_SHADER_SO_OUTPUT_REGISTER_INDEX(so_info->output[i].register_index) | 239 VIRGL_OBJ_SHADER_SO_OUTPUT_START_COMPONENT(so_info->output[i].start_component) | 240 VIRGL_OBJ_SHADER_SO_OUTPUT_NUM_COMPONENTS(so_info->output[i].num_components) | 241 VIRGL_OBJ_SHADER_SO_OUTPUT_BUFFER(so_info->output[i].output_buffer) | 242 VIRGL_OBJ_SHADER_SO_OUTPUT_DST_OFFSET(so_info->output[i].dst_offset); 243 virgl_encoder_write_dword(ctx->cbuf, tmp); 244 virgl_encoder_write_dword(ctx->cbuf, so_info->output[i].stream); 245 } 246 } 247} 248 249int virgl_encode_shader_state(struct virgl_context *ctx, 250 uint32_t handle, 251 uint32_t type, 252 const struct pipe_stream_output_info *so_info, 253 uint32_t cs_req_local_mem, 254 const struct tgsi_token *tokens) 255{ 256 char *str, *sptr; 257 uint32_t shader_len, len; 258 bool bret; 259 int num_tokens = tgsi_num_tokens(tokens); 260 int str_total_size = 65536; 261 int retry_size = 1; 262 uint32_t left_bytes, base_hdr_size, strm_hdr_size, thispass; 263 bool first_pass; 264 str = CALLOC(1, str_total_size); 265 if (!str) 266 return -1; 267 268 do { 269 int old_size; 270 271 bret = tgsi_dump_str(tokens, TGSI_DUMP_FLOAT_AS_HEX, str, str_total_size); 272 if (bret == false) { 273 if (virgl_debug & VIRGL_DEBUG_VERBOSE) 274 debug_printf("Failed to translate shader in available space - trying again\n"); 275 old_size = str_total_size; 276 str_total_size = 65536 * ++retry_size; 277 str = REALLOC(str, old_size, str_total_size); 278 if (!str) 279 return -1; 280 } 281 } while (bret == false && retry_size < 10); 282 283 if (bret == false) 284 return -1; 285 286 if (virgl_debug & VIRGL_DEBUG_TGSI) 287 debug_printf("TGSI:\n---8<---\n%s\n---8<---\n", str); 288 289 shader_len = strlen(str) + 1; 290 291 left_bytes = shader_len; 292 293 base_hdr_size = 5; 294 strm_hdr_size = so_info->num_outputs ? so_info->num_outputs * 2 + 4 : 0; 295 first_pass = true; 296 sptr = str; 297 while (left_bytes) { 298 uint32_t length, offlen; 299 int hdr_len = base_hdr_size + (first_pass ? strm_hdr_size : 0); 300 if (ctx->cbuf->cdw + hdr_len + 1 >= VIRGL_ENCODE_MAX_DWORDS) 301 ctx->base.flush(&ctx->base, NULL, 0); 302 303 thispass = (VIRGL_ENCODE_MAX_DWORDS - ctx->cbuf->cdw - hdr_len - 1) * 4; 304 305 length = MIN2(thispass, left_bytes); 306 len = ((length + 3) / 4) + hdr_len; 307 308 if (first_pass) 309 offlen = VIRGL_OBJ_SHADER_OFFSET_VAL(shader_len); 310 else 311 offlen = VIRGL_OBJ_SHADER_OFFSET_VAL((uintptr_t)sptr - (uintptr_t)str) | VIRGL_OBJ_SHADER_OFFSET_CONT; 312 313 virgl_emit_shader_header(ctx, handle, len, type, offlen, num_tokens); 314 315 if (type == PIPE_SHADER_COMPUTE) 316 virgl_encoder_write_dword(ctx->cbuf, cs_req_local_mem); 317 else 318 virgl_emit_shader_streamout(ctx, first_pass ? so_info : NULL); 319 320 virgl_encoder_write_block(ctx->cbuf, (uint8_t *)sptr, length); 321 322 sptr += length; 323 first_pass = false; 324 left_bytes -= length; 325 } 326 327 FREE(str); 328 return 0; 329} 330 331 332int virgl_encode_clear(struct virgl_context *ctx, 333 unsigned buffers, 334 const union pipe_color_union *color, 335 double depth, unsigned stencil) 336{ 337 int i; 338 uint64_t qword; 339 340 STATIC_ASSERT(sizeof(qword) == sizeof(depth)); 341 memcpy(&qword, &depth, sizeof(qword)); 342 343 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CLEAR, 0, VIRGL_OBJ_CLEAR_SIZE)); 344 virgl_encoder_write_dword(ctx->cbuf, buffers); 345 for (i = 0; i < 4; i++) 346 virgl_encoder_write_dword(ctx->cbuf, color->ui[i]); 347 virgl_encoder_write_qword(ctx->cbuf, qword); 348 virgl_encoder_write_dword(ctx->cbuf, stencil); 349 return 0; 350} 351 352int virgl_encoder_set_framebuffer_state(struct virgl_context *ctx, 353 const struct pipe_framebuffer_state *state) 354{ 355 struct virgl_surface *zsurf = virgl_surface(state->zsbuf); 356 int i; 357 358 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_FRAMEBUFFER_STATE, 0, VIRGL_SET_FRAMEBUFFER_STATE_SIZE(state->nr_cbufs))); 359 virgl_encoder_write_dword(ctx->cbuf, state->nr_cbufs); 360 virgl_encoder_write_dword(ctx->cbuf, zsurf ? zsurf->handle : 0); 361 for (i = 0; i < state->nr_cbufs; i++) { 362 struct virgl_surface *surf = virgl_surface(state->cbufs[i]); 363 virgl_encoder_write_dword(ctx->cbuf, surf ? surf->handle : 0); 364 } 365 366 struct virgl_screen *rs = virgl_screen(ctx->base.screen); 367 if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_FB_NO_ATTACH) { 368 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_FRAMEBUFFER_STATE_NO_ATTACH, 0, VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_SIZE)); 369 virgl_encoder_write_dword(ctx->cbuf, state->width | (state->height << 16)); 370 virgl_encoder_write_dword(ctx->cbuf, state->layers | (state->samples << 16)); 371 } 372 return 0; 373} 374 375int virgl_encoder_set_viewport_states(struct virgl_context *ctx, 376 int start_slot, 377 int num_viewports, 378 const struct pipe_viewport_state *states) 379{ 380 int i,v; 381 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_VIEWPORT_STATE, 0, VIRGL_SET_VIEWPORT_STATE_SIZE(num_viewports))); 382 virgl_encoder_write_dword(ctx->cbuf, start_slot); 383 for (v = 0; v < num_viewports; v++) { 384 for (i = 0; i < 3; i++) 385 virgl_encoder_write_dword(ctx->cbuf, fui(states[v].scale[i])); 386 for (i = 0; i < 3; i++) 387 virgl_encoder_write_dword(ctx->cbuf, fui(states[v].translate[i])); 388 } 389 return 0; 390} 391 392int virgl_encoder_create_vertex_elements(struct virgl_context *ctx, 393 uint32_t handle, 394 unsigned num_elements, 395 const struct pipe_vertex_element *element) 396{ 397 int i; 398 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_VERTEX_ELEMENTS, VIRGL_OBJ_VERTEX_ELEMENTS_SIZE(num_elements))); 399 virgl_encoder_write_dword(ctx->cbuf, handle); 400 for (i = 0; i < num_elements; i++) { 401 virgl_encoder_write_dword(ctx->cbuf, element[i].src_offset); 402 virgl_encoder_write_dword(ctx->cbuf, element[i].instance_divisor); 403 virgl_encoder_write_dword(ctx->cbuf, element[i].vertex_buffer_index); 404 virgl_encoder_write_dword(ctx->cbuf, element[i].src_format); 405 } 406 return 0; 407} 408 409int virgl_encoder_set_vertex_buffers(struct virgl_context *ctx, 410 unsigned num_buffers, 411 const struct pipe_vertex_buffer *buffers) 412{ 413 int i; 414 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_VERTEX_BUFFERS, 0, VIRGL_SET_VERTEX_BUFFERS_SIZE(num_buffers))); 415 for (i = 0; i < num_buffers; i++) { 416 struct virgl_resource *res = virgl_resource(buffers[i].buffer.resource); 417 virgl_encoder_write_dword(ctx->cbuf, buffers[i].stride); 418 virgl_encoder_write_dword(ctx->cbuf, buffers[i].buffer_offset); 419 virgl_encoder_write_res(ctx, res); 420 } 421 return 0; 422} 423 424int virgl_encoder_set_index_buffer(struct virgl_context *ctx, 425 const struct virgl_indexbuf *ib) 426{ 427 int length = VIRGL_SET_INDEX_BUFFER_SIZE(ib); 428 struct virgl_resource *res = NULL; 429 if (ib) 430 res = virgl_resource(ib->buffer); 431 432 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_INDEX_BUFFER, 0, length)); 433 virgl_encoder_write_res(ctx, res); 434 if (ib) { 435 virgl_encoder_write_dword(ctx->cbuf, ib->index_size); 436 virgl_encoder_write_dword(ctx->cbuf, ib->offset); 437 } 438 return 0; 439} 440 441int virgl_encoder_draw_vbo(struct virgl_context *ctx, 442 const struct pipe_draw_info *info) 443{ 444 uint32_t length = VIRGL_DRAW_VBO_SIZE; 445 if (info->mode == PIPE_PRIM_PATCHES) 446 length = VIRGL_DRAW_VBO_SIZE_TESS; 447 if (info->indirect) 448 length = VIRGL_DRAW_VBO_SIZE_INDIRECT; 449 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DRAW_VBO, 0, length)); 450 virgl_encoder_write_dword(ctx->cbuf, info->start); 451 virgl_encoder_write_dword(ctx->cbuf, info->count); 452 virgl_encoder_write_dword(ctx->cbuf, info->mode); 453 virgl_encoder_write_dword(ctx->cbuf, !!info->index_size); 454 virgl_encoder_write_dword(ctx->cbuf, info->instance_count); 455 virgl_encoder_write_dword(ctx->cbuf, info->index_bias); 456 virgl_encoder_write_dword(ctx->cbuf, info->start_instance); 457 virgl_encoder_write_dword(ctx->cbuf, info->primitive_restart); 458 virgl_encoder_write_dword(ctx->cbuf, info->restart_index); 459 virgl_encoder_write_dword(ctx->cbuf, info->min_index); 460 virgl_encoder_write_dword(ctx->cbuf, info->max_index); 461 if (info->count_from_stream_output) 462 virgl_encoder_write_dword(ctx->cbuf, info->count_from_stream_output->buffer_size); 463 else 464 virgl_encoder_write_dword(ctx->cbuf, 0); 465 if (length >= VIRGL_DRAW_VBO_SIZE_TESS) { 466 virgl_encoder_write_dword(ctx->cbuf, info->vertices_per_patch); /* vertices per patch */ 467 virgl_encoder_write_dword(ctx->cbuf, info->drawid); /* drawid */ 468 } 469 if (length == VIRGL_DRAW_VBO_SIZE_INDIRECT) { 470 virgl_encoder_write_res(ctx, virgl_resource(info->indirect->buffer)); 471 virgl_encoder_write_dword(ctx->cbuf, info->indirect->offset); 472 virgl_encoder_write_dword(ctx->cbuf, info->indirect->stride); /* indirect stride */ 473 virgl_encoder_write_dword(ctx->cbuf, info->indirect->draw_count); /* indirect draw count */ 474 virgl_encoder_write_dword(ctx->cbuf, info->indirect->indirect_draw_count_offset); /* indirect draw count offset */ 475 if (info->indirect->indirect_draw_count) 476 virgl_encoder_write_res(ctx, virgl_resource(info->indirect->indirect_draw_count)); 477 else 478 virgl_encoder_write_dword(ctx->cbuf, 0); /* indirect draw count handle */ 479 } 480 return 0; 481} 482 483int virgl_encoder_create_surface(struct virgl_context *ctx, 484 uint32_t handle, 485 struct virgl_resource *res, 486 const struct pipe_surface *templat) 487{ 488 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_SURFACE, VIRGL_OBJ_SURFACE_SIZE)); 489 virgl_encoder_write_dword(ctx->cbuf, handle); 490 virgl_encoder_write_res(ctx, res); 491 virgl_encoder_write_dword(ctx->cbuf, templat->format); 492 if (templat->texture->target == PIPE_BUFFER) { 493 virgl_encoder_write_dword(ctx->cbuf, templat->u.buf.first_element); 494 virgl_encoder_write_dword(ctx->cbuf, templat->u.buf.last_element); 495 496 } else { 497 virgl_encoder_write_dword(ctx->cbuf, templat->u.tex.level); 498 virgl_encoder_write_dword(ctx->cbuf, templat->u.tex.first_layer | (templat->u.tex.last_layer << 16)); 499 } 500 return 0; 501} 502 503int virgl_encoder_create_so_target(struct virgl_context *ctx, 504 uint32_t handle, 505 struct virgl_resource *res, 506 unsigned buffer_offset, 507 unsigned buffer_size) 508{ 509 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_STREAMOUT_TARGET, VIRGL_OBJ_STREAMOUT_SIZE)); 510 virgl_encoder_write_dword(ctx->cbuf, handle); 511 virgl_encoder_write_res(ctx, res); 512 virgl_encoder_write_dword(ctx->cbuf, buffer_offset); 513 virgl_encoder_write_dword(ctx->cbuf, buffer_size); 514 return 0; 515} 516 517static void virgl_encoder_transfer3d_common(struct virgl_screen *vs, 518 struct virgl_cmd_buf *buf, 519 struct virgl_transfer *xfer) 520{ 521 struct pipe_transfer *transfer = &xfer->base; 522 struct virgl_resource *res = virgl_resource(transfer->resource); 523 524 virgl_encoder_emit_resource(vs, buf, res); 525 virgl_encoder_write_dword(buf, transfer->level); 526 virgl_encoder_write_dword(buf, transfer->usage); 527 virgl_encoder_write_dword(buf, 0); 528 virgl_encoder_write_dword(buf, 0); 529 virgl_encoder_write_dword(buf, transfer->box.x); 530 virgl_encoder_write_dword(buf, transfer->box.y); 531 virgl_encoder_write_dword(buf, transfer->box.z); 532 virgl_encoder_write_dword(buf, transfer->box.width); 533 virgl_encoder_write_dword(buf, transfer->box.height); 534 virgl_encoder_write_dword(buf, transfer->box.depth); 535} 536 537int virgl_encoder_inline_write(struct virgl_context *ctx, 538 struct virgl_resource *res, 539 unsigned level, unsigned usage, 540 const struct pipe_box *box, 541 const void *data, unsigned stride, 542 unsigned layer_stride) 543{ 544 uint32_t size = (stride ? stride : box->width) * box->height; 545 uint32_t length, thispass, left_bytes; 546 struct virgl_transfer transfer; 547 struct virgl_screen *vs = virgl_screen(ctx->base.screen); 548 549 transfer.base.resource = &res->u.b; 550 transfer.base.level = level; 551 transfer.base.usage = usage; 552 transfer.base.box = *box; 553 554 length = 11 + (size + 3) / 4; 555 if ((ctx->cbuf->cdw + length + 1) > VIRGL_ENCODE_MAX_DWORDS) { 556 if (box->height > 1 || box->depth > 1) { 557 debug_printf("inline transfer failed due to multi dimensions and too large\n"); 558 assert(0); 559 } 560 } 561 562 left_bytes = size; 563 while (left_bytes) { 564 if (ctx->cbuf->cdw + 12 >= VIRGL_ENCODE_MAX_DWORDS) 565 ctx->base.flush(&ctx->base, NULL, 0); 566 567 thispass = (VIRGL_ENCODE_MAX_DWORDS - ctx->cbuf->cdw - 12) * 4; 568 569 length = MIN2(thispass, left_bytes); 570 571 transfer.base.box.width = length; 572 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_RESOURCE_INLINE_WRITE, 0, ((length + 3) / 4) + 11)); 573 virgl_encoder_transfer3d_common(vs, ctx->cbuf, &transfer); 574 virgl_encoder_write_block(ctx->cbuf, data, length); 575 left_bytes -= length; 576 transfer.base.box.x += length; 577 data += length; 578 } 579 return 0; 580} 581 582int virgl_encoder_flush_frontbuffer(struct virgl_context *ctx, 583 struct virgl_resource *res) 584{ 585// virgl_encoder_write_dword(ctx->cbuf, VIRGL_CMD0(VIRGL_CCMD_FLUSH_FRONTUBFFER, 0, 1)); 586// virgl_encoder_write_dword(ctx->cbuf, res_handle); 587 return 0; 588} 589 590int virgl_encode_sampler_state(struct virgl_context *ctx, 591 uint32_t handle, 592 const struct pipe_sampler_state *state) 593{ 594 uint32_t tmp; 595 int i; 596 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_SAMPLER_STATE, VIRGL_OBJ_SAMPLER_STATE_SIZE)); 597 virgl_encoder_write_dword(ctx->cbuf, handle); 598 599 tmp = VIRGL_OBJ_SAMPLE_STATE_S0_WRAP_S(state->wrap_s) | 600 VIRGL_OBJ_SAMPLE_STATE_S0_WRAP_T(state->wrap_t) | 601 VIRGL_OBJ_SAMPLE_STATE_S0_WRAP_R(state->wrap_r) | 602 VIRGL_OBJ_SAMPLE_STATE_S0_MIN_IMG_FILTER(state->min_img_filter) | 603 VIRGL_OBJ_SAMPLE_STATE_S0_MIN_MIP_FILTER(state->min_mip_filter) | 604 VIRGL_OBJ_SAMPLE_STATE_S0_MAG_IMG_FILTER(state->mag_img_filter) | 605 VIRGL_OBJ_SAMPLE_STATE_S0_COMPARE_MODE(state->compare_mode) | 606 VIRGL_OBJ_SAMPLE_STATE_S0_COMPARE_FUNC(state->compare_func) | 607 VIRGL_OBJ_SAMPLE_STATE_S0_SEAMLESS_CUBE_MAP(state->seamless_cube_map); 608 609 virgl_encoder_write_dword(ctx->cbuf, tmp); 610 virgl_encoder_write_dword(ctx->cbuf, fui(state->lod_bias)); 611 virgl_encoder_write_dword(ctx->cbuf, fui(state->min_lod)); 612 virgl_encoder_write_dword(ctx->cbuf, fui(state->max_lod)); 613 for (i = 0; i < 4; i++) 614 virgl_encoder_write_dword(ctx->cbuf, state->border_color.ui[i]); 615 return 0; 616} 617 618 619int virgl_encode_sampler_view(struct virgl_context *ctx, 620 uint32_t handle, 621 struct virgl_resource *res, 622 const struct pipe_sampler_view *state) 623{ 624 unsigned elem_size = util_format_get_blocksize(state->format); 625 struct virgl_screen *rs = virgl_screen(ctx->base.screen); 626 uint32_t tmp; 627 uint32_t dword_fmt_target = state->format; 628 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_SAMPLER_VIEW, VIRGL_OBJ_SAMPLER_VIEW_SIZE)); 629 virgl_encoder_write_dword(ctx->cbuf, handle); 630 virgl_encoder_write_res(ctx, res); 631 if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_TEXTURE_VIEW) 632 dword_fmt_target |= (state->target << 24); 633 virgl_encoder_write_dword(ctx->cbuf, dword_fmt_target); 634 if (res->u.b.target == PIPE_BUFFER) { 635 virgl_encoder_write_dword(ctx->cbuf, state->u.buf.offset / elem_size); 636 virgl_encoder_write_dword(ctx->cbuf, (state->u.buf.offset + state->u.buf.size) / elem_size - 1); 637 } else { 638 virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_layer | state->u.tex.last_layer << 16); 639 virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_level | state->u.tex.last_level << 8); 640 } 641 tmp = VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE_R(state->swizzle_r) | 642 VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE_G(state->swizzle_g) | 643 VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE_B(state->swizzle_b) | 644 VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE_A(state->swizzle_a); 645 virgl_encoder_write_dword(ctx->cbuf, tmp); 646 return 0; 647} 648 649int virgl_encode_set_sampler_views(struct virgl_context *ctx, 650 uint32_t shader_type, 651 uint32_t start_slot, 652 uint32_t num_views, 653 struct virgl_sampler_view **views) 654{ 655 int i; 656 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_SAMPLER_VIEWS, 0, VIRGL_SET_SAMPLER_VIEWS_SIZE(num_views))); 657 virgl_encoder_write_dword(ctx->cbuf, shader_type); 658 virgl_encoder_write_dword(ctx->cbuf, start_slot); 659 for (i = 0; i < num_views; i++) { 660 uint32_t handle = views[i] ? views[i]->handle : 0; 661 virgl_encoder_write_dword(ctx->cbuf, handle); 662 } 663 return 0; 664} 665 666int virgl_encode_bind_sampler_states(struct virgl_context *ctx, 667 uint32_t shader_type, 668 uint32_t start_slot, 669 uint32_t num_handles, 670 uint32_t *handles) 671{ 672 int i; 673 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_BIND_SAMPLER_STATES, 0, VIRGL_BIND_SAMPLER_STATES(num_handles))); 674 virgl_encoder_write_dword(ctx->cbuf, shader_type); 675 virgl_encoder_write_dword(ctx->cbuf, start_slot); 676 for (i = 0; i < num_handles; i++) 677 virgl_encoder_write_dword(ctx->cbuf, handles[i]); 678 return 0; 679} 680 681int virgl_encoder_write_constant_buffer(struct virgl_context *ctx, 682 uint32_t shader, 683 uint32_t index, 684 uint32_t size, 685 const void *data) 686{ 687 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_CONSTANT_BUFFER, 0, size + 2)); 688 virgl_encoder_write_dword(ctx->cbuf, shader); 689 virgl_encoder_write_dword(ctx->cbuf, index); 690 if (data) 691 virgl_encoder_write_block(ctx->cbuf, data, size * 4); 692 return 0; 693} 694 695int virgl_encoder_set_uniform_buffer(struct virgl_context *ctx, 696 uint32_t shader, 697 uint32_t index, 698 uint32_t offset, 699 uint32_t length, 700 struct virgl_resource *res) 701{ 702 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_UNIFORM_BUFFER, 0, VIRGL_SET_UNIFORM_BUFFER_SIZE)); 703 virgl_encoder_write_dword(ctx->cbuf, shader); 704 virgl_encoder_write_dword(ctx->cbuf, index); 705 virgl_encoder_write_dword(ctx->cbuf, offset); 706 virgl_encoder_write_dword(ctx->cbuf, length); 707 virgl_encoder_write_res(ctx, res); 708 return 0; 709} 710 711 712int virgl_encoder_set_stencil_ref(struct virgl_context *ctx, 713 const struct pipe_stencil_ref *ref) 714{ 715 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_STENCIL_REF, 0, VIRGL_SET_STENCIL_REF_SIZE)); 716 virgl_encoder_write_dword(ctx->cbuf, VIRGL_STENCIL_REF_VAL(ref->ref_value[0] , (ref->ref_value[1]))); 717 return 0; 718} 719 720int virgl_encoder_set_blend_color(struct virgl_context *ctx, 721 const struct pipe_blend_color *color) 722{ 723 int i; 724 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_BLEND_COLOR, 0, VIRGL_SET_BLEND_COLOR_SIZE)); 725 for (i = 0; i < 4; i++) 726 virgl_encoder_write_dword(ctx->cbuf, fui(color->color[i])); 727 return 0; 728} 729 730int virgl_encoder_set_scissor_state(struct virgl_context *ctx, 731 unsigned start_slot, 732 int num_scissors, 733 const struct pipe_scissor_state *ss) 734{ 735 int i; 736 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_SCISSOR_STATE, 0, VIRGL_SET_SCISSOR_STATE_SIZE(num_scissors))); 737 virgl_encoder_write_dword(ctx->cbuf, start_slot); 738 for (i = 0; i < num_scissors; i++) { 739 virgl_encoder_write_dword(ctx->cbuf, (ss[i].minx | ss[i].miny << 16)); 740 virgl_encoder_write_dword(ctx->cbuf, (ss[i].maxx | ss[i].maxy << 16)); 741 } 742 return 0; 743} 744 745void virgl_encoder_set_polygon_stipple(struct virgl_context *ctx, 746 const struct pipe_poly_stipple *ps) 747{ 748 int i; 749 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_POLYGON_STIPPLE, 0, VIRGL_POLYGON_STIPPLE_SIZE)); 750 for (i = 0; i < VIRGL_POLYGON_STIPPLE_SIZE; i++) { 751 virgl_encoder_write_dword(ctx->cbuf, ps->stipple[i]); 752 } 753} 754 755void virgl_encoder_set_sample_mask(struct virgl_context *ctx, 756 unsigned sample_mask) 757{ 758 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_SAMPLE_MASK, 0, VIRGL_SET_SAMPLE_MASK_SIZE)); 759 virgl_encoder_write_dword(ctx->cbuf, sample_mask); 760} 761 762void virgl_encoder_set_min_samples(struct virgl_context *ctx, 763 unsigned min_samples) 764{ 765 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_MIN_SAMPLES, 0, VIRGL_SET_MIN_SAMPLES_SIZE)); 766 virgl_encoder_write_dword(ctx->cbuf, min_samples); 767} 768 769void virgl_encoder_set_clip_state(struct virgl_context *ctx, 770 const struct pipe_clip_state *clip) 771{ 772 int i, j; 773 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_CLIP_STATE, 0, VIRGL_SET_CLIP_STATE_SIZE)); 774 for (i = 0; i < VIRGL_MAX_CLIP_PLANES; i++) { 775 for (j = 0; j < 4; j++) { 776 virgl_encoder_write_dword(ctx->cbuf, fui(clip->ucp[i][j])); 777 } 778 } 779} 780 781int virgl_encode_resource_copy_region(struct virgl_context *ctx, 782 struct virgl_resource *dst_res, 783 unsigned dst_level, 784 unsigned dstx, unsigned dsty, unsigned dstz, 785 struct virgl_resource *src_res, 786 unsigned src_level, 787 const struct pipe_box *src_box) 788{ 789 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_RESOURCE_COPY_REGION, 0, VIRGL_CMD_RESOURCE_COPY_REGION_SIZE)); 790 virgl_encoder_write_res(ctx, dst_res); 791 virgl_encoder_write_dword(ctx->cbuf, dst_level); 792 virgl_encoder_write_dword(ctx->cbuf, dstx); 793 virgl_encoder_write_dword(ctx->cbuf, dsty); 794 virgl_encoder_write_dword(ctx->cbuf, dstz); 795 virgl_encoder_write_res(ctx, src_res); 796 virgl_encoder_write_dword(ctx->cbuf, src_level); 797 virgl_encoder_write_dword(ctx->cbuf, src_box->x); 798 virgl_encoder_write_dword(ctx->cbuf, src_box->y); 799 virgl_encoder_write_dword(ctx->cbuf, src_box->z); 800 virgl_encoder_write_dword(ctx->cbuf, src_box->width); 801 virgl_encoder_write_dword(ctx->cbuf, src_box->height); 802 virgl_encoder_write_dword(ctx->cbuf, src_box->depth); 803 return 0; 804} 805 806int virgl_encode_blit(struct virgl_context *ctx, 807 struct virgl_resource *dst_res, 808 struct virgl_resource *src_res, 809 const struct pipe_blit_info *blit) 810{ 811 uint32_t tmp; 812 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_BLIT, 0, VIRGL_CMD_BLIT_SIZE)); 813 tmp = VIRGL_CMD_BLIT_S0_MASK(blit->mask) | 814 VIRGL_CMD_BLIT_S0_FILTER(blit->filter) | 815 VIRGL_CMD_BLIT_S0_SCISSOR_ENABLE(blit->scissor_enable) | 816 VIRGL_CMD_BLIT_S0_RENDER_CONDITION_ENABLE(blit->render_condition_enable) | 817 VIRGL_CMD_BLIT_S0_ALPHA_BLEND(blit->alpha_blend); 818 virgl_encoder_write_dword(ctx->cbuf, tmp); 819 virgl_encoder_write_dword(ctx->cbuf, (blit->scissor.minx | blit->scissor.miny << 16)); 820 virgl_encoder_write_dword(ctx->cbuf, (blit->scissor.maxx | blit->scissor.maxy << 16)); 821 822 virgl_encoder_write_res(ctx, dst_res); 823 virgl_encoder_write_dword(ctx->cbuf, blit->dst.level); 824 virgl_encoder_write_dword(ctx->cbuf, blit->dst.format); 825 virgl_encoder_write_dword(ctx->cbuf, blit->dst.box.x); 826 virgl_encoder_write_dword(ctx->cbuf, blit->dst.box.y); 827 virgl_encoder_write_dword(ctx->cbuf, blit->dst.box.z); 828 virgl_encoder_write_dword(ctx->cbuf, blit->dst.box.width); 829 virgl_encoder_write_dword(ctx->cbuf, blit->dst.box.height); 830 virgl_encoder_write_dword(ctx->cbuf, blit->dst.box.depth); 831 832 virgl_encoder_write_res(ctx, src_res); 833 virgl_encoder_write_dword(ctx->cbuf, blit->src.level); 834 virgl_encoder_write_dword(ctx->cbuf, blit->src.format); 835 virgl_encoder_write_dword(ctx->cbuf, blit->src.box.x); 836 virgl_encoder_write_dword(ctx->cbuf, blit->src.box.y); 837 virgl_encoder_write_dword(ctx->cbuf, blit->src.box.z); 838 virgl_encoder_write_dword(ctx->cbuf, blit->src.box.width); 839 virgl_encoder_write_dword(ctx->cbuf, blit->src.box.height); 840 virgl_encoder_write_dword(ctx->cbuf, blit->src.box.depth); 841 return 0; 842} 843 844int virgl_encoder_create_query(struct virgl_context *ctx, 845 uint32_t handle, 846 uint query_type, 847 uint query_index, 848 struct virgl_resource *res, 849 uint32_t offset) 850{ 851 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_QUERY, VIRGL_OBJ_QUERY_SIZE)); 852 virgl_encoder_write_dword(ctx->cbuf, handle); 853 virgl_encoder_write_dword(ctx->cbuf, ((query_type & 0xffff) | (query_index << 16))); 854 virgl_encoder_write_dword(ctx->cbuf, offset); 855 virgl_encoder_write_res(ctx, res); 856 return 0; 857} 858 859int virgl_encoder_begin_query(struct virgl_context *ctx, 860 uint32_t handle) 861{ 862 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_BEGIN_QUERY, 0, 1)); 863 virgl_encoder_write_dword(ctx->cbuf, handle); 864 return 0; 865} 866 867int virgl_encoder_end_query(struct virgl_context *ctx, 868 uint32_t handle) 869{ 870 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_END_QUERY, 0, 1)); 871 virgl_encoder_write_dword(ctx->cbuf, handle); 872 return 0; 873} 874 875int virgl_encoder_get_query_result(struct virgl_context *ctx, 876 uint32_t handle, boolean wait) 877{ 878 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_GET_QUERY_RESULT, 0, 2)); 879 virgl_encoder_write_dword(ctx->cbuf, handle); 880 virgl_encoder_write_dword(ctx->cbuf, wait ? 1 : 0); 881 return 0; 882} 883 884int virgl_encoder_render_condition(struct virgl_context *ctx, 885 uint32_t handle, boolean condition, 886 enum pipe_render_cond_flag mode) 887{ 888 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_RENDER_CONDITION, 0, VIRGL_RENDER_CONDITION_SIZE)); 889 virgl_encoder_write_dword(ctx->cbuf, handle); 890 virgl_encoder_write_dword(ctx->cbuf, condition); 891 virgl_encoder_write_dword(ctx->cbuf, mode); 892 return 0; 893} 894 895int virgl_encoder_set_so_targets(struct virgl_context *ctx, 896 unsigned num_targets, 897 struct pipe_stream_output_target **targets, 898 unsigned append_bitmask) 899{ 900 int i; 901 902 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_STREAMOUT_TARGETS, 0, num_targets + 1)); 903 virgl_encoder_write_dword(ctx->cbuf, append_bitmask); 904 for (i = 0; i < num_targets; i++) { 905 struct virgl_so_target *tg = virgl_so_target(targets[i]); 906 virgl_encoder_write_dword(ctx->cbuf, tg ? tg->handle : 0); 907 } 908 return 0; 909} 910 911 912int virgl_encoder_set_sub_ctx(struct virgl_context *ctx, uint32_t sub_ctx_id) 913{ 914 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_SUB_CTX, 0, 1)); 915 virgl_encoder_write_dword(ctx->cbuf, sub_ctx_id); 916 return 0; 917} 918 919int virgl_encoder_create_sub_ctx(struct virgl_context *ctx, uint32_t sub_ctx_id) 920{ 921 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_SUB_CTX, 0, 1)); 922 virgl_encoder_write_dword(ctx->cbuf, sub_ctx_id); 923 return 0; 924} 925 926int virgl_encoder_destroy_sub_ctx(struct virgl_context *ctx, uint32_t sub_ctx_id) 927{ 928 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DESTROY_SUB_CTX, 0, 1)); 929 virgl_encoder_write_dword(ctx->cbuf, sub_ctx_id); 930 return 0; 931} 932 933int virgl_encode_bind_shader(struct virgl_context *ctx, 934 uint32_t handle, uint32_t type) 935{ 936 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_BIND_SHADER, 0, 2)); 937 virgl_encoder_write_dword(ctx->cbuf, handle); 938 virgl_encoder_write_dword(ctx->cbuf, type); 939 return 0; 940} 941 942int virgl_encode_set_tess_state(struct virgl_context *ctx, 943 const float outer[4], 944 const float inner[2]) 945{ 946 int i; 947 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_TESS_STATE, 0, 6)); 948 for (i = 0; i < 4; i++) 949 virgl_encoder_write_dword(ctx->cbuf, fui(outer[i])); 950 for (i = 0; i < 2; i++) 951 virgl_encoder_write_dword(ctx->cbuf, fui(inner[i])); 952 return 0; 953} 954 955int virgl_encode_set_shader_buffers(struct virgl_context *ctx, 956 enum pipe_shader_type shader, 957 unsigned start_slot, unsigned count, 958 const struct pipe_shader_buffer *buffers) 959{ 960 int i; 961 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_SHADER_BUFFERS, 0, VIRGL_SET_SHADER_BUFFER_SIZE(count))); 962 963 virgl_encoder_write_dword(ctx->cbuf, shader); 964 virgl_encoder_write_dword(ctx->cbuf, start_slot); 965 for (i = 0; i < count; i++) { 966 if (buffers) { 967 struct virgl_resource *res = virgl_resource(buffers[i].buffer); 968 virgl_encoder_write_dword(ctx->cbuf, buffers[i].buffer_offset); 969 virgl_encoder_write_dword(ctx->cbuf, buffers[i].buffer_size); 970 virgl_encoder_write_res(ctx, res); 971 virgl_resource_dirty(res, 0); 972 } else { 973 virgl_encoder_write_dword(ctx->cbuf, 0); 974 virgl_encoder_write_dword(ctx->cbuf, 0); 975 virgl_encoder_write_dword(ctx->cbuf, 0); 976 } 977 } 978 return 0; 979} 980 981int virgl_encode_set_hw_atomic_buffers(struct virgl_context *ctx, 982 unsigned start_slot, unsigned count, 983 const struct pipe_shader_buffer *buffers) 984{ 985 int i; 986 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_ATOMIC_BUFFERS, 0, VIRGL_SET_ATOMIC_BUFFER_SIZE(count))); 987 988 virgl_encoder_write_dword(ctx->cbuf, start_slot); 989 for (i = 0; i < count; i++) { 990 if (buffers) { 991 struct virgl_resource *res = virgl_resource(buffers[i].buffer); 992 virgl_encoder_write_dword(ctx->cbuf, buffers[i].buffer_offset); 993 virgl_encoder_write_dword(ctx->cbuf, buffers[i].buffer_size); 994 virgl_encoder_write_res(ctx, res); 995 virgl_resource_dirty(res, 0); 996 } else { 997 virgl_encoder_write_dword(ctx->cbuf, 0); 998 virgl_encoder_write_dword(ctx->cbuf, 0); 999 virgl_encoder_write_dword(ctx->cbuf, 0); 1000 } 1001 } 1002 return 0; 1003} 1004 1005int virgl_encode_set_shader_images(struct virgl_context *ctx, 1006 enum pipe_shader_type shader, 1007 unsigned start_slot, unsigned count, 1008 const struct pipe_image_view *images) 1009{ 1010 int i; 1011 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_SHADER_IMAGES, 0, VIRGL_SET_SHADER_IMAGE_SIZE(count))); 1012 1013 virgl_encoder_write_dword(ctx->cbuf, shader); 1014 virgl_encoder_write_dword(ctx->cbuf, start_slot); 1015 for (i = 0; i < count; i++) { 1016 if (images) { 1017 struct virgl_resource *res = virgl_resource(images[i].resource); 1018 virgl_encoder_write_dword(ctx->cbuf, images[i].format); 1019 virgl_encoder_write_dword(ctx->cbuf, images[i].access); 1020 virgl_encoder_write_dword(ctx->cbuf, images[i].u.buf.offset); 1021 virgl_encoder_write_dword(ctx->cbuf, images[i].u.buf.size); 1022 virgl_encoder_write_res(ctx, res); 1023 virgl_resource_dirty(res, images[i].u.tex.level); 1024 } else { 1025 virgl_encoder_write_dword(ctx->cbuf, 0); 1026 virgl_encoder_write_dword(ctx->cbuf, 0); 1027 virgl_encoder_write_dword(ctx->cbuf, 0); 1028 virgl_encoder_write_dword(ctx->cbuf, 0); 1029 virgl_encoder_write_dword(ctx->cbuf, 0); 1030 } 1031 } 1032 return 0; 1033} 1034 1035int virgl_encode_memory_barrier(struct virgl_context *ctx, 1036 unsigned flags) 1037{ 1038 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_MEMORY_BARRIER, 0, 1)); 1039 virgl_encoder_write_dword(ctx->cbuf, flags); 1040 return 0; 1041} 1042 1043int virgl_encode_launch_grid(struct virgl_context *ctx, 1044 const struct pipe_grid_info *grid_info) 1045{ 1046 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_LAUNCH_GRID, 0, VIRGL_LAUNCH_GRID_SIZE)); 1047 virgl_encoder_write_dword(ctx->cbuf, grid_info->block[0]); 1048 virgl_encoder_write_dword(ctx->cbuf, grid_info->block[1]); 1049 virgl_encoder_write_dword(ctx->cbuf, grid_info->block[2]); 1050 virgl_encoder_write_dword(ctx->cbuf, grid_info->grid[0]); 1051 virgl_encoder_write_dword(ctx->cbuf, grid_info->grid[1]); 1052 virgl_encoder_write_dword(ctx->cbuf, grid_info->grid[2]); 1053 if (grid_info->indirect) { 1054 struct virgl_resource *res = virgl_resource(grid_info->indirect); 1055 virgl_encoder_write_res(ctx, res); 1056 } else 1057 virgl_encoder_write_dword(ctx->cbuf, 0); 1058 virgl_encoder_write_dword(ctx->cbuf, grid_info->indirect_offset); 1059 return 0; 1060} 1061 1062int virgl_encode_texture_barrier(struct virgl_context *ctx, 1063 unsigned flags) 1064{ 1065 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_TEXTURE_BARRIER, 0, 1)); 1066 virgl_encoder_write_dword(ctx->cbuf, flags); 1067 return 0; 1068} 1069 1070int virgl_encode_host_debug_flagstring(struct virgl_context *ctx, 1071 const char *flagstring) 1072{ 1073 unsigned long slen = strlen(flagstring) + 1; 1074 uint32_t sslen; 1075 uint32_t string_length; 1076 1077 if (!slen) 1078 return 0; 1079 1080 if (slen > 4 * 0xffff) { 1081 debug_printf("VIRGL: host debug flag string too long, will be truncated\n"); 1082 slen = 4 * 0xffff; 1083 } 1084 1085 sslen = (uint32_t )(slen + 3) / 4; 1086 string_length = (uint32_t)MIN2(sslen * 4, slen); 1087 1088 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_DEBUG_FLAGS, 0, sslen)); 1089 virgl_encoder_write_block(ctx->cbuf, (const uint8_t *)flagstring, string_length); 1090 return 0; 1091} 1092 1093int virgl_encode_get_query_result_qbo(struct virgl_context *ctx, 1094 uint32_t handle, 1095 struct virgl_resource *res, boolean wait, 1096 uint32_t result_type, 1097 uint32_t offset, 1098 uint32_t index) 1099{ 1100 virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_GET_QUERY_RESULT_QBO, 0, VIRGL_QUERY_RESULT_QBO_SIZE)); 1101 virgl_encoder_write_dword(ctx->cbuf, handle); 1102 virgl_encoder_write_res(ctx, res); 1103 virgl_encoder_write_dword(ctx->cbuf, wait ? 1 : 0); 1104 virgl_encoder_write_dword(ctx->cbuf, result_type); 1105 virgl_encoder_write_dword(ctx->cbuf, offset); 1106 virgl_encoder_write_dword(ctx->cbuf, index); 1107 return 0; 1108} 1109 1110void virgl_encode_transfer(struct virgl_screen *vs, struct virgl_cmd_buf *buf, 1111 struct virgl_transfer *trans, uint32_t direction) 1112{ 1113 uint32_t command; 1114 command = VIRGL_CMD0(VIRGL_CCMD_TRANSFER3D, 0, VIRGL_TRANSFER3D_SIZE); 1115 virgl_encoder_write_dword(buf, command); 1116 virgl_encoder_transfer3d_common(vs, buf, trans); 1117 virgl_encoder_write_dword(buf, trans->offset); 1118 virgl_encoder_write_dword(buf, direction); 1119} 1120 1121void virgl_encode_end_transfers(struct virgl_cmd_buf *buf) 1122{ 1123 uint32_t command, diff; 1124 diff = VIRGL_MAX_TBUF_DWORDS - buf->cdw; 1125 if (diff) { 1126 command = VIRGL_CMD0(VIRGL_CCMD_END_TRANSFERS, 0, diff - 1); 1127 virgl_encoder_write_dword(buf, command); 1128 } 1129} 1130