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
testvirgl_init_simple_1d_resource(struct virgl_renderer_resource_create_args * res,int handle)38 void testvirgl_init_simple_1d_resource(struct virgl_renderer_resource_create_args *res, int handle)
39 {
40 res->handle = handle;
41 res->target = PIPE_TEXTURE_1D;
42 res->format = PIPE_FORMAT_B8G8R8X8_UNORM;
43 res->width = 50;
44 res->height = 1;
45 res->depth = 1;
46 res->array_size = 1;
47 res->last_level = 0;
48 res->nr_samples = 0;
49 res->bind = PIPE_BIND_SAMPLER_VIEW;
50 res->flags = 0;
51 }
52
testvirgl_init_simple_buffer_sized(struct virgl_renderer_resource_create_args * res,int handle,int width)53 void testvirgl_init_simple_buffer_sized(struct virgl_renderer_resource_create_args *res, int handle, int width)
54 {
55 res->handle = handle;
56 res->target = PIPE_BUFFER;
57 res->format = PIPE_FORMAT_R8_UNORM;
58 res->width = width;
59 res->height = 1;
60 res->depth = 1;
61 res->array_size = 1;
62 res->last_level = 0;
63 res->nr_samples = 0;
64 res->bind = 0;
65 res->flags = 0;
66 }
67
testvirgl_init_simple_buffer(struct virgl_renderer_resource_create_args * res,int handle)68 void testvirgl_init_simple_buffer(struct virgl_renderer_resource_create_args *res, int handle)
69 {
70 testvirgl_init_simple_buffer_sized(res, handle, 50);
71 }
72
testvirgl_init_simple_2d_resource(struct virgl_renderer_resource_create_args * res,int handle)73 void testvirgl_init_simple_2d_resource(struct virgl_renderer_resource_create_args *res, int handle)
74 {
75 res->handle = handle;
76 res->target = PIPE_TEXTURE_2D;
77 res->format = PIPE_FORMAT_B8G8R8X8_UNORM;
78 res->width = 50;
79 res->height = 50;
80 res->depth = 1;
81 res->array_size = 1;
82 res->last_level = 0;
83 res->nr_samples = 0;
84 res->bind = PIPE_BIND_SAMPLER_VIEW;
85 res->flags = 0;
86 }
87
88
89 struct myinfo_struct {
90 uint32_t test;
91 };
92
93 static struct myinfo_struct mystruct;
94
95 static struct virgl_renderer_callbacks test_cbs;
96
97 static uint32_t testvirgl_last_fence;
testvirgl_write_fence(UNUSED void * cookie,uint32_t fence)98 static void testvirgl_write_fence(UNUSED void *cookie, uint32_t fence)
99 {
100 testvirgl_last_fence = fence;
101 }
102
testvirgl_get_last_fence(void)103 uint32_t testvirgl_get_last_fence(void)
104 {
105 return testvirgl_last_fence;
106 }
107
testvirgl_reset_fence(void)108 void testvirgl_reset_fence(void)
109 {
110 testvirgl_last_fence = 0;
111 }
112
testvirgl_init_single_ctx(void)113 int testvirgl_init_single_ctx(void)
114 {
115 int ret;
116
117 test_cbs.version = 1;
118 test_cbs.write_fence = testvirgl_write_fence;
119 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
120 ck_assert_int_eq(ret, 0);
121 if (ret)
122 return ret;
123 ret = virgl_renderer_context_create(1, strlen("test1"), "test1");
124 ck_assert_int_eq(ret, 0);
125 return ret;
126
127 }
128
testvirgl_init_single_ctx_nr(void)129 void testvirgl_init_single_ctx_nr(void)
130 {
131 testvirgl_init_single_ctx();
132 }
133
testvirgl_fini_single_ctx(void)134 void testvirgl_fini_single_ctx(void)
135 {
136 virgl_renderer_context_destroy(1);
137 virgl_renderer_cleanup(&mystruct);
138 }
139
testvirgl_flush(struct virgl_context * ctx)140 static void testvirgl_flush(struct virgl_context *ctx)
141 {
142 virgl_renderer_submit_cmd(ctx->cbuf->buf, ctx->ctx_id, ctx->cbuf->cdw);
143 ctx->cbuf->cdw = 0;
144 }
145
testvirgl_init_ctx_cmdbuf(struct virgl_context * ctx)146 int testvirgl_init_ctx_cmdbuf(struct virgl_context *ctx)
147 {
148 int ret;
149 ret = testvirgl_init_single_ctx();
150 if (ret)
151 return ret;
152
153 ctx->flush = testvirgl_flush;
154 ctx->ctx_id = 1;
155 ctx->cbuf = CALLOC_STRUCT(virgl_cmd_buf);
156 if (!ctx->cbuf) {
157 testvirgl_fini_single_ctx();
158 return ENOMEM;
159 }
160
161 ctx->cbuf->buf = CALLOC(1, VIRGL_MAX_CMDBUF_DWORDS * 4);
162 if (!ctx->cbuf->buf) {
163 FREE(ctx->cbuf);
164 testvirgl_fini_single_ctx();
165 return ENOMEM;
166 }
167 return 0;
168 }
169
testvirgl_fini_ctx_cmdbuf(struct virgl_context * ctx)170 void testvirgl_fini_ctx_cmdbuf(struct virgl_context *ctx)
171 {
172 FREE(ctx->cbuf->buf);
173 FREE(ctx->cbuf);
174 testvirgl_fini_single_ctx();
175 }
176
testvirgl_create_backed_simple_2d_res(struct virgl_resource * res,int handle,int w,int h)177 int testvirgl_create_backed_simple_2d_res(struct virgl_resource *res,
178 int handle, int w, int h)
179 {
180 struct virgl_renderer_resource_create_args args;
181 uint32_t backing_size;
182 int ret;
183
184 testvirgl_init_simple_2d_resource(&args, handle);
185 args.width = w;
186 args.height = h;
187 ret = virgl_renderer_resource_create(&args, NULL, 0);
188 ck_assert_int_eq(ret, 0);
189
190 res->handle = handle;
191 res->base.target = args.target;
192 res->base.format = args.format;
193
194 backing_size = args.width * args.height * util_format_get_blocksize(res->base.format);
195 res->iovs = malloc(sizeof(struct iovec));
196
197 res->iovs[0].iov_base = malloc(backing_size);
198 res->iovs[0].iov_len = backing_size;
199 res->niovs = 1;
200
201 virgl_renderer_resource_attach_iov(res->handle, res->iovs, res->niovs);
202 return 0;
203 }
204
testvirgl_create_backed_simple_1d_res(struct virgl_resource * res,int handle)205 int testvirgl_create_backed_simple_1d_res(struct virgl_resource *res,
206 int handle)
207 {
208 struct virgl_renderer_resource_create_args args;
209 uint32_t backing_size;
210 int ret;
211
212 testvirgl_init_simple_1d_resource(&args, handle);
213 ret = virgl_renderer_resource_create(&args, NULL, 0);
214 ck_assert_int_eq(ret, 0);
215
216 res->handle = handle;
217 res->base.target = args.target;
218 res->base.format = args.format;
219
220 backing_size = args.width * util_format_get_blocksize(res->base.format);
221 res->iovs = malloc(sizeof(struct iovec));
222
223 res->iovs[0].iov_base = malloc(backing_size);
224 res->iovs[0].iov_len = backing_size;
225 res->niovs = 1;
226
227 virgl_renderer_resource_attach_iov(res->handle, res->iovs, res->niovs);
228 return 0;
229 }
230
testvirgl_destroy_backed_res(struct virgl_resource * res)231 void testvirgl_destroy_backed_res(struct virgl_resource *res)
232 {
233 struct iovec *iovs;
234 int niovs;
235
236 virgl_renderer_resource_detach_iov(res->handle, &iovs, &niovs);
237
238 free(iovs[0].iov_base);
239 free(iovs);
240 virgl_renderer_resource_unref(res->handle);
241 }
242
testvirgl_create_backed_simple_buffer(struct virgl_resource * res,int handle,int size,int binding)243 int testvirgl_create_backed_simple_buffer(struct virgl_resource *res,
244 int handle, int size, int binding)
245 {
246 struct virgl_renderer_resource_create_args args;
247 uint32_t backing_size;
248 int ret;
249
250 testvirgl_init_simple_buffer_sized(&args, handle, size);
251 args.bind = binding;
252 ret = virgl_renderer_resource_create(&args, NULL, 0);
253 ck_assert_int_eq(ret, 0);
254
255 res->handle = handle;
256 res->base.target = args.target;
257 res->base.format = args.format;
258 res->base.bind = args.bind;
259 backing_size = args.width * args.height * util_format_get_blocksize(res->base.format);
260 res->iovs = malloc(sizeof(struct iovec));
261
262 res->iovs[0].iov_base = malloc(backing_size);
263 res->iovs[0].iov_len = backing_size;
264 res->niovs = 1;
265
266 virgl_renderer_resource_attach_iov(res->handle, res->iovs, res->niovs);
267 return 0;
268 }
269
get_caps(void)270 static void *get_caps(void)
271 {
272 uint32_t max_ver, max_size;
273 void *caps;
274
275 virgl_renderer_get_cap_set(1, &max_ver, &max_size);
276 ck_assert_int_ge(max_ver, 1);
277 ck_assert_int_ne(max_size, 0);
278 ck_assert_int_ge(max_size, sizeof(struct virgl_caps_v1));
279 caps = malloc(max_size);
280
281 virgl_renderer_fill_caps(0, 0, caps);
282 return caps;
283 }
284
testvirgl_get_glsl_level_from_caps(void)285 uint32_t testvirgl_get_glsl_level_from_caps(void)
286 {
287 uint32_t glsl_level;
288 void *caps = get_caps();
289 struct virgl_caps_v1 *v1 = (struct virgl_caps_v1*) caps;
290 glsl_level = v1->glsl_level;
291
292 free(caps);
293
294 return glsl_level;
295 }
296
testvirgl_get_multisample_from_caps(void)297 unsigned testvirgl_get_multisample_from_caps(void)
298 {
299 void *caps = get_caps();
300 unsigned multisample;
301
302 struct virgl_caps_v1 *v1 = (struct virgl_caps_v1*) caps;
303 multisample = v1->bset.texture_multisample;
304
305 free(caps);
306
307 return multisample;
308 }
309