Home | History | Annotate | Download | only in noop
      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