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