1 /**************************************************************************
2 *
3 * Copyright (C) 2014 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24
25 /* helper functions for testing purposes */
26 #include <check.h>
27 #include <errno.h>
28 #include <sys/uio.h>
29 #include "pipe/p_defines.h"
30 #include "pipe/p_format.h"
31 #include "util/u_memory.h"
32 #include "util/u_format.h"
33 #include "testvirgl.h"
34
35 #include "virgl_hw.h"
36 #include "virglrenderer.h"
37
38 int context_flags = VIRGL_RENDERER_USE_EGL;
39
testvirgl_init_simple_1d_resource(struct virgl_renderer_resource_create_args * res,int handle)40 void testvirgl_init_simple_1d_resource(struct virgl_renderer_resource_create_args *res, int handle)
41 {
42 res->handle = handle;
43 res->target = PIPE_TEXTURE_1D;
44 res->format = PIPE_FORMAT_B8G8R8X8_UNORM;
45 res->width = 50;
46 res->height = 1;
47 res->depth = 1;
48 res->array_size = 1;
49 res->last_level = 0;
50 res->nr_samples = 0;
51 res->bind = PIPE_BIND_SAMPLER_VIEW;
52 res->flags = 0;
53 }
54
testvirgl_init_simple_buffer_sized(struct virgl_renderer_resource_create_args * res,int handle,int width)55 void testvirgl_init_simple_buffer_sized(struct virgl_renderer_resource_create_args *res, int handle, int width)
56 {
57 res->handle = handle;
58 res->target = PIPE_BUFFER;
59 res->format = PIPE_FORMAT_R8_UNORM;
60 res->width = width;
61 res->height = 1;
62 res->depth = 1;
63 res->array_size = 1;
64 res->last_level = 0;
65 res->nr_samples = 0;
66 res->bind = 0;
67 res->flags = 0;
68 }
69
testvirgl_init_simple_buffer(struct virgl_renderer_resource_create_args * res,int handle)70 void testvirgl_init_simple_buffer(struct virgl_renderer_resource_create_args *res, int handle)
71 {
72 testvirgl_init_simple_buffer_sized(res, handle, 50);
73 }
74
testvirgl_init_simple_2d_resource(struct virgl_renderer_resource_create_args * res,int handle)75 void testvirgl_init_simple_2d_resource(struct virgl_renderer_resource_create_args *res, int handle)
76 {
77 res->handle = handle;
78 res->target = PIPE_TEXTURE_2D;
79 res->format = PIPE_FORMAT_B8G8R8X8_UNORM;
80 res->width = 50;
81 res->height = 50;
82 res->depth = 1;
83 res->array_size = 1;
84 res->last_level = 0;
85 res->nr_samples = 0;
86 res->bind = PIPE_BIND_SAMPLER_VIEW;
87 res->flags = 0;
88 }
89
90
91 struct myinfo_struct {
92 uint32_t test;
93 };
94
95 static struct myinfo_struct mystruct;
96
97 static struct virgl_renderer_callbacks test_cbs;
98
99 static uint32_t testvirgl_last_fence;
testvirgl_write_fence(UNUSED void * cookie,uint32_t fence)100 static void testvirgl_write_fence(UNUSED void *cookie, uint32_t fence)
101 {
102 testvirgl_last_fence = fence;
103 }
104
testvirgl_get_last_fence(void)105 uint32_t testvirgl_get_last_fence(void)
106 {
107 return testvirgl_last_fence;
108 }
109
testvirgl_reset_fence(void)110 void testvirgl_reset_fence(void)
111 {
112 testvirgl_last_fence = 0;
113 }
114
testvirgl_init_single_ctx(void)115 int testvirgl_init_single_ctx(void)
116 {
117 int ret;
118
119 test_cbs.version = 1;
120 test_cbs.write_fence = testvirgl_write_fence;
121 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
122 ck_assert_int_eq(ret, 0);
123 if (ret)
124 return ret;
125 ret = virgl_renderer_context_create(1, strlen("test1"), "test1");
126 ck_assert_int_eq(ret, 0);
127 return ret;
128
129 }
130
testvirgl_init_single_ctx_nr(void)131 void testvirgl_init_single_ctx_nr(void)
132 {
133 testvirgl_init_single_ctx();
134 }
135
testvirgl_fini_single_ctx(void)136 void testvirgl_fini_single_ctx(void)
137 {
138 virgl_renderer_context_destroy(1);
139 virgl_renderer_cleanup(&mystruct);
140 }
141
testvirgl_flush(struct virgl_context * ctx)142 static void testvirgl_flush(struct virgl_context *ctx)
143 {
144 virgl_renderer_submit_cmd(ctx->cbuf->buf, ctx->ctx_id, ctx->cbuf->cdw);
145 ctx->cbuf->cdw = 0;
146 }
147
testvirgl_init_ctx_cmdbuf(struct virgl_context * ctx)148 int testvirgl_init_ctx_cmdbuf(struct virgl_context *ctx)
149 {
150 int ret;
151 ret = testvirgl_init_single_ctx();
152 if (ret)
153 return ret;
154
155 ctx->flush = testvirgl_flush;
156 ctx->ctx_id = 1;
157 ctx->cbuf = CALLOC_STRUCT(virgl_cmd_buf);
158 if (!ctx->cbuf) {
159 testvirgl_fini_single_ctx();
160 return ENOMEM;
161 }
162
163 ctx->cbuf->buf = CALLOC(1, VIRGL_MAX_CMDBUF_DWORDS * 4);
164 if (!ctx->cbuf->buf) {
165 FREE(ctx->cbuf);
166 testvirgl_fini_single_ctx();
167 return ENOMEM;
168 }
169 return 0;
170 }
171
testvirgl_fini_ctx_cmdbuf(struct virgl_context * ctx)172 void testvirgl_fini_ctx_cmdbuf(struct virgl_context *ctx)
173 {
174 FREE(ctx->cbuf->buf);
175 FREE(ctx->cbuf);
176 testvirgl_fini_single_ctx();
177 }
178
testvirgl_create_backed_simple_2d_res(struct virgl_resource * res,int handle,int w,int h)179 int testvirgl_create_backed_simple_2d_res(struct virgl_resource *res,
180 int handle, int w, int h)
181 {
182 struct virgl_renderer_resource_create_args args;
183 uint32_t backing_size;
184 int ret;
185
186 testvirgl_init_simple_2d_resource(&args, handle);
187 args.width = w;
188 args.height = h;
189 ret = virgl_renderer_resource_create(&args, NULL, 0);
190 ck_assert_int_eq(ret, 0);
191
192 res->handle = handle;
193 res->base.target = args.target;
194 res->base.format = args.format;
195
196 backing_size = args.width * args.height * util_format_get_blocksize(res->base.format);
197 res->iovs = malloc(sizeof(struct iovec));
198
199 res->iovs[0].iov_base = malloc(backing_size);
200 res->iovs[0].iov_len = backing_size;
201 res->niovs = 1;
202
203 virgl_renderer_resource_attach_iov(res->handle, res->iovs, res->niovs);
204 return 0;
205 }
206
testvirgl_create_backed_simple_1d_res(struct virgl_resource * res,int handle)207 int testvirgl_create_backed_simple_1d_res(struct virgl_resource *res,
208 int handle)
209 {
210 struct virgl_renderer_resource_create_args args;
211 uint32_t backing_size;
212 int ret;
213
214 testvirgl_init_simple_1d_resource(&args, handle);
215 ret = virgl_renderer_resource_create(&args, NULL, 0);
216 ck_assert_int_eq(ret, 0);
217
218 res->handle = handle;
219 res->base.target = args.target;
220 res->base.format = args.format;
221
222 backing_size = args.width * util_format_get_blocksize(res->base.format);
223 res->iovs = malloc(sizeof(struct iovec));
224
225 res->iovs[0].iov_base = malloc(backing_size);
226 res->iovs[0].iov_len = backing_size;
227 res->niovs = 1;
228
229 virgl_renderer_resource_attach_iov(res->handle, res->iovs, res->niovs);
230 return 0;
231 }
232
testvirgl_destroy_backed_res(struct virgl_resource * res)233 void testvirgl_destroy_backed_res(struct virgl_resource *res)
234 {
235 struct iovec *iovs;
236 int niovs;
237
238 virgl_renderer_resource_detach_iov(res->handle, &iovs, &niovs);
239
240 free(iovs[0].iov_base);
241 free(iovs);
242 virgl_renderer_resource_unref(res->handle);
243 }
244
testvirgl_create_backed_simple_buffer(struct virgl_resource * res,int handle,int size,int binding)245 int testvirgl_create_backed_simple_buffer(struct virgl_resource *res,
246 int handle, int size, int binding)
247 {
248 struct virgl_renderer_resource_create_args args;
249 uint32_t backing_size;
250 int ret;
251
252 testvirgl_init_simple_buffer_sized(&args, handle, size);
253 args.bind = binding;
254 ret = virgl_renderer_resource_create(&args, NULL, 0);
255 ck_assert_int_eq(ret, 0);
256
257 res->handle = handle;
258 res->base.target = args.target;
259 res->base.format = args.format;
260 res->base.bind = args.bind;
261 backing_size = args.width * args.height * util_format_get_blocksize(res->base.format);
262 res->iovs = malloc(sizeof(struct iovec));
263
264 res->iovs[0].iov_base = malloc(backing_size);
265 res->iovs[0].iov_len = backing_size;
266 res->niovs = 1;
267
268 virgl_renderer_resource_attach_iov(res->handle, res->iovs, res->niovs);
269 return 0;
270 }
271
testvirgl_create_unbacked_simple_buffer(struct virgl_resource * res,int handle,int size,int binding)272 int testvirgl_create_unbacked_simple_buffer(struct virgl_resource *res,
273 int handle, int size, int binding)
274 {
275 struct virgl_renderer_resource_create_args args;
276 int ret;
277
278 testvirgl_init_simple_buffer_sized(&args, handle, size);
279 args.bind = binding;
280 ret = virgl_renderer_resource_create(&args, NULL, 0);
281 ck_assert_int_eq(ret, 0);
282
283 res->handle = handle;
284 res->base.target = args.target;
285 res->base.format = args.format;
286 res->base.bind = args.bind;
287
288 return 0;
289 }
290
get_caps(void)291 static void *get_caps(void)
292 {
293 uint32_t max_ver, max_size;
294 void *caps;
295
296 virgl_renderer_get_cap_set(1, &max_ver, &max_size);
297 ck_assert_int_ge(max_ver, 1);
298 ck_assert_int_ne(max_size, 0);
299 ck_assert_int_ge(max_size, sizeof(struct virgl_caps_v1));
300 caps = malloc(max_size);
301
302 virgl_renderer_fill_caps(0, 0, caps);
303 return caps;
304 }
305
testvirgl_get_glsl_level_from_caps(void)306 uint32_t testvirgl_get_glsl_level_from_caps(void)
307 {
308 uint32_t glsl_level;
309 void *caps = get_caps();
310 struct virgl_caps_v1 *v1 = (struct virgl_caps_v1*) caps;
311 glsl_level = v1->glsl_level;
312
313 free(caps);
314
315 return glsl_level;
316 }
317
testvirgl_get_multisample_from_caps(void)318 unsigned testvirgl_get_multisample_from_caps(void)
319 {
320 void *caps = get_caps();
321 unsigned multisample;
322
323 struct virgl_caps_v1 *v1 = (struct virgl_caps_v1*) caps;
324 multisample = v1->bset.texture_multisample;
325
326 free(caps);
327
328 return multisample;
329 }
330