1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker *
3*bbecb9d1SAndroid Build Coastguard Worker * Copyright (C) 2014 Red Hat Inc.
4*bbecb9d1SAndroid Build Coastguard Worker *
5*bbecb9d1SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
6*bbecb9d1SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
7*bbecb9d1SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
8*bbecb9d1SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*bbecb9d1SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
10*bbecb9d1SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
11*bbecb9d1SAndroid Build Coastguard Worker *
12*bbecb9d1SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
13*bbecb9d1SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
14*bbecb9d1SAndroid Build Coastguard Worker *
15*bbecb9d1SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*bbecb9d1SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*bbecb9d1SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*bbecb9d1SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19*bbecb9d1SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*bbecb9d1SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21*bbecb9d1SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
22*bbecb9d1SAndroid Build Coastguard Worker *
23*bbecb9d1SAndroid Build Coastguard Worker **************************************************************************/
24*bbecb9d1SAndroid Build Coastguard Worker #include <stdint.h>
25*bbecb9d1SAndroid Build Coastguard Worker #include <string.h>
26*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
27*bbecb9d1SAndroid Build Coastguard Worker #include <errno.h>
28*bbecb9d1SAndroid Build Coastguard Worker #include <epoxy/gl.h>
29*bbecb9d1SAndroid Build Coastguard Worker #include <fcntl.h>
30*bbecb9d1SAndroid Build Coastguard Worker
31*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_memory.h"
32*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_defines.h"
33*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_state.h"
34*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_shader_tokens.h"
35*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_context.h"
36*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_resource.h"
37*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_renderer.h"
38*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_object.h"
39*bbecb9d1SAndroid Build Coastguard Worker #include "tgsi/tgsi_text.h"
40*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_debug.h"
41*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_tweaks.h"
42*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_util.h"
43*bbecb9d1SAndroid Build Coastguard Worker
44*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
45*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_video.h"
46*bbecb9d1SAndroid Build Coastguard Worker #endif
47*bbecb9d1SAndroid Build Coastguard Worker
48*bbecb9d1SAndroid Build Coastguard Worker /* decode side */
49*bbecb9d1SAndroid Build Coastguard Worker #define DECODE_MAX_TOKENS 8000
50*bbecb9d1SAndroid Build Coastguard Worker
51*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx {
52*bbecb9d1SAndroid Build Coastguard Worker struct virgl_context base;
53*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *grctx;
54*bbecb9d1SAndroid Build Coastguard Worker };
55*bbecb9d1SAndroid Build Coastguard Worker
get_buf_entry(const uint32_t * buf,uint32_t offset)56*bbecb9d1SAndroid Build Coastguard Worker static inline uint32_t get_buf_entry(const uint32_t *buf, uint32_t offset)
57*bbecb9d1SAndroid Build Coastguard Worker {
58*bbecb9d1SAndroid Build Coastguard Worker return buf[offset];
59*bbecb9d1SAndroid Build Coastguard Worker }
60*bbecb9d1SAndroid Build Coastguard Worker
get_buf_ptr(const uint32_t * buf,uint32_t offset)61*bbecb9d1SAndroid Build Coastguard Worker static inline const void *get_buf_ptr(const uint32_t *buf, uint32_t offset)
62*bbecb9d1SAndroid Build Coastguard Worker {
63*bbecb9d1SAndroid Build Coastguard Worker return &buf[offset];
64*bbecb9d1SAndroid Build Coastguard Worker }
65*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_shader(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)66*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_shader(struct vrend_context *ctx,
67*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
68*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
69*bbecb9d1SAndroid Build Coastguard Worker uint16_t length)
70*bbecb9d1SAndroid Build Coastguard Worker {
71*bbecb9d1SAndroid Build Coastguard Worker struct pipe_stream_output_info so_info;
72*bbecb9d1SAndroid Build Coastguard Worker uint i;
73*bbecb9d1SAndroid Build Coastguard Worker int ret;
74*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_offset, req_local_mem = 0;
75*bbecb9d1SAndroid Build Coastguard Worker unsigned num_tokens, num_so_outputs, offlen;
76*bbecb9d1SAndroid Build Coastguard Worker const uint8_t *shd_text;
77*bbecb9d1SAndroid Build Coastguard Worker uint32_t type;
78*bbecb9d1SAndroid Build Coastguard Worker
79*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_OBJ_SHADER_HDR_SIZE(0))
80*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
81*bbecb9d1SAndroid Build Coastguard Worker
82*bbecb9d1SAndroid Build Coastguard Worker type = get_buf_entry(buf, VIRGL_OBJ_SHADER_TYPE);
83*bbecb9d1SAndroid Build Coastguard Worker num_tokens = get_buf_entry(buf, VIRGL_OBJ_SHADER_NUM_TOKENS);
84*bbecb9d1SAndroid Build Coastguard Worker offlen = get_buf_entry(buf, VIRGL_OBJ_SHADER_OFFSET);
85*bbecb9d1SAndroid Build Coastguard Worker
86*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_COMPUTE) {
87*bbecb9d1SAndroid Build Coastguard Worker req_local_mem = get_buf_entry(buf, VIRGL_OBJ_SHADER_SO_NUM_OUTPUTS);
88*bbecb9d1SAndroid Build Coastguard Worker num_so_outputs = 0;
89*bbecb9d1SAndroid Build Coastguard Worker } else {
90*bbecb9d1SAndroid Build Coastguard Worker num_so_outputs = get_buf_entry(buf, VIRGL_OBJ_SHADER_SO_NUM_OUTPUTS);
91*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_OBJ_SHADER_HDR_SIZE(num_so_outputs))
92*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
93*bbecb9d1SAndroid Build Coastguard Worker
94*bbecb9d1SAndroid Build Coastguard Worker if (num_so_outputs > PIPE_MAX_SO_OUTPUTS)
95*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
96*bbecb9d1SAndroid Build Coastguard Worker }
97*bbecb9d1SAndroid Build Coastguard Worker
98*bbecb9d1SAndroid Build Coastguard Worker shader_offset = 6;
99*bbecb9d1SAndroid Build Coastguard Worker if (num_so_outputs) {
100*bbecb9d1SAndroid Build Coastguard Worker so_info.num_outputs = num_so_outputs;
101*bbecb9d1SAndroid Build Coastguard Worker if (so_info.num_outputs) {
102*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 4; i++)
103*bbecb9d1SAndroid Build Coastguard Worker so_info.stride[i] = get_buf_entry(buf, VIRGL_OBJ_SHADER_SO_STRIDE(i));
104*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < so_info.num_outputs; i++) {
105*bbecb9d1SAndroid Build Coastguard Worker uint32_t tmp = get_buf_entry(buf, VIRGL_OBJ_SHADER_SO_OUTPUT0(i));
106*bbecb9d1SAndroid Build Coastguard Worker
107*bbecb9d1SAndroid Build Coastguard Worker so_info.output[i].register_index = tmp & 0xff;
108*bbecb9d1SAndroid Build Coastguard Worker so_info.output[i].start_component = (tmp >> 8) & 0x3;
109*bbecb9d1SAndroid Build Coastguard Worker so_info.output[i].num_components = (tmp >> 10) & 0x7;
110*bbecb9d1SAndroid Build Coastguard Worker so_info.output[i].output_buffer = (tmp >> 13) & 0x7;
111*bbecb9d1SAndroid Build Coastguard Worker so_info.output[i].dst_offset = (tmp >> 16) & 0xffff;
112*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_SHADER_SO_OUTPUT0_SO(i));
113*bbecb9d1SAndroid Build Coastguard Worker so_info.output[i].stream = (tmp & 0x3);
114*bbecb9d1SAndroid Build Coastguard Worker so_info.output[i].need_temp = so_info.output[i].num_components < 4;
115*bbecb9d1SAndroid Build Coastguard Worker }
116*bbecb9d1SAndroid Build Coastguard Worker
117*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < so_info.num_outputs - 1; i++) {
118*bbecb9d1SAndroid Build Coastguard Worker for (unsigned j = i + 1; j < so_info.num_outputs; j++) {
119*bbecb9d1SAndroid Build Coastguard Worker so_info.output[j].need_temp |=
120*bbecb9d1SAndroid Build Coastguard Worker (so_info.output[i].register_index == so_info.output[j].register_index);
121*bbecb9d1SAndroid Build Coastguard Worker }
122*bbecb9d1SAndroid Build Coastguard Worker }
123*bbecb9d1SAndroid Build Coastguard Worker }
124*bbecb9d1SAndroid Build Coastguard Worker shader_offset += 4 + (2 * num_so_outputs);
125*bbecb9d1SAndroid Build Coastguard Worker } else
126*bbecb9d1SAndroid Build Coastguard Worker memset(&so_info, 0, sizeof(so_info));
127*bbecb9d1SAndroid Build Coastguard Worker
128*bbecb9d1SAndroid Build Coastguard Worker shd_text = get_buf_ptr(buf, shader_offset);
129*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_create_shader(ctx, handle, &so_info, req_local_mem, (const char *)shd_text, offlen, num_tokens, type, length - shader_offset + 1);
130*bbecb9d1SAndroid Build Coastguard Worker
131*bbecb9d1SAndroid Build Coastguard Worker return ret;
132*bbecb9d1SAndroid Build Coastguard Worker }
133*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_stream_output_target(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)134*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_stream_output_target(struct vrend_context *ctx, const uint32_t *buf,
135*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle, uint16_t length)
136*bbecb9d1SAndroid Build Coastguard Worker {
137*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle, buffer_size, buffer_offset;
138*bbecb9d1SAndroid Build Coastguard Worker
139*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_STREAMOUT_SIZE)
140*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
141*bbecb9d1SAndroid Build Coastguard Worker
142*bbecb9d1SAndroid Build Coastguard Worker res_handle = get_buf_entry(buf, VIRGL_OBJ_STREAMOUT_RES_HANDLE);
143*bbecb9d1SAndroid Build Coastguard Worker buffer_offset = get_buf_entry(buf, VIRGL_OBJ_STREAMOUT_BUFFER_OFFSET);
144*bbecb9d1SAndroid Build Coastguard Worker buffer_size = get_buf_entry(buf, VIRGL_OBJ_STREAMOUT_BUFFER_SIZE);
145*bbecb9d1SAndroid Build Coastguard Worker
146*bbecb9d1SAndroid Build Coastguard Worker return vrend_create_so_target(ctx, handle, res_handle, buffer_offset,
147*bbecb9d1SAndroid Build Coastguard Worker buffer_size);
148*bbecb9d1SAndroid Build Coastguard Worker }
149*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_framebuffer_state(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)150*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_framebuffer_state(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
151*bbecb9d1SAndroid Build Coastguard Worker {
152*bbecb9d1SAndroid Build Coastguard Worker if (length < 2)
153*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
154*bbecb9d1SAndroid Build Coastguard Worker
155*bbecb9d1SAndroid Build Coastguard Worker uint32_t nr_cbufs = get_buf_entry(buf, VIRGL_SET_FRAMEBUFFER_STATE_NR_CBUFS);
156*bbecb9d1SAndroid Build Coastguard Worker uint32_t zsurf_handle = get_buf_entry(buf, VIRGL_SET_FRAMEBUFFER_STATE_NR_ZSURF_HANDLE);
157*bbecb9d1SAndroid Build Coastguard Worker uint32_t surf_handle[8];
158*bbecb9d1SAndroid Build Coastguard Worker uint32_t i;
159*bbecb9d1SAndroid Build Coastguard Worker
160*bbecb9d1SAndroid Build Coastguard Worker if (length != (2u + nr_cbufs))
161*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
162*bbecb9d1SAndroid Build Coastguard Worker
163*bbecb9d1SAndroid Build Coastguard Worker if (nr_cbufs > 8)
164*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
165*bbecb9d1SAndroid Build Coastguard Worker
166*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < nr_cbufs; i++)
167*bbecb9d1SAndroid Build Coastguard Worker surf_handle[i] = get_buf_entry(buf, VIRGL_SET_FRAMEBUFFER_STATE_CBUF_HANDLE(i));
168*bbecb9d1SAndroid Build Coastguard Worker vrend_set_framebuffer_state(ctx, nr_cbufs, surf_handle, zsurf_handle);
169*bbecb9d1SAndroid Build Coastguard Worker return 0;
170*bbecb9d1SAndroid Build Coastguard Worker }
171*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_framebuffer_state_no_attach(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)172*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_framebuffer_state_no_attach(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
173*bbecb9d1SAndroid Build Coastguard Worker {
174*bbecb9d1SAndroid Build Coastguard Worker uint32_t width, height;
175*bbecb9d1SAndroid Build Coastguard Worker uint32_t layers, samples;
176*bbecb9d1SAndroid Build Coastguard Worker uint32_t tmp;
177*bbecb9d1SAndroid Build Coastguard Worker
178*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_SIZE)
179*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
180*bbecb9d1SAndroid Build Coastguard Worker
181*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_WIDTH_HEIGHT);
182*bbecb9d1SAndroid Build Coastguard Worker width = VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_WIDTH(tmp);
183*bbecb9d1SAndroid Build Coastguard Worker height = VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_HEIGHT(tmp);
184*bbecb9d1SAndroid Build Coastguard Worker
185*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_LAYERS_SAMPLES);
186*bbecb9d1SAndroid Build Coastguard Worker layers = VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_LAYERS(tmp);
187*bbecb9d1SAndroid Build Coastguard Worker samples = VIRGL_SET_FRAMEBUFFER_STATE_NO_ATTACH_SAMPLES(tmp);
188*bbecb9d1SAndroid Build Coastguard Worker
189*bbecb9d1SAndroid Build Coastguard Worker vrend_set_framebuffer_state_no_attach(ctx, width, height, layers, samples);
190*bbecb9d1SAndroid Build Coastguard Worker return 0;
191*bbecb9d1SAndroid Build Coastguard Worker }
192*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_clear(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)193*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_clear(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
194*bbecb9d1SAndroid Build Coastguard Worker {
195*bbecb9d1SAndroid Build Coastguard Worker union pipe_color_union color;
196*bbecb9d1SAndroid Build Coastguard Worker double depth;
197*bbecb9d1SAndroid Build Coastguard Worker unsigned stencil, buffers;
198*bbecb9d1SAndroid Build Coastguard Worker int i;
199*bbecb9d1SAndroid Build Coastguard Worker
200*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_CLEAR_SIZE)
201*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
202*bbecb9d1SAndroid Build Coastguard Worker buffers = get_buf_entry(buf, VIRGL_OBJ_CLEAR_BUFFERS);
203*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 4; i++)
204*bbecb9d1SAndroid Build Coastguard Worker color.ui[i] = get_buf_entry(buf, VIRGL_OBJ_CLEAR_COLOR_0 + i);
205*bbecb9d1SAndroid Build Coastguard Worker const void *depth_ptr = get_buf_ptr(buf, VIRGL_OBJ_CLEAR_DEPTH_0);
206*bbecb9d1SAndroid Build Coastguard Worker memcpy(&depth, depth_ptr, sizeof(double));
207*bbecb9d1SAndroid Build Coastguard Worker stencil = get_buf_entry(buf, VIRGL_OBJ_CLEAR_STENCIL);
208*bbecb9d1SAndroid Build Coastguard Worker
209*bbecb9d1SAndroid Build Coastguard Worker vrend_clear(ctx, buffers, &color, depth, stencil);
210*bbecb9d1SAndroid Build Coastguard Worker return 0;
211*bbecb9d1SAndroid Build Coastguard Worker }
212*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_clear_texture(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)213*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_clear_texture(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
214*bbecb9d1SAndroid Build Coastguard Worker {
215*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box box;
216*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle;
217*bbecb9d1SAndroid Build Coastguard Worker uint32_t level;
218*bbecb9d1SAndroid Build Coastguard Worker uint32_t arr[4] = {0};
219*bbecb9d1SAndroid Build Coastguard Worker
220*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_CLEAR_TEXTURE_SIZE)
221*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
222*bbecb9d1SAndroid Build Coastguard Worker
223*bbecb9d1SAndroid Build Coastguard Worker handle = get_buf_entry(buf, VIRGL_TEXTURE_HANDLE);
224*bbecb9d1SAndroid Build Coastguard Worker level = get_buf_entry(buf, VIRGL_TEXTURE_LEVEL);
225*bbecb9d1SAndroid Build Coastguard Worker box.x = get_buf_entry(buf, VIRGL_TEXTURE_SRC_X);
226*bbecb9d1SAndroid Build Coastguard Worker box.y = get_buf_entry(buf, VIRGL_TEXTURE_SRC_Y);
227*bbecb9d1SAndroid Build Coastguard Worker box.z = get_buf_entry(buf, VIRGL_TEXTURE_SRC_Z);
228*bbecb9d1SAndroid Build Coastguard Worker box.width = get_buf_entry(buf, VIRGL_TEXTURE_SRC_W);
229*bbecb9d1SAndroid Build Coastguard Worker box.height = get_buf_entry(buf, VIRGL_TEXTURE_SRC_H);
230*bbecb9d1SAndroid Build Coastguard Worker box.depth = get_buf_entry(buf, VIRGL_TEXTURE_SRC_D);
231*bbecb9d1SAndroid Build Coastguard Worker arr[0] = get_buf_entry(buf, VIRGL_TEXTURE_ARRAY_A);
232*bbecb9d1SAndroid Build Coastguard Worker arr[1] = get_buf_entry(buf, VIRGL_TEXTURE_ARRAY_B);
233*bbecb9d1SAndroid Build Coastguard Worker arr[2] = get_buf_entry(buf, VIRGL_TEXTURE_ARRAY_C);
234*bbecb9d1SAndroid Build Coastguard Worker arr[3] = get_buf_entry(buf, VIRGL_TEXTURE_ARRAY_D);
235*bbecb9d1SAndroid Build Coastguard Worker
236*bbecb9d1SAndroid Build Coastguard Worker return vrend_clear_texture(ctx, handle, level, &box, (void *) &arr);
237*bbecb9d1SAndroid Build Coastguard Worker }
238*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_viewport_state(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)239*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_viewport_state(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
240*bbecb9d1SAndroid Build Coastguard Worker {
241*bbecb9d1SAndroid Build Coastguard Worker struct pipe_viewport_state vps[PIPE_MAX_VIEWPORTS];
242*bbecb9d1SAndroid Build Coastguard Worker uint i, v;
243*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_viewports, start_slot;
244*bbecb9d1SAndroid Build Coastguard Worker if (length < 1)
245*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
246*bbecb9d1SAndroid Build Coastguard Worker
247*bbecb9d1SAndroid Build Coastguard Worker if ((length - 1) % 6)
248*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
249*bbecb9d1SAndroid Build Coastguard Worker
250*bbecb9d1SAndroid Build Coastguard Worker num_viewports = (length - 1) / 6;
251*bbecb9d1SAndroid Build Coastguard Worker start_slot = get_buf_entry(buf, VIRGL_SET_VIEWPORT_START_SLOT);
252*bbecb9d1SAndroid Build Coastguard Worker
253*bbecb9d1SAndroid Build Coastguard Worker if (num_viewports > PIPE_MAX_VIEWPORTS ||
254*bbecb9d1SAndroid Build Coastguard Worker start_slot > (PIPE_MAX_VIEWPORTS - num_viewports))
255*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
256*bbecb9d1SAndroid Build Coastguard Worker
257*bbecb9d1SAndroid Build Coastguard Worker for (v = 0; v < num_viewports; v++) {
258*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 3; i++)
259*bbecb9d1SAndroid Build Coastguard Worker vps[v].scale[i] = uif(get_buf_entry(buf, VIRGL_SET_VIEWPORT_STATE_SCALE_0(v) + i));
260*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 3; i++)
261*bbecb9d1SAndroid Build Coastguard Worker vps[v].translate[i] = uif(get_buf_entry(buf, VIRGL_SET_VIEWPORT_STATE_TRANSLATE_0(v) + i));
262*bbecb9d1SAndroid Build Coastguard Worker }
263*bbecb9d1SAndroid Build Coastguard Worker
264*bbecb9d1SAndroid Build Coastguard Worker vrend_set_viewport_states(ctx, start_slot, num_viewports, vps);
265*bbecb9d1SAndroid Build Coastguard Worker return 0;
266*bbecb9d1SAndroid Build Coastguard Worker }
267*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_index_buffer(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)268*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_index_buffer(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
269*bbecb9d1SAndroid Build Coastguard Worker {
270*bbecb9d1SAndroid Build Coastguard Worker if (length != 1 && length != 3)
271*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
272*bbecb9d1SAndroid Build Coastguard Worker vrend_set_index_buffer(ctx,
273*bbecb9d1SAndroid Build Coastguard Worker get_buf_entry(buf, VIRGL_SET_INDEX_BUFFER_HANDLE),
274*bbecb9d1SAndroid Build Coastguard Worker (length == 3) ? get_buf_entry(buf, VIRGL_SET_INDEX_BUFFER_INDEX_SIZE) : 0,
275*bbecb9d1SAndroid Build Coastguard Worker (length == 3) ? get_buf_entry(buf, VIRGL_SET_INDEX_BUFFER_OFFSET) : 0);
276*bbecb9d1SAndroid Build Coastguard Worker return 0;
277*bbecb9d1SAndroid Build Coastguard Worker }
278*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_constant_buffer(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)279*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_constant_buffer(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
280*bbecb9d1SAndroid Build Coastguard Worker {
281*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader;
282*bbecb9d1SAndroid Build Coastguard Worker int nc = (length - 2);
283*bbecb9d1SAndroid Build Coastguard Worker
284*bbecb9d1SAndroid Build Coastguard Worker if (length < 2)
285*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
286*bbecb9d1SAndroid Build Coastguard Worker
287*bbecb9d1SAndroid Build Coastguard Worker shader = get_buf_entry(buf, VIRGL_SET_CONSTANT_BUFFER_SHADER_TYPE);
288*bbecb9d1SAndroid Build Coastguard Worker /* VIRGL_SET_CONSTANT_BUFFER_INDEX is not used */
289*bbecb9d1SAndroid Build Coastguard Worker
290*bbecb9d1SAndroid Build Coastguard Worker if (shader >= PIPE_SHADER_TYPES)
291*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
292*bbecb9d1SAndroid Build Coastguard Worker
293*bbecb9d1SAndroid Build Coastguard Worker vrend_set_constants(ctx, shader, nc, get_buf_ptr(buf, VIRGL_SET_CONSTANT_BUFFER_DATA_START));
294*bbecb9d1SAndroid Build Coastguard Worker return 0;
295*bbecb9d1SAndroid Build Coastguard Worker }
296*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_uniform_buffer(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)297*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_uniform_buffer(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
298*bbecb9d1SAndroid Build Coastguard Worker {
299*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_SET_UNIFORM_BUFFER_SIZE)
300*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
301*bbecb9d1SAndroid Build Coastguard Worker
302*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader = get_buf_entry(buf, VIRGL_SET_UNIFORM_BUFFER_SHADER_TYPE);
303*bbecb9d1SAndroid Build Coastguard Worker uint32_t index = get_buf_entry(buf, VIRGL_SET_UNIFORM_BUFFER_INDEX);
304*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset = get_buf_entry(buf, VIRGL_SET_UNIFORM_BUFFER_OFFSET);
305*bbecb9d1SAndroid Build Coastguard Worker uint32_t blength = get_buf_entry(buf, VIRGL_SET_UNIFORM_BUFFER_LENGTH);
306*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_SET_UNIFORM_BUFFER_RES_HANDLE);
307*bbecb9d1SAndroid Build Coastguard Worker
308*bbecb9d1SAndroid Build Coastguard Worker if (shader >= PIPE_SHADER_TYPES)
309*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
310*bbecb9d1SAndroid Build Coastguard Worker
311*bbecb9d1SAndroid Build Coastguard Worker if (index >= PIPE_MAX_CONSTANT_BUFFERS)
312*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
313*bbecb9d1SAndroid Build Coastguard Worker
314*bbecb9d1SAndroid Build Coastguard Worker vrend_set_uniform_buffer(ctx, shader, index, offset, blength, handle);
315*bbecb9d1SAndroid Build Coastguard Worker return 0;
316*bbecb9d1SAndroid Build Coastguard Worker }
317*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_vertex_buffers(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)318*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_vertex_buffers(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
319*bbecb9d1SAndroid Build Coastguard Worker {
320*bbecb9d1SAndroid Build Coastguard Worker int num_vbo;
321*bbecb9d1SAndroid Build Coastguard Worker int i;
322*bbecb9d1SAndroid Build Coastguard Worker
323*bbecb9d1SAndroid Build Coastguard Worker /* must be a multiple of 3 */
324*bbecb9d1SAndroid Build Coastguard Worker if (length && (length % 3))
325*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
326*bbecb9d1SAndroid Build Coastguard Worker
327*bbecb9d1SAndroid Build Coastguard Worker num_vbo = (length / 3);
328*bbecb9d1SAndroid Build Coastguard Worker if (num_vbo > PIPE_MAX_ATTRIBS)
329*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
330*bbecb9d1SAndroid Build Coastguard Worker
331*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_vbo; i++) {
332*bbecb9d1SAndroid Build Coastguard Worker vrend_set_single_vbo(ctx, i,
333*bbecb9d1SAndroid Build Coastguard Worker get_buf_entry(buf, VIRGL_SET_VERTEX_BUFFER_STRIDE(i)),
334*bbecb9d1SAndroid Build Coastguard Worker get_buf_entry(buf, VIRGL_SET_VERTEX_BUFFER_OFFSET(i)),
335*bbecb9d1SAndroid Build Coastguard Worker get_buf_entry(buf, VIRGL_SET_VERTEX_BUFFER_HANDLE(i)));
336*bbecb9d1SAndroid Build Coastguard Worker }
337*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_vbo(ctx, num_vbo);
338*bbecb9d1SAndroid Build Coastguard Worker return 0;
339*bbecb9d1SAndroid Build Coastguard Worker }
340*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_sampler_views(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)341*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_sampler_views(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
342*bbecb9d1SAndroid Build Coastguard Worker {
343*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_samps;
344*bbecb9d1SAndroid Build Coastguard Worker uint32_t i;
345*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type;
346*bbecb9d1SAndroid Build Coastguard Worker uint32_t start_slot;
347*bbecb9d1SAndroid Build Coastguard Worker
348*bbecb9d1SAndroid Build Coastguard Worker if (length < 2)
349*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
350*bbecb9d1SAndroid Build Coastguard Worker num_samps = length - 2;
351*bbecb9d1SAndroid Build Coastguard Worker shader_type = get_buf_entry(buf, VIRGL_SET_SAMPLER_VIEWS_SHADER_TYPE);
352*bbecb9d1SAndroid Build Coastguard Worker start_slot = get_buf_entry(buf, VIRGL_SET_SAMPLER_VIEWS_START_SLOT);
353*bbecb9d1SAndroid Build Coastguard Worker
354*bbecb9d1SAndroid Build Coastguard Worker if (shader_type >= PIPE_SHADER_TYPES)
355*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
356*bbecb9d1SAndroid Build Coastguard Worker
357*bbecb9d1SAndroid Build Coastguard Worker if (num_samps > PIPE_MAX_SHADER_SAMPLER_VIEWS ||
358*bbecb9d1SAndroid Build Coastguard Worker start_slot > (PIPE_MAX_SHADER_SAMPLER_VIEWS - num_samps))
359*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
360*bbecb9d1SAndroid Build Coastguard Worker
361*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_samps; i++) {
362*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_SET_SAMPLER_VIEWS_V0_HANDLE + i);
363*bbecb9d1SAndroid Build Coastguard Worker vrend_set_single_sampler_view(ctx, shader_type, i + start_slot, handle);
364*bbecb9d1SAndroid Build Coastguard Worker }
365*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_sampler_views(ctx, shader_type, start_slot, num_samps);
366*bbecb9d1SAndroid Build Coastguard Worker return 0;
367*bbecb9d1SAndroid Build Coastguard Worker }
368*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_transfer_common(const uint32_t * buf,uint32_t * dst_handle,struct vrend_transfer_info * info)369*bbecb9d1SAndroid Build Coastguard Worker static void vrend_decode_transfer_common(const uint32_t *buf,
370*bbecb9d1SAndroid Build Coastguard Worker uint32_t *dst_handle,
371*bbecb9d1SAndroid Build Coastguard Worker struct vrend_transfer_info *info)
372*bbecb9d1SAndroid Build Coastguard Worker {
373*bbecb9d1SAndroid Build Coastguard Worker *dst_handle = get_buf_entry(buf, VIRGL_RESOURCE_IW_RES_HANDLE);
374*bbecb9d1SAndroid Build Coastguard Worker
375*bbecb9d1SAndroid Build Coastguard Worker info->level = get_buf_entry(buf, VIRGL_RESOURCE_IW_LEVEL);
376*bbecb9d1SAndroid Build Coastguard Worker info->stride = get_buf_entry(buf, VIRGL_RESOURCE_IW_STRIDE);
377*bbecb9d1SAndroid Build Coastguard Worker info->layer_stride = get_buf_entry(buf, VIRGL_RESOURCE_IW_LAYER_STRIDE);
378*bbecb9d1SAndroid Build Coastguard Worker info->box->x = get_buf_entry(buf, VIRGL_RESOURCE_IW_X);
379*bbecb9d1SAndroid Build Coastguard Worker info->box->y = get_buf_entry(buf, VIRGL_RESOURCE_IW_Y);
380*bbecb9d1SAndroid Build Coastguard Worker info->box->z = get_buf_entry(buf, VIRGL_RESOURCE_IW_Z);
381*bbecb9d1SAndroid Build Coastguard Worker info->box->width = get_buf_entry(buf, VIRGL_RESOURCE_IW_W);
382*bbecb9d1SAndroid Build Coastguard Worker info->box->height = get_buf_entry(buf, VIRGL_RESOURCE_IW_H);
383*bbecb9d1SAndroid Build Coastguard Worker info->box->depth = get_buf_entry(buf, VIRGL_RESOURCE_IW_D);
384*bbecb9d1SAndroid Build Coastguard Worker }
385*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_resource_inline_write(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)386*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_resource_inline_write(struct vrend_context *ctx, const uint32_t *buf,
387*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
388*bbecb9d1SAndroid Build Coastguard Worker {
389*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box box;
390*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle;
391*bbecb9d1SAndroid Build Coastguard Worker struct vrend_transfer_info info;
392*bbecb9d1SAndroid Build Coastguard Worker uint32_t data_len;
393*bbecb9d1SAndroid Build Coastguard Worker struct iovec dataiovec;
394*bbecb9d1SAndroid Build Coastguard Worker const void *data;
395*bbecb9d1SAndroid Build Coastguard Worker
396*bbecb9d1SAndroid Build Coastguard Worker if (length < 12)
397*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
398*bbecb9d1SAndroid Build Coastguard Worker
399*bbecb9d1SAndroid Build Coastguard Worker memset(&info, 0, sizeof(info));
400*bbecb9d1SAndroid Build Coastguard Worker info.box = &box;
401*bbecb9d1SAndroid Build Coastguard Worker vrend_decode_transfer_common(buf, &dst_handle, &info);
402*bbecb9d1SAndroid Build Coastguard Worker data_len = (length - 11) * 4;
403*bbecb9d1SAndroid Build Coastguard Worker data = get_buf_ptr(buf, VIRGL_RESOURCE_IW_DATA_START);
404*bbecb9d1SAndroid Build Coastguard Worker
405*bbecb9d1SAndroid Build Coastguard Worker info.offset = 0;
406*bbecb9d1SAndroid Build Coastguard Worker
407*bbecb9d1SAndroid Build Coastguard Worker dataiovec.iov_base = (void*)data;
408*bbecb9d1SAndroid Build Coastguard Worker dataiovec.iov_len = data_len;
409*bbecb9d1SAndroid Build Coastguard Worker
410*bbecb9d1SAndroid Build Coastguard Worker info.iovec = &dataiovec;
411*bbecb9d1SAndroid Build Coastguard Worker info.iovec_cnt = 1;
412*bbecb9d1SAndroid Build Coastguard Worker return vrend_transfer_inline_write(ctx, dst_handle, &info);
413*bbecb9d1SAndroid Build Coastguard Worker }
414*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_draw_vbo(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)415*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_draw_vbo(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
416*bbecb9d1SAndroid Build Coastguard Worker {
417*bbecb9d1SAndroid Build Coastguard Worker struct pipe_draw_info info;
418*bbecb9d1SAndroid Build Coastguard Worker uint32_t cso;
419*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = 0, indirect_draw_count_handle = 0;
420*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_DRAW_VBO_SIZE && length != VIRGL_DRAW_VBO_SIZE_TESS &&
421*bbecb9d1SAndroid Build Coastguard Worker length != VIRGL_DRAW_VBO_SIZE_INDIRECT)
422*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
423*bbecb9d1SAndroid Build Coastguard Worker memset(&info, 0, sizeof(struct pipe_draw_info));
424*bbecb9d1SAndroid Build Coastguard Worker
425*bbecb9d1SAndroid Build Coastguard Worker info.start = get_buf_entry(buf, VIRGL_DRAW_VBO_START);
426*bbecb9d1SAndroid Build Coastguard Worker info.count = get_buf_entry(buf, VIRGL_DRAW_VBO_COUNT);
427*bbecb9d1SAndroid Build Coastguard Worker info.mode = get_buf_entry(buf, VIRGL_DRAW_VBO_MODE);
428*bbecb9d1SAndroid Build Coastguard Worker info.indexed = !!get_buf_entry(buf, VIRGL_DRAW_VBO_INDEXED);
429*bbecb9d1SAndroid Build Coastguard Worker info.instance_count = get_buf_entry(buf, VIRGL_DRAW_VBO_INSTANCE_COUNT);
430*bbecb9d1SAndroid Build Coastguard Worker info.index_bias = get_buf_entry(buf, VIRGL_DRAW_VBO_INDEX_BIAS);
431*bbecb9d1SAndroid Build Coastguard Worker info.start_instance = get_buf_entry(buf, VIRGL_DRAW_VBO_START_INSTANCE);
432*bbecb9d1SAndroid Build Coastguard Worker info.primitive_restart = !!get_buf_entry(buf, VIRGL_DRAW_VBO_PRIMITIVE_RESTART);
433*bbecb9d1SAndroid Build Coastguard Worker info.restart_index = get_buf_entry(buf, VIRGL_DRAW_VBO_RESTART_INDEX);
434*bbecb9d1SAndroid Build Coastguard Worker info.min_index = get_buf_entry(buf, VIRGL_DRAW_VBO_MIN_INDEX);
435*bbecb9d1SAndroid Build Coastguard Worker info.max_index = get_buf_entry(buf, VIRGL_DRAW_VBO_MAX_INDEX);
436*bbecb9d1SAndroid Build Coastguard Worker
437*bbecb9d1SAndroid Build Coastguard Worker if (length >= VIRGL_DRAW_VBO_SIZE_TESS) {
438*bbecb9d1SAndroid Build Coastguard Worker info.vertices_per_patch = get_buf_entry(buf, VIRGL_DRAW_VBO_VERTICES_PER_PATCH);
439*bbecb9d1SAndroid Build Coastguard Worker info.drawid = get_buf_entry(buf, VIRGL_DRAW_VBO_DRAWID);
440*bbecb9d1SAndroid Build Coastguard Worker }
441*bbecb9d1SAndroid Build Coastguard Worker
442*bbecb9d1SAndroid Build Coastguard Worker if (length == VIRGL_DRAW_VBO_SIZE_INDIRECT) {
443*bbecb9d1SAndroid Build Coastguard Worker handle = get_buf_entry(buf, VIRGL_DRAW_VBO_INDIRECT_HANDLE);
444*bbecb9d1SAndroid Build Coastguard Worker info.indirect.offset = get_buf_entry(buf, VIRGL_DRAW_VBO_INDIRECT_OFFSET);
445*bbecb9d1SAndroid Build Coastguard Worker info.indirect.stride = get_buf_entry(buf, VIRGL_DRAW_VBO_INDIRECT_STRIDE);
446*bbecb9d1SAndroid Build Coastguard Worker info.indirect.draw_count = get_buf_entry(buf, VIRGL_DRAW_VBO_INDIRECT_DRAW_COUNT);
447*bbecb9d1SAndroid Build Coastguard Worker info.indirect.indirect_draw_count_offset = get_buf_entry(buf, VIRGL_DRAW_VBO_INDIRECT_DRAW_COUNT_OFFSET);
448*bbecb9d1SAndroid Build Coastguard Worker indirect_draw_count_handle = get_buf_entry(buf, VIRGL_DRAW_VBO_INDIRECT_DRAW_COUNT_HANDLE);
449*bbecb9d1SAndroid Build Coastguard Worker }
450*bbecb9d1SAndroid Build Coastguard Worker
451*bbecb9d1SAndroid Build Coastguard Worker cso = get_buf_entry(buf, VIRGL_DRAW_VBO_COUNT_FROM_SO);
452*bbecb9d1SAndroid Build Coastguard Worker
453*bbecb9d1SAndroid Build Coastguard Worker return vrend_draw_vbo(ctx, &info, cso, handle, indirect_draw_count_handle);
454*bbecb9d1SAndroid Build Coastguard Worker }
455*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_blend(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)456*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_blend(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
457*bbecb9d1SAndroid Build Coastguard Worker {
458*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_state *blend_state;
459*bbecb9d1SAndroid Build Coastguard Worker uint32_t tmp;
460*bbecb9d1SAndroid Build Coastguard Worker int i;
461*bbecb9d1SAndroid Build Coastguard Worker
462*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_BLEND_SIZE) {
463*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
464*bbecb9d1SAndroid Build Coastguard Worker }
465*bbecb9d1SAndroid Build Coastguard Worker
466*bbecb9d1SAndroid Build Coastguard Worker blend_state = CALLOC_STRUCT(pipe_blend_state);
467*bbecb9d1SAndroid Build Coastguard Worker if (!blend_state)
468*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
469*bbecb9d1SAndroid Build Coastguard Worker
470*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_BLEND_S0);
471*bbecb9d1SAndroid Build Coastguard Worker blend_state->independent_blend_enable = (tmp & 1);
472*bbecb9d1SAndroid Build Coastguard Worker blend_state->logicop_enable = (tmp >> 1) & 0x1;
473*bbecb9d1SAndroid Build Coastguard Worker blend_state->dither = (tmp >> 2) & 0x1;
474*bbecb9d1SAndroid Build Coastguard Worker blend_state->alpha_to_coverage = (tmp >> 3) & 0x1;
475*bbecb9d1SAndroid Build Coastguard Worker blend_state->alpha_to_one = (tmp >> 4) & 0x1;
476*bbecb9d1SAndroid Build Coastguard Worker
477*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_BLEND_S1);
478*bbecb9d1SAndroid Build Coastguard Worker blend_state->logicop_func = tmp & 0xf;
479*bbecb9d1SAndroid Build Coastguard Worker
480*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
481*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_BLEND_S2(i));
482*bbecb9d1SAndroid Build Coastguard Worker blend_state->rt[i].blend_enable = tmp & 0x1;
483*bbecb9d1SAndroid Build Coastguard Worker blend_state->rt[i].rgb_func = (tmp >> 1) & 0x7;
484*bbecb9d1SAndroid Build Coastguard Worker blend_state->rt[i].rgb_src_factor = (tmp >> 4) & 0x1f;
485*bbecb9d1SAndroid Build Coastguard Worker blend_state->rt[i].rgb_dst_factor = (tmp >> 9) & 0x1f;
486*bbecb9d1SAndroid Build Coastguard Worker blend_state->rt[i].alpha_func = (tmp >> 14) & 0x7;
487*bbecb9d1SAndroid Build Coastguard Worker blend_state->rt[i].alpha_src_factor = (tmp >> 17) & 0x1f;
488*bbecb9d1SAndroid Build Coastguard Worker blend_state->rt[i].alpha_dst_factor = (tmp >> 22) & 0x1f;
489*bbecb9d1SAndroid Build Coastguard Worker blend_state->rt[i].colormask = (tmp >> 27) & 0xf;
490*bbecb9d1SAndroid Build Coastguard Worker }
491*bbecb9d1SAndroid Build Coastguard Worker
492*bbecb9d1SAndroid Build Coastguard Worker tmp = vrend_renderer_object_insert(ctx, blend_state, handle,
493*bbecb9d1SAndroid Build Coastguard Worker VIRGL_OBJECT_BLEND);
494*bbecb9d1SAndroid Build Coastguard Worker if (tmp == 0) {
495*bbecb9d1SAndroid Build Coastguard Worker FREE(blend_state);
496*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
497*bbecb9d1SAndroid Build Coastguard Worker }
498*bbecb9d1SAndroid Build Coastguard Worker return 0;
499*bbecb9d1SAndroid Build Coastguard Worker }
500*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_dsa(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)501*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_dsa(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
502*bbecb9d1SAndroid Build Coastguard Worker {
503*bbecb9d1SAndroid Build Coastguard Worker int i;
504*bbecb9d1SAndroid Build Coastguard Worker struct pipe_depth_stencil_alpha_state *dsa_state;
505*bbecb9d1SAndroid Build Coastguard Worker uint32_t tmp;
506*bbecb9d1SAndroid Build Coastguard Worker
507*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_DSA_SIZE)
508*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
509*bbecb9d1SAndroid Build Coastguard Worker
510*bbecb9d1SAndroid Build Coastguard Worker dsa_state = CALLOC_STRUCT(pipe_depth_stencil_alpha_state);
511*bbecb9d1SAndroid Build Coastguard Worker if (!dsa_state)
512*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
513*bbecb9d1SAndroid Build Coastguard Worker
514*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_DSA_S0);
515*bbecb9d1SAndroid Build Coastguard Worker dsa_state->depth.enabled = tmp & 0x1;
516*bbecb9d1SAndroid Build Coastguard Worker dsa_state->depth.writemask = (tmp >> 1) & 0x1;
517*bbecb9d1SAndroid Build Coastguard Worker dsa_state->depth.func = (tmp >> 2) & 0x7;
518*bbecb9d1SAndroid Build Coastguard Worker
519*bbecb9d1SAndroid Build Coastguard Worker dsa_state->alpha.enabled = (tmp >> 8) & 0x1;
520*bbecb9d1SAndroid Build Coastguard Worker dsa_state->alpha.func = (tmp >> 9) & 0x7;
521*bbecb9d1SAndroid Build Coastguard Worker
522*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
523*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_DSA_S1 + i);
524*bbecb9d1SAndroid Build Coastguard Worker dsa_state->stencil[i].enabled = tmp & 0x1;
525*bbecb9d1SAndroid Build Coastguard Worker dsa_state->stencil[i].func = (tmp >> 1) & 0x7;
526*bbecb9d1SAndroid Build Coastguard Worker dsa_state->stencil[i].fail_op = (tmp >> 4) & 0x7;
527*bbecb9d1SAndroid Build Coastguard Worker dsa_state->stencil[i].zpass_op = (tmp >> 7) & 0x7;
528*bbecb9d1SAndroid Build Coastguard Worker dsa_state->stencil[i].zfail_op = (tmp >> 10) & 0x7;
529*bbecb9d1SAndroid Build Coastguard Worker dsa_state->stencil[i].valuemask = (tmp >> 13) & 0xff;
530*bbecb9d1SAndroid Build Coastguard Worker dsa_state->stencil[i].writemask = (tmp >> 21) & 0xff;
531*bbecb9d1SAndroid Build Coastguard Worker }
532*bbecb9d1SAndroid Build Coastguard Worker
533*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_DSA_ALPHA_REF);
534*bbecb9d1SAndroid Build Coastguard Worker dsa_state->alpha.ref_value = uif(tmp);
535*bbecb9d1SAndroid Build Coastguard Worker
536*bbecb9d1SAndroid Build Coastguard Worker tmp = vrend_renderer_object_insert(ctx, dsa_state, handle,
537*bbecb9d1SAndroid Build Coastguard Worker VIRGL_OBJECT_DSA);
538*bbecb9d1SAndroid Build Coastguard Worker if (tmp == 0) {
539*bbecb9d1SAndroid Build Coastguard Worker FREE(dsa_state);
540*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
541*bbecb9d1SAndroid Build Coastguard Worker }
542*bbecb9d1SAndroid Build Coastguard Worker return 0;
543*bbecb9d1SAndroid Build Coastguard Worker }
544*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_rasterizer(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)545*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_rasterizer(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
546*bbecb9d1SAndroid Build Coastguard Worker {
547*bbecb9d1SAndroid Build Coastguard Worker struct pipe_rasterizer_state *rs_state;
548*bbecb9d1SAndroid Build Coastguard Worker uint32_t tmp;
549*bbecb9d1SAndroid Build Coastguard Worker
550*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_RS_SIZE)
551*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
552*bbecb9d1SAndroid Build Coastguard Worker
553*bbecb9d1SAndroid Build Coastguard Worker rs_state = CALLOC_STRUCT(pipe_rasterizer_state);
554*bbecb9d1SAndroid Build Coastguard Worker if (!rs_state)
555*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
556*bbecb9d1SAndroid Build Coastguard Worker
557*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_RS_S0);
558*bbecb9d1SAndroid Build Coastguard Worker #define ebit(name, bit) rs_state->name = (tmp >> bit) & 0x1
559*bbecb9d1SAndroid Build Coastguard Worker #define emask(name, bit, mask) rs_state->name = (tmp >> bit) & mask
560*bbecb9d1SAndroid Build Coastguard Worker
561*bbecb9d1SAndroid Build Coastguard Worker ebit(flatshade, 0);
562*bbecb9d1SAndroid Build Coastguard Worker ebit(depth_clip, 1);
563*bbecb9d1SAndroid Build Coastguard Worker ebit(clip_halfz, 2);
564*bbecb9d1SAndroid Build Coastguard Worker ebit(rasterizer_discard, 3);
565*bbecb9d1SAndroid Build Coastguard Worker ebit(flatshade_first, 4);
566*bbecb9d1SAndroid Build Coastguard Worker ebit(light_twoside, 5);
567*bbecb9d1SAndroid Build Coastguard Worker ebit(sprite_coord_mode, 6);
568*bbecb9d1SAndroid Build Coastguard Worker ebit(point_quad_rasterization, 7);
569*bbecb9d1SAndroid Build Coastguard Worker emask(cull_face, 8, 0x3);
570*bbecb9d1SAndroid Build Coastguard Worker emask(fill_front, 10, 0x3);
571*bbecb9d1SAndroid Build Coastguard Worker emask(fill_back, 12, 0x3);
572*bbecb9d1SAndroid Build Coastguard Worker ebit(scissor, 14);
573*bbecb9d1SAndroid Build Coastguard Worker ebit(front_ccw, 15);
574*bbecb9d1SAndroid Build Coastguard Worker ebit(clamp_vertex_color, 16);
575*bbecb9d1SAndroid Build Coastguard Worker ebit(clamp_fragment_color, 17);
576*bbecb9d1SAndroid Build Coastguard Worker ebit(offset_line, 18);
577*bbecb9d1SAndroid Build Coastguard Worker ebit(offset_point, 19);
578*bbecb9d1SAndroid Build Coastguard Worker ebit(offset_tri, 20);
579*bbecb9d1SAndroid Build Coastguard Worker ebit(poly_smooth, 21);
580*bbecb9d1SAndroid Build Coastguard Worker ebit(poly_stipple_enable, 22);
581*bbecb9d1SAndroid Build Coastguard Worker ebit(point_smooth, 23);
582*bbecb9d1SAndroid Build Coastguard Worker ebit(point_size_per_vertex, 24);
583*bbecb9d1SAndroid Build Coastguard Worker ebit(multisample, 25);
584*bbecb9d1SAndroid Build Coastguard Worker ebit(line_smooth, 26);
585*bbecb9d1SAndroid Build Coastguard Worker ebit(line_stipple_enable, 27);
586*bbecb9d1SAndroid Build Coastguard Worker ebit(line_last_pixel, 28);
587*bbecb9d1SAndroid Build Coastguard Worker ebit(half_pixel_center, 29);
588*bbecb9d1SAndroid Build Coastguard Worker ebit(bottom_edge_rule, 30);
589*bbecb9d1SAndroid Build Coastguard Worker ebit(force_persample_interp, 31);
590*bbecb9d1SAndroid Build Coastguard Worker rs_state->point_size = uif(get_buf_entry(buf, VIRGL_OBJ_RS_POINT_SIZE));
591*bbecb9d1SAndroid Build Coastguard Worker rs_state->sprite_coord_enable = get_buf_entry(buf, VIRGL_OBJ_RS_SPRITE_COORD_ENABLE);
592*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_RS_S3);
593*bbecb9d1SAndroid Build Coastguard Worker emask(line_stipple_pattern, 0, 0xffff);
594*bbecb9d1SAndroid Build Coastguard Worker emask(line_stipple_factor, 16, 0xff);
595*bbecb9d1SAndroid Build Coastguard Worker emask(clip_plane_enable, 24, 0xff);
596*bbecb9d1SAndroid Build Coastguard Worker
597*bbecb9d1SAndroid Build Coastguard Worker rs_state->line_width = uif(get_buf_entry(buf, VIRGL_OBJ_RS_LINE_WIDTH));
598*bbecb9d1SAndroid Build Coastguard Worker rs_state->offset_units = uif(get_buf_entry(buf, VIRGL_OBJ_RS_OFFSET_UNITS));
599*bbecb9d1SAndroid Build Coastguard Worker rs_state->offset_scale = uif(get_buf_entry(buf, VIRGL_OBJ_RS_OFFSET_SCALE));
600*bbecb9d1SAndroid Build Coastguard Worker rs_state->offset_clamp = uif(get_buf_entry(buf, VIRGL_OBJ_RS_OFFSET_CLAMP));
601*bbecb9d1SAndroid Build Coastguard Worker
602*bbecb9d1SAndroid Build Coastguard Worker tmp = vrend_renderer_object_insert(ctx, rs_state, handle,
603*bbecb9d1SAndroid Build Coastguard Worker VIRGL_OBJECT_RASTERIZER);
604*bbecb9d1SAndroid Build Coastguard Worker if (tmp == 0) {
605*bbecb9d1SAndroid Build Coastguard Worker FREE(rs_state);
606*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
607*bbecb9d1SAndroid Build Coastguard Worker }
608*bbecb9d1SAndroid Build Coastguard Worker return 0;
609*bbecb9d1SAndroid Build Coastguard Worker }
610*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_surface_common(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint32_t sample_count)611*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_surface_common(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint32_t sample_count)
612*bbecb9d1SAndroid Build Coastguard Worker {
613*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle, format, val0, val1;
614*bbecb9d1SAndroid Build Coastguard Worker
615*bbecb9d1SAndroid Build Coastguard Worker res_handle = get_buf_entry(buf, VIRGL_OBJ_SURFACE_RES_HANDLE);
616*bbecb9d1SAndroid Build Coastguard Worker format = get_buf_entry(buf, VIRGL_OBJ_SURFACE_FORMAT);
617*bbecb9d1SAndroid Build Coastguard Worker /* decide later if these are texture or buffer */
618*bbecb9d1SAndroid Build Coastguard Worker val0 = get_buf_entry(buf, VIRGL_OBJ_SURFACE_BUFFER_FIRST_ELEMENT);
619*bbecb9d1SAndroid Build Coastguard Worker val1 = get_buf_entry(buf, VIRGL_OBJ_SURFACE_BUFFER_LAST_ELEMENT);
620*bbecb9d1SAndroid Build Coastguard Worker
621*bbecb9d1SAndroid Build Coastguard Worker return vrend_create_surface(ctx, handle, res_handle, format, val0, val1, sample_count);
622*bbecb9d1SAndroid Build Coastguard Worker }
623*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_surface(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)624*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_surface(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
625*bbecb9d1SAndroid Build Coastguard Worker {
626*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_SURFACE_SIZE)
627*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
628*bbecb9d1SAndroid Build Coastguard Worker
629*bbecb9d1SAndroid Build Coastguard Worker return vrend_decode_create_surface_common(ctx, buf, handle, 0);
630*bbecb9d1SAndroid Build Coastguard Worker }
631*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_msaa_surface(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)632*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_msaa_surface(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
633*bbecb9d1SAndroid Build Coastguard Worker {
634*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_MSAA_SURFACE_SIZE)
635*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
636*bbecb9d1SAndroid Build Coastguard Worker
637*bbecb9d1SAndroid Build Coastguard Worker uint32_t sample_count = get_buf_entry(buf, VIRGL_OBJ_SURFACE_SAMPLE_COUNT);
638*bbecb9d1SAndroid Build Coastguard Worker return vrend_decode_create_surface_common(ctx, buf, handle, sample_count);
639*bbecb9d1SAndroid Build Coastguard Worker }
640*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_sampler_view(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)641*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_sampler_view(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
642*bbecb9d1SAndroid Build Coastguard Worker {
643*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle, format, val0, val1, swizzle_packed;
644*bbecb9d1SAndroid Build Coastguard Worker
645*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_SAMPLER_VIEW_SIZE)
646*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
647*bbecb9d1SAndroid Build Coastguard Worker
648*bbecb9d1SAndroid Build Coastguard Worker res_handle = get_buf_entry(buf, VIRGL_OBJ_SAMPLER_VIEW_RES_HANDLE);
649*bbecb9d1SAndroid Build Coastguard Worker format = get_buf_entry(buf, VIRGL_OBJ_SAMPLER_VIEW_FORMAT);
650*bbecb9d1SAndroid Build Coastguard Worker val0 = get_buf_entry(buf, VIRGL_OBJ_SAMPLER_VIEW_BUFFER_FIRST_ELEMENT);
651*bbecb9d1SAndroid Build Coastguard Worker val1 = get_buf_entry(buf, VIRGL_OBJ_SAMPLER_VIEW_BUFFER_LAST_ELEMENT);
652*bbecb9d1SAndroid Build Coastguard Worker swizzle_packed = get_buf_entry(buf, VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE);
653*bbecb9d1SAndroid Build Coastguard Worker return vrend_create_sampler_view(ctx, handle, res_handle, format, val0, val1,swizzle_packed);
654*bbecb9d1SAndroid Build Coastguard Worker }
655*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_sampler_state(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)656*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_sampler_state(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
657*bbecb9d1SAndroid Build Coastguard Worker {
658*bbecb9d1SAndroid Build Coastguard Worker struct pipe_sampler_state state;
659*bbecb9d1SAndroid Build Coastguard Worker int i;
660*bbecb9d1SAndroid Build Coastguard Worker uint32_t tmp;
661*bbecb9d1SAndroid Build Coastguard Worker
662*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_SAMPLER_STATE_SIZE)
663*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
664*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_SAMPLER_STATE_S0);
665*bbecb9d1SAndroid Build Coastguard Worker state.wrap_s = tmp & 0x7;
666*bbecb9d1SAndroid Build Coastguard Worker state.wrap_t = (tmp >> 3) & 0x7;
667*bbecb9d1SAndroid Build Coastguard Worker state.wrap_r = (tmp >> 6) & 0x7;
668*bbecb9d1SAndroid Build Coastguard Worker state.min_img_filter = (tmp >> 9) & 0x3;
669*bbecb9d1SAndroid Build Coastguard Worker state.min_mip_filter = (tmp >> 11) & 0x3;
670*bbecb9d1SAndroid Build Coastguard Worker state.mag_img_filter = (tmp >> 13) & 0x3;
671*bbecb9d1SAndroid Build Coastguard Worker state.compare_mode = (tmp >> 15) & 0x1;
672*bbecb9d1SAndroid Build Coastguard Worker state.compare_func = (tmp >> 16) & 0x7;
673*bbecb9d1SAndroid Build Coastguard Worker state.seamless_cube_map = (tmp >> 19) & 0x1;
674*bbecb9d1SAndroid Build Coastguard Worker state.max_anisotropy = (float)((tmp >> 20) & 0x3f);
675*bbecb9d1SAndroid Build Coastguard Worker state.normalized_coords = 0;
676*bbecb9d1SAndroid Build Coastguard Worker
677*bbecb9d1SAndroid Build Coastguard Worker state.lod_bias = uif(get_buf_entry(buf, VIRGL_OBJ_SAMPLER_STATE_LOD_BIAS));
678*bbecb9d1SAndroid Build Coastguard Worker state.min_lod = uif(get_buf_entry(buf, VIRGL_OBJ_SAMPLER_STATE_MIN_LOD));
679*bbecb9d1SAndroid Build Coastguard Worker state.max_lod = uif(get_buf_entry(buf, VIRGL_OBJ_SAMPLER_STATE_MAX_LOD));
680*bbecb9d1SAndroid Build Coastguard Worker
681*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 4; i++)
682*bbecb9d1SAndroid Build Coastguard Worker state.border_color.ui[i] = get_buf_entry(buf, VIRGL_OBJ_SAMPLER_STATE_BORDER_COLOR(i));
683*bbecb9d1SAndroid Build Coastguard Worker
684*bbecb9d1SAndroid Build Coastguard Worker if (state.min_mip_filter != PIPE_TEX_MIPFILTER_NONE &&
685*bbecb9d1SAndroid Build Coastguard Worker state.min_mip_filter != PIPE_TEX_MIPFILTER_LINEAR &&
686*bbecb9d1SAndroid Build Coastguard Worker state.min_mip_filter != PIPE_TEX_MIPFILTER_NEAREST)
687*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
688*bbecb9d1SAndroid Build Coastguard Worker
689*bbecb9d1SAndroid Build Coastguard Worker return vrend_create_sampler_state(ctx, handle, &state);
690*bbecb9d1SAndroid Build Coastguard Worker }
691*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_ve(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)692*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_ve(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
693*bbecb9d1SAndroid Build Coastguard Worker {
694*bbecb9d1SAndroid Build Coastguard Worker struct pipe_vertex_element *ve = NULL;
695*bbecb9d1SAndroid Build Coastguard Worker int num_elements;
696*bbecb9d1SAndroid Build Coastguard Worker int i;
697*bbecb9d1SAndroid Build Coastguard Worker int ret;
698*bbecb9d1SAndroid Build Coastguard Worker
699*bbecb9d1SAndroid Build Coastguard Worker if (length < 1)
700*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
701*bbecb9d1SAndroid Build Coastguard Worker
702*bbecb9d1SAndroid Build Coastguard Worker if ((length - 1) % 4)
703*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
704*bbecb9d1SAndroid Build Coastguard Worker
705*bbecb9d1SAndroid Build Coastguard Worker num_elements = (length - 1) / 4;
706*bbecb9d1SAndroid Build Coastguard Worker
707*bbecb9d1SAndroid Build Coastguard Worker if (num_elements) {
708*bbecb9d1SAndroid Build Coastguard Worker ve = calloc(num_elements, sizeof(struct pipe_vertex_element));
709*bbecb9d1SAndroid Build Coastguard Worker
710*bbecb9d1SAndroid Build Coastguard Worker if (!ve)
711*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
712*bbecb9d1SAndroid Build Coastguard Worker
713*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_elements; i++) {
714*bbecb9d1SAndroid Build Coastguard Worker ve[i].src_offset = get_buf_entry(buf, VIRGL_OBJ_VERTEX_ELEMENTS_V0_SRC_OFFSET(i));
715*bbecb9d1SAndroid Build Coastguard Worker ve[i].instance_divisor = get_buf_entry(buf, VIRGL_OBJ_VERTEX_ELEMENTS_V0_INSTANCE_DIVISOR(i));
716*bbecb9d1SAndroid Build Coastguard Worker ve[i].vertex_buffer_index = get_buf_entry(buf, VIRGL_OBJ_VERTEX_ELEMENTS_V0_VERTEX_BUFFER_INDEX(i));
717*bbecb9d1SAndroid Build Coastguard Worker
718*bbecb9d1SAndroid Build Coastguard Worker if (ve[i].vertex_buffer_index >= PIPE_MAX_ATTRIBS) {
719*bbecb9d1SAndroid Build Coastguard Worker FREE(ve);
720*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
721*bbecb9d1SAndroid Build Coastguard Worker }
722*bbecb9d1SAndroid Build Coastguard Worker
723*bbecb9d1SAndroid Build Coastguard Worker ve[i].src_format = get_buf_entry(buf, VIRGL_OBJ_VERTEX_ELEMENTS_V0_SRC_FORMAT(i));
724*bbecb9d1SAndroid Build Coastguard Worker }
725*bbecb9d1SAndroid Build Coastguard Worker }
726*bbecb9d1SAndroid Build Coastguard Worker
727*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_create_vertex_elements_state(ctx, handle, num_elements, ve);
728*bbecb9d1SAndroid Build Coastguard Worker
729*bbecb9d1SAndroid Build Coastguard Worker FREE(ve);
730*bbecb9d1SAndroid Build Coastguard Worker return ret;
731*bbecb9d1SAndroid Build Coastguard Worker }
732*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_query(struct vrend_context * ctx,const uint32_t * buf,uint32_t handle,uint16_t length)733*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_query(struct vrend_context *ctx, const uint32_t *buf, uint32_t handle, uint16_t length)
734*bbecb9d1SAndroid Build Coastguard Worker {
735*bbecb9d1SAndroid Build Coastguard Worker uint32_t query_type;
736*bbecb9d1SAndroid Build Coastguard Worker uint32_t query_index;
737*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle;
738*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset;
739*bbecb9d1SAndroid Build Coastguard Worker uint32_t tmp;
740*bbecb9d1SAndroid Build Coastguard Worker
741*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_OBJ_QUERY_SIZE)
742*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
743*bbecb9d1SAndroid Build Coastguard Worker
744*bbecb9d1SAndroid Build Coastguard Worker tmp = get_buf_entry(buf, VIRGL_OBJ_QUERY_TYPE_INDEX);
745*bbecb9d1SAndroid Build Coastguard Worker query_type = VIRGL_OBJ_QUERY_TYPE(tmp);
746*bbecb9d1SAndroid Build Coastguard Worker query_index = (tmp >> 16) & 0xffff;
747*bbecb9d1SAndroid Build Coastguard Worker
748*bbecb9d1SAndroid Build Coastguard Worker offset = get_buf_entry(buf, VIRGL_OBJ_QUERY_OFFSET);
749*bbecb9d1SAndroid Build Coastguard Worker res_handle = get_buf_entry(buf, VIRGL_OBJ_QUERY_RES_HANDLE);
750*bbecb9d1SAndroid Build Coastguard Worker
751*bbecb9d1SAndroid Build Coastguard Worker return vrend_create_query(ctx, handle, query_type, query_index, res_handle, offset);
752*bbecb9d1SAndroid Build Coastguard Worker }
753*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_object(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)754*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_object(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
755*bbecb9d1SAndroid Build Coastguard Worker {
756*bbecb9d1SAndroid Build Coastguard Worker if (length < 1)
757*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
758*bbecb9d1SAndroid Build Coastguard Worker
759*bbecb9d1SAndroid Build Coastguard Worker uint32_t header = get_buf_entry(buf, VIRGL_OBJ_CREATE_HEADER);
760*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_OBJ_CREATE_HANDLE);
761*bbecb9d1SAndroid Build Coastguard Worker uint8_t obj_type = (header >> 8) & 0xff;
762*bbecb9d1SAndroid Build Coastguard Worker int ret = 0;
763*bbecb9d1SAndroid Build Coastguard Worker
764*bbecb9d1SAndroid Build Coastguard Worker if (handle == 0)
765*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
766*bbecb9d1SAndroid Build Coastguard Worker
767*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_object, ctx," CREATE %-18s handle:0x%x len:%d\n",
768*bbecb9d1SAndroid Build Coastguard Worker vrend_get_object_type_name(obj_type), handle, length);
769*bbecb9d1SAndroid Build Coastguard Worker
770*bbecb9d1SAndroid Build Coastguard Worker TRACE_SCOPE(vrend_get_object_type_name(obj_type));
771*bbecb9d1SAndroid Build Coastguard Worker
772*bbecb9d1SAndroid Build Coastguard Worker switch (obj_type){
773*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_BLEND:
774*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_blend(ctx, buf, handle, length);
775*bbecb9d1SAndroid Build Coastguard Worker break;
776*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_DSA:
777*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_dsa(ctx, buf, handle, length);
778*bbecb9d1SAndroid Build Coastguard Worker break;
779*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_RASTERIZER:
780*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_rasterizer(ctx, buf, handle, length);
781*bbecb9d1SAndroid Build Coastguard Worker break;
782*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_SHADER:
783*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_shader(ctx, buf, handle, length);
784*bbecb9d1SAndroid Build Coastguard Worker break;
785*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_VERTEX_ELEMENTS:
786*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_ve(ctx, buf, handle, length);
787*bbecb9d1SAndroid Build Coastguard Worker break;
788*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_SURFACE:
789*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_surface(ctx, buf, handle, length);
790*bbecb9d1SAndroid Build Coastguard Worker break;
791*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_SAMPLER_VIEW:
792*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_sampler_view(ctx, buf, handle, length);
793*bbecb9d1SAndroid Build Coastguard Worker break;
794*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_SAMPLER_STATE:
795*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_sampler_state(ctx, buf, handle, length);
796*bbecb9d1SAndroid Build Coastguard Worker break;
797*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_QUERY:
798*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_query(ctx, buf, handle, length);
799*bbecb9d1SAndroid Build Coastguard Worker break;
800*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_STREAMOUT_TARGET:
801*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_stream_output_target(ctx, buf, handle, length);
802*bbecb9d1SAndroid Build Coastguard Worker break;
803*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_MSAA_SURFACE:
804*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_decode_create_msaa_surface(ctx, buf, handle, length);
805*bbecb9d1SAndroid Build Coastguard Worker break;
806*bbecb9d1SAndroid Build Coastguard Worker default:
807*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
808*bbecb9d1SAndroid Build Coastguard Worker }
809*bbecb9d1SAndroid Build Coastguard Worker
810*bbecb9d1SAndroid Build Coastguard Worker return ret;
811*bbecb9d1SAndroid Build Coastguard Worker }
812*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_bind_object(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)813*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_bind_object(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
814*bbecb9d1SAndroid Build Coastguard Worker {
815*bbecb9d1SAndroid Build Coastguard Worker if (length != 1)
816*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
817*bbecb9d1SAndroid Build Coastguard Worker
818*bbecb9d1SAndroid Build Coastguard Worker uint32_t header = get_buf_entry(buf, VIRGL_OBJ_BIND_HEADER);
819*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_OBJ_BIND_HANDLE);
820*bbecb9d1SAndroid Build Coastguard Worker uint8_t obj_type = (header >> 8) & 0xff;
821*bbecb9d1SAndroid Build Coastguard Worker
822*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_object, ctx,
823*bbecb9d1SAndroid Build Coastguard Worker " BIND %-20s handle:0x%x len:%d\n",
824*bbecb9d1SAndroid Build Coastguard Worker vrend_get_object_type_name(obj_type), handle, length);
825*bbecb9d1SAndroid Build Coastguard Worker
826*bbecb9d1SAndroid Build Coastguard Worker switch (obj_type) {
827*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_BLEND:
828*bbecb9d1SAndroid Build Coastguard Worker vrend_object_bind_blend(ctx, handle);
829*bbecb9d1SAndroid Build Coastguard Worker break;
830*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_DSA:
831*bbecb9d1SAndroid Build Coastguard Worker vrend_object_bind_dsa(ctx, handle);
832*bbecb9d1SAndroid Build Coastguard Worker break;
833*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_RASTERIZER:
834*bbecb9d1SAndroid Build Coastguard Worker vrend_object_bind_rasterizer(ctx, handle);
835*bbecb9d1SAndroid Build Coastguard Worker break;
836*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_OBJECT_VERTEX_ELEMENTS:
837*bbecb9d1SAndroid Build Coastguard Worker vrend_bind_vertex_elements_state(ctx, handle);
838*bbecb9d1SAndroid Build Coastguard Worker break;
839*bbecb9d1SAndroid Build Coastguard Worker default:
840*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
841*bbecb9d1SAndroid Build Coastguard Worker }
842*bbecb9d1SAndroid Build Coastguard Worker
843*bbecb9d1SAndroid Build Coastguard Worker return 0;
844*bbecb9d1SAndroid Build Coastguard Worker }
845*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_destroy_object(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)846*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_destroy_object(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
847*bbecb9d1SAndroid Build Coastguard Worker {
848*bbecb9d1SAndroid Build Coastguard Worker if (length != 1)
849*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
850*bbecb9d1SAndroid Build Coastguard Worker
851*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_OBJ_DESTROY_HANDLE);
852*bbecb9d1SAndroid Build Coastguard Worker
853*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG_EXT(dbg_object, ctx,
854*bbecb9d1SAndroid Build Coastguard Worker uint32_t obj = (get_buf_entry(buf, 0) >> 8) & 0xFF;
855*bbecb9d1SAndroid Build Coastguard Worker vrend_printf(" DESTROY %-17s handle:0x%x\n",
856*bbecb9d1SAndroid Build Coastguard Worker vrend_get_object_type_name(obj), handle));
857*bbecb9d1SAndroid Build Coastguard Worker
858*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_object_destroy(ctx, handle);
859*bbecb9d1SAndroid Build Coastguard Worker return 0;
860*bbecb9d1SAndroid Build Coastguard Worker }
861*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_stencil_ref(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)862*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_stencil_ref(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
863*bbecb9d1SAndroid Build Coastguard Worker {
864*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_SET_STENCIL_REF_SIZE)
865*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
866*bbecb9d1SAndroid Build Coastguard Worker
867*bbecb9d1SAndroid Build Coastguard Worker struct pipe_stencil_ref ref;
868*bbecb9d1SAndroid Build Coastguard Worker uint32_t val = get_buf_entry(buf, VIRGL_SET_STENCIL_REF);
869*bbecb9d1SAndroid Build Coastguard Worker
870*bbecb9d1SAndroid Build Coastguard Worker ref.ref_value[0] = val & 0xff;
871*bbecb9d1SAndroid Build Coastguard Worker ref.ref_value[1] = (val >> 8) & 0xff;
872*bbecb9d1SAndroid Build Coastguard Worker vrend_set_stencil_ref(ctx, &ref);
873*bbecb9d1SAndroid Build Coastguard Worker return 0;
874*bbecb9d1SAndroid Build Coastguard Worker }
875*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_blend_color(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)876*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_blend_color(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
877*bbecb9d1SAndroid Build Coastguard Worker {
878*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_color color;
879*bbecb9d1SAndroid Build Coastguard Worker int i;
880*bbecb9d1SAndroid Build Coastguard Worker
881*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_SET_BLEND_COLOR_SIZE)
882*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
883*bbecb9d1SAndroid Build Coastguard Worker
884*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 4; i++)
885*bbecb9d1SAndroid Build Coastguard Worker color.color[i] = uif(get_buf_entry(buf, VIRGL_SET_BLEND_COLOR(i)));
886*bbecb9d1SAndroid Build Coastguard Worker
887*bbecb9d1SAndroid Build Coastguard Worker vrend_set_blend_color(ctx, &color);
888*bbecb9d1SAndroid Build Coastguard Worker return 0;
889*bbecb9d1SAndroid Build Coastguard Worker }
890*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_scissor_state(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)891*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_scissor_state(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
892*bbecb9d1SAndroid Build Coastguard Worker {
893*bbecb9d1SAndroid Build Coastguard Worker struct pipe_scissor_state ss[PIPE_MAX_VIEWPORTS];
894*bbecb9d1SAndroid Build Coastguard Worker uint32_t temp;
895*bbecb9d1SAndroid Build Coastguard Worker int32_t num_scissor;
896*bbecb9d1SAndroid Build Coastguard Worker uint32_t start_slot;
897*bbecb9d1SAndroid Build Coastguard Worker int s;
898*bbecb9d1SAndroid Build Coastguard Worker if (length < 1)
899*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
900*bbecb9d1SAndroid Build Coastguard Worker
901*bbecb9d1SAndroid Build Coastguard Worker if ((length - 1) % 2)
902*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
903*bbecb9d1SAndroid Build Coastguard Worker
904*bbecb9d1SAndroid Build Coastguard Worker num_scissor = (length - 1) / 2;
905*bbecb9d1SAndroid Build Coastguard Worker if (num_scissor > PIPE_MAX_VIEWPORTS)
906*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
907*bbecb9d1SAndroid Build Coastguard Worker
908*bbecb9d1SAndroid Build Coastguard Worker start_slot = get_buf_entry(buf, VIRGL_SET_SCISSOR_START_SLOT);
909*bbecb9d1SAndroid Build Coastguard Worker
910*bbecb9d1SAndroid Build Coastguard Worker for (s = 0; s < num_scissor; s++) {
911*bbecb9d1SAndroid Build Coastguard Worker temp = get_buf_entry(buf, VIRGL_SET_SCISSOR_MINX_MINY(s));
912*bbecb9d1SAndroid Build Coastguard Worker ss[s].minx = temp & 0xffff;
913*bbecb9d1SAndroid Build Coastguard Worker ss[s].miny = (temp >> 16) & 0xffff;
914*bbecb9d1SAndroid Build Coastguard Worker
915*bbecb9d1SAndroid Build Coastguard Worker temp = get_buf_entry(buf, VIRGL_SET_SCISSOR_MAXX_MAXY(s));
916*bbecb9d1SAndroid Build Coastguard Worker ss[s].maxx = temp & 0xffff;
917*bbecb9d1SAndroid Build Coastguard Worker ss[s].maxy = (temp >> 16) & 0xffff;
918*bbecb9d1SAndroid Build Coastguard Worker }
919*bbecb9d1SAndroid Build Coastguard Worker
920*bbecb9d1SAndroid Build Coastguard Worker vrend_set_scissor_state(ctx, start_slot, num_scissor, ss);
921*bbecb9d1SAndroid Build Coastguard Worker return 0;
922*bbecb9d1SAndroid Build Coastguard Worker }
923*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_polygon_stipple(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)924*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_polygon_stipple(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
925*bbecb9d1SAndroid Build Coastguard Worker {
926*bbecb9d1SAndroid Build Coastguard Worker struct pipe_poly_stipple ps;
927*bbecb9d1SAndroid Build Coastguard Worker int i;
928*bbecb9d1SAndroid Build Coastguard Worker
929*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_POLYGON_STIPPLE_SIZE)
930*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
931*bbecb9d1SAndroid Build Coastguard Worker
932*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 32; i++)
933*bbecb9d1SAndroid Build Coastguard Worker ps.stipple[i] = get_buf_entry(buf, VIRGL_POLYGON_STIPPLE_P0 + i);
934*bbecb9d1SAndroid Build Coastguard Worker
935*bbecb9d1SAndroid Build Coastguard Worker vrend_set_polygon_stipple(ctx, &ps);
936*bbecb9d1SAndroid Build Coastguard Worker return 0;
937*bbecb9d1SAndroid Build Coastguard Worker }
938*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_clip_state(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)939*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_clip_state(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
940*bbecb9d1SAndroid Build Coastguard Worker {
941*bbecb9d1SAndroid Build Coastguard Worker struct pipe_clip_state clip;
942*bbecb9d1SAndroid Build Coastguard Worker int i, j;
943*bbecb9d1SAndroid Build Coastguard Worker
944*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_SET_CLIP_STATE_SIZE)
945*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
946*bbecb9d1SAndroid Build Coastguard Worker
947*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 8; i++)
948*bbecb9d1SAndroid Build Coastguard Worker for (j = 0; j < 4; j++)
949*bbecb9d1SAndroid Build Coastguard Worker clip.ucp[i][j] = uif(get_buf_entry(buf, VIRGL_SET_CLIP_STATE_C0 + (i * 4) + j));
950*bbecb9d1SAndroid Build Coastguard Worker vrend_set_clip_state(ctx, &clip);
951*bbecb9d1SAndroid Build Coastguard Worker return 0;
952*bbecb9d1SAndroid Build Coastguard Worker }
953*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_sample_mask(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)954*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_sample_mask(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
955*bbecb9d1SAndroid Build Coastguard Worker {
956*bbecb9d1SAndroid Build Coastguard Worker unsigned mask;
957*bbecb9d1SAndroid Build Coastguard Worker
958*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_SET_SAMPLE_MASK_SIZE)
959*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
960*bbecb9d1SAndroid Build Coastguard Worker mask = get_buf_entry(buf, VIRGL_SET_SAMPLE_MASK_MASK);
961*bbecb9d1SAndroid Build Coastguard Worker vrend_set_sample_mask(ctx, mask);
962*bbecb9d1SAndroid Build Coastguard Worker return 0;
963*bbecb9d1SAndroid Build Coastguard Worker }
964*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_min_samples(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)965*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_min_samples(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
966*bbecb9d1SAndroid Build Coastguard Worker {
967*bbecb9d1SAndroid Build Coastguard Worker unsigned min_samples;
968*bbecb9d1SAndroid Build Coastguard Worker
969*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_SET_MIN_SAMPLES_SIZE)
970*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
971*bbecb9d1SAndroid Build Coastguard Worker min_samples = get_buf_entry(buf, VIRGL_SET_MIN_SAMPLES_MASK);
972*bbecb9d1SAndroid Build Coastguard Worker vrend_set_min_samples(ctx, min_samples);
973*bbecb9d1SAndroid Build Coastguard Worker return 0;
974*bbecb9d1SAndroid Build Coastguard Worker }
975*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_resource_copy_region(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)976*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_resource_copy_region(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
977*bbecb9d1SAndroid Build Coastguard Worker {
978*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box box;
979*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle, src_handle;
980*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_level, dstx, dsty, dstz;
981*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_level;
982*bbecb9d1SAndroid Build Coastguard Worker
983*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_CMD_RESOURCE_COPY_REGION_SIZE)
984*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
985*bbecb9d1SAndroid Build Coastguard Worker
986*bbecb9d1SAndroid Build Coastguard Worker dst_handle = get_buf_entry(buf, VIRGL_CMD_RCR_DST_RES_HANDLE);
987*bbecb9d1SAndroid Build Coastguard Worker dst_level = get_buf_entry(buf, VIRGL_CMD_RCR_DST_LEVEL);
988*bbecb9d1SAndroid Build Coastguard Worker dstx = get_buf_entry(buf, VIRGL_CMD_RCR_DST_X);
989*bbecb9d1SAndroid Build Coastguard Worker dsty = get_buf_entry(buf, VIRGL_CMD_RCR_DST_Y);
990*bbecb9d1SAndroid Build Coastguard Worker dstz = get_buf_entry(buf, VIRGL_CMD_RCR_DST_Z);
991*bbecb9d1SAndroid Build Coastguard Worker src_handle = get_buf_entry(buf, VIRGL_CMD_RCR_SRC_RES_HANDLE);
992*bbecb9d1SAndroid Build Coastguard Worker src_level = get_buf_entry(buf, VIRGL_CMD_RCR_SRC_LEVEL);
993*bbecb9d1SAndroid Build Coastguard Worker box.x = get_buf_entry(buf, VIRGL_CMD_RCR_SRC_X);
994*bbecb9d1SAndroid Build Coastguard Worker box.y = get_buf_entry(buf, VIRGL_CMD_RCR_SRC_Y);
995*bbecb9d1SAndroid Build Coastguard Worker box.z = get_buf_entry(buf, VIRGL_CMD_RCR_SRC_Z);
996*bbecb9d1SAndroid Build Coastguard Worker box.width = get_buf_entry(buf, VIRGL_CMD_RCR_SRC_W);
997*bbecb9d1SAndroid Build Coastguard Worker box.height = get_buf_entry(buf, VIRGL_CMD_RCR_SRC_H);
998*bbecb9d1SAndroid Build Coastguard Worker box.depth = get_buf_entry(buf, VIRGL_CMD_RCR_SRC_D);
999*bbecb9d1SAndroid Build Coastguard Worker
1000*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_resource_copy_region(ctx, dst_handle,
1001*bbecb9d1SAndroid Build Coastguard Worker dst_level, dstx, dsty, dstz,
1002*bbecb9d1SAndroid Build Coastguard Worker src_handle, src_level,
1003*bbecb9d1SAndroid Build Coastguard Worker &box);
1004*bbecb9d1SAndroid Build Coastguard Worker return 0;
1005*bbecb9d1SAndroid Build Coastguard Worker }
1006*bbecb9d1SAndroid Build Coastguard Worker
1007*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_blit(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1008*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_blit(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1009*bbecb9d1SAndroid Build Coastguard Worker {
1010*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blit_info info;
1011*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle, src_handle, temp;
1012*bbecb9d1SAndroid Build Coastguard Worker
1013*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_CMD_BLIT_SIZE)
1014*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1015*bbecb9d1SAndroid Build Coastguard Worker temp = get_buf_entry(buf, VIRGL_CMD_BLIT_S0);
1016*bbecb9d1SAndroid Build Coastguard Worker info.mask = temp & 0xff;
1017*bbecb9d1SAndroid Build Coastguard Worker info.filter = (temp >> 8) & 0x3;
1018*bbecb9d1SAndroid Build Coastguard Worker info.scissor_enable = (temp >> 10) & 0x1;
1019*bbecb9d1SAndroid Build Coastguard Worker info.render_condition_enable = (temp >> 11) & 0x1;
1020*bbecb9d1SAndroid Build Coastguard Worker info.alpha_blend = (temp >> 12) & 0x1;
1021*bbecb9d1SAndroid Build Coastguard Worker temp = get_buf_entry(buf, VIRGL_CMD_BLIT_SCISSOR_MINX_MINY);
1022*bbecb9d1SAndroid Build Coastguard Worker info.scissor.minx = temp & 0xffff;
1023*bbecb9d1SAndroid Build Coastguard Worker info.scissor.miny = (temp >> 16) & 0xffff;
1024*bbecb9d1SAndroid Build Coastguard Worker temp = get_buf_entry(buf, VIRGL_CMD_BLIT_SCISSOR_MAXX_MAXY);
1025*bbecb9d1SAndroid Build Coastguard Worker info.scissor.maxx = temp & 0xffff;
1026*bbecb9d1SAndroid Build Coastguard Worker info.scissor.maxy = (temp >> 16) & 0xffff;
1027*bbecb9d1SAndroid Build Coastguard Worker dst_handle = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_RES_HANDLE);
1028*bbecb9d1SAndroid Build Coastguard Worker info.dst.level = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_LEVEL);
1029*bbecb9d1SAndroid Build Coastguard Worker info.dst.format = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_FORMAT);
1030*bbecb9d1SAndroid Build Coastguard Worker info.dst.box.x = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_X);
1031*bbecb9d1SAndroid Build Coastguard Worker info.dst.box.y = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_Y);
1032*bbecb9d1SAndroid Build Coastguard Worker info.dst.box.z = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_Z);
1033*bbecb9d1SAndroid Build Coastguard Worker info.dst.box.width = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_W);
1034*bbecb9d1SAndroid Build Coastguard Worker info.dst.box.height = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_H);
1035*bbecb9d1SAndroid Build Coastguard Worker info.dst.box.depth = get_buf_entry(buf, VIRGL_CMD_BLIT_DST_D);
1036*bbecb9d1SAndroid Build Coastguard Worker
1037*bbecb9d1SAndroid Build Coastguard Worker src_handle = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_RES_HANDLE);
1038*bbecb9d1SAndroid Build Coastguard Worker info.src.level = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_LEVEL);
1039*bbecb9d1SAndroid Build Coastguard Worker info.src.format = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_FORMAT);
1040*bbecb9d1SAndroid Build Coastguard Worker info.src.box.x = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_X);
1041*bbecb9d1SAndroid Build Coastguard Worker info.src.box.y = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_Y);
1042*bbecb9d1SAndroid Build Coastguard Worker info.src.box.z = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_Z);
1043*bbecb9d1SAndroid Build Coastguard Worker info.src.box.width = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_W);
1044*bbecb9d1SAndroid Build Coastguard Worker info.src.box.height = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_H);
1045*bbecb9d1SAndroid Build Coastguard Worker info.src.box.depth = get_buf_entry(buf, VIRGL_CMD_BLIT_SRC_D);
1046*bbecb9d1SAndroid Build Coastguard Worker
1047*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_blit(ctx, dst_handle, src_handle, &info);
1048*bbecb9d1SAndroid Build Coastguard Worker return 0;
1049*bbecb9d1SAndroid Build Coastguard Worker }
1050*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_bind_sampler_states(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1051*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_bind_sampler_states(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1052*bbecb9d1SAndroid Build Coastguard Worker {
1053*bbecb9d1SAndroid Build Coastguard Worker if (length < 2)
1054*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1055*bbecb9d1SAndroid Build Coastguard Worker
1056*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type = get_buf_entry(buf, VIRGL_BIND_SAMPLER_STATES_SHADER_TYPE);
1057*bbecb9d1SAndroid Build Coastguard Worker uint32_t start_slot = get_buf_entry(buf, VIRGL_BIND_SAMPLER_STATES_START_SLOT);
1058*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_states = length - 2;
1059*bbecb9d1SAndroid Build Coastguard Worker
1060*bbecb9d1SAndroid Build Coastguard Worker if (shader_type >= PIPE_SHADER_TYPES)
1061*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1062*bbecb9d1SAndroid Build Coastguard Worker
1063*bbecb9d1SAndroid Build Coastguard Worker vrend_bind_sampler_states(ctx, shader_type, start_slot, num_states,
1064*bbecb9d1SAndroid Build Coastguard Worker get_buf_ptr(buf, VIRGL_BIND_SAMPLER_STATES_S0_HANDLE));
1065*bbecb9d1SAndroid Build Coastguard Worker return 0;
1066*bbecb9d1SAndroid Build Coastguard Worker }
1067*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_begin_query(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1068*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_begin_query(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1069*bbecb9d1SAndroid Build Coastguard Worker {
1070*bbecb9d1SAndroid Build Coastguard Worker if (length != 1)
1071*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1072*bbecb9d1SAndroid Build Coastguard Worker
1073*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_QUERY_BEGIN_HANDLE);
1074*bbecb9d1SAndroid Build Coastguard Worker
1075*bbecb9d1SAndroid Build Coastguard Worker return vrend_begin_query(ctx, handle);
1076*bbecb9d1SAndroid Build Coastguard Worker }
1077*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_end_query(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1078*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_end_query(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1079*bbecb9d1SAndroid Build Coastguard Worker {
1080*bbecb9d1SAndroid Build Coastguard Worker if (length != 1)
1081*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1082*bbecb9d1SAndroid Build Coastguard Worker
1083*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_QUERY_END_HANDLE);
1084*bbecb9d1SAndroid Build Coastguard Worker
1085*bbecb9d1SAndroid Build Coastguard Worker return vrend_end_query(ctx, handle);
1086*bbecb9d1SAndroid Build Coastguard Worker }
1087*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_get_query_result(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1088*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_get_query_result(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1089*bbecb9d1SAndroid Build Coastguard Worker {
1090*bbecb9d1SAndroid Build Coastguard Worker if (length != 2)
1091*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1092*bbecb9d1SAndroid Build Coastguard Worker
1093*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_QUERY_RESULT_HANDLE);
1094*bbecb9d1SAndroid Build Coastguard Worker uint32_t wait = get_buf_entry(buf, VIRGL_QUERY_RESULT_WAIT);
1095*bbecb9d1SAndroid Build Coastguard Worker
1096*bbecb9d1SAndroid Build Coastguard Worker vrend_get_query_result(ctx, handle, wait);
1097*bbecb9d1SAndroid Build Coastguard Worker return 0;
1098*bbecb9d1SAndroid Build Coastguard Worker }
1099*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_get_query_result_qbo(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1100*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_get_query_result_qbo(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1101*bbecb9d1SAndroid Build Coastguard Worker {
1102*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_QUERY_RESULT_QBO_SIZE)
1103*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1104*bbecb9d1SAndroid Build Coastguard Worker
1105*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_QUERY_RESULT_QBO_HANDLE);
1106*bbecb9d1SAndroid Build Coastguard Worker uint32_t qbo_handle = get_buf_entry(buf, VIRGL_QUERY_RESULT_QBO_QBO_HANDLE);
1107*bbecb9d1SAndroid Build Coastguard Worker uint32_t wait = get_buf_entry(buf, VIRGL_QUERY_RESULT_QBO_WAIT);
1108*bbecb9d1SAndroid Build Coastguard Worker uint32_t result_type = get_buf_entry(buf, VIRGL_QUERY_RESULT_QBO_RESULT_TYPE);
1109*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset = get_buf_entry(buf, VIRGL_QUERY_RESULT_QBO_OFFSET);
1110*bbecb9d1SAndroid Build Coastguard Worker int32_t index = get_buf_entry(buf, VIRGL_QUERY_RESULT_QBO_INDEX);
1111*bbecb9d1SAndroid Build Coastguard Worker
1112*bbecb9d1SAndroid Build Coastguard Worker vrend_get_query_result_qbo(ctx, handle, qbo_handle, wait, result_type, offset, index);
1113*bbecb9d1SAndroid Build Coastguard Worker return 0;
1114*bbecb9d1SAndroid Build Coastguard Worker }
1115*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_render_condition(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1116*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_render_condition(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1117*bbecb9d1SAndroid Build Coastguard Worker {
1118*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_RENDER_CONDITION_SIZE)
1119*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1120*bbecb9d1SAndroid Build Coastguard Worker
1121*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_RENDER_CONDITION_HANDLE);
1122*bbecb9d1SAndroid Build Coastguard Worker bool condition = get_buf_entry(buf, VIRGL_RENDER_CONDITION_CONDITION) & 1;
1123*bbecb9d1SAndroid Build Coastguard Worker uint mode = get_buf_entry(buf, VIRGL_RENDER_CONDITION_MODE);
1124*bbecb9d1SAndroid Build Coastguard Worker
1125*bbecb9d1SAndroid Build Coastguard Worker vrend_render_condition(ctx, handle, condition, mode);
1126*bbecb9d1SAndroid Build Coastguard Worker return 0;
1127*bbecb9d1SAndroid Build Coastguard Worker }
1128*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_sub_ctx(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1129*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_sub_ctx(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1130*bbecb9d1SAndroid Build Coastguard Worker {
1131*bbecb9d1SAndroid Build Coastguard Worker if (length != 1)
1132*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1133*bbecb9d1SAndroid Build Coastguard Worker
1134*bbecb9d1SAndroid Build Coastguard Worker uint32_t ctx_sub_id = get_buf_entry(buf, 1);
1135*bbecb9d1SAndroid Build Coastguard Worker
1136*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_set_sub_ctx(ctx, ctx_sub_id);
1137*bbecb9d1SAndroid Build Coastguard Worker return 0;
1138*bbecb9d1SAndroid Build Coastguard Worker }
1139*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_sub_ctx(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1140*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_sub_ctx(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1141*bbecb9d1SAndroid Build Coastguard Worker {
1142*bbecb9d1SAndroid Build Coastguard Worker if (length != 1)
1143*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1144*bbecb9d1SAndroid Build Coastguard Worker
1145*bbecb9d1SAndroid Build Coastguard Worker uint32_t ctx_sub_id = get_buf_entry(buf, 1);
1146*bbecb9d1SAndroid Build Coastguard Worker
1147*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_create_sub_ctx(ctx, ctx_sub_id);
1148*bbecb9d1SAndroid Build Coastguard Worker return 0;
1149*bbecb9d1SAndroid Build Coastguard Worker }
1150*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_destroy_sub_ctx(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1151*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_destroy_sub_ctx(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1152*bbecb9d1SAndroid Build Coastguard Worker {
1153*bbecb9d1SAndroid Build Coastguard Worker if (length != 1)
1154*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1155*bbecb9d1SAndroid Build Coastguard Worker
1156*bbecb9d1SAndroid Build Coastguard Worker uint32_t ctx_sub_id = get_buf_entry(buf, 1);
1157*bbecb9d1SAndroid Build Coastguard Worker
1158*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_destroy_sub_ctx(ctx, ctx_sub_id);
1159*bbecb9d1SAndroid Build Coastguard Worker return 0;
1160*bbecb9d1SAndroid Build Coastguard Worker }
1161*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_link_shader(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1162*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_link_shader(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1163*bbecb9d1SAndroid Build Coastguard Worker {
1164*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_LINK_SHADER_SIZE)
1165*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1166*bbecb9d1SAndroid Build Coastguard Worker
1167*bbecb9d1SAndroid Build Coastguard Worker uint32_t handles[PIPE_SHADER_TYPES];
1168*bbecb9d1SAndroid Build Coastguard Worker handles[PIPE_SHADER_VERTEX] = get_buf_entry(buf, VIRGL_LINK_SHADER_VERTEX_HANDLE);
1169*bbecb9d1SAndroid Build Coastguard Worker handles[PIPE_SHADER_FRAGMENT] = get_buf_entry(buf, VIRGL_LINK_SHADER_FRAGMENT_HANDLE);
1170*bbecb9d1SAndroid Build Coastguard Worker handles[PIPE_SHADER_GEOMETRY] = get_buf_entry(buf, VIRGL_LINK_SHADER_GEOMETRY_HANDLE);
1171*bbecb9d1SAndroid Build Coastguard Worker handles[PIPE_SHADER_TESS_CTRL] = get_buf_entry(buf, VIRGL_LINK_SHADER_TESS_CTRL_HANDLE);
1172*bbecb9d1SAndroid Build Coastguard Worker handles[PIPE_SHADER_TESS_EVAL] = get_buf_entry(buf, VIRGL_LINK_SHADER_TESS_EVAL_HANDLE);
1173*bbecb9d1SAndroid Build Coastguard Worker handles[PIPE_SHADER_COMPUTE] = get_buf_entry(buf, VIRGL_LINK_SHADER_COMPUTE_HANDLE);
1174*bbecb9d1SAndroid Build Coastguard Worker
1175*bbecb9d1SAndroid Build Coastguard Worker vrend_link_program_hook(ctx, handles);
1176*bbecb9d1SAndroid Build Coastguard Worker return 0;
1177*bbecb9d1SAndroid Build Coastguard Worker }
1178*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_bind_shader(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1179*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_bind_shader(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1180*bbecb9d1SAndroid Build Coastguard Worker {
1181*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle, type;
1182*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_BIND_SHADER_SIZE)
1183*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1184*bbecb9d1SAndroid Build Coastguard Worker
1185*bbecb9d1SAndroid Build Coastguard Worker handle = get_buf_entry(buf, VIRGL_BIND_SHADER_HANDLE);
1186*bbecb9d1SAndroid Build Coastguard Worker type = get_buf_entry(buf, VIRGL_BIND_SHADER_TYPE);
1187*bbecb9d1SAndroid Build Coastguard Worker
1188*bbecb9d1SAndroid Build Coastguard Worker vrend_bind_shader(ctx, handle, type);
1189*bbecb9d1SAndroid Build Coastguard Worker return 0;
1190*bbecb9d1SAndroid Build Coastguard Worker }
1191*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_tess_state(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1192*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_tess_state(struct vrend_context *ctx,
1193*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf, uint32_t length)
1194*bbecb9d1SAndroid Build Coastguard Worker {
1195*bbecb9d1SAndroid Build Coastguard Worker float tess_factors[6];
1196*bbecb9d1SAndroid Build Coastguard Worker int i;
1197*bbecb9d1SAndroid Build Coastguard Worker
1198*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_TESS_STATE_SIZE)
1199*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1200*bbecb9d1SAndroid Build Coastguard Worker
1201*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 6; i++) {
1202*bbecb9d1SAndroid Build Coastguard Worker tess_factors[i] = uif(get_buf_entry(buf, i + 1));
1203*bbecb9d1SAndroid Build Coastguard Worker }
1204*bbecb9d1SAndroid Build Coastguard Worker vrend_set_tess_state(ctx, tess_factors);
1205*bbecb9d1SAndroid Build Coastguard Worker return 0;
1206*bbecb9d1SAndroid Build Coastguard Worker }
1207*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_shader_buffers(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1208*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_shader_buffers(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1209*bbecb9d1SAndroid Build Coastguard Worker {
1210*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_ssbo;
1211*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type, start_slot;
1212*bbecb9d1SAndroid Build Coastguard Worker
1213*bbecb9d1SAndroid Build Coastguard Worker if (length < 2)
1214*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1215*bbecb9d1SAndroid Build Coastguard Worker
1216*bbecb9d1SAndroid Build Coastguard Worker num_ssbo = (length - 2) / VIRGL_SET_SHADER_BUFFER_ELEMENT_SIZE;
1217*bbecb9d1SAndroid Build Coastguard Worker shader_type = get_buf_entry(buf, VIRGL_SET_SHADER_BUFFER_SHADER_TYPE);
1218*bbecb9d1SAndroid Build Coastguard Worker start_slot = get_buf_entry(buf, VIRGL_SET_SHADER_BUFFER_START_SLOT);
1219*bbecb9d1SAndroid Build Coastguard Worker if (shader_type >= PIPE_SHADER_TYPES)
1220*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1221*bbecb9d1SAndroid Build Coastguard Worker
1222*bbecb9d1SAndroid Build Coastguard Worker if (num_ssbo < 1)
1223*bbecb9d1SAndroid Build Coastguard Worker return 0;
1224*bbecb9d1SAndroid Build Coastguard Worker
1225*bbecb9d1SAndroid Build Coastguard Worker if (start_slot > PIPE_MAX_SHADER_BUFFERS ||
1226*bbecb9d1SAndroid Build Coastguard Worker num_ssbo > PIPE_MAX_SHADER_BUFFERS - start_slot)
1227*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1228*bbecb9d1SAndroid Build Coastguard Worker
1229*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < num_ssbo; i++) {
1230*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset = get_buf_entry(buf, VIRGL_SET_SHADER_BUFFER_OFFSET(i));
1231*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_len = get_buf_entry(buf, VIRGL_SET_SHADER_BUFFER_LENGTH(i));
1232*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_SET_SHADER_BUFFER_RES_HANDLE(i));
1233*bbecb9d1SAndroid Build Coastguard Worker vrend_set_single_ssbo(ctx, shader_type, start_slot + i, offset, buf_len,
1234*bbecb9d1SAndroid Build Coastguard Worker handle);
1235*bbecb9d1SAndroid Build Coastguard Worker }
1236*bbecb9d1SAndroid Build Coastguard Worker return 0;
1237*bbecb9d1SAndroid Build Coastguard Worker }
1238*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_atomic_buffers(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1239*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_atomic_buffers(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1240*bbecb9d1SAndroid Build Coastguard Worker {
1241*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_abo;
1242*bbecb9d1SAndroid Build Coastguard Worker uint32_t start_slot;
1243*bbecb9d1SAndroid Build Coastguard Worker
1244*bbecb9d1SAndroid Build Coastguard Worker if (length < 2)
1245*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1246*bbecb9d1SAndroid Build Coastguard Worker
1247*bbecb9d1SAndroid Build Coastguard Worker num_abo = (length - 1) / VIRGL_SET_ATOMIC_BUFFER_ELEMENT_SIZE;
1248*bbecb9d1SAndroid Build Coastguard Worker start_slot = get_buf_entry(buf, VIRGL_SET_ATOMIC_BUFFER_START_SLOT);
1249*bbecb9d1SAndroid Build Coastguard Worker if (num_abo < 1)
1250*bbecb9d1SAndroid Build Coastguard Worker return 0;
1251*bbecb9d1SAndroid Build Coastguard Worker
1252*bbecb9d1SAndroid Build Coastguard Worker if (num_abo > PIPE_MAX_HW_ATOMIC_BUFFERS ||
1253*bbecb9d1SAndroid Build Coastguard Worker start_slot > PIPE_MAX_HW_ATOMIC_BUFFERS ||
1254*bbecb9d1SAndroid Build Coastguard Worker start_slot > PIPE_MAX_HW_ATOMIC_BUFFERS - num_abo)
1255*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1256*bbecb9d1SAndroid Build Coastguard Worker
1257*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < num_abo; i++) {
1258*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset = get_buf_entry(buf, i * VIRGL_SET_ATOMIC_BUFFER_ELEMENT_SIZE + 2);
1259*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_len = get_buf_entry(buf, i * VIRGL_SET_ATOMIC_BUFFER_ELEMENT_SIZE + 3);
1260*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, i * VIRGL_SET_ATOMIC_BUFFER_ELEMENT_SIZE + 4);
1261*bbecb9d1SAndroid Build Coastguard Worker vrend_set_single_abo(ctx, start_slot + i, offset, buf_len, handle);
1262*bbecb9d1SAndroid Build Coastguard Worker }
1263*bbecb9d1SAndroid Build Coastguard Worker
1264*bbecb9d1SAndroid Build Coastguard Worker return 0;
1265*bbecb9d1SAndroid Build Coastguard Worker }
1266*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_shader_images(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1267*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_shader_images(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1268*bbecb9d1SAndroid Build Coastguard Worker {
1269*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_images;
1270*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type, start_slot;
1271*bbecb9d1SAndroid Build Coastguard Worker if (length < 2)
1272*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1273*bbecb9d1SAndroid Build Coastguard Worker
1274*bbecb9d1SAndroid Build Coastguard Worker num_images = (length - 2) / VIRGL_SET_SHADER_IMAGE_ELEMENT_SIZE;
1275*bbecb9d1SAndroid Build Coastguard Worker shader_type = get_buf_entry(buf, VIRGL_SET_SHADER_IMAGE_SHADER_TYPE);
1276*bbecb9d1SAndroid Build Coastguard Worker start_slot = get_buf_entry(buf, VIRGL_SET_SHADER_IMAGE_START_SLOT);
1277*bbecb9d1SAndroid Build Coastguard Worker if (shader_type >= PIPE_SHADER_TYPES)
1278*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1279*bbecb9d1SAndroid Build Coastguard Worker
1280*bbecb9d1SAndroid Build Coastguard Worker if (num_images < 1) {
1281*bbecb9d1SAndroid Build Coastguard Worker return 0;
1282*bbecb9d1SAndroid Build Coastguard Worker }
1283*bbecb9d1SAndroid Build Coastguard Worker
1284*bbecb9d1SAndroid Build Coastguard Worker if (start_slot > PIPE_MAX_SHADER_IMAGES ||
1285*bbecb9d1SAndroid Build Coastguard Worker start_slot + num_images > PIPE_MAX_SHADER_IMAGES)
1286*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1287*bbecb9d1SAndroid Build Coastguard Worker
1288*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < num_images; i++) {
1289*bbecb9d1SAndroid Build Coastguard Worker uint32_t format = get_buf_entry(buf, VIRGL_SET_SHADER_IMAGE_FORMAT(i));
1290*bbecb9d1SAndroid Build Coastguard Worker uint32_t access = get_buf_entry(buf, VIRGL_SET_SHADER_IMAGE_ACCESS(i));
1291*bbecb9d1SAndroid Build Coastguard Worker uint32_t layer_offset = get_buf_entry(buf, VIRGL_SET_SHADER_IMAGE_LAYER_OFFSET(i));
1292*bbecb9d1SAndroid Build Coastguard Worker uint32_t level_size = get_buf_entry(buf, VIRGL_SET_SHADER_IMAGE_LEVEL_SIZE(i));
1293*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_SET_SHADER_IMAGE_RES_HANDLE(i));
1294*bbecb9d1SAndroid Build Coastguard Worker vrend_set_single_image_view(ctx, shader_type, start_slot + i, format, access,
1295*bbecb9d1SAndroid Build Coastguard Worker layer_offset, level_size, handle);
1296*bbecb9d1SAndroid Build Coastguard Worker }
1297*bbecb9d1SAndroid Build Coastguard Worker return 0;
1298*bbecb9d1SAndroid Build Coastguard Worker }
1299*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_memory_barrier(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1300*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_memory_barrier(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1301*bbecb9d1SAndroid Build Coastguard Worker {
1302*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_MEMORY_BARRIER_SIZE)
1303*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1304*bbecb9d1SAndroid Build Coastguard Worker
1305*bbecb9d1SAndroid Build Coastguard Worker unsigned flags = get_buf_entry(buf, VIRGL_MEMORY_BARRIER_FLAGS);
1306*bbecb9d1SAndroid Build Coastguard Worker vrend_memory_barrier(ctx, flags);
1307*bbecb9d1SAndroid Build Coastguard Worker return 0;
1308*bbecb9d1SAndroid Build Coastguard Worker }
1309*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_launch_grid(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1310*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_launch_grid(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1311*bbecb9d1SAndroid Build Coastguard Worker {
1312*bbecb9d1SAndroid Build Coastguard Worker uint32_t block[3], grid[3];
1313*bbecb9d1SAndroid Build Coastguard Worker uint32_t indirect_handle, indirect_offset;
1314*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_LAUNCH_GRID_SIZE)
1315*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1316*bbecb9d1SAndroid Build Coastguard Worker
1317*bbecb9d1SAndroid Build Coastguard Worker block[0] = get_buf_entry(buf, VIRGL_LAUNCH_BLOCK_X);
1318*bbecb9d1SAndroid Build Coastguard Worker block[1] = get_buf_entry(buf, VIRGL_LAUNCH_BLOCK_Y);
1319*bbecb9d1SAndroid Build Coastguard Worker block[2] = get_buf_entry(buf, VIRGL_LAUNCH_BLOCK_Z);
1320*bbecb9d1SAndroid Build Coastguard Worker grid[0] = get_buf_entry(buf, VIRGL_LAUNCH_GRID_X);
1321*bbecb9d1SAndroid Build Coastguard Worker grid[1] = get_buf_entry(buf, VIRGL_LAUNCH_GRID_Y);
1322*bbecb9d1SAndroid Build Coastguard Worker grid[2] = get_buf_entry(buf, VIRGL_LAUNCH_GRID_Z);
1323*bbecb9d1SAndroid Build Coastguard Worker indirect_handle = get_buf_entry(buf, VIRGL_LAUNCH_INDIRECT_HANDLE);
1324*bbecb9d1SAndroid Build Coastguard Worker indirect_offset = get_buf_entry(buf, VIRGL_LAUNCH_INDIRECT_OFFSET);
1325*bbecb9d1SAndroid Build Coastguard Worker vrend_launch_grid(ctx, block, grid, indirect_handle, indirect_offset);
1326*bbecb9d1SAndroid Build Coastguard Worker return 0;
1327*bbecb9d1SAndroid Build Coastguard Worker }
1328*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_streamout_targets(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1329*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_streamout_targets(struct vrend_context *ctx,
1330*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf, uint32_t length)
1331*bbecb9d1SAndroid Build Coastguard Worker {
1332*bbecb9d1SAndroid Build Coastguard Worker uint32_t handles[16];
1333*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_handles = length - 1;
1334*bbecb9d1SAndroid Build Coastguard Worker uint32_t append_bitmask;
1335*bbecb9d1SAndroid Build Coastguard Worker uint i;
1336*bbecb9d1SAndroid Build Coastguard Worker
1337*bbecb9d1SAndroid Build Coastguard Worker if (length < 1)
1338*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1339*bbecb9d1SAndroid Build Coastguard Worker if (num_handles > ARRAY_SIZE(handles))
1340*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1341*bbecb9d1SAndroid Build Coastguard Worker
1342*bbecb9d1SAndroid Build Coastguard Worker append_bitmask = get_buf_entry(buf, VIRGL_SET_STREAMOUT_TARGETS_APPEND_BITMASK);
1343*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_handles; i++)
1344*bbecb9d1SAndroid Build Coastguard Worker handles[i] = get_buf_entry(buf, VIRGL_SET_STREAMOUT_TARGETS_H0 + i);
1345*bbecb9d1SAndroid Build Coastguard Worker vrend_set_streamout_targets(ctx, append_bitmask, num_handles, handles);
1346*bbecb9d1SAndroid Build Coastguard Worker return 0;
1347*bbecb9d1SAndroid Build Coastguard Worker }
1348*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_texture_barrier(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1349*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_texture_barrier(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1350*bbecb9d1SAndroid Build Coastguard Worker {
1351*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_TEXTURE_BARRIER_SIZE)
1352*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1353*bbecb9d1SAndroid Build Coastguard Worker
1354*bbecb9d1SAndroid Build Coastguard Worker unsigned flags = get_buf_entry(buf, VIRGL_TEXTURE_BARRIER_FLAGS);
1355*bbecb9d1SAndroid Build Coastguard Worker vrend_texture_barrier(ctx, flags);
1356*bbecb9d1SAndroid Build Coastguard Worker return 0;
1357*bbecb9d1SAndroid Build Coastguard Worker }
1358*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_debug_mask(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1359*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_debug_mask(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1360*bbecb9d1SAndroid Build Coastguard Worker {
1361*bbecb9d1SAndroid Build Coastguard Worker char *flagstring;
1362*bbecb9d1SAndroid Build Coastguard Worker int slen = sizeof(uint32_t) * length;
1363*bbecb9d1SAndroid Build Coastguard Worker
1364*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_SET_DEBUG_FLAGS_MIN_SIZE)
1365*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1366*bbecb9d1SAndroid Build Coastguard Worker
1367*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *flag_buf = get_buf_ptr(buf, VIRGL_SET_DEBUG_FLAGSTRING_OFFSET);
1368*bbecb9d1SAndroid Build Coastguard Worker flagstring = malloc(slen+1);
1369*bbecb9d1SAndroid Build Coastguard Worker
1370*bbecb9d1SAndroid Build Coastguard Worker if (!flagstring) {
1371*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
1372*bbecb9d1SAndroid Build Coastguard Worker }
1373*bbecb9d1SAndroid Build Coastguard Worker
1374*bbecb9d1SAndroid Build Coastguard Worker memcpy(flagstring, flag_buf, slen);
1375*bbecb9d1SAndroid Build Coastguard Worker flagstring[slen] = 0;
1376*bbecb9d1SAndroid Build Coastguard Worker vrend_context_set_debug_flags(ctx, flagstring);
1377*bbecb9d1SAndroid Build Coastguard Worker
1378*bbecb9d1SAndroid Build Coastguard Worker free(flagstring);
1379*bbecb9d1SAndroid Build Coastguard Worker
1380*bbecb9d1SAndroid Build Coastguard Worker return 0;
1381*bbecb9d1SAndroid Build Coastguard Worker }
1382*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_set_tweaks(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1383*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_set_tweaks(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1384*bbecb9d1SAndroid Build Coastguard Worker {
1385*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_tweak, NULL, "Received TWEAK set command\n");
1386*bbecb9d1SAndroid Build Coastguard Worker
1387*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_SET_TWEAKS_SIZE)
1388*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1389*bbecb9d1SAndroid Build Coastguard Worker
1390*bbecb9d1SAndroid Build Coastguard Worker uint32_t tweak_id = get_buf_entry(buf, VIRGL_SET_TWEAKS_ID);
1391*bbecb9d1SAndroid Build Coastguard Worker uint32_t tweak_value = get_buf_entry(buf, VIRGL_SET_TWEAKS_VALUE);
1392*bbecb9d1SAndroid Build Coastguard Worker
1393*bbecb9d1SAndroid Build Coastguard Worker vrend_set_active_tweaks(vrend_get_context_tweaks(ctx), tweak_id, tweak_value);
1394*bbecb9d1SAndroid Build Coastguard Worker return 0;
1395*bbecb9d1SAndroid Build Coastguard Worker }
1396*bbecb9d1SAndroid Build Coastguard Worker
1397*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_transfer3d(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1398*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_transfer3d(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1399*bbecb9d1SAndroid Build Coastguard Worker {
1400*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box box;
1401*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle;
1402*bbecb9d1SAndroid Build Coastguard Worker struct vrend_transfer_info info;
1403*bbecb9d1SAndroid Build Coastguard Worker
1404*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_TRANSFER3D_SIZE)
1405*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1406*bbecb9d1SAndroid Build Coastguard Worker
1407*bbecb9d1SAndroid Build Coastguard Worker memset(&info, 0, sizeof(info));
1408*bbecb9d1SAndroid Build Coastguard Worker info.box = &box;
1409*bbecb9d1SAndroid Build Coastguard Worker vrend_decode_transfer_common(buf, &dst_handle, &info);
1410*bbecb9d1SAndroid Build Coastguard Worker info.offset = get_buf_entry(buf, VIRGL_TRANSFER3D_DATA_OFFSET);
1411*bbecb9d1SAndroid Build Coastguard Worker int transfer_mode = get_buf_entry(buf, VIRGL_TRANSFER3D_DIRECTION);
1412*bbecb9d1SAndroid Build Coastguard Worker
1413*bbecb9d1SAndroid Build Coastguard Worker if (transfer_mode != VIRGL_TRANSFER_TO_HOST &&
1414*bbecb9d1SAndroid Build Coastguard Worker transfer_mode != VIRGL_TRANSFER_FROM_HOST)
1415*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1416*bbecb9d1SAndroid Build Coastguard Worker
1417*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_transfer_iov(ctx, dst_handle, &info,
1418*bbecb9d1SAndroid Build Coastguard Worker transfer_mode);
1419*bbecb9d1SAndroid Build Coastguard Worker }
1420*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_copy_transfer3d(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1421*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_copy_transfer3d(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1422*bbecb9d1SAndroid Build Coastguard Worker {
1423*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box box;
1424*bbecb9d1SAndroid Build Coastguard Worker struct vrend_transfer_info info;
1425*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle;
1426*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_handle;
1427*bbecb9d1SAndroid Build Coastguard Worker
1428*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_COPY_TRANSFER3D_SIZE)
1429*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1430*bbecb9d1SAndroid Build Coastguard Worker
1431*bbecb9d1SAndroid Build Coastguard Worker memset(&info, 0, sizeof(info));
1432*bbecb9d1SAndroid Build Coastguard Worker info.box = &box;
1433*bbecb9d1SAndroid Build Coastguard Worker
1434*bbecb9d1SAndroid Build Coastguard Worker // synchronized is set either to 1 or 0. This means that we can use other bits
1435*bbecb9d1SAndroid Build Coastguard Worker // to identify the direction of copy transfer
1436*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags = get_buf_entry(buf, VIRGL_COPY_TRANSFER3D_FLAGS);
1437*bbecb9d1SAndroid Build Coastguard Worker bool read_from_host = (flags & VIRGL_COPY_TRANSFER3D_FLAGS_READ_FROM_HOST) != 0;
1438*bbecb9d1SAndroid Build Coastguard Worker info.synchronized = (flags & VIRGL_COPY_TRANSFER3D_FLAGS_SYNCHRONIZED) != 0;
1439*bbecb9d1SAndroid Build Coastguard Worker
1440*bbecb9d1SAndroid Build Coastguard Worker if (!read_from_host) {
1441*bbecb9d1SAndroid Build Coastguard Worker // this means that guest would like to make transfer to host
1442*bbecb9d1SAndroid Build Coastguard Worker // it can also mean that guest is using legacy copy transfer path
1443*bbecb9d1SAndroid Build Coastguard Worker vrend_decode_transfer_common(buf, &dst_handle, &info);
1444*bbecb9d1SAndroid Build Coastguard Worker info.offset = get_buf_entry(buf, VIRGL_COPY_TRANSFER3D_SRC_RES_OFFSET);
1445*bbecb9d1SAndroid Build Coastguard Worker src_handle = get_buf_entry(buf, VIRGL_COPY_TRANSFER3D_SRC_RES_HANDLE);
1446*bbecb9d1SAndroid Build Coastguard Worker
1447*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_copy_transfer3d(ctx, dst_handle, src_handle,
1448*bbecb9d1SAndroid Build Coastguard Worker &info);
1449*bbecb9d1SAndroid Build Coastguard Worker } else {
1450*bbecb9d1SAndroid Build Coastguard Worker vrend_decode_transfer_common(buf, &src_handle, &info);
1451*bbecb9d1SAndroid Build Coastguard Worker info.offset = get_buf_entry(buf, VIRGL_COPY_TRANSFER3D_SRC_RES_OFFSET);
1452*bbecb9d1SAndroid Build Coastguard Worker dst_handle = get_buf_entry(buf, VIRGL_COPY_TRANSFER3D_SRC_RES_HANDLE);
1453*bbecb9d1SAndroid Build Coastguard Worker
1454*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_copy_transfer3d_from_host(ctx, dst_handle, src_handle,
1455*bbecb9d1SAndroid Build Coastguard Worker &info);
1456*bbecb9d1SAndroid Build Coastguard Worker }
1457*bbecb9d1SAndroid Build Coastguard Worker }
1458*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_pipe_resource_create(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1459*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_pipe_resource_create(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1460*bbecb9d1SAndroid Build Coastguard Worker {
1461*bbecb9d1SAndroid Build Coastguard Worker struct vrend_renderer_resource_create_args args = { 0 };
1462*bbecb9d1SAndroid Build Coastguard Worker uint32_t blob_id;
1463*bbecb9d1SAndroid Build Coastguard Worker
1464*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_PIPE_RES_CREATE_SIZE)
1465*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1466*bbecb9d1SAndroid Build Coastguard Worker
1467*bbecb9d1SAndroid Build Coastguard Worker args.target = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_TARGET);
1468*bbecb9d1SAndroid Build Coastguard Worker args.format = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_FORMAT);
1469*bbecb9d1SAndroid Build Coastguard Worker args.bind = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_BIND);
1470*bbecb9d1SAndroid Build Coastguard Worker args.width = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_WIDTH);
1471*bbecb9d1SAndroid Build Coastguard Worker args.height = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_HEIGHT);
1472*bbecb9d1SAndroid Build Coastguard Worker args.depth = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_DEPTH);
1473*bbecb9d1SAndroid Build Coastguard Worker args.array_size = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_ARRAY_SIZE);
1474*bbecb9d1SAndroid Build Coastguard Worker args.last_level = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_LAST_LEVEL);
1475*bbecb9d1SAndroid Build Coastguard Worker args.nr_samples = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_NR_SAMPLES);
1476*bbecb9d1SAndroid Build Coastguard Worker args.flags = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_FLAGS);
1477*bbecb9d1SAndroid Build Coastguard Worker blob_id = get_buf_entry(buf, VIRGL_PIPE_RES_CREATE_BLOB_ID);
1478*bbecb9d1SAndroid Build Coastguard Worker
1479*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_pipe_resource_create(ctx, blob_id, &args);
1480*bbecb9d1SAndroid Build Coastguard Worker }
1481*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_pipe_resource_set_type(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1482*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_pipe_resource_set_type(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1483*bbecb9d1SAndroid Build Coastguard Worker {
1484*bbecb9d1SAndroid Build Coastguard Worker struct vrend_renderer_resource_set_type_args args = { 0 };
1485*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_id;
1486*bbecb9d1SAndroid Build Coastguard Worker
1487*bbecb9d1SAndroid Build Coastguard Worker if (length >= VIRGL_PIPE_RES_SET_TYPE_SIZE(0))
1488*bbecb9d1SAndroid Build Coastguard Worker args.plane_count = (length - VIRGL_PIPE_RES_SET_TYPE_SIZE(0)) / 2;
1489*bbecb9d1SAndroid Build Coastguard Worker
1490*bbecb9d1SAndroid Build Coastguard Worker if (length != VIRGL_PIPE_RES_SET_TYPE_SIZE(args.plane_count) ||
1491*bbecb9d1SAndroid Build Coastguard Worker !args.plane_count || args.plane_count > VIRGL_GBM_MAX_PLANES)
1492*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1493*bbecb9d1SAndroid Build Coastguard Worker
1494*bbecb9d1SAndroid Build Coastguard Worker res_id = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_RES_HANDLE);
1495*bbecb9d1SAndroid Build Coastguard Worker args.format = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_FORMAT);
1496*bbecb9d1SAndroid Build Coastguard Worker args.bind = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_BIND);
1497*bbecb9d1SAndroid Build Coastguard Worker args.width = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_WIDTH);
1498*bbecb9d1SAndroid Build Coastguard Worker args.height = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_HEIGHT);
1499*bbecb9d1SAndroid Build Coastguard Worker args.usage = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_USAGE);
1500*bbecb9d1SAndroid Build Coastguard Worker args.modifier = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_MODIFIER_LO);
1501*bbecb9d1SAndroid Build Coastguard Worker args.modifier |= (uint64_t)get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_MODIFIER_HI) << 32;
1502*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < args.plane_count; i++) {
1503*bbecb9d1SAndroid Build Coastguard Worker args.plane_strides[i] = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_PLANE_STRIDE(i));
1504*bbecb9d1SAndroid Build Coastguard Worker args.plane_offsets[i] = get_buf_entry(buf, VIRGL_PIPE_RES_SET_TYPE_PLANE_OFFSET(i));
1505*bbecb9d1SAndroid Build Coastguard Worker }
1506*bbecb9d1SAndroid Build Coastguard Worker
1507*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_pipe_resource_set_type(ctx, res_id, &args);
1508*bbecb9d1SAndroid Build Coastguard Worker }
1509*bbecb9d1SAndroid Build Coastguard Worker
1510*bbecb9d1SAndroid Build Coastguard Worker static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx,
1511*bbecb9d1SAndroid Build Coastguard Worker uint32_t ctx_id);
1512*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_fence_retire(uint64_t fence_id,void * retire_data)1513*bbecb9d1SAndroid Build Coastguard Worker static void vrend_decode_ctx_fence_retire(uint64_t fence_id,
1514*bbecb9d1SAndroid Build Coastguard Worker void *retire_data)
1515*bbecb9d1SAndroid Build Coastguard Worker {
1516*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *dctx = retire_data;
1517*bbecb9d1SAndroid Build Coastguard Worker dctx->base.fence_retire(&dctx->base, 0, fence_id);
1518*bbecb9d1SAndroid Build Coastguard Worker }
1519*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_context_create(uint32_t handle,uint32_t nlen,const char * debug_name)1520*bbecb9d1SAndroid Build Coastguard Worker struct virgl_context *vrend_renderer_context_create(uint32_t handle,
1521*bbecb9d1SAndroid Build Coastguard Worker uint32_t nlen,
1522*bbecb9d1SAndroid Build Coastguard Worker const char *debug_name)
1523*bbecb9d1SAndroid Build Coastguard Worker {
1524*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *dctx;
1525*bbecb9d1SAndroid Build Coastguard Worker
1526*bbecb9d1SAndroid Build Coastguard Worker dctx = malloc(sizeof(struct vrend_decode_ctx));
1527*bbecb9d1SAndroid Build Coastguard Worker if (!dctx)
1528*bbecb9d1SAndroid Build Coastguard Worker return NULL;
1529*bbecb9d1SAndroid Build Coastguard Worker
1530*bbecb9d1SAndroid Build Coastguard Worker vrend_decode_ctx_init_base(dctx, handle);
1531*bbecb9d1SAndroid Build Coastguard Worker
1532*bbecb9d1SAndroid Build Coastguard Worker dctx->grctx = vrend_create_context(handle, nlen, debug_name);
1533*bbecb9d1SAndroid Build Coastguard Worker if (!dctx->grctx) {
1534*bbecb9d1SAndroid Build Coastguard Worker free(dctx);
1535*bbecb9d1SAndroid Build Coastguard Worker return NULL;
1536*bbecb9d1SAndroid Build Coastguard Worker }
1537*bbecb9d1SAndroid Build Coastguard Worker
1538*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_set_fence_retire(dctx->grctx,
1539*bbecb9d1SAndroid Build Coastguard Worker vrend_decode_ctx_fence_retire,
1540*bbecb9d1SAndroid Build Coastguard Worker dctx);
1541*bbecb9d1SAndroid Build Coastguard Worker
1542*bbecb9d1SAndroid Build Coastguard Worker return &dctx->base;
1543*bbecb9d1SAndroid Build Coastguard Worker }
1544*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_destroy(struct virgl_context * ctx)1545*bbecb9d1SAndroid Build Coastguard Worker static void vrend_decode_ctx_destroy(struct virgl_context *ctx)
1546*bbecb9d1SAndroid Build Coastguard Worker {
1547*bbecb9d1SAndroid Build Coastguard Worker TRACE_FUNC();
1548*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
1549*bbecb9d1SAndroid Build Coastguard Worker
1550*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_context(dctx->grctx);
1551*bbecb9d1SAndroid Build Coastguard Worker free(dctx);
1552*bbecb9d1SAndroid Build Coastguard Worker }
1553*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_attach_resource(struct virgl_context * ctx,struct virgl_resource * res)1554*bbecb9d1SAndroid Build Coastguard Worker static void vrend_decode_ctx_attach_resource(struct virgl_context *ctx,
1555*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *res)
1556*bbecb9d1SAndroid Build Coastguard Worker {
1557*bbecb9d1SAndroid Build Coastguard Worker TRACE_FUNC();
1558*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
1559*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_attach_res_ctx(dctx->grctx, res);
1560*bbecb9d1SAndroid Build Coastguard Worker }
1561*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_detach_resource(struct virgl_context * ctx,struct virgl_resource * res)1562*bbecb9d1SAndroid Build Coastguard Worker static void vrend_decode_ctx_detach_resource(struct virgl_context *ctx,
1563*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *res)
1564*bbecb9d1SAndroid Build Coastguard Worker {
1565*bbecb9d1SAndroid Build Coastguard Worker TRACE_FUNC();
1566*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
1567*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_detach_res_ctx(dctx->grctx, res);
1568*bbecb9d1SAndroid Build Coastguard Worker }
1569*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_transfer_3d(struct virgl_context * ctx,struct virgl_resource * res,const struct vrend_transfer_info * info,int transfer_mode)1570*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_ctx_transfer_3d(struct virgl_context *ctx,
1571*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *res,
1572*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info,
1573*bbecb9d1SAndroid Build Coastguard Worker int transfer_mode)
1574*bbecb9d1SAndroid Build Coastguard Worker {
1575*bbecb9d1SAndroid Build Coastguard Worker TRACE_FUNC();
1576*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
1577*bbecb9d1SAndroid Build Coastguard Worker int ret = vrend_renderer_transfer_iov(dctx->grctx, res->res_id, info,
1578*bbecb9d1SAndroid Build Coastguard Worker transfer_mode);
1579*bbecb9d1SAndroid Build Coastguard Worker return vrend_check_no_error(dctx->grctx) || ret ? ret : EINVAL;
1580*bbecb9d1SAndroid Build Coastguard Worker }
1581*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_get_blob(struct virgl_context * ctx,UNUSED uint32_t res_id,uint64_t blob_id,UNUSED uint64_t blob_size,UNUSED uint32_t blob_flags,struct virgl_context_blob * blob)1582*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_ctx_get_blob(struct virgl_context *ctx,
1583*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint32_t res_id,
1584*bbecb9d1SAndroid Build Coastguard Worker uint64_t blob_id,
1585*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint64_t blob_size,
1586*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint32_t blob_flags,
1587*bbecb9d1SAndroid Build Coastguard Worker struct virgl_context_blob *blob)
1588*bbecb9d1SAndroid Build Coastguard Worker {
1589*bbecb9d1SAndroid Build Coastguard Worker TRACE_FUNC();
1590*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
1591*bbecb9d1SAndroid Build Coastguard Worker
1592*bbecb9d1SAndroid Build Coastguard Worker blob->type = VIRGL_RESOURCE_FD_INVALID;
1593*bbecb9d1SAndroid Build Coastguard Worker /* this transfers ownership and blob_id is no longer valid */
1594*bbecb9d1SAndroid Build Coastguard Worker blob->u.pipe_resource = vrend_get_blob_pipe(dctx->grctx, blob_id);
1595*bbecb9d1SAndroid Build Coastguard Worker if (!blob->u.pipe_resource)
1596*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
1597*bbecb9d1SAndroid Build Coastguard Worker
1598*bbecb9d1SAndroid Build Coastguard Worker blob->map_info = vrend_renderer_resource_get_map_info(blob->u.pipe_resource);
1599*bbecb9d1SAndroid Build Coastguard Worker return 0;
1600*bbecb9d1SAndroid Build Coastguard Worker }
1601*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_get_memory_info(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1602*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_get_memory_info(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1603*bbecb9d1SAndroid Build Coastguard Worker {
1604*bbecb9d1SAndroid Build Coastguard Worker TRACE_FUNC();
1605*bbecb9d1SAndroid Build Coastguard Worker if (length != 1)
1606*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1607*bbecb9d1SAndroid Build Coastguard Worker
1608*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle = get_buf_entry(buf, 1);
1609*bbecb9d1SAndroid Build Coastguard Worker
1610*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_get_meminfo(ctx, res_handle);
1611*bbecb9d1SAndroid Build Coastguard Worker
1612*bbecb9d1SAndroid Build Coastguard Worker return 0;
1613*bbecb9d1SAndroid Build Coastguard Worker }
1614*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_send_string_marker(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1615*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_send_string_marker(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1616*bbecb9d1SAndroid Build Coastguard Worker {
1617*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_len = sizeof(uint32_t) * (length - 1);
1618*bbecb9d1SAndroid Build Coastguard Worker
1619*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_SEND_STRING_MARKER_MIN_SIZE) {
1620*bbecb9d1SAndroid Build Coastguard Worker fprintf(stderr, "minimal command length not okay\n");
1621*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1622*bbecb9d1SAndroid Build Coastguard Worker }
1623*bbecb9d1SAndroid Build Coastguard Worker
1624*bbecb9d1SAndroid Build Coastguard Worker uint32_t str_len = get_buf_entry(buf, VIRGL_SEND_STRING_MARKER_STRING_SIZE);
1625*bbecb9d1SAndroid Build Coastguard Worker if (str_len > buf_len) {
1626*bbecb9d1SAndroid Build Coastguard Worker fprintf(stderr, "String len %u > buf_len %u\n", str_len, buf_len);
1627*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1628*bbecb9d1SAndroid Build Coastguard Worker }
1629*bbecb9d1SAndroid Build Coastguard Worker
1630*bbecb9d1SAndroid Build Coastguard Worker vrend_context_emit_string_marker(ctx, str_len, get_buf_ptr(buf, VIRGL_SEND_STRING_MARKER_OFFSET));
1631*bbecb9d1SAndroid Build Coastguard Worker
1632*bbecb9d1SAndroid Build Coastguard Worker return 0;
1633*bbecb9d1SAndroid Build Coastguard Worker }
1634*bbecb9d1SAndroid Build Coastguard Worker
1635*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
1636*bbecb9d1SAndroid Build Coastguard Worker /* video codec related functions */
1637*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_video_codec(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1638*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_video_codec(struct vrend_context *ctx,
1639*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1640*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1641*bbecb9d1SAndroid Build Coastguard Worker {
1642*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx = vrend_context_get_video_ctx(ctx);
1643*bbecb9d1SAndroid Build Coastguard Worker
1644*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_CREATE_VIDEO_CODEC_MIN_SIZE)
1645*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1646*bbecb9d1SAndroid Build Coastguard Worker
1647*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_CREATE_VIDEO_CODEC_HANDLE);
1648*bbecb9d1SAndroid Build Coastguard Worker uint32_t profile = get_buf_entry(buf, VIRGL_CREATE_VIDEO_CODEC_PROFILE);
1649*bbecb9d1SAndroid Build Coastguard Worker uint32_t entrypoint = get_buf_entry(buf, VIRGL_CREATE_VIDEO_CODEC_ENTRYPOINT);
1650*bbecb9d1SAndroid Build Coastguard Worker uint32_t chroma_fmt = get_buf_entry(buf, VIRGL_CREATE_VIDEO_CODEC_CHROMA_FMT);
1651*bbecb9d1SAndroid Build Coastguard Worker uint32_t level = get_buf_entry(buf, VIRGL_CREATE_VIDEO_CODEC_LEVEL);
1652*bbecb9d1SAndroid Build Coastguard Worker uint32_t width = get_buf_entry(buf, VIRGL_CREATE_VIDEO_CODEC_WIDTH);
1653*bbecb9d1SAndroid Build Coastguard Worker uint32_t height = get_buf_entry(buf, VIRGL_CREATE_VIDEO_CODEC_HEIGHT);
1654*bbecb9d1SAndroid Build Coastguard Worker uint32_t max_ref = 2; /* The max number of ref frames is 2 by default */
1655*bbecb9d1SAndroid Build Coastguard Worker
1656*bbecb9d1SAndroid Build Coastguard Worker if (length >= VIRGL_CREATE_VIDEO_CODEC_MAX_REF)
1657*bbecb9d1SAndroid Build Coastguard Worker max_ref = get_buf_entry(buf, VIRGL_CREATE_VIDEO_CODEC_MAX_REF);
1658*bbecb9d1SAndroid Build Coastguard Worker
1659*bbecb9d1SAndroid Build Coastguard Worker vrend_video_create_codec(vctx, handle, profile, entrypoint,
1660*bbecb9d1SAndroid Build Coastguard Worker chroma_fmt, level, width, height, max_ref, 0);
1661*bbecb9d1SAndroid Build Coastguard Worker
1662*bbecb9d1SAndroid Build Coastguard Worker return 0;
1663*bbecb9d1SAndroid Build Coastguard Worker }
1664*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_destroy_video_codec(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1665*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_destroy_video_codec(struct vrend_context *ctx,
1666*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1667*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1668*bbecb9d1SAndroid Build Coastguard Worker {
1669*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx = vrend_context_get_video_ctx(ctx);
1670*bbecb9d1SAndroid Build Coastguard Worker
1671*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_DESTROY_VIDEO_CODEC_MIN_SIZE)
1672*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1673*bbecb9d1SAndroid Build Coastguard Worker
1674*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_DESTROY_VIDEO_CODEC_HANDLE);
1675*bbecb9d1SAndroid Build Coastguard Worker vrend_video_destroy_codec(vctx, handle);
1676*bbecb9d1SAndroid Build Coastguard Worker
1677*bbecb9d1SAndroid Build Coastguard Worker return 0;
1678*bbecb9d1SAndroid Build Coastguard Worker }
1679*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_create_video_buffer(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1680*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_create_video_buffer(struct vrend_context *ctx,
1681*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1682*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1683*bbecb9d1SAndroid Build Coastguard Worker {
1684*bbecb9d1SAndroid Build Coastguard Worker uint32_t i, num_res;
1685*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handles[VREND_VIDEO_BUFFER_PLANE_NUM];
1686*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx = vrend_context_get_video_ctx(ctx);
1687*bbecb9d1SAndroid Build Coastguard Worker
1688*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_CREATE_VIDEO_BUFFER_MIN_SIZE)
1689*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1690*bbecb9d1SAndroid Build Coastguard Worker
1691*bbecb9d1SAndroid Build Coastguard Worker num_res = length - VIRGL_CREATE_VIDEO_BUFFER_RES_BASE + 1;
1692*bbecb9d1SAndroid Build Coastguard Worker if (num_res > VREND_VIDEO_BUFFER_PLANE_NUM)
1693*bbecb9d1SAndroid Build Coastguard Worker num_res = VREND_VIDEO_BUFFER_PLANE_NUM;
1694*bbecb9d1SAndroid Build Coastguard Worker
1695*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_CREATE_VIDEO_BUFFER_HANDLE);
1696*bbecb9d1SAndroid Build Coastguard Worker uint32_t format = get_buf_entry(buf, VIRGL_CREATE_VIDEO_BUFFER_FORMAT);
1697*bbecb9d1SAndroid Build Coastguard Worker uint32_t width = get_buf_entry(buf, VIRGL_CREATE_VIDEO_BUFFER_WIDTH);
1698*bbecb9d1SAndroid Build Coastguard Worker uint32_t height = get_buf_entry(buf, VIRGL_CREATE_VIDEO_BUFFER_HEIGHT);
1699*bbecb9d1SAndroid Build Coastguard Worker
1700*bbecb9d1SAndroid Build Coastguard Worker memset(res_handles, 0, sizeof(res_handles));
1701*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_res; i++)
1702*bbecb9d1SAndroid Build Coastguard Worker res_handles[i] = get_buf_entry(buf,
1703*bbecb9d1SAndroid Build Coastguard Worker VIRGL_CREATE_VIDEO_BUFFER_RES_BASE + i);
1704*bbecb9d1SAndroid Build Coastguard Worker
1705*bbecb9d1SAndroid Build Coastguard Worker vrend_video_create_buffer(vctx, handle, format, width, height,
1706*bbecb9d1SAndroid Build Coastguard Worker res_handles, num_res);
1707*bbecb9d1SAndroid Build Coastguard Worker
1708*bbecb9d1SAndroid Build Coastguard Worker return 0;
1709*bbecb9d1SAndroid Build Coastguard Worker }
1710*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_destroy_video_buffer(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1711*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_destroy_video_buffer(struct vrend_context *ctx,
1712*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1713*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1714*bbecb9d1SAndroid Build Coastguard Worker {
1715*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx = vrend_context_get_video_ctx(ctx);
1716*bbecb9d1SAndroid Build Coastguard Worker
1717*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_DESTROY_VIDEO_BUFFER_MIN_SIZE)
1718*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1719*bbecb9d1SAndroid Build Coastguard Worker
1720*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = get_buf_entry(buf, VIRGL_DESTROY_VIDEO_BUFFER_HANDLE);
1721*bbecb9d1SAndroid Build Coastguard Worker vrend_video_destroy_buffer(vctx, handle);
1722*bbecb9d1SAndroid Build Coastguard Worker
1723*bbecb9d1SAndroid Build Coastguard Worker return 0;
1724*bbecb9d1SAndroid Build Coastguard Worker }
1725*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_begin_frame(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1726*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_begin_frame(struct vrend_context *ctx,
1727*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1728*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1729*bbecb9d1SAndroid Build Coastguard Worker {
1730*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx = vrend_context_get_video_ctx(ctx);
1731*bbecb9d1SAndroid Build Coastguard Worker
1732*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_BEGIN_FRAME_MIN_SIZE)
1733*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1734*bbecb9d1SAndroid Build Coastguard Worker
1735*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle = get_buf_entry(buf, VIRGL_BEGIN_FRAME_CDC_HANDLE);
1736*bbecb9d1SAndroid Build Coastguard Worker uint32_t tgt_handle = get_buf_entry(buf, VIRGL_BEGIN_FRAME_TGT_HANDLE);
1737*bbecb9d1SAndroid Build Coastguard Worker vrend_video_begin_frame(vctx, cdc_handle, tgt_handle);
1738*bbecb9d1SAndroid Build Coastguard Worker
1739*bbecb9d1SAndroid Build Coastguard Worker return 0;
1740*bbecb9d1SAndroid Build Coastguard Worker }
1741*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_decode_bitstream(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1742*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_decode_bitstream(struct vrend_context *ctx,
1743*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1744*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1745*bbecb9d1SAndroid Build Coastguard Worker {
1746*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx = vrend_context_get_video_ctx(ctx);
1747*bbecb9d1SAndroid Build Coastguard Worker
1748*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_DECODE_BS_MIN_SIZE)
1749*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1750*bbecb9d1SAndroid Build Coastguard Worker
1751*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle = get_buf_entry(buf, VIRGL_DECODE_BS_CDC_HANDLE);
1752*bbecb9d1SAndroid Build Coastguard Worker uint32_t tgt_handle = get_buf_entry(buf, VIRGL_DECODE_BS_TGT_HANDLE);
1753*bbecb9d1SAndroid Build Coastguard Worker uint32_t dsc_handle = get_buf_entry(buf, VIRGL_DECODE_BS_DSC_HANDLE);
1754*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_handle = get_buf_entry(buf, VIRGL_DECODE_BS_BUF_HANDLE);
1755*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_size = get_buf_entry(buf, VIRGL_DECODE_BS_BUF_SIZE);
1756*bbecb9d1SAndroid Build Coastguard Worker
1757*bbecb9d1SAndroid Build Coastguard Worker vrend_video_decode_bitstream(vctx, cdc_handle, tgt_handle,
1758*bbecb9d1SAndroid Build Coastguard Worker dsc_handle, 1, &buf_handle, &buf_size);
1759*bbecb9d1SAndroid Build Coastguard Worker
1760*bbecb9d1SAndroid Build Coastguard Worker return 0;
1761*bbecb9d1SAndroid Build Coastguard Worker }
1762*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_encode_bitstream(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1763*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_encode_bitstream(struct vrend_context *ctx,
1764*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1765*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1766*bbecb9d1SAndroid Build Coastguard Worker {
1767*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx = vrend_context_get_video_ctx(ctx);
1768*bbecb9d1SAndroid Build Coastguard Worker
1769*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_ENCODE_BS_MIN_SIZE)
1770*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1771*bbecb9d1SAndroid Build Coastguard Worker
1772*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle = get_buf_entry(buf, VIRGL_ENCODE_BS_CDC_HANDLE);
1773*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_handle = get_buf_entry(buf, VIRGL_ENCODE_BS_SRC_HANDLE);
1774*bbecb9d1SAndroid Build Coastguard Worker uint32_t dest_handle = get_buf_entry(buf, VIRGL_ENCODE_BS_DEST_HANDLE);
1775*bbecb9d1SAndroid Build Coastguard Worker uint32_t desc_handle = get_buf_entry(buf, VIRGL_ENCODE_BS_DESC_HANDLE);
1776*bbecb9d1SAndroid Build Coastguard Worker uint32_t feed_handle = get_buf_entry(buf, VIRGL_ENCODE_BS_FEED_HANDLE);
1777*bbecb9d1SAndroid Build Coastguard Worker
1778*bbecb9d1SAndroid Build Coastguard Worker vrend_video_encode_bitstream(vctx, cdc_handle, src_handle, dest_handle,
1779*bbecb9d1SAndroid Build Coastguard Worker desc_handle, feed_handle);
1780*bbecb9d1SAndroid Build Coastguard Worker
1781*bbecb9d1SAndroid Build Coastguard Worker return 0;
1782*bbecb9d1SAndroid Build Coastguard Worker }
1783*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_end_frame(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1784*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_end_frame(struct vrend_context *ctx,
1785*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1786*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1787*bbecb9d1SAndroid Build Coastguard Worker {
1788*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx = vrend_context_get_video_ctx(ctx);
1789*bbecb9d1SAndroid Build Coastguard Worker
1790*bbecb9d1SAndroid Build Coastguard Worker if (length < VIRGL_END_FRAME_MIN_SIZE)
1791*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1792*bbecb9d1SAndroid Build Coastguard Worker
1793*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle = get_buf_entry(buf, VIRGL_END_FRAME_CDC_HANDLE);
1794*bbecb9d1SAndroid Build Coastguard Worker uint32_t tgt_handle = get_buf_entry(buf, VIRGL_END_FRAME_TGT_HANDLE);
1795*bbecb9d1SAndroid Build Coastguard Worker
1796*bbecb9d1SAndroid Build Coastguard Worker vrend_video_end_frame(vctx, cdc_handle, tgt_handle);
1797*bbecb9d1SAndroid Build Coastguard Worker
1798*bbecb9d1SAndroid Build Coastguard Worker return 0;
1799*bbecb9d1SAndroid Build Coastguard Worker }
1800*bbecb9d1SAndroid Build Coastguard Worker
1801*bbecb9d1SAndroid Build Coastguard Worker #else
1802*bbecb9d1SAndroid Build Coastguard Worker
vrend_unsupported(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1803*bbecb9d1SAndroid Build Coastguard Worker static int vrend_unsupported(struct vrend_context *ctx,
1804*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf,
1805*bbecb9d1SAndroid Build Coastguard Worker uint32_t length)
1806*bbecb9d1SAndroid Build Coastguard Worker {
1807*bbecb9d1SAndroid Build Coastguard Worker (void)ctx;
1808*bbecb9d1SAndroid Build Coastguard Worker (void)buf;
1809*bbecb9d1SAndroid Build Coastguard Worker (void)length;
1810*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1811*bbecb9d1SAndroid Build Coastguard Worker }
1812*bbecb9d1SAndroid Build Coastguard Worker
1813*bbecb9d1SAndroid Build Coastguard Worker #endif /* ENABLE_VIDEO */
1814*bbecb9d1SAndroid Build Coastguard Worker
1815*bbecb9d1SAndroid Build Coastguard Worker
1816*bbecb9d1SAndroid Build Coastguard Worker typedef int (*vrend_decode_callback)(struct vrend_context *ctx, const uint32_t *buf, uint32_t length);
1817*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_dummy(struct vrend_context * ctx,const uint32_t * buf,uint32_t length)1818*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_dummy(struct vrend_context *ctx, const uint32_t *buf, uint32_t length)
1819*bbecb9d1SAndroid Build Coastguard Worker {
1820*bbecb9d1SAndroid Build Coastguard Worker (void)ctx;
1821*bbecb9d1SAndroid Build Coastguard Worker (void)buf;
1822*bbecb9d1SAndroid Build Coastguard Worker (void)length;
1823*bbecb9d1SAndroid Build Coastguard Worker return 0;
1824*bbecb9d1SAndroid Build Coastguard Worker }
1825*bbecb9d1SAndroid Build Coastguard Worker
1826*bbecb9d1SAndroid Build Coastguard Worker static const vrend_decode_callback decode_table[VIRGL_MAX_COMMANDS] = {
1827*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_NOP] = vrend_decode_dummy,
1828*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_CREATE_OBJECT] = vrend_decode_create_object,
1829*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_BIND_OBJECT] = vrend_decode_bind_object,
1830*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DESTROY_OBJECT] = vrend_decode_destroy_object,
1831*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_CLEAR] = vrend_decode_clear,
1832*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_CLEAR_TEXTURE] = vrend_decode_clear_texture,
1833*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DRAW_VBO] = vrend_decode_draw_vbo,
1834*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_FRAMEBUFFER_STATE] = vrend_decode_set_framebuffer_state,
1835*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_VERTEX_BUFFERS] = vrend_decode_set_vertex_buffers,
1836*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_RESOURCE_INLINE_WRITE] = vrend_decode_resource_inline_write,
1837*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_VIEWPORT_STATE] = vrend_decode_set_viewport_state,
1838*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_SAMPLER_VIEWS] = vrend_decode_set_sampler_views,
1839*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_INDEX_BUFFER] = vrend_decode_set_index_buffer,
1840*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_CONSTANT_BUFFER] = vrend_decode_set_constant_buffer,
1841*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_STENCIL_REF] = vrend_decode_set_stencil_ref,
1842*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_BLEND_COLOR] = vrend_decode_set_blend_color,
1843*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_SCISSOR_STATE] = vrend_decode_set_scissor_state,
1844*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_BLIT] = vrend_decode_blit,
1845*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_RESOURCE_COPY_REGION] = vrend_decode_resource_copy_region,
1846*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_BIND_SAMPLER_STATES] = vrend_decode_bind_sampler_states,
1847*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_BEGIN_QUERY] = vrend_decode_begin_query,
1848*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_END_QUERY] = vrend_decode_end_query,
1849*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_GET_QUERY_RESULT] = vrend_decode_get_query_result,
1850*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_POLYGON_STIPPLE] = vrend_decode_set_polygon_stipple,
1851*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_CLIP_STATE] = vrend_decode_set_clip_state,
1852*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_SAMPLE_MASK] = vrend_decode_set_sample_mask,
1853*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_MIN_SAMPLES] = vrend_decode_set_min_samples,
1854*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_STREAMOUT_TARGETS] = vrend_decode_set_streamout_targets,
1855*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_RENDER_CONDITION] = vrend_decode_set_render_condition,
1856*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_UNIFORM_BUFFER] = vrend_decode_set_uniform_buffer,
1857*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_SUB_CTX] = vrend_decode_set_sub_ctx,
1858*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_CREATE_SUB_CTX] = vrend_decode_create_sub_ctx,
1859*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DESTROY_SUB_CTX] = vrend_decode_destroy_sub_ctx,
1860*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_BIND_SHADER] = vrend_decode_bind_shader,
1861*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_TESS_STATE] = vrend_decode_set_tess_state,
1862*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_SHADER_BUFFERS] = vrend_decode_set_shader_buffers,
1863*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_SHADER_IMAGES] = vrend_decode_set_shader_images,
1864*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_ATOMIC_BUFFERS] = vrend_decode_set_atomic_buffers,
1865*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_MEMORY_BARRIER] = vrend_decode_memory_barrier,
1866*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_LAUNCH_GRID] = vrend_decode_launch_grid,
1867*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_FRAMEBUFFER_STATE_NO_ATTACH] = vrend_decode_set_framebuffer_state_no_attach,
1868*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_TEXTURE_BARRIER] = vrend_decode_texture_barrier,
1869*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_DEBUG_FLAGS] = vrend_decode_set_debug_mask,
1870*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_GET_QUERY_RESULT_QBO] = vrend_decode_get_query_result_qbo,
1871*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_TRANSFER3D] = vrend_decode_transfer3d,
1872*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_COPY_TRANSFER3D] = vrend_decode_copy_transfer3d,
1873*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_END_TRANSFERS] = vrend_decode_dummy,
1874*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SET_TWEAKS] = vrend_decode_set_tweaks,
1875*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_PIPE_RESOURCE_CREATE] = vrend_decode_pipe_resource_create,
1876*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_PIPE_RESOURCE_SET_TYPE] = vrend_decode_pipe_resource_set_type,
1877*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_GET_MEMORY_INFO] = vrend_decode_get_memory_info,
1878*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_SEND_STRING_MARKER] = vrend_decode_send_string_marker,
1879*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_LINK_SHADER] = vrend_decode_link_shader,
1880*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
1881*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_CREATE_VIDEO_CODEC] = vrend_decode_create_video_codec,
1882*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DESTROY_VIDEO_CODEC] = vrend_decode_destroy_video_codec,
1883*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_CREATE_VIDEO_BUFFER] = vrend_decode_create_video_buffer,
1884*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DESTROY_VIDEO_BUFFER] = vrend_decode_destroy_video_buffer,
1885*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_BEGIN_FRAME] = vrend_decode_begin_frame,
1886*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DECODE_MACROBLOCK] = vrend_decode_dummy,
1887*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DECODE_BITSTREAM] = vrend_decode_decode_bitstream,
1888*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_ENCODE_BITSTREAM] = vrend_decode_encode_bitstream,
1889*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_END_FRAME] = vrend_decode_end_frame,
1890*bbecb9d1SAndroid Build Coastguard Worker #else
1891*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_CREATE_VIDEO_CODEC] = vrend_unsupported,
1892*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DESTROY_VIDEO_CODEC] = vrend_unsupported,
1893*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_CREATE_VIDEO_BUFFER] = vrend_unsupported,
1894*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DESTROY_VIDEO_BUFFER] = vrend_unsupported,
1895*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_BEGIN_FRAME] = vrend_unsupported,
1896*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DECODE_MACROBLOCK] = vrend_unsupported,
1897*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_DECODE_BITSTREAM] = vrend_unsupported,
1898*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_ENCODE_BITSTREAM] = vrend_unsupported,
1899*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_CCMD_END_FRAME] = vrend_unsupported,
1900*bbecb9d1SAndroid Build Coastguard Worker #endif
1901*bbecb9d1SAndroid Build Coastguard Worker };
1902*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_submit_cmd(struct virgl_context * ctx,const void * buffer,size_t size)1903*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_ctx_submit_cmd(struct virgl_context *ctx,
1904*bbecb9d1SAndroid Build Coastguard Worker const void *buffer,
1905*bbecb9d1SAndroid Build Coastguard Worker size_t size)
1906*bbecb9d1SAndroid Build Coastguard Worker {
1907*bbecb9d1SAndroid Build Coastguard Worker TRACE_FUNC();
1908*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *gdctx = (struct vrend_decode_ctx *)ctx;
1909*bbecb9d1SAndroid Build Coastguard Worker bool bret;
1910*bbecb9d1SAndroid Build Coastguard Worker int ret;
1911*bbecb9d1SAndroid Build Coastguard Worker
1912*bbecb9d1SAndroid Build Coastguard Worker bret = vrend_hw_switch_context(gdctx->grctx, true);
1913*bbecb9d1SAndroid Build Coastguard Worker if (bret == false)
1914*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1915*bbecb9d1SAndroid Build Coastguard Worker
1916*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *typed_buf = (const uint32_t *)buffer;
1917*bbecb9d1SAndroid Build Coastguard Worker const uint32_t buf_total = (uint32_t)(size / sizeof(uint32_t));
1918*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_offset = 0;
1919*bbecb9d1SAndroid Build Coastguard Worker
1920*bbecb9d1SAndroid Build Coastguard Worker while (buf_offset < buf_total) {
1921*bbecb9d1SAndroid Build Coastguard Worker const uint32_t cur_offset = buf_offset;
1922*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buf = &typed_buf[buf_offset];
1923*bbecb9d1SAndroid Build Coastguard Worker uint32_t len = *buf >> 16;
1924*bbecb9d1SAndroid Build Coastguard Worker uint32_t cmd = *buf & 0xff;
1925*bbecb9d1SAndroid Build Coastguard Worker
1926*bbecb9d1SAndroid Build Coastguard Worker if (cmd >= VIRGL_MAX_COMMANDS)
1927*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
1928*bbecb9d1SAndroid Build Coastguard Worker
1929*bbecb9d1SAndroid Build Coastguard Worker buf_offset += len + 1;
1930*bbecb9d1SAndroid Build Coastguard Worker
1931*bbecb9d1SAndroid Build Coastguard Worker ret = 0;
1932*bbecb9d1SAndroid Build Coastguard Worker /* check if the guest is doing something bad */
1933*bbecb9d1SAndroid Build Coastguard Worker if (buf_offset > buf_total) {
1934*bbecb9d1SAndroid Build Coastguard Worker vrend_report_buffer_error(gdctx->grctx, 0);
1935*bbecb9d1SAndroid Build Coastguard Worker break;
1936*bbecb9d1SAndroid Build Coastguard Worker }
1937*bbecb9d1SAndroid Build Coastguard Worker
1938*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_cmd, gdctx->grctx, "%-4d %-20s len:%d\n",
1939*bbecb9d1SAndroid Build Coastguard Worker cur_offset, vrend_get_comand_name(cmd), len);
1940*bbecb9d1SAndroid Build Coastguard Worker
1941*bbecb9d1SAndroid Build Coastguard Worker TRACE_SCOPE_SLOW(vrend_get_comand_name(cmd));
1942*bbecb9d1SAndroid Build Coastguard Worker
1943*bbecb9d1SAndroid Build Coastguard Worker ret = decode_table[cmd](gdctx->grctx, buf, len);
1944*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_check_no_error(gdctx->grctx) && !ret)
1945*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
1946*bbecb9d1SAndroid Build Coastguard Worker if (ret) {
1947*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("context %d failed to dispatch %s: %d\n",
1948*bbecb9d1SAndroid Build Coastguard Worker gdctx->base.ctx_id, vrend_get_comand_name(cmd), ret);
1949*bbecb9d1SAndroid Build Coastguard Worker if (ret == EINVAL)
1950*bbecb9d1SAndroid Build Coastguard Worker vrend_report_buffer_error(gdctx->grctx, *buf);
1951*bbecb9d1SAndroid Build Coastguard Worker return ret;
1952*bbecb9d1SAndroid Build Coastguard Worker }
1953*bbecb9d1SAndroid Build Coastguard Worker }
1954*bbecb9d1SAndroid Build Coastguard Worker return 0;
1955*bbecb9d1SAndroid Build Coastguard Worker }
1956*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_get_fencing_fd(UNUSED struct virgl_context * ctx)1957*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_ctx_get_fencing_fd(UNUSED struct virgl_context *ctx)
1958*bbecb9d1SAndroid Build Coastguard Worker {
1959*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_get_poll_fd();
1960*bbecb9d1SAndroid Build Coastguard Worker }
1961*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_retire_fences(UNUSED struct virgl_context * ctx)1962*bbecb9d1SAndroid Build Coastguard Worker static void vrend_decode_ctx_retire_fences(UNUSED struct virgl_context *ctx)
1963*bbecb9d1SAndroid Build Coastguard Worker {
1964*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_check_fences();
1965*bbecb9d1SAndroid Build Coastguard Worker }
1966*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_submit_fence(struct virgl_context * ctx,uint32_t flags,uint32_t ring_idx,uint64_t fence_id)1967*bbecb9d1SAndroid Build Coastguard Worker static int vrend_decode_ctx_submit_fence(struct virgl_context *ctx,
1968*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags,
1969*bbecb9d1SAndroid Build Coastguard Worker uint32_t ring_idx,
1970*bbecb9d1SAndroid Build Coastguard Worker uint64_t fence_id)
1971*bbecb9d1SAndroid Build Coastguard Worker {
1972*bbecb9d1SAndroid Build Coastguard Worker struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
1973*bbecb9d1SAndroid Build Coastguard Worker
1974*bbecb9d1SAndroid Build Coastguard Worker if (ring_idx)
1975*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
1976*bbecb9d1SAndroid Build Coastguard Worker
1977*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_create_fence(dctx->grctx, flags, fence_id);
1978*bbecb9d1SAndroid Build Coastguard Worker }
1979*bbecb9d1SAndroid Build Coastguard Worker
vrend_decode_ctx_init_base(struct vrend_decode_ctx * dctx,uint32_t ctx_id)1980*bbecb9d1SAndroid Build Coastguard Worker static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx,
1981*bbecb9d1SAndroid Build Coastguard Worker uint32_t ctx_id)
1982*bbecb9d1SAndroid Build Coastguard Worker {
1983*bbecb9d1SAndroid Build Coastguard Worker struct virgl_context *ctx = &dctx->base ;
1984*bbecb9d1SAndroid Build Coastguard Worker
1985*bbecb9d1SAndroid Build Coastguard Worker for (unsigned i = 0; i < VIRGL_MAX_COMMANDS; ++i)
1986*bbecb9d1SAndroid Build Coastguard Worker assert(decode_table[i]);
1987*bbecb9d1SAndroid Build Coastguard Worker
1988*bbecb9d1SAndroid Build Coastguard Worker ctx->ctx_id = ctx_id;
1989*bbecb9d1SAndroid Build Coastguard Worker ctx->destroy = vrend_decode_ctx_destroy;
1990*bbecb9d1SAndroid Build Coastguard Worker ctx->attach_resource = vrend_decode_ctx_attach_resource;
1991*bbecb9d1SAndroid Build Coastguard Worker ctx->detach_resource = vrend_decode_ctx_detach_resource;
1992*bbecb9d1SAndroid Build Coastguard Worker ctx->transfer_3d = vrend_decode_ctx_transfer_3d;
1993*bbecb9d1SAndroid Build Coastguard Worker ctx->get_blob = vrend_decode_ctx_get_blob;
1994*bbecb9d1SAndroid Build Coastguard Worker ctx->submit_cmd = vrend_decode_ctx_submit_cmd;
1995*bbecb9d1SAndroid Build Coastguard Worker
1996*bbecb9d1SAndroid Build Coastguard Worker ctx->get_fencing_fd = vrend_decode_ctx_get_fencing_fd;
1997*bbecb9d1SAndroid Build Coastguard Worker ctx->retire_fences = vrend_decode_ctx_retire_fences;
1998*bbecb9d1SAndroid Build Coastguard Worker ctx->submit_fence = vrend_decode_ctx_submit_fence;
1999*bbecb9d1SAndroid Build Coastguard Worker }
2000