Home | History | Annotate | Download | only in rbug
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 
     29 #include "pipe/p_screen.h"
     30 #include "pipe/p_state.h"
     31 #include "util/u_memory.h"
     32 #include "util/u_debug.h"
     33 #include "util/u_simple_list.h"
     34 
     35 #include "rbug_public.h"
     36 #include "rbug_screen.h"
     37 #include "rbug_context.h"
     38 #include "rbug_objects.h"
     39 
     40 DEBUG_GET_ONCE_BOOL_OPTION(rbug, "GALLIUM_RBUG", FALSE)
     41 
     42 static void
     43 rbug_screen_destroy(struct pipe_screen *_screen)
     44 {
     45    struct rbug_screen *rb_screen = rbug_screen(_screen);
     46    struct pipe_screen *screen = rb_screen->screen;
     47 
     48    screen->destroy(screen);
     49 
     50    FREE(rb_screen);
     51 }
     52 
     53 static const char *
     54 rbug_screen_get_name(struct pipe_screen *_screen)
     55 {
     56    struct rbug_screen *rb_screen = rbug_screen(_screen);
     57    struct pipe_screen *screen = rb_screen->screen;
     58 
     59    return screen->get_name(screen);
     60 }
     61 
     62 static const char *
     63 rbug_screen_get_vendor(struct pipe_screen *_screen)
     64 {
     65    struct rbug_screen *rb_screen = rbug_screen(_screen);
     66    struct pipe_screen *screen = rb_screen->screen;
     67 
     68    return screen->get_vendor(screen);
     69 }
     70 
     71 static int
     72 rbug_screen_get_param(struct pipe_screen *_screen,
     73                       enum pipe_cap param)
     74 {
     75    struct rbug_screen *rb_screen = rbug_screen(_screen);
     76    struct pipe_screen *screen = rb_screen->screen;
     77 
     78    return screen->get_param(screen,
     79                             param);
     80 }
     81 
     82 static int
     83 rbug_screen_get_shader_param(struct pipe_screen *_screen,
     84                       unsigned shader, enum pipe_shader_cap param)
     85 {
     86    struct rbug_screen *rb_screen = rbug_screen(_screen);
     87    struct pipe_screen *screen = rb_screen->screen;
     88 
     89    return screen->get_shader_param(screen, shader,
     90                             param);
     91 }
     92 
     93 static float
     94 rbug_screen_get_paramf(struct pipe_screen *_screen,
     95                        enum pipe_capf param)
     96 {
     97    struct rbug_screen *rb_screen = rbug_screen(_screen);
     98    struct pipe_screen *screen = rb_screen->screen;
     99 
    100    return screen->get_paramf(screen,
    101                              param);
    102 }
    103 
    104 static boolean
    105 rbug_screen_is_format_supported(struct pipe_screen *_screen,
    106                                 enum pipe_format format,
    107                                 enum pipe_texture_target target,
    108                                 unsigned sample_count,
    109                                 unsigned tex_usage)
    110 {
    111    struct rbug_screen *rb_screen = rbug_screen(_screen);
    112    struct pipe_screen *screen = rb_screen->screen;
    113 
    114    return screen->is_format_supported(screen,
    115                                       format,
    116                                       target,
    117                                       sample_count,
    118                                       tex_usage);
    119 }
    120 
    121 static struct pipe_context *
    122 rbug_screen_context_create(struct pipe_screen *_screen,
    123                            void *priv)
    124 {
    125    struct rbug_screen *rb_screen = rbug_screen(_screen);
    126    struct pipe_screen *screen = rb_screen->screen;
    127    struct pipe_context *result;
    128 
    129    result = screen->context_create(screen, priv);
    130    if (result)
    131       return rbug_context_create(_screen, result);
    132    return NULL;
    133 }
    134 
    135 static struct pipe_resource *
    136 rbug_screen_resource_create(struct pipe_screen *_screen,
    137                             const struct pipe_resource *templat)
    138 {
    139    struct rbug_screen *rb_screen = rbug_screen(_screen);
    140    struct pipe_screen *screen = rb_screen->screen;
    141    struct pipe_resource *result;
    142 
    143    result = screen->resource_create(screen,
    144                                     templat);
    145 
    146    if (result)
    147       return rbug_resource_create(rb_screen, result);
    148    return NULL;
    149 }
    150 
    151 static struct pipe_resource *
    152 rbug_screen_resource_from_handle(struct pipe_screen *_screen,
    153                                  const struct pipe_resource *templ,
    154                                  struct winsys_handle *handle)
    155 {
    156    struct rbug_screen *rb_screen = rbug_screen(_screen);
    157    struct pipe_screen *screen = rb_screen->screen;
    158    struct pipe_resource *result;
    159 
    160    result = screen->resource_from_handle(screen, templ, handle);
    161 
    162    result = rbug_resource_create(rbug_screen(_screen), result);
    163 
    164    return result;
    165 }
    166 
    167 static boolean
    168 rbug_screen_resource_get_handle(struct pipe_screen *_screen,
    169                                 struct pipe_resource *_resource,
    170                                 struct winsys_handle *handle)
    171 {
    172    struct rbug_screen *rb_screen = rbug_screen(_screen);
    173    struct rbug_resource *rb_resource = rbug_resource(_resource);
    174    struct pipe_screen *screen = rb_screen->screen;
    175    struct pipe_resource *resource = rb_resource->resource;
    176 
    177    return screen->resource_get_handle(screen, resource, handle);
    178 }
    179 
    180 
    181 
    182 static void
    183 rbug_screen_resource_destroy(struct pipe_screen *screen,
    184                              struct pipe_resource *_resource)
    185 {
    186    rbug_resource_destroy(rbug_resource(_resource));
    187 }
    188 
    189 static void
    190 rbug_screen_flush_frontbuffer(struct pipe_screen *_screen,
    191                               struct pipe_resource *_resource,
    192                               unsigned level, unsigned layer,
    193                               void *context_private)
    194 {
    195    struct rbug_screen *rb_screen = rbug_screen(_screen);
    196    struct rbug_resource *rb_resource = rbug_resource(_resource);
    197    struct pipe_screen *screen = rb_screen->screen;
    198    struct pipe_resource *resource = rb_resource->resource;
    199 
    200    screen->flush_frontbuffer(screen,
    201                              resource,
    202                              level, layer,
    203                              context_private);
    204 }
    205 
    206 static void
    207 rbug_screen_fence_reference(struct pipe_screen *_screen,
    208                             struct pipe_fence_handle **ptr,
    209                             struct pipe_fence_handle *fence)
    210 {
    211    struct rbug_screen *rb_screen = rbug_screen(_screen);
    212    struct pipe_screen *screen = rb_screen->screen;
    213 
    214    screen->fence_reference(screen,
    215                            ptr,
    216                            fence);
    217 }
    218 
    219 static boolean
    220 rbug_screen_fence_signalled(struct pipe_screen *_screen,
    221                             struct pipe_fence_handle *fence)
    222 {
    223    struct rbug_screen *rb_screen = rbug_screen(_screen);
    224    struct pipe_screen *screen = rb_screen->screen;
    225 
    226    return screen->fence_signalled(screen,
    227                                   fence);
    228 }
    229 
    230 static boolean
    231 rbug_screen_fence_finish(struct pipe_screen *_screen,
    232                          struct pipe_fence_handle *fence,
    233                          uint64_t timeout)
    234 {
    235    struct rbug_screen *rb_screen = rbug_screen(_screen);
    236    struct pipe_screen *screen = rb_screen->screen;
    237 
    238    return screen->fence_finish(screen,
    239                                fence,
    240                                timeout);
    241 }
    242 
    243 boolean
    244 rbug_enabled()
    245 {
    246    return debug_get_option_rbug();
    247 }
    248 
    249 struct pipe_screen *
    250 rbug_screen_create(struct pipe_screen *screen)
    251 {
    252    struct rbug_screen *rb_screen;
    253 
    254    if (!debug_get_option_rbug())
    255       return screen;
    256 
    257    rb_screen = CALLOC_STRUCT(rbug_screen);
    258    if (!rb_screen)
    259       return screen;
    260 
    261    pipe_mutex_init(rb_screen->list_mutex);
    262    make_empty_list(&rb_screen->contexts);
    263    make_empty_list(&rb_screen->resources);
    264    make_empty_list(&rb_screen->surfaces);
    265    make_empty_list(&rb_screen->transfers);
    266 
    267    rb_screen->base.destroy = rbug_screen_destroy;
    268    rb_screen->base.get_name = rbug_screen_get_name;
    269    rb_screen->base.get_vendor = rbug_screen_get_vendor;
    270    rb_screen->base.get_param = rbug_screen_get_param;
    271    rb_screen->base.get_shader_param = rbug_screen_get_shader_param;
    272    rb_screen->base.get_paramf = rbug_screen_get_paramf;
    273    rb_screen->base.is_format_supported = rbug_screen_is_format_supported;
    274    rb_screen->base.context_create = rbug_screen_context_create;
    275    rb_screen->base.resource_create = rbug_screen_resource_create;
    276    rb_screen->base.resource_from_handle = rbug_screen_resource_from_handle;
    277    rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle;
    278    rb_screen->base.resource_destroy = rbug_screen_resource_destroy;
    279    rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer;
    280    rb_screen->base.fence_reference = rbug_screen_fence_reference;
    281    rb_screen->base.fence_signalled = rbug_screen_fence_signalled;
    282    rb_screen->base.fence_finish = rbug_screen_fence_finish;
    283 
    284    rb_screen->screen = screen;
    285 
    286    rb_screen->private_context = screen->context_create(screen, NULL);
    287    if (!rb_screen->private_context)
    288       goto err_free;
    289 
    290    rb_screen->rbug = rbug_start(rb_screen);
    291 
    292    if (!rb_screen->rbug)
    293       goto err_context;
    294 
    295    return &rb_screen->base;
    296 
    297 err_context:
    298    rb_screen->private_context->destroy(rb_screen->private_context);
    299 err_free:
    300    FREE(rb_screen);
    301    return screen;
    302 }
    303