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) 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 void noop_begin_query(struct pipe_context *ctx, struct pipe_query *query) 62 { 63 } 64 65 static void noop_end_query(struct pipe_context *ctx, struct pipe_query *query) 66 { 67 } 68 69 static boolean noop_get_query_result(struct pipe_context *ctx, 70 struct pipe_query *query, 71 boolean wait, 72 union pipe_query_result *vresult) 73 { 74 uint64_t *result = (uint64_t*)vresult; 75 76 *result = 0; 77 return TRUE; 78 } 79 80 81 /* 82 * resource 83 */ 84 struct noop_resource { 85 struct pipe_resource base; 86 unsigned size; 87 char *data; 88 struct sw_displaytarget *dt; 89 }; 90 91 static struct pipe_resource *noop_resource_create(struct pipe_screen *screen, 92 const struct pipe_resource *templ) 93 { 94 struct noop_resource *nresource; 95 unsigned stride; 96 97 nresource = CALLOC_STRUCT(noop_resource); 98 if (nresource == NULL) 99 return NULL; 100 101 stride = util_format_get_stride(templ->format, templ->width0); 102 nresource->base = *templ; 103 nresource->base.screen = screen; 104 nresource->size = stride * templ->height0 * templ->depth0; 105 nresource->data = MALLOC(nresource->size); 106 pipe_reference_init(&nresource->base.reference, 1); 107 if (nresource->data == NULL) { 108 FREE(nresource); 109 return NULL; 110 } 111 return &nresource->base; 112 } 113 114 static struct pipe_resource *noop_resource_from_handle(struct pipe_screen *screen, 115 const struct pipe_resource *templ, 116 struct winsys_handle *handle) 117 { 118 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 119 struct pipe_screen *oscreen = noop_screen->oscreen; 120 struct pipe_resource *result; 121 struct pipe_resource *noop_resource; 122 123 result = oscreen->resource_from_handle(oscreen, templ, handle); 124 noop_resource = noop_resource_create(screen, result); 125 pipe_resource_reference(&result, NULL); 126 return noop_resource; 127 } 128 129 static boolean noop_resource_get_handle(struct pipe_screen *screen, 130 struct pipe_resource *resource, 131 struct winsys_handle *handle) 132 { 133 return FALSE; 134 } 135 136 static void noop_resource_destroy(struct pipe_screen *screen, 137 struct pipe_resource *resource) 138 { 139 struct noop_resource *nresource = (struct noop_resource *)resource; 140 141 FREE(nresource->data); 142 FREE(resource); 143 } 144 145 146 /* 147 * transfer 148 */ 149 static struct pipe_transfer *noop_get_transfer(struct pipe_context *context, 150 struct pipe_resource *resource, 151 unsigned level, 152 enum pipe_transfer_usage usage, 153 const struct pipe_box *box) 154 { 155 struct pipe_transfer *transfer; 156 157 transfer = CALLOC_STRUCT(pipe_transfer); 158 if (transfer == NULL) 159 return NULL; 160 pipe_resource_reference(&transfer->resource, resource); 161 transfer->level = level; 162 transfer->usage = usage; 163 transfer->box = *box; 164 transfer->stride = 1; 165 transfer->layer_stride = 1; 166 return transfer; 167 } 168 169 static void *noop_transfer_map(struct pipe_context *pipe, 170 struct pipe_transfer *transfer) 171 { 172 struct noop_resource *nresource = (struct noop_resource *)transfer->resource; 173 174 return nresource->data; 175 } 176 177 static void noop_transfer_flush_region(struct pipe_context *pipe, 178 struct pipe_transfer *transfer, 179 const struct pipe_box *box) 180 { 181 } 182 183 static void noop_transfer_unmap(struct pipe_context *pipe, 184 struct pipe_transfer *transfer) 185 { 186 } 187 188 static void noop_transfer_destroy(struct pipe_context *pipe, 189 struct pipe_transfer *transfer) 190 { 191 pipe_resource_reference(&transfer->resource, NULL); 192 FREE(transfer); 193 } 194 195 static void noop_transfer_inline_write(struct pipe_context *pipe, 196 struct pipe_resource *resource, 197 unsigned level, 198 unsigned usage, 199 const struct pipe_box *box, 200 const void *data, 201 unsigned stride, 202 unsigned layer_stride) 203 { 204 } 205 206 207 /* 208 * clear/copy 209 */ 210 static void noop_clear(struct pipe_context *ctx, unsigned buffers, 211 const union pipe_color_union *color, double depth, unsigned stencil) 212 { 213 } 214 215 static void noop_clear_render_target(struct pipe_context *ctx, 216 struct pipe_surface *dst, 217 const union pipe_color_union *color, 218 unsigned dstx, unsigned dsty, 219 unsigned width, unsigned height) 220 { 221 } 222 223 static void noop_clear_depth_stencil(struct pipe_context *ctx, 224 struct pipe_surface *dst, 225 unsigned clear_flags, 226 double depth, 227 unsigned stencil, 228 unsigned dstx, unsigned dsty, 229 unsigned width, unsigned height) 230 { 231 } 232 233 static void noop_resource_copy_region(struct pipe_context *ctx, 234 struct pipe_resource *dst, 235 unsigned dst_level, 236 unsigned dstx, unsigned dsty, unsigned dstz, 237 struct pipe_resource *src, 238 unsigned src_level, 239 const struct pipe_box *src_box) 240 { 241 } 242 243 244 /* 245 * context 246 */ 247 static void noop_flush(struct pipe_context *ctx, 248 struct pipe_fence_handle **fence) 249 { 250 } 251 252 static void noop_destroy_context(struct pipe_context *ctx) 253 { 254 FREE(ctx); 255 } 256 257 static struct pipe_context *noop_create_context(struct pipe_screen *screen, void *priv) 258 { 259 struct pipe_context *ctx = CALLOC_STRUCT(pipe_context); 260 261 if (ctx == NULL) 262 return NULL; 263 ctx->screen = screen; 264 ctx->priv = priv; 265 ctx->destroy = noop_destroy_context; 266 ctx->flush = noop_flush; 267 ctx->clear = noop_clear; 268 ctx->clear_render_target = noop_clear_render_target; 269 ctx->clear_depth_stencil = noop_clear_depth_stencil; 270 ctx->resource_copy_region = noop_resource_copy_region; 271 ctx->create_query = noop_create_query; 272 ctx->destroy_query = noop_destroy_query; 273 ctx->begin_query = noop_begin_query; 274 ctx->end_query = noop_end_query; 275 ctx->get_query_result = noop_get_query_result; 276 ctx->get_transfer = noop_get_transfer; 277 ctx->transfer_map = noop_transfer_map; 278 ctx->transfer_flush_region = noop_transfer_flush_region; 279 ctx->transfer_unmap = noop_transfer_unmap; 280 ctx->transfer_destroy = noop_transfer_destroy; 281 ctx->transfer_inline_write = noop_transfer_inline_write; 282 noop_init_state_functions(ctx); 283 284 return ctx; 285 } 286 287 288 /* 289 * pipe_screen 290 */ 291 static void noop_flush_frontbuffer(struct pipe_screen *_screen, 292 struct pipe_resource *resource, 293 unsigned level, unsigned layer, 294 void *context_private) 295 { 296 } 297 298 static const char *noop_get_vendor(struct pipe_screen* pscreen) 299 { 300 return "X.Org"; 301 } 302 303 static const char *noop_get_name(struct pipe_screen* pscreen) 304 { 305 return "NOOP"; 306 } 307 308 static int noop_get_param(struct pipe_screen* pscreen, enum pipe_cap param) 309 { 310 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 311 312 return screen->get_param(screen, param); 313 } 314 315 static float noop_get_paramf(struct pipe_screen* pscreen, 316 enum pipe_capf param) 317 { 318 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 319 320 return screen->get_paramf(screen, param); 321 } 322 323 static int noop_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param) 324 { 325 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 326 327 return screen->get_shader_param(screen, shader, param); 328 } 329 330 static boolean noop_is_format_supported(struct pipe_screen* pscreen, 331 enum pipe_format format, 332 enum pipe_texture_target target, 333 unsigned sample_count, 334 unsigned usage) 335 { 336 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 337 338 return screen->is_format_supported(screen, format, target, sample_count, usage); 339 } 340 341 static uint64_t noop_get_timestamp(struct pipe_screen *pscreen) 342 { 343 return 0; 344 } 345 346 static void noop_destroy_screen(struct pipe_screen *screen) 347 { 348 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 349 struct pipe_screen *oscreen = noop_screen->oscreen; 350 351 oscreen->destroy(oscreen); 352 FREE(screen); 353 } 354 355 struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen) 356 { 357 struct noop_pipe_screen *noop_screen; 358 struct pipe_screen *screen; 359 360 if (!debug_get_option_noop()) { 361 return oscreen; 362 } 363 364 noop_screen = CALLOC_STRUCT(noop_pipe_screen); 365 if (noop_screen == NULL) { 366 return NULL; 367 } 368 noop_screen->oscreen = oscreen; 369 screen = &noop_screen->pscreen; 370 371 screen->destroy = noop_destroy_screen; 372 screen->get_name = noop_get_name; 373 screen->get_vendor = noop_get_vendor; 374 screen->get_param = noop_get_param; 375 screen->get_shader_param = noop_get_shader_param; 376 screen->get_paramf = noop_get_paramf; 377 screen->is_format_supported = noop_is_format_supported; 378 screen->context_create = noop_create_context; 379 screen->resource_create = noop_resource_create; 380 screen->resource_from_handle = noop_resource_from_handle; 381 screen->resource_get_handle = noop_resource_get_handle; 382 screen->resource_destroy = noop_resource_destroy; 383 screen->flush_frontbuffer = noop_flush_frontbuffer; 384 screen->get_timestamp = noop_get_timestamp; 385 386 return screen; 387 } 388