Home | History | Annotate | Download | only in galahad
      1 /**************************************************************************
      2  *
      3  * Copyright 2009 VMware, Inc.
      4  * 2010 Corbin Simpson <MostAwesomeDude (at) gmail.com>
      5  * All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation the rights to use, copy, modify, merge, publish,
     11  * distribute, sub license, and/or sell copies of the Software, and to
     12  * permit persons to whom the Software is furnished to do so, subject to
     13  * the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial portions
     17  * of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  *
     27  **************************************************************************/
     28 
     29 
     30 #include "pipe/p_screen.h"
     31 #include "pipe/p_state.h"
     32 #include "util/u_memory.h"
     33 #include "util/u_math.h"
     34 #include "util/u_format.h"
     35 
     36 #include "glhd_public.h"
     37 #include "glhd_screen.h"
     38 #include "glhd_context.h"
     39 #include "glhd_objects.h"
     40 
     41 DEBUG_GET_ONCE_BOOL_OPTION(galahad, "GALLIUM_GALAHAD", FALSE)
     42 
     43 static void
     44 galahad_screen_destroy(struct pipe_screen *_screen)
     45 {
     46    struct galahad_screen *glhd_screen = galahad_screen(_screen);
     47    struct pipe_screen *screen = glhd_screen->screen;
     48 
     49    screen->destroy(screen);
     50 
     51    FREE(glhd_screen);
     52 }
     53 
     54 static const char *
     55 galahad_screen_get_name(struct pipe_screen *_screen)
     56 {
     57    struct galahad_screen *glhd_screen = galahad_screen(_screen);
     58    struct pipe_screen *screen = glhd_screen->screen;
     59 
     60    return screen->get_name(screen);
     61 }
     62 
     63 static const char *
     64 galahad_screen_get_vendor(struct pipe_screen *_screen)
     65 {
     66    struct galahad_screen *glhd_screen = galahad_screen(_screen);
     67    struct pipe_screen *screen = glhd_screen->screen;
     68 
     69    return screen->get_vendor(screen);
     70 }
     71 
     72 static int
     73 galahad_screen_get_param(struct pipe_screen *_screen,
     74                           enum pipe_cap param)
     75 {
     76    struct galahad_screen *glhd_screen = galahad_screen(_screen);
     77    struct pipe_screen *screen = glhd_screen->screen;
     78 
     79    return screen->get_param(screen,
     80                             param);
     81 }
     82 
     83 static int
     84 galahad_screen_get_shader_param(struct pipe_screen *_screen,
     85                           unsigned shader, enum pipe_shader_cap param)
     86 {
     87    struct galahad_screen *glhd_screen = galahad_screen(_screen);
     88    struct pipe_screen *screen = glhd_screen->screen;
     89 
     90    return screen->get_shader_param(screen, shader,
     91                             param);
     92 }
     93 
     94 static float
     95 galahad_screen_get_paramf(struct pipe_screen *_screen,
     96                            enum pipe_capf param)
     97 {
     98    struct galahad_screen *glhd_screen = galahad_screen(_screen);
     99    struct pipe_screen *screen = glhd_screen->screen;
    100 
    101    return screen->get_paramf(screen,
    102                              param);
    103 }
    104 
    105 static boolean
    106 galahad_screen_is_format_supported(struct pipe_screen *_screen,
    107                                     enum pipe_format format,
    108                                     enum pipe_texture_target target,
    109                                     unsigned sample_count,
    110                                     unsigned tex_usage)
    111 {
    112    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    113    struct pipe_screen *screen = glhd_screen->screen;
    114 
    115    if (target >= PIPE_MAX_TEXTURE_TYPES) {
    116       glhd_warn("Received bogus texture target %d", target);
    117    }
    118 
    119    return screen->is_format_supported(screen,
    120                                       format,
    121                                       target,
    122                                       sample_count,
    123                                       tex_usage);
    124 }
    125 
    126 static struct pipe_context *
    127 galahad_screen_context_create(struct pipe_screen *_screen,
    128                                void *priv)
    129 {
    130    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    131    struct pipe_screen *screen = glhd_screen->screen;
    132    struct pipe_context *result;
    133 
    134    result = screen->context_create(screen, priv);
    135    if (result)
    136       return galahad_context_create(_screen, result);
    137    return NULL;
    138 }
    139 
    140 static struct pipe_resource *
    141 galahad_screen_resource_create(struct pipe_screen *_screen,
    142                                 const struct pipe_resource *templat)
    143 {
    144    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    145    struct pipe_screen *screen = glhd_screen->screen;
    146    struct pipe_resource *result;
    147 
    148    glhd_check("%u", templat->width0, >= 1);
    149    glhd_check("%u", templat->height0, >= 1);
    150    glhd_check("%u", templat->depth0, >= 1);
    151    glhd_check("%u", templat->array_size, >= 1);
    152 
    153    if (templat->target == PIPE_BUFFER) {
    154       glhd_check("%u", templat->last_level, == 0);
    155       glhd_check("%u", templat->height0, == 1);
    156       glhd_check("%u", templat->depth0,  == 1);
    157       glhd_check("%u", templat->array_size, == 1);
    158    } else if (templat->target == PIPE_TEXTURE_1D) {
    159       unsigned max_texture_2d_levels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
    160       glhd_check("%u", templat->last_level, < max_texture_2d_levels);
    161       glhd_check("%u", templat->width0,  <= (1 << (max_texture_2d_levels - 1)));
    162       glhd_check("%u", templat->height0, == 1);
    163       glhd_check("%u", templat->depth0,  == 1);
    164       glhd_check("%u", templat->array_size, == 1);
    165    } else if (templat->target == PIPE_TEXTURE_2D) {
    166       unsigned max_texture_2d_levels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
    167       glhd_check("%u", templat->last_level, < max_texture_2d_levels);
    168       glhd_check("%u", templat->width0,  <= (1 << (max_texture_2d_levels - 1)));
    169       glhd_check("%u", templat->height0, <= (1 << (max_texture_2d_levels - 1)));
    170       glhd_check("%u", templat->depth0,  == 1);
    171       glhd_check("%u", templat->array_size, == 1);
    172    } else if (templat->target == PIPE_TEXTURE_CUBE) {
    173       unsigned max_texture_cube_levels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS);
    174       glhd_check("%u", templat->last_level, < max_texture_cube_levels);
    175       glhd_check("%u", templat->width0,  <= (1 << (max_texture_cube_levels - 1)));
    176       glhd_check("%u", templat->height0, == templat->width0);
    177       glhd_check("%u", templat->depth0,  == 1);
    178       glhd_check("%u", templat->array_size, == 6);
    179    } else if (templat->target == PIPE_TEXTURE_RECT) {
    180       unsigned max_texture_2d_levels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
    181       glhd_check("%u", templat->last_level, == 0);
    182       glhd_check("%u", templat->width0,  <= (1 << (max_texture_2d_levels - 1)));
    183       glhd_check("%u", templat->height0, <= (1 << (max_texture_2d_levels - 1)));
    184       glhd_check("%u", templat->depth0,  == 1);
    185       glhd_check("%u", templat->array_size, == 1);
    186    } else if (templat->target == PIPE_TEXTURE_3D) {
    187       unsigned max_texture_3d_levels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS);
    188       glhd_check("%u", templat->last_level, < max_texture_3d_levels);
    189       glhd_check("%u", templat->width0,  <= (1 << (max_texture_3d_levels - 1)));
    190       glhd_check("%u", templat->height0, <= (1 << (max_texture_3d_levels - 1)));
    191       glhd_check("%u", templat->depth0,  <= (1 << (max_texture_3d_levels - 1)));
    192       glhd_check("%u", templat->array_size, == 1);
    193    } else if (templat->target == PIPE_TEXTURE_1D_ARRAY) {
    194       unsigned max_texture_2d_levels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
    195       glhd_check("%u", templat->last_level, < max_texture_2d_levels);
    196       glhd_check("%u", templat->width0,  <= (1 << (max_texture_2d_levels - 1)));
    197       glhd_check("%u", templat->height0, == 1);
    198       glhd_check("%u", templat->depth0,  == 1);
    199       glhd_check("%u", templat->array_size, <= screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS));
    200    } else if (templat->target == PIPE_TEXTURE_2D_ARRAY) {
    201       unsigned max_texture_2d_levels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
    202       glhd_check("%u", templat->last_level, < max_texture_2d_levels);
    203       glhd_check("%u", templat->width0,  <= (1 << (max_texture_2d_levels - 1)));
    204       glhd_check("%u", templat->height0, <= (1 << (max_texture_2d_levels - 1)));
    205       glhd_check("%u", templat->depth0,  == 1);
    206       glhd_check("%u", templat->array_size, <= screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS));
    207    } else {
    208       glhd_warn("Received bogus resource target %d", templat->target);
    209    }
    210 
    211    if(templat->target != PIPE_TEXTURE_RECT && templat->target != PIPE_BUFFER && !screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES))
    212    {
    213       if(!util_is_power_of_two(templat->width0) || !util_is_power_of_two(templat->height0))
    214          glhd_warn("Requested NPOT (%ux%u) non-rectangle texture without NPOT support", templat->width0, templat->height0);
    215    }
    216 
    217    if (templat->target != PIPE_BUFFER &&
    218        !screen->is_format_supported(screen, templat->format, templat->target, templat->nr_samples, templat->bind)) {
    219       glhd_warn("Requested format=%s target=%u samples=%u bind=0x%x unsupported",
    220          util_format_name(templat->format), templat->target, templat->nr_samples, templat->bind);
    221    }
    222 
    223    result = screen->resource_create(screen,
    224                                     templat);
    225 
    226    if (result)
    227       return galahad_resource_create(glhd_screen, result);
    228    return NULL;
    229 }
    230 
    231 static struct pipe_resource *
    232 galahad_screen_resource_from_handle(struct pipe_screen *_screen,
    233                                      const struct pipe_resource *templ,
    234                                      struct winsys_handle *handle)
    235 {
    236    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    237    struct pipe_screen *screen = glhd_screen->screen;
    238    struct pipe_resource *result;
    239 
    240    /* TODO trace call */
    241 
    242    result = screen->resource_from_handle(screen, templ, handle);
    243 
    244    result = galahad_resource_create(galahad_screen(_screen), result);
    245 
    246    return result;
    247 }
    248 
    249 static boolean
    250 galahad_screen_resource_get_handle(struct pipe_screen *_screen,
    251                                     struct pipe_resource *_resource,
    252                                     struct winsys_handle *handle)
    253 {
    254    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    255    struct galahad_resource *glhd_resource = galahad_resource(_resource);
    256    struct pipe_screen *screen = glhd_screen->screen;
    257    struct pipe_resource *resource = glhd_resource->resource;
    258 
    259    /* TODO trace call */
    260 
    261    return screen->resource_get_handle(screen, resource, handle);
    262 }
    263 
    264 
    265 
    266 static void
    267 galahad_screen_resource_destroy(struct pipe_screen *screen,
    268                                  struct pipe_resource *_resource)
    269 {
    270    galahad_resource_destroy(galahad_resource(_resource));
    271 }
    272 
    273 
    274 static void
    275 galahad_screen_flush_frontbuffer(struct pipe_screen *_screen,
    276                                   struct pipe_resource *_resource,
    277                                   unsigned level, unsigned layer,
    278                                   void *context_private)
    279 {
    280    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    281    struct galahad_resource *glhd_resource = galahad_resource(_resource);
    282    struct pipe_screen *screen = glhd_screen->screen;
    283    struct pipe_resource *resource = glhd_resource->resource;
    284 
    285    screen->flush_frontbuffer(screen,
    286                              resource,
    287                              level, layer,
    288                              context_private);
    289 }
    290 
    291 static void
    292 galahad_screen_fence_reference(struct pipe_screen *_screen,
    293                                 struct pipe_fence_handle **ptr,
    294                                 struct pipe_fence_handle *fence)
    295 {
    296    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    297    struct pipe_screen *screen = glhd_screen->screen;
    298 
    299    screen->fence_reference(screen,
    300                            ptr,
    301                            fence);
    302 }
    303 
    304 static boolean
    305 galahad_screen_fence_signalled(struct pipe_screen *_screen,
    306                                 struct pipe_fence_handle *fence)
    307 {
    308    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    309    struct pipe_screen *screen = glhd_screen->screen;
    310 
    311    return screen->fence_signalled(screen,
    312                                   fence);
    313 }
    314 
    315 static boolean
    316 galahad_screen_fence_finish(struct pipe_screen *_screen,
    317                              struct pipe_fence_handle *fence,
    318                              uint64_t timeout)
    319 {
    320    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    321    struct pipe_screen *screen = glhd_screen->screen;
    322 
    323    return screen->fence_finish(screen,
    324                                fence,
    325                                timeout);
    326 }
    327 
    328 static uint64_t
    329 galahad_screen_get_timestamp(struct pipe_screen *_screen)
    330 {
    331    struct galahad_screen *glhd_screen = galahad_screen(_screen);
    332    struct pipe_screen *screen = glhd_screen->screen;
    333 
    334    return screen->get_timestamp(screen);
    335 }
    336 
    337 struct pipe_screen *
    338 galahad_screen_create(struct pipe_screen *screen)
    339 {
    340    struct galahad_screen *glhd_screen;
    341 
    342    if (!debug_get_option_galahad())
    343       return screen;
    344 
    345    glhd_screen = CALLOC_STRUCT(galahad_screen);
    346    if (!glhd_screen) {
    347       return screen;
    348    }
    349 
    350 #define GLHD_SCREEN_INIT(_member) \
    351    glhd_screen->base . _member = screen -> _member ? galahad_screen_ ## _member : NULL
    352 
    353    GLHD_SCREEN_INIT(destroy);
    354    GLHD_SCREEN_INIT(get_name);
    355    GLHD_SCREEN_INIT(get_vendor);
    356    GLHD_SCREEN_INIT(get_param);
    357    GLHD_SCREEN_INIT(get_shader_param);
    358    //GLHD_SCREEN_INIT(get_video_param);
    359    //GLHD_SCREEN_INIT(get_compute_param);
    360    GLHD_SCREEN_INIT(get_paramf);
    361    GLHD_SCREEN_INIT(is_format_supported);
    362    //GLHD_SCREEN_INIT(is_video_format_supported);
    363    GLHD_SCREEN_INIT(context_create);
    364    GLHD_SCREEN_INIT(resource_create);
    365    GLHD_SCREEN_INIT(resource_from_handle);
    366    GLHD_SCREEN_INIT(resource_get_handle);
    367    GLHD_SCREEN_INIT(resource_destroy);
    368    GLHD_SCREEN_INIT(flush_frontbuffer);
    369    GLHD_SCREEN_INIT(fence_reference);
    370    GLHD_SCREEN_INIT(fence_signalled);
    371    GLHD_SCREEN_INIT(fence_finish);
    372    GLHD_SCREEN_INIT(get_timestamp);
    373 
    374 #undef GLHD_SCREEN_INIT
    375 
    376    glhd_screen->screen = screen;
    377 
    378    return &glhd_screen->base;
    379 }
    380