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 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 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 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 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; 98 static void testvirgl_write_fence(UNUSED void *cookie, uint32_t fence) 99 { 100 testvirgl_last_fence = fence; 101 } 102 103 uint32_t testvirgl_get_last_fence(void) 104 { 105 return testvirgl_last_fence; 106 } 107 108 void testvirgl_reset_fence(void) 109 { 110 testvirgl_last_fence = 0; 111 } 112 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 129 void testvirgl_init_single_ctx_nr(void) 130 { 131 testvirgl_init_single_ctx(); 132 } 133 134 void testvirgl_fini_single_ctx(void) 135 { 136 virgl_renderer_context_destroy(1); 137 virgl_renderer_cleanup(&mystruct); 138 } 139 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 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 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 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 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 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 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 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 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 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