Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 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.   * Authors:
  30.   *   Keith Whitwell <keithw@vmware.com>
  31.   *   Brian Paul
  32.   */
  33.  
  34. #include "util/u_math.h"
  35. #include "util/u_memory.h"
  36.  
  37. #include "pipe/p_shader_tokens.h"
  38.  
  39. #include "draw_private.h"
  40. #include "draw_context.h"
  41. #include "draw_vs.h"
  42.  
  43. #include "translate/translate.h"
  44. #include "translate/translate_cache.h"
  45.  
  46. #include "tgsi/tgsi_dump.h"
  47. #include "tgsi/tgsi_exec.h"
  48.  
  49. DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE)
  50.  
  51.  
  52. struct draw_vertex_shader *
  53. draw_create_vertex_shader(struct draw_context *draw,
  54.                           const struct pipe_shader_state *shader)
  55. {
  56.    struct draw_vertex_shader *vs = NULL;
  57.  
  58.    if (draw->dump_vs) {
  59.       tgsi_dump(shader->tokens, 0);
  60.    }
  61.  
  62. #if HAVE_LLVM
  63.    if (draw->pt.middle.llvm) {
  64.       vs = draw_create_vs_llvm(draw, shader);
  65.    }
  66. #endif
  67.  
  68.    if (!vs) {
  69.       vs = draw_create_vs_exec( draw, shader );
  70.    }
  71.  
  72.    if (vs)
  73.    {
  74.       uint i;
  75.       bool found_clipvertex = FALSE;
  76.       vs->position_output = -1;
  77.       for (i = 0; i < vs->info.num_outputs; i++) {
  78.          if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
  79.              vs->info.output_semantic_index[i] == 0)
  80.             vs->position_output = i;
  81.          else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_EDGEFLAG &&
  82.              vs->info.output_semantic_index[i] == 0)
  83.             vs->edgeflag_output = i;
  84.          else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPVERTEX &&
  85.                   vs->info.output_semantic_index[i] == 0) {
  86.             found_clipvertex = TRUE;
  87.             vs->clipvertex_output = i;
  88.          } else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
  89.             vs->viewport_index_output = i;
  90.          else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
  91.             debug_assert(vs->info.output_semantic_index[i] <
  92.                          PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
  93.             vs->clipdistance_output[vs->info.output_semantic_index[i]] = i;
  94.          } else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CULLDIST) {
  95.             debug_assert(vs->info.output_semantic_index[i] <
  96.                          PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
  97.             vs->culldistance_output[vs->info.output_semantic_index[i]] = i;
  98.          }
  99.       }
  100.       if (!found_clipvertex)
  101.          vs->clipvertex_output = vs->position_output;
  102.    }
  103.  
  104.    assert(vs);
  105.    return vs;
  106. }
  107.  
  108.  
  109. void
  110. draw_bind_vertex_shader(struct draw_context *draw,
  111.                         struct draw_vertex_shader *dvs)
  112. {
  113.    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
  114.    
  115.    if (dvs)
  116.    {
  117.       draw->vs.vertex_shader = dvs;
  118.       draw->vs.num_vs_outputs = dvs->info.num_outputs;
  119.       draw->vs.position_output = dvs->position_output;
  120.       draw->vs.edgeflag_output = dvs->edgeflag_output;
  121.       draw->vs.clipvertex_output = dvs->clipvertex_output;
  122.       draw->vs.clipdistance_output[0] = dvs->clipdistance_output[0];
  123.       draw->vs.clipdistance_output[1] = dvs->clipdistance_output[1];
  124.       dvs->prepare( dvs, draw );
  125.       draw_update_clip_flags(draw);
  126.       draw_update_viewport_flags(draw);
  127.    }
  128.    else {
  129.       draw->vs.vertex_shader = NULL;
  130.       draw->vs.num_vs_outputs = 0;
  131.    }
  132. }
  133.  
  134.  
  135. void
  136. draw_delete_vertex_shader(struct draw_context *draw,
  137.                           struct draw_vertex_shader *dvs)
  138. {
  139.    unsigned i;
  140.  
  141.    for (i = 0; i < dvs->nr_variants; i++)
  142.       dvs->variant[i]->destroy( dvs->variant[i] );
  143.  
  144.    dvs->nr_variants = 0;
  145.  
  146.    dvs->delete( dvs );
  147. }
  148.  
  149.  
  150.  
  151. boolean
  152. draw_vs_init( struct draw_context *draw )
  153. {
  154.    draw->dump_vs = debug_get_option_gallium_dump_vs();
  155.  
  156.    if (!draw->llvm) {
  157.       draw->vs.tgsi.machine = tgsi_exec_machine_create();
  158.       if (!draw->vs.tgsi.machine)
  159.          return FALSE;
  160.    }
  161.  
  162.    draw->vs.emit_cache = translate_cache_create();
  163.    if (!draw->vs.emit_cache)
  164.       return FALSE;
  165.      
  166.    draw->vs.fetch_cache = translate_cache_create();
  167.    if (!draw->vs.fetch_cache)
  168.       return FALSE;
  169.  
  170.    return TRUE;
  171. }
  172.  
  173. void
  174. draw_vs_destroy( struct draw_context *draw )
  175. {
  176.    if (draw->vs.fetch_cache)
  177.       translate_cache_destroy(draw->vs.fetch_cache);
  178.  
  179.    if (draw->vs.emit_cache)
  180.       translate_cache_destroy(draw->vs.emit_cache);
  181.  
  182.    if (!draw->llvm)
  183.       tgsi_exec_machine_destroy(draw->vs.tgsi.machine);
  184. }
  185.  
  186.  
  187. struct draw_vs_variant *
  188. draw_vs_lookup_variant( struct draw_vertex_shader *vs,
  189.                         const struct draw_vs_variant_key *key )
  190. {
  191.    struct draw_vs_variant *variant;
  192.    unsigned i;
  193.  
  194.    /* Lookup existing variant:
  195.     */
  196.    for (i = 0; i < vs->nr_variants; i++)
  197.       if (draw_vs_variant_key_compare(key, &vs->variant[i]->key) == 0)
  198.          return vs->variant[i];
  199.    
  200.    /* Else have to create a new one:
  201.     */
  202.    variant = vs->create_variant( vs, key );
  203.    if (variant == NULL)
  204.       return NULL;
  205.  
  206.    /* Add it to our list, could be smarter:
  207.     */
  208.    if (vs->nr_variants < Elements(vs->variant)) {
  209.       vs->variant[vs->nr_variants++] = variant;
  210.    }
  211.    else {
  212.       vs->last_variant++;
  213.       vs->last_variant %= Elements(vs->variant);
  214.       vs->variant[vs->last_variant]->destroy(vs->variant[vs->last_variant]);
  215.       vs->variant[vs->last_variant] = variant;
  216.    }
  217.  
  218.    /* Done
  219.     */
  220.    return variant;
  221. }
  222.  
  223.  
  224. struct translate *
  225. draw_vs_get_fetch( struct draw_context *draw,
  226.                    struct translate_key *key )
  227. {
  228.    if (!draw->vs.fetch ||
  229.        translate_key_compare(&draw->vs.fetch->key, key) != 0)
  230.    {
  231.       translate_key_sanitize(key);
  232.       draw->vs.fetch = translate_cache_find(draw->vs.fetch_cache, key);
  233.    }
  234.    
  235.    return draw->vs.fetch;
  236. }
  237.  
  238. struct translate *
  239. draw_vs_get_emit( struct draw_context *draw,
  240.                   struct translate_key *key )
  241. {
  242.    if (!draw->vs.emit ||
  243.        translate_key_compare(&draw->vs.emit->key, key) != 0)
  244.    {
  245.       translate_key_sanitize(key);
  246.       draw->vs.emit = translate_cache_find(draw->vs.emit_cache, key);
  247.    }
  248.    
  249.    return draw->vs.emit;
  250. }
  251.  
  252. void
  253. draw_vs_attach_so(struct draw_vertex_shader *dvs,
  254.                   const struct pipe_stream_output_info *info)
  255. {
  256.    dvs->state.stream_output = *info;
  257. }
  258.  
  259. void
  260. draw_vs_reset_so(struct draw_vertex_shader *dvs)
  261. {
  262.    memset(&dvs->state.stream_output, 0, sizeof(dvs->state.stream_output));
  263. }
  264.