Home | History | Annotate | Download | only in svga
      1 /**********************************************************
      2  * Copyright 2014 VMware, Inc.  All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person
      5  * obtaining a copy of this software and associated documentation
      6  * files (the "Software"), to deal in the Software without
      7  * restriction, including without limitation the rights to use, copy,
      8  * modify, merge, publish, distribute, sublicense, and/or sell copies
      9  * of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be
     13  * included in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  **********************************************************/
     25 
     26 #include "util/u_inlines.h"
     27 #include "util/u_memory.h"
     28 #include "util/u_bitmask.h"
     29 #include "translate/translate.h"
     30 #include "tgsi/tgsi_ureg.h"
     31 
     32 #include "svga_context.h"
     33 #include "svga_cmd.h"
     34 #include "svga_shader.h"
     35 #include "svga_tgsi.h"
     36 #include "svga_streamout.h"
     37 #include "svga_format.h"
     38 
     39 /**
     40  * If we fail to compile a geometry shader we'll use a dummy/fallback shader
     41  * that simply emits the incoming vertices.
     42  */
     43 static const struct tgsi_token *
     44 get_dummy_geometry_shader(void)
     45 {
     46    //XXX
     47    return NULL;
     48 }
     49 
     50 
     51 static struct svga_shader_variant *
     52 translate_geometry_program(struct svga_context *svga,
     53                            const struct svga_geometry_shader *gs,
     54                            const struct svga_compile_key *key)
     55 {
     56    assert(svga_have_vgpu10(svga));
     57    return svga_tgsi_vgpu10_translate(svga, &gs->base, key,
     58                                      PIPE_SHADER_GEOMETRY);
     59 }
     60 
     61 
     62 /**
     63  * Translate TGSI shader into an svga shader variant.
     64  */
     65 static enum pipe_error
     66 compile_gs(struct svga_context *svga,
     67            struct svga_geometry_shader *gs,
     68            const struct svga_compile_key *key,
     69            struct svga_shader_variant **out_variant)
     70 {
     71    struct svga_shader_variant *variant;
     72    enum pipe_error ret = PIPE_ERROR;
     73 
     74    variant = translate_geometry_program(svga, gs, key);
     75    if (!variant) {
     76       /* some problem during translation, try the dummy shader */
     77       const struct tgsi_token *dummy = get_dummy_geometry_shader();
     78       if (!dummy) {
     79          return PIPE_ERROR_OUT_OF_MEMORY;
     80       }
     81       debug_printf("Failed to compile geometry shader, using dummy shader instead.\n");
     82       FREE((void *) gs->base.tokens);
     83       gs->base.tokens = dummy;
     84       variant = translate_geometry_program(svga, gs, key);
     85       if (!variant) {
     86          return PIPE_ERROR;
     87       }
     88    }
     89 
     90    ret = svga_define_shader(svga, SVGA3D_SHADERTYPE_GS, variant);
     91    if (ret != PIPE_OK) {
     92       svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_GS, variant);
     93       return ret;
     94    }
     95 
     96    *out_variant = variant;
     97 
     98    return PIPE_OK;
     99 }
    100 
    101 
    102 static void
    103 make_gs_key(struct svga_context *svga, struct svga_compile_key *key)
    104 {
    105    struct svga_geometry_shader *gs = svga->curr.gs;
    106 
    107    memset(key, 0, sizeof *key);
    108 
    109    /*
    110     * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
    111     */
    112    svga_init_shader_key_common(svga, PIPE_SHADER_GEOMETRY, key);
    113 
    114    memcpy(key->generic_remap_table, gs->generic_remap_table,
    115           sizeof(gs->generic_remap_table));
    116 
    117    key->gs.vs_generic_outputs = svga->curr.vs->generic_outputs;
    118 
    119    key->gs.need_prescale = svga->state.hw_clear.prescale.enabled;
    120 
    121    key->gs.writes_psize = gs->base.info.writes_psize;
    122    key->gs.wide_point = gs->wide_point;
    123    key->sprite_coord_enable = svga->curr.rast->templ.sprite_coord_enable;
    124    key->sprite_origin_lower_left = (svga->curr.rast->templ.sprite_coord_mode
    125                                     == PIPE_SPRITE_COORD_LOWER_LEFT);
    126 
    127    /* SVGA_NEW_RAST */
    128    key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable;
    129 }
    130 
    131 
    132 /**
    133  * svga_reemit_gs_bindings - Reemit the geometry shader bindings
    134  */
    135 enum pipe_error
    136 svga_reemit_gs_bindings(struct svga_context *svga)
    137 {
    138    enum pipe_error ret;
    139    struct svga_winsys_gb_shader *gbshader = NULL;
    140    SVGA3dShaderId shaderId = SVGA3D_INVALID_ID;
    141 
    142    assert(svga->rebind.flags.gs);
    143    assert(svga_have_gb_objects(svga));
    144 
    145    /* Geometry Shader is only supported in vgpu10 */
    146    assert(svga_have_vgpu10(svga));
    147 
    148    if (svga->state.hw_draw.gs) {
    149       gbshader = svga->state.hw_draw.gs->gb_shader;
    150       shaderId = svga->state.hw_draw.gs->id;
    151    }
    152 
    153    if (!svga_need_to_rebind_resources(svga)) {
    154       ret =  svga->swc->resource_rebind(svga->swc, NULL, gbshader,
    155                                         SVGA_RELOC_READ);
    156       goto out;
    157    }
    158 
    159    ret = SVGA3D_vgpu10_SetShader(svga->swc, SVGA3D_SHADERTYPE_GS,
    160                                  gbshader, shaderId);
    161 
    162  out:
    163    if (ret != PIPE_OK)
    164       return ret;
    165 
    166    svga->rebind.flags.gs = FALSE;
    167    return PIPE_OK;
    168 }
    169 
    170 static enum pipe_error
    171 emit_hw_gs(struct svga_context *svga, unsigned dirty)
    172 {
    173    struct svga_shader_variant *variant;
    174    struct svga_geometry_shader *gs = svga->curr.gs;
    175    enum pipe_error ret = PIPE_OK;
    176    struct svga_compile_key key;
    177 
    178    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITGS);
    179 
    180    /* If there's a user-defined GS, we should have a pointer to a derived
    181     * GS.  This should have been resolved in update_tgsi_transform().
    182     */
    183    if (svga->curr.user_gs)
    184       assert(svga->curr.gs);
    185 
    186    if (!gs) {
    187       if (svga->state.hw_draw.gs != NULL) {
    188 
    189          /** The previous geometry shader is made inactive.
    190           *  Needs to unbind the geometry shader.
    191           */
    192          ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL);
    193          svga->state.hw_draw.gs = NULL;
    194       }
    195       goto done;
    196    }
    197 
    198    /* If there is stream output info for this geometry shader, then use
    199     * it instead of the one from the vertex shader.
    200     */
    201    if (svga_have_gs_streamout(svga)) {
    202       svga_set_stream_output(svga, gs->base.stream_output);
    203    }
    204    else if (!svga_have_vs_streamout(svga)) {
    205       /* turn off stream out */
    206       svga_set_stream_output(svga, NULL);
    207    }
    208 
    209    /* SVGA_NEW_NEED_SWTNL */
    210    if (svga->state.sw.need_swtnl && !svga_have_vgpu10(svga)) {
    211       /* No geometry shader is needed */
    212       variant = NULL;
    213    }
    214    else {
    215       make_gs_key(svga, &key);
    216 
    217       /* See if we already have a GS variant that matches the key */
    218       variant = svga_search_shader_key(&gs->base, &key);
    219 
    220       if (!variant) {
    221          ret = compile_gs(svga, gs, &key, &variant);
    222          if (ret != PIPE_OK)
    223             goto done;
    224 
    225          /* insert the new variant at head of linked list */
    226          assert(variant);
    227          variant->next = gs->base.variants;
    228          gs->base.variants = variant;
    229       }
    230    }
    231 
    232    if (variant != svga->state.hw_draw.gs) {
    233       /* Bind the new variant */
    234       ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, variant);
    235       if (ret != PIPE_OK)
    236          goto done;
    237 
    238       svga->rebind.flags.gs = FALSE;
    239       svga->dirty |= SVGA_NEW_GS_VARIANT;
    240       svga->state.hw_draw.gs = variant;
    241    }
    242 
    243 done:
    244    SVGA_STATS_TIME_POP(svga_sws(svga));
    245    return ret;
    246 }
    247 
    248 struct svga_tracked_state svga_hw_gs =
    249 {
    250    "geometry shader (hwtnl)",
    251    (SVGA_NEW_VS |
    252     SVGA_NEW_FS |
    253     SVGA_NEW_GS |
    254     SVGA_NEW_TEXTURE_BINDING |
    255     SVGA_NEW_SAMPLER |
    256     SVGA_NEW_RAST |
    257     SVGA_NEW_NEED_SWTNL),
    258    emit_hw_gs
    259 };
    260