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, 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