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