1 /* 2 * Copyright 2010 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 #include <stdio.h> 24 #include <errno.h> 25 #include "pipe/p_defines.h" 26 #include "pipe/p_state.h" 27 #include "pipe/p_context.h" 28 #include "pipe/p_screen.h" 29 #include "util/u_memory.h" 30 #include "util/u_inlines.h" 31 #include "util/u_format.h" 32 #include "noop_public.h" 33 34 DEBUG_GET_ONCE_BOOL_OPTION(noop, "GALLIUM_NOOP", FALSE) 35 36 void noop_init_state_functions(struct pipe_context *ctx); 37 38 struct noop_pipe_screen { 39 struct pipe_screen pscreen; 40 struct pipe_screen *oscreen; 41 }; 42 43 /* 44 * query 45 */ 46 struct noop_query { 47 unsigned query; 48 }; 49 static struct pipe_query *noop_create_query(struct pipe_context *ctx, unsigned query_type, unsigned index) 50 { 51 struct noop_query *query = CALLOC_STRUCT(noop_query); 52 53 return (struct pipe_query *)query; 54 } 55 56 static void noop_destroy_query(struct pipe_context *ctx, struct pipe_query *query) 57 { 58 FREE(query); 59 } 60 61 static boolean noop_begin_query(struct pipe_context *ctx, struct pipe_query *query) 62 { 63 return true; 64 } 65 66 static bool noop_end_query(struct pipe_context *ctx, struct pipe_query *query) 67 { 68 return true; 69 } 70 71 static boolean noop_get_query_result(struct pipe_context *ctx, 72 struct pipe_query *query, 73 boolean wait, 74 union pipe_query_result *vresult) 75 { 76 uint64_t *result = (uint64_t*)vresult; 77 78 *result = 0; 79 return TRUE; 80 } 81 82 static void 83 noop_set_active_query_state(struct pipe_context *pipe, boolean enable) 84 { 85 } 86 87 88 /* 89 * resource 90 */ 91 struct noop_resource { 92 struct pipe_resource base; 93 unsigned size; 94 char *data; 95 struct sw_displaytarget *dt; 96 }; 97 98 static struct pipe_resource *noop_resource_create(struct pipe_screen *screen, 99 const struct pipe_resource *templ) 100 { 101 struct noop_resource *nresource; 102 unsigned stride; 103 104 nresource = CALLOC_STRUCT(noop_resource); 105 if (!nresource) 106 return NULL; 107 108 stride = util_format_get_stride(templ->format, templ->width0); 109 nresource->base = *templ; 110 nresource->base.screen = screen; 111 nresource->size = stride * templ->height0 * templ->depth0; 112 nresource->data = MALLOC(nresource->size); 113 pipe_reference_init(&nresource->base.reference, 1); 114 if (nresource->data == NULL) { 115 FREE(nresource); 116 return NULL; 117 } 118 return &nresource->base; 119 } 120 121 static struct pipe_resource *noop_resource_from_handle(struct pipe_screen *screen, 122 const struct pipe_resource *templ, 123 struct winsys_handle *handle, 124 unsigned usage) 125 { 126 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 127 struct pipe_screen *oscreen = noop_screen->oscreen; 128 struct pipe_resource *result; 129 struct pipe_resource *noop_resource; 130 131 result = oscreen->resource_from_handle(oscreen, templ, handle, usage); 132 noop_resource = noop_resource_create(screen, result); 133 pipe_resource_reference(&result, NULL); 134 return noop_resource; 135 } 136 137 static boolean noop_resource_get_handle(struct pipe_screen *pscreen, 138 struct pipe_context *ctx, 139 struct pipe_resource *resource, 140 struct winsys_handle *handle, 141 unsigned usage) 142 { 143 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; 144 struct pipe_screen *screen = noop_screen->oscreen; 145 struct pipe_resource *tex; 146 bool result; 147 148 /* resource_get_handle musn't fail. Just create something and return it. */ 149 tex = screen->resource_create(screen, resource); 150 if (!tex) 151 return false; 152 153 result = screen->resource_get_handle(screen, NULL, tex, handle, usage); 154 pipe_resource_reference(&tex, NULL); 155 return result; 156 } 157 158 static void noop_resource_destroy(struct pipe_screen *screen, 159 struct pipe_resource *resource) 160 { 161 struct noop_resource *nresource = (struct noop_resource *)resource; 162 163 FREE(nresource->data); 164 FREE(resource); 165 } 166 167 168 /* 169 * transfer 170 */ 171 static void *noop_transfer_map(struct pipe_context *pipe, 172 struct pipe_resource *resource, 173 unsigned level, 174 enum pipe_transfer_usage usage, 175 const struct pipe_box *box, 176 struct pipe_transfer **ptransfer) 177 { 178 struct pipe_transfer *transfer; 179 struct noop_resource *nresource = (struct noop_resource *)resource; 180 181 transfer = CALLOC_STRUCT(pipe_transfer); 182 if (!transfer) 183 return NULL; 184 pipe_resource_reference(&transfer->resource, resource); 185 transfer->level = level; 186 transfer->usage = usage; 187 transfer->box = *box; 188 transfer->stride = 1; 189 transfer->layer_stride = 1; 190 *ptransfer = transfer; 191 192 return nresource->data; 193 } 194 195 static void noop_transfer_flush_region(struct pipe_context *pipe, 196 struct pipe_transfer *transfer, 197 const struct pipe_box *box) 198 { 199 } 200 201 static void noop_transfer_unmap(struct pipe_context *pipe, 202 struct pipe_transfer *transfer) 203 { 204 pipe_resource_reference(&transfer->resource, NULL); 205 FREE(transfer); 206 } 207 208 static void noop_buffer_subdata(struct pipe_context *pipe, 209 struct pipe_resource *resource, 210 unsigned usage, unsigned offset, 211 unsigned size, const void *data) 212 { 213 } 214 215 static void noop_texture_subdata(struct pipe_context *pipe, 216 struct pipe_resource *resource, 217 unsigned level, 218 unsigned usage, 219 const struct pipe_box *box, 220 const void *data, 221 unsigned stride, 222 unsigned layer_stride) 223 { 224 } 225 226 227 /* 228 * clear/copy 229 */ 230 static void noop_clear(struct pipe_context *ctx, unsigned buffers, 231 const union pipe_color_union *color, double depth, unsigned stencil) 232 { 233 } 234 235 static void noop_clear_render_target(struct pipe_context *ctx, 236 struct pipe_surface *dst, 237 const union pipe_color_union *color, 238 unsigned dstx, unsigned dsty, 239 unsigned width, unsigned height, 240 bool render_condition_enabled) 241 { 242 } 243 244 static void noop_clear_depth_stencil(struct pipe_context *ctx, 245 struct pipe_surface *dst, 246 unsigned clear_flags, 247 double depth, 248 unsigned stencil, 249 unsigned dstx, unsigned dsty, 250 unsigned width, unsigned height, 251 bool render_condition_enabled) 252 { 253 } 254 255 static void noop_resource_copy_region(struct pipe_context *ctx, 256 struct pipe_resource *dst, 257 unsigned dst_level, 258 unsigned dstx, unsigned dsty, unsigned dstz, 259 struct pipe_resource *src, 260 unsigned src_level, 261 const struct pipe_box *src_box) 262 { 263 } 264 265 266 static void noop_blit(struct pipe_context *ctx, 267 const struct pipe_blit_info *info) 268 { 269 } 270 271 272 static void 273 noop_flush_resource(struct pipe_context *ctx, 274 struct pipe_resource *resource) 275 { 276 } 277 278 279 /* 280 * context 281 */ 282 static void noop_flush(struct pipe_context *ctx, 283 struct pipe_fence_handle **fence, 284 unsigned flags) 285 { 286 if (fence) 287 *fence = NULL; 288 } 289 290 static void noop_destroy_context(struct pipe_context *ctx) 291 { 292 FREE(ctx); 293 } 294 295 static boolean noop_generate_mipmap(struct pipe_context *ctx, 296 struct pipe_resource *resource, 297 enum pipe_format format, 298 unsigned base_level, 299 unsigned last_level, 300 unsigned first_layer, 301 unsigned last_layer) 302 { 303 return true; 304 } 305 306 static struct pipe_context *noop_create_context(struct pipe_screen *screen, 307 void *priv, unsigned flags) 308 { 309 struct pipe_context *ctx = CALLOC_STRUCT(pipe_context); 310 311 if (!ctx) 312 return NULL; 313 ctx->screen = screen; 314 ctx->priv = priv; 315 ctx->destroy = noop_destroy_context; 316 ctx->flush = noop_flush; 317 ctx->clear = noop_clear; 318 ctx->clear_render_target = noop_clear_render_target; 319 ctx->clear_depth_stencil = noop_clear_depth_stencil; 320 ctx->resource_copy_region = noop_resource_copy_region; 321 ctx->generate_mipmap = noop_generate_mipmap; 322 ctx->blit = noop_blit; 323 ctx->flush_resource = noop_flush_resource; 324 ctx->create_query = noop_create_query; 325 ctx->destroy_query = noop_destroy_query; 326 ctx->begin_query = noop_begin_query; 327 ctx->end_query = noop_end_query; 328 ctx->get_query_result = noop_get_query_result; 329 ctx->set_active_query_state = noop_set_active_query_state; 330 ctx->transfer_map = noop_transfer_map; 331 ctx->transfer_flush_region = noop_transfer_flush_region; 332 ctx->transfer_unmap = noop_transfer_unmap; 333 ctx->buffer_subdata = noop_buffer_subdata; 334 ctx->texture_subdata = noop_texture_subdata; 335 noop_init_state_functions(ctx); 336 337 return ctx; 338 } 339 340 341 /* 342 * pipe_screen 343 */ 344 static void noop_flush_frontbuffer(struct pipe_screen *_screen, 345 struct pipe_resource *resource, 346 unsigned level, unsigned layer, 347 void *context_private, struct pipe_box *box) 348 { 349 } 350 351 static const char *noop_get_vendor(struct pipe_screen* pscreen) 352 { 353 return "X.Org"; 354 } 355 356 static const char *noop_get_device_vendor(struct pipe_screen* pscreen) 357 { 358 return "NONE"; 359 } 360 361 static const char *noop_get_name(struct pipe_screen* pscreen) 362 { 363 return "NOOP"; 364 } 365 366 static int noop_get_param(struct pipe_screen* pscreen, enum pipe_cap param) 367 { 368 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 369 370 return screen->get_param(screen, param); 371 } 372 373 static float noop_get_paramf(struct pipe_screen* pscreen, 374 enum pipe_capf param) 375 { 376 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 377 378 return screen->get_paramf(screen, param); 379 } 380 381 static int noop_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param) 382 { 383 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 384 385 return screen->get_shader_param(screen, shader, param); 386 } 387 388 static int noop_get_compute_param(struct pipe_screen *pscreen, 389 enum pipe_shader_ir ir_type, 390 enum pipe_compute_cap param, 391 void *ret) 392 { 393 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 394 395 return screen->get_compute_param(screen, ir_type, param, ret); 396 } 397 398 static boolean noop_is_format_supported(struct pipe_screen* pscreen, 399 enum pipe_format format, 400 enum pipe_texture_target target, 401 unsigned sample_count, 402 unsigned usage) 403 { 404 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 405 406 return screen->is_format_supported(screen, format, target, sample_count, usage); 407 } 408 409 static uint64_t noop_get_timestamp(struct pipe_screen *pscreen) 410 { 411 return 0; 412 } 413 414 static void noop_destroy_screen(struct pipe_screen *screen) 415 { 416 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 417 struct pipe_screen *oscreen = noop_screen->oscreen; 418 419 oscreen->destroy(oscreen); 420 FREE(screen); 421 } 422 423 static void noop_fence_reference(struct pipe_screen *screen, 424 struct pipe_fence_handle **ptr, 425 struct pipe_fence_handle *fence) 426 { 427 } 428 429 static boolean noop_fence_finish(struct pipe_screen *screen, 430 struct pipe_context *ctx, 431 struct pipe_fence_handle *fence, 432 uint64_t timeout) 433 { 434 return true; 435 } 436 437 static void noop_query_memory_info(struct pipe_screen *pscreen, 438 struct pipe_memory_info *info) 439 { 440 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; 441 struct pipe_screen *screen = noop_screen->oscreen; 442 443 screen->query_memory_info(screen, info); 444 } 445 446 struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen) 447 { 448 struct noop_pipe_screen *noop_screen; 449 struct pipe_screen *screen; 450 451 if (!debug_get_option_noop()) { 452 return oscreen; 453 } 454 455 noop_screen = CALLOC_STRUCT(noop_pipe_screen); 456 if (!noop_screen) { 457 return NULL; 458 } 459 noop_screen->oscreen = oscreen; 460 screen = &noop_screen->pscreen; 461 462 screen->destroy = noop_destroy_screen; 463 screen->get_name = noop_get_name; 464 screen->get_vendor = noop_get_vendor; 465 screen->get_device_vendor = noop_get_device_vendor; 466 screen->get_param = noop_get_param; 467 screen->get_shader_param = noop_get_shader_param; 468 screen->get_compute_param = noop_get_compute_param; 469 screen->get_paramf = noop_get_paramf; 470 screen->is_format_supported = noop_is_format_supported; 471 screen->context_create = noop_create_context; 472 screen->resource_create = noop_resource_create; 473 screen->resource_from_handle = noop_resource_from_handle; 474 screen->resource_get_handle = noop_resource_get_handle; 475 screen->resource_destroy = noop_resource_destroy; 476 screen->flush_frontbuffer = noop_flush_frontbuffer; 477 screen->get_timestamp = noop_get_timestamp; 478 screen->fence_reference = noop_fence_reference; 479 screen->fence_finish = noop_fence_finish; 480 screen->query_memory_info = noop_query_memory_info; 481 482 return screen; 483 } 484