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