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 "util/u_upload_mgr.h" 33 #include "noop_public.h" 34 35 DEBUG_GET_ONCE_BOOL_OPTION(noop, "GALLIUM_NOOP", FALSE) 36 37 void noop_init_state_functions(struct pipe_context *ctx); 38 39 struct noop_pipe_screen { 40 struct pipe_screen pscreen; 41 struct pipe_screen *oscreen; 42 }; 43 44 /* 45 * query 46 */ 47 struct noop_query { 48 unsigned query; 49 }; 50 static struct pipe_query *noop_create_query(struct pipe_context *ctx, unsigned query_type, unsigned index) 51 { 52 struct noop_query *query = CALLOC_STRUCT(noop_query); 53 54 return (struct pipe_query *)query; 55 } 56 57 static void noop_destroy_query(struct pipe_context *ctx, struct pipe_query *query) 58 { 59 FREE(query); 60 } 61 62 static boolean noop_begin_query(struct pipe_context *ctx, struct pipe_query *query) 63 { 64 return true; 65 } 66 67 static bool noop_end_query(struct pipe_context *ctx, struct pipe_query *query) 68 { 69 return true; 70 } 71 72 static boolean noop_get_query_result(struct pipe_context *ctx, 73 struct pipe_query *query, 74 boolean wait, 75 union pipe_query_result *vresult) 76 { 77 uint64_t *result = (uint64_t*)vresult; 78 79 *result = 0; 80 return TRUE; 81 } 82 83 static void 84 noop_set_active_query_state(struct pipe_context *pipe, boolean enable) 85 { 86 } 87 88 89 /* 90 * resource 91 */ 92 struct noop_resource { 93 struct pipe_resource base; 94 unsigned size; 95 char *data; 96 struct sw_displaytarget *dt; 97 }; 98 99 static struct pipe_resource *noop_resource_create(struct pipe_screen *screen, 100 const struct pipe_resource *templ) 101 { 102 struct noop_resource *nresource; 103 unsigned stride; 104 105 nresource = CALLOC_STRUCT(noop_resource); 106 if (!nresource) 107 return NULL; 108 109 stride = util_format_get_stride(templ->format, templ->width0); 110 nresource->base = *templ; 111 nresource->base.screen = screen; 112 nresource->size = stride * templ->height0 * templ->depth0; 113 nresource->data = MALLOC(nresource->size); 114 pipe_reference_init(&nresource->base.reference, 1); 115 if (nresource->data == NULL) { 116 FREE(nresource); 117 return NULL; 118 } 119 return &nresource->base; 120 } 121 122 static struct pipe_resource *noop_resource_from_handle(struct pipe_screen *screen, 123 const struct pipe_resource *templ, 124 struct winsys_handle *handle, 125 unsigned usage) 126 { 127 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 128 struct pipe_screen *oscreen = noop_screen->oscreen; 129 struct pipe_resource *result; 130 struct pipe_resource *noop_resource; 131 132 result = oscreen->resource_from_handle(oscreen, templ, handle, usage); 133 noop_resource = noop_resource_create(screen, result); 134 pipe_resource_reference(&result, NULL); 135 return noop_resource; 136 } 137 138 static boolean noop_resource_get_handle(struct pipe_screen *pscreen, 139 struct pipe_context *ctx, 140 struct pipe_resource *resource, 141 struct winsys_handle *handle, 142 unsigned usage) 143 { 144 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; 145 struct pipe_screen *screen = noop_screen->oscreen; 146 struct pipe_resource *tex; 147 bool result; 148 149 /* resource_get_handle musn't fail. Just create something and return it. */ 150 tex = screen->resource_create(screen, resource); 151 if (!tex) 152 return false; 153 154 result = screen->resource_get_handle(screen, NULL, tex, handle, usage); 155 pipe_resource_reference(&tex, NULL); 156 return result; 157 } 158 159 static void noop_resource_destroy(struct pipe_screen *screen, 160 struct pipe_resource *resource) 161 { 162 struct noop_resource *nresource = (struct noop_resource *)resource; 163 164 FREE(nresource->data); 165 FREE(resource); 166 } 167 168 169 /* 170 * transfer 171 */ 172 static void *noop_transfer_map(struct pipe_context *pipe, 173 struct pipe_resource *resource, 174 unsigned level, 175 enum pipe_transfer_usage usage, 176 const struct pipe_box *box, 177 struct pipe_transfer **ptransfer) 178 { 179 struct pipe_transfer *transfer; 180 struct noop_resource *nresource = (struct noop_resource *)resource; 181 182 transfer = CALLOC_STRUCT(pipe_transfer); 183 if (!transfer) 184 return NULL; 185 pipe_resource_reference(&transfer->resource, resource); 186 transfer->level = level; 187 transfer->usage = usage; 188 transfer->box = *box; 189 transfer->stride = 1; 190 transfer->layer_stride = 1; 191 *ptransfer = transfer; 192 193 return nresource->data; 194 } 195 196 static void noop_transfer_flush_region(struct pipe_context *pipe, 197 struct pipe_transfer *transfer, 198 const struct pipe_box *box) 199 { 200 } 201 202 static void noop_transfer_unmap(struct pipe_context *pipe, 203 struct pipe_transfer *transfer) 204 { 205 pipe_resource_reference(&transfer->resource, NULL); 206 FREE(transfer); 207 } 208 209 static void noop_buffer_subdata(struct pipe_context *pipe, 210 struct pipe_resource *resource, 211 unsigned usage, unsigned offset, 212 unsigned size, const void *data) 213 { 214 } 215 216 static void noop_texture_subdata(struct pipe_context *pipe, 217 struct pipe_resource *resource, 218 unsigned level, 219 unsigned usage, 220 const struct pipe_box *box, 221 const void *data, 222 unsigned stride, 223 unsigned layer_stride) 224 { 225 } 226 227 228 /* 229 * clear/copy 230 */ 231 static void noop_clear(struct pipe_context *ctx, unsigned buffers, 232 const union pipe_color_union *color, double depth, unsigned stencil) 233 { 234 } 235 236 static void noop_clear_render_target(struct pipe_context *ctx, 237 struct pipe_surface *dst, 238 const union pipe_color_union *color, 239 unsigned dstx, unsigned dsty, 240 unsigned width, unsigned height, 241 bool render_condition_enabled) 242 { 243 } 244 245 static void noop_clear_depth_stencil(struct pipe_context *ctx, 246 struct pipe_surface *dst, 247 unsigned clear_flags, 248 double depth, 249 unsigned stencil, 250 unsigned dstx, unsigned dsty, 251 unsigned width, unsigned height, 252 bool render_condition_enabled) 253 { 254 } 255 256 static void noop_resource_copy_region(struct pipe_context *ctx, 257 struct pipe_resource *dst, 258 unsigned dst_level, 259 unsigned dstx, unsigned dsty, unsigned dstz, 260 struct pipe_resource *src, 261 unsigned src_level, 262 const struct pipe_box *src_box) 263 { 264 } 265 266 267 static void noop_blit(struct pipe_context *ctx, 268 const struct pipe_blit_info *info) 269 { 270 } 271 272 273 static void 274 noop_flush_resource(struct pipe_context *ctx, 275 struct pipe_resource *resource) 276 { 277 } 278 279 280 /* 281 * context 282 */ 283 static void noop_flush(struct pipe_context *ctx, 284 struct pipe_fence_handle **fence, 285 unsigned flags) 286 { 287 if (fence) 288 *fence = NULL; 289 } 290 291 static void noop_destroy_context(struct pipe_context *ctx) 292 { 293 if (ctx->stream_uploader) 294 u_upload_destroy(ctx->stream_uploader); 295 296 FREE(ctx); 297 } 298 299 static boolean noop_generate_mipmap(struct pipe_context *ctx, 300 struct pipe_resource *resource, 301 enum pipe_format format, 302 unsigned base_level, 303 unsigned last_level, 304 unsigned first_layer, 305 unsigned last_layer) 306 { 307 return true; 308 } 309 310 static struct pipe_context *noop_create_context(struct pipe_screen *screen, 311 void *priv, unsigned flags) 312 { 313 struct pipe_context *ctx = CALLOC_STRUCT(pipe_context); 314 315 if (!ctx) 316 return NULL; 317 318 ctx->screen = screen; 319 ctx->priv = priv; 320 321 ctx->stream_uploader = u_upload_create_default(ctx); 322 if (!ctx->stream_uploader) { 323 FREE(ctx); 324 return NULL; 325 } 326 ctx->const_uploader = ctx->stream_uploader; 327 328 ctx->destroy = noop_destroy_context; 329 ctx->flush = noop_flush; 330 ctx->clear = noop_clear; 331 ctx->clear_render_target = noop_clear_render_target; 332 ctx->clear_depth_stencil = noop_clear_depth_stencil; 333 ctx->resource_copy_region = noop_resource_copy_region; 334 ctx->generate_mipmap = noop_generate_mipmap; 335 ctx->blit = noop_blit; 336 ctx->flush_resource = noop_flush_resource; 337 ctx->create_query = noop_create_query; 338 ctx->destroy_query = noop_destroy_query; 339 ctx->begin_query = noop_begin_query; 340 ctx->end_query = noop_end_query; 341 ctx->get_query_result = noop_get_query_result; 342 ctx->set_active_query_state = noop_set_active_query_state; 343 ctx->transfer_map = noop_transfer_map; 344 ctx->transfer_flush_region = noop_transfer_flush_region; 345 ctx->transfer_unmap = noop_transfer_unmap; 346 ctx->buffer_subdata = noop_buffer_subdata; 347 ctx->texture_subdata = noop_texture_subdata; 348 noop_init_state_functions(ctx); 349 350 return ctx; 351 } 352 353 354 /* 355 * pipe_screen 356 */ 357 static void noop_flush_frontbuffer(struct pipe_screen *_screen, 358 struct pipe_resource *resource, 359 unsigned level, unsigned layer, 360 void *context_private, struct pipe_box *box) 361 { 362 } 363 364 static const char *noop_get_vendor(struct pipe_screen* pscreen) 365 { 366 return "X.Org"; 367 } 368 369 static const char *noop_get_device_vendor(struct pipe_screen* pscreen) 370 { 371 return "NONE"; 372 } 373 374 static const char *noop_get_name(struct pipe_screen* pscreen) 375 { 376 return "NOOP"; 377 } 378 379 static int noop_get_param(struct pipe_screen* pscreen, enum pipe_cap param) 380 { 381 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 382 383 return screen->get_param(screen, param); 384 } 385 386 static float noop_get_paramf(struct pipe_screen* pscreen, 387 enum pipe_capf param) 388 { 389 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 390 391 return screen->get_paramf(screen, param); 392 } 393 394 static int noop_get_shader_param(struct pipe_screen* pscreen, 395 enum pipe_shader_type shader, 396 enum pipe_shader_cap param) 397 { 398 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 399 400 return screen->get_shader_param(screen, shader, param); 401 } 402 403 static int noop_get_compute_param(struct pipe_screen *pscreen, 404 enum pipe_shader_ir ir_type, 405 enum pipe_compute_cap param, 406 void *ret) 407 { 408 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 409 410 return screen->get_compute_param(screen, ir_type, param, ret); 411 } 412 413 static boolean noop_is_format_supported(struct pipe_screen* pscreen, 414 enum pipe_format format, 415 enum pipe_texture_target target, 416 unsigned sample_count, 417 unsigned usage) 418 { 419 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 420 421 return screen->is_format_supported(screen, format, target, sample_count, usage); 422 } 423 424 static uint64_t noop_get_timestamp(struct pipe_screen *pscreen) 425 { 426 return 0; 427 } 428 429 static void noop_destroy_screen(struct pipe_screen *screen) 430 { 431 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 432 struct pipe_screen *oscreen = noop_screen->oscreen; 433 434 oscreen->destroy(oscreen); 435 FREE(screen); 436 } 437 438 static void noop_fence_reference(struct pipe_screen *screen, 439 struct pipe_fence_handle **ptr, 440 struct pipe_fence_handle *fence) 441 { 442 } 443 444 static boolean noop_fence_finish(struct pipe_screen *screen, 445 struct pipe_context *ctx, 446 struct pipe_fence_handle *fence, 447 uint64_t timeout) 448 { 449 return true; 450 } 451 452 static void noop_query_memory_info(struct pipe_screen *pscreen, 453 struct pipe_memory_info *info) 454 { 455 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; 456 struct pipe_screen *screen = noop_screen->oscreen; 457 458 screen->query_memory_info(screen, info); 459 } 460 461 struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen) 462 { 463 struct noop_pipe_screen *noop_screen; 464 struct pipe_screen *screen; 465 466 if (!debug_get_option_noop()) { 467 return oscreen; 468 } 469 470 noop_screen = CALLOC_STRUCT(noop_pipe_screen); 471 if (!noop_screen) { 472 return NULL; 473 } 474 noop_screen->oscreen = oscreen; 475 screen = &noop_screen->pscreen; 476 477 screen->destroy = noop_destroy_screen; 478 screen->get_name = noop_get_name; 479 screen->get_vendor = noop_get_vendor; 480 screen->get_device_vendor = noop_get_device_vendor; 481 screen->get_param = noop_get_param; 482 screen->get_shader_param = noop_get_shader_param; 483 screen->get_compute_param = noop_get_compute_param; 484 screen->get_paramf = noop_get_paramf; 485 screen->is_format_supported = noop_is_format_supported; 486 screen->context_create = noop_create_context; 487 screen->resource_create = noop_resource_create; 488 screen->resource_from_handle = noop_resource_from_handle; 489 screen->resource_get_handle = noop_resource_get_handle; 490 screen->resource_destroy = noop_resource_destroy; 491 screen->flush_frontbuffer = noop_flush_frontbuffer; 492 screen->get_timestamp = noop_get_timestamp; 493 screen->fence_reference = noop_fence_reference; 494 screen->fence_finish = noop_fence_finish; 495 screen->query_memory_info = noop_query_memory_info; 496 497 return screen; 498 } 499