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