Home | History | Annotate | Download | only in softpipe
      1 /**************************************************************************
      2  *
      3  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
      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 TUNGSTEN GRAPHICS 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 "util/u_memory.h"
     30 #include "util/u_format.h"
     31 #include "util/u_format_s3tc.h"
     32 #include "util/u_video.h"
     33 #include "os/os_time.h"
     34 #include "pipe/p_defines.h"
     35 #include "pipe/p_screen.h"
     36 #include "draw/draw_context.h"
     37 #include "vl/vl_decoder.h"
     38 #include "vl/vl_video_buffer.h"
     39 
     40 #include "state_tracker/sw_winsys.h"
     41 #include "tgsi/tgsi_exec.h"
     42 
     43 #include "sp_texture.h"
     44 #include "sp_screen.h"
     45 #include "sp_context.h"
     46 #include "sp_fence.h"
     47 #include "sp_public.h"
     48 
     49 DEBUG_GET_ONCE_BOOL_OPTION(use_llvm, "SOFTPIPE_USE_LLVM", FALSE)
     50 
     51 static const char *
     52 softpipe_get_vendor(struct pipe_screen *screen)
     53 {
     54    return "VMware, Inc.";
     55 }
     56 
     57 
     58 static const char *
     59 softpipe_get_name(struct pipe_screen *screen)
     60 {
     61    return "softpipe";
     62 }
     63 
     64 
     65 static int
     66 softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
     67 {
     68    switch (param) {
     69    case PIPE_CAP_MAX_COMBINED_SAMPLERS:
     70       return 2 * PIPE_MAX_SAMPLERS;  /* VS + FS */
     71    case PIPE_CAP_NPOT_TEXTURES:
     72       return 1;
     73    case PIPE_CAP_TWO_SIDED_STENCIL:
     74       return 1;
     75    case PIPE_CAP_SM3:
     76       return 1;
     77    case PIPE_CAP_ANISOTROPIC_FILTER:
     78       return 1;
     79    case PIPE_CAP_POINT_SPRITE:
     80       return 1;
     81    case PIPE_CAP_MAX_RENDER_TARGETS:
     82       return PIPE_MAX_COLOR_BUFS;
     83    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
     84       return 1;
     85    case PIPE_CAP_OCCLUSION_QUERY:
     86       return 1;
     87    case PIPE_CAP_TIMER_QUERY:
     88       return 1;
     89    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
     90       return 1;
     91    case PIPE_CAP_TEXTURE_SHADOW_MAP:
     92       return 1;
     93    case PIPE_CAP_TEXTURE_SWIZZLE:
     94       return 1;
     95    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
     96       return SP_MAX_TEXTURE_2D_LEVELS;
     97    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
     98       return SP_MAX_TEXTURE_3D_LEVELS;
     99    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
    100       return SP_MAX_TEXTURE_CUBE_LEVELS;
    101    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
    102       return 1;
    103    case PIPE_CAP_INDEP_BLEND_ENABLE:
    104       return 1;
    105    case PIPE_CAP_INDEP_BLEND_FUNC:
    106       return 1;
    107    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
    108    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
    109    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
    110    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
    111       return 1;
    112    case PIPE_CAP_DEPTH_CLIP_DISABLE:
    113       return 0;
    114    case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
    115       return PIPE_MAX_SO_BUFFERS;
    116    case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
    117    case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
    118       return 16*4;
    119    case PIPE_CAP_PRIMITIVE_RESTART:
    120       return 1;
    121    case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
    122       return 0;
    123    case PIPE_CAP_SHADER_STENCIL_EXPORT:
    124       return 1;
    125    case PIPE_CAP_TGSI_INSTANCEID:
    126    case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
    127       return 1;
    128    case PIPE_CAP_SEAMLESS_CUBE_MAP:
    129    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
    130       return 0;
    131    case PIPE_CAP_SCALED_RESOLVE:
    132       return 0;
    133    case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
    134       return 256; /* for GL3 */
    135    case PIPE_CAP_MIN_TEXEL_OFFSET:
    136       return -8;
    137    case PIPE_CAP_MAX_TEXEL_OFFSET:
    138       return 7;
    139    case PIPE_CAP_CONDITIONAL_RENDER:
    140       return 1;
    141    case PIPE_CAP_TEXTURE_BARRIER:
    142       return 0;
    143    case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
    144    case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: /* draw module */
    145    case PIPE_CAP_VERTEX_COLOR_CLAMPED: /* draw module */
    146       return 1;
    147    case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
    148       return 0;
    149    case PIPE_CAP_GLSL_FEATURE_LEVEL:
    150       return 130;
    151    case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
    152       return 0;
    153    case PIPE_CAP_COMPUTE:
    154       return 0;
    155    case PIPE_CAP_USER_VERTEX_BUFFERS:
    156    case PIPE_CAP_USER_INDEX_BUFFERS:
    157    case PIPE_CAP_USER_CONSTANT_BUFFERS:
    158       return 1;
    159    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
    160       return 16;
    161    case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
    162    case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
    163    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
    164    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
    165    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
    166    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
    167    case PIPE_CAP_START_INSTANCE:
    168       return 0;
    169    case PIPE_CAP_QUERY_TIMESTAMP:
    170       return 1;
    171    }
    172    /* should only get here on unhandled cases */
    173    debug_printf("Unexpected PIPE_CAP %d query\n", param);
    174    return 0;
    175 }
    176 
    177 static int
    178 softpipe_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
    179 {
    180    struct softpipe_screen *sp_screen = softpipe_screen(screen);
    181    switch(shader)
    182    {
    183    case PIPE_SHADER_FRAGMENT:
    184       return tgsi_exec_get_shader_param(param);
    185    case PIPE_SHADER_VERTEX:
    186    case PIPE_SHADER_GEOMETRY:
    187       switch (param) {
    188       case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
    189          if (sp_screen->use_llvm)
    190             /* Softpipe doesn't yet know how to tell draw/llvm about textures */
    191             return 0;
    192 	 else
    193             return PIPE_MAX_SAMPLERS;
    194       default:
    195 	 if (sp_screen->use_llvm)
    196             return draw_get_shader_param(shader, param);
    197          else
    198             return draw_get_shader_param_no_llvm(shader, param);
    199       }
    200    default:
    201       return 0;
    202    }
    203 }
    204 
    205 static float
    206 softpipe_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
    207 {
    208    switch (param) {
    209    case PIPE_CAPF_MAX_LINE_WIDTH:
    210       /* fall-through */
    211    case PIPE_CAPF_MAX_LINE_WIDTH_AA:
    212       return 255.0; /* arbitrary */
    213    case PIPE_CAPF_MAX_POINT_WIDTH:
    214       /* fall-through */
    215    case PIPE_CAPF_MAX_POINT_WIDTH_AA:
    216       return 255.0; /* arbitrary */
    217    case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
    218       return 16.0;
    219    case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
    220       return 16.0; /* arbitrary */
    221    case PIPE_CAPF_GUARD_BAND_LEFT:
    222    case PIPE_CAPF_GUARD_BAND_TOP:
    223    case PIPE_CAPF_GUARD_BAND_RIGHT:
    224    case PIPE_CAPF_GUARD_BAND_BOTTOM:
    225       return 0.0;
    226    }
    227    /* should only get here on unhandled cases */
    228    debug_printf("Unexpected PIPE_CAPF %d query\n", param);
    229    return 0.0;
    230 }
    231 
    232 static int
    233 softpipe_get_video_param(struct pipe_screen *screen,
    234                          enum pipe_video_profile profile,
    235                          enum pipe_video_cap param)
    236 {
    237    switch (param) {
    238    case PIPE_VIDEO_CAP_SUPPORTED:
    239        return vl_profile_supported(screen, profile);
    240    case PIPE_VIDEO_CAP_NPOT_TEXTURES:
    241       return 0;
    242    case PIPE_VIDEO_CAP_MAX_WIDTH:
    243    case PIPE_VIDEO_CAP_MAX_HEIGHT:
    244       return vl_video_buffer_max_size(screen);
    245    case PIPE_VIDEO_CAP_PREFERED_FORMAT:
    246       return PIPE_FORMAT_NV12;
    247    case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
    248       return false;
    249    case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
    250       return false;
    251    case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
    252       return true;
    253    default:
    254       return 0;
    255    }
    256 }
    257 
    258 /**
    259  * Query format support for creating a texture, drawing surface, etc.
    260  * \param format  the format to test
    261  * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
    262  */
    263 static boolean
    264 softpipe_is_format_supported( struct pipe_screen *screen,
    265                               enum pipe_format format,
    266                               enum pipe_texture_target target,
    267                               unsigned sample_count,
    268                               unsigned bind)
    269 {
    270    struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
    271    const struct util_format_description *format_desc;
    272 
    273    assert(target == PIPE_BUFFER ||
    274           target == PIPE_TEXTURE_1D ||
    275           target == PIPE_TEXTURE_1D_ARRAY ||
    276           target == PIPE_TEXTURE_2D ||
    277           target == PIPE_TEXTURE_2D_ARRAY ||
    278           target == PIPE_TEXTURE_RECT ||
    279           target == PIPE_TEXTURE_3D ||
    280           target == PIPE_TEXTURE_CUBE);
    281 
    282    format_desc = util_format_description(format);
    283    if (!format_desc)
    284       return FALSE;
    285 
    286    if (sample_count > 1)
    287       return FALSE;
    288 
    289    if (bind & (PIPE_BIND_DISPLAY_TARGET |
    290                PIPE_BIND_SCANOUT |
    291                PIPE_BIND_SHARED)) {
    292       if(!winsys->is_displaytarget_format_supported(winsys, bind, format))
    293          return FALSE;
    294    }
    295 
    296    if (bind & PIPE_BIND_RENDER_TARGET) {
    297       if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
    298          return FALSE;
    299 
    300       /*
    301        * Although possible, it is unnatural to render into compressed or YUV
    302        * surfaces. So disable these here to avoid going into weird paths
    303        * inside the state trackers.
    304        */
    305       if (format_desc->block.width != 1 ||
    306           format_desc->block.height != 1)
    307          return FALSE;
    308    }
    309 
    310    if (bind & PIPE_BIND_DEPTH_STENCIL) {
    311       if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
    312          return FALSE;
    313    }
    314 
    315    /*
    316     * All other operations (sampling, transfer, etc).
    317     */
    318 
    319    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
    320       return util_format_s3tc_enabled;
    321    }
    322 
    323    /*
    324     * Everything else should be supported by u_format.
    325     */
    326    return TRUE;
    327 }
    328 
    329 
    330 static void
    331 softpipe_destroy_screen( struct pipe_screen *screen )
    332 {
    333    struct softpipe_screen *sp_screen = softpipe_screen(screen);
    334    struct sw_winsys *winsys = sp_screen->winsys;
    335 
    336    if(winsys->destroy)
    337       winsys->destroy(winsys);
    338 
    339    FREE(screen);
    340 }
    341 
    342 
    343 /* This is often overriden by the co-state tracker.
    344  */
    345 static void
    346 softpipe_flush_frontbuffer(struct pipe_screen *_screen,
    347                            struct pipe_resource *resource,
    348                            unsigned level, unsigned layer,
    349                            void *context_private)
    350 {
    351    struct softpipe_screen *screen = softpipe_screen(_screen);
    352    struct sw_winsys *winsys = screen->winsys;
    353    struct softpipe_resource *texture = softpipe_resource(resource);
    354 
    355    assert(texture->dt);
    356    if (texture->dt)
    357       winsys->displaytarget_display(winsys, texture->dt, context_private);
    358 }
    359 
    360 static uint64_t
    361 softpipe_get_timestamp(struct pipe_screen *_screen)
    362 {
    363    return os_time_get()*1000;
    364 }
    365 
    366 /**
    367  * Create a new pipe_screen object
    368  * Note: we're not presently subclassing pipe_screen (no softpipe_screen).
    369  */
    370 struct pipe_screen *
    371 softpipe_create_screen(struct sw_winsys *winsys)
    372 {
    373    struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
    374 
    375    if (!screen)
    376       return NULL;
    377 
    378    screen->winsys = winsys;
    379 
    380    screen->base.destroy = softpipe_destroy_screen;
    381 
    382    screen->base.get_name = softpipe_get_name;
    383    screen->base.get_vendor = softpipe_get_vendor;
    384    screen->base.get_param = softpipe_get_param;
    385    screen->base.get_shader_param = softpipe_get_shader_param;
    386    screen->base.get_paramf = softpipe_get_paramf;
    387    screen->base.get_video_param = softpipe_get_video_param;
    388    screen->base.get_timestamp = softpipe_get_timestamp;
    389    screen->base.is_format_supported = softpipe_is_format_supported;
    390    screen->base.is_video_format_supported = vl_video_buffer_is_format_supported;
    391    screen->base.context_create = softpipe_create_context;
    392    screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
    393 
    394    screen->use_llvm = debug_get_option_use_llvm();
    395 
    396    util_format_s3tc_init();
    397 
    398    softpipe_init_screen_texture_funcs(&screen->base);
    399    softpipe_init_screen_fence_funcs(&screen->base);
    400 
    401    return &screen->base;
    402 }
    403