Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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. #include "util/u_memory.h"
  29. #include "util/u_math.h"
  30. #include "util/u_format.h"
  31. #include "draw/draw_context.h"
  32. #include "draw/draw_private.h"
  33. #include "draw/draw_pt.h"
  34. #include "translate/translate.h"
  35. #include "translate/translate_cache.h"
  36.  
  37.  
  38. struct pt_fetch {
  39.    struct draw_context *draw;
  40.  
  41.    struct translate *translate;
  42.  
  43.    unsigned vertex_size;
  44.  
  45.    struct translate_cache *cache;
  46. };
  47.  
  48.  
  49. /**
  50.  * Perform the fetch from API vertex elements & vertex buffers, to a
  51.  * contiguous set of float[4] attributes as required for the
  52.  * vertex_shader->run_linear() method.
  53.  *
  54.  * This is used in all cases except pure passthrough
  55.  * (draw_pt_fetch_emit.c) which has its own version to translate
  56.  * directly to hw vertices.
  57.  *
  58.  */
  59. void
  60. draw_pt_fetch_prepare(struct pt_fetch *fetch,
  61.                       unsigned vs_input_count,
  62.                       unsigned vertex_size,
  63.                       unsigned instance_id_index)
  64. {
  65.    struct draw_context *draw = fetch->draw;
  66.    unsigned nr_inputs;
  67.    unsigned i, nr = 0, ei = 0;
  68.    unsigned dst_offset = 0;
  69.    unsigned num_extra_inputs = 0;
  70.    struct translate_key key;
  71.  
  72.    fetch->vertex_size = vertex_size;
  73.  
  74.    /* Leave the clipmask/edgeflags/pad/vertex_id untouched
  75.     */
  76.    dst_offset += 1 * sizeof(float);
  77.    /* Just leave the clip[] and pre_clip_pos[] array untouched.
  78.     */
  79.    dst_offset += 8 * sizeof(float);
  80.  
  81.    if (instance_id_index != ~0) {
  82.       num_extra_inputs++;
  83.    }
  84.  
  85.    assert(draw->pt.nr_vertex_elements + num_extra_inputs >= vs_input_count);
  86.  
  87.    nr_inputs = MIN2(vs_input_count, draw->pt.nr_vertex_elements + num_extra_inputs);
  88.  
  89.    for (i = 0; i < nr_inputs; i++) {
  90.       if (i == instance_id_index) {
  91.          key.element[nr].type = TRANSLATE_ELEMENT_INSTANCE_ID;
  92.          key.element[nr].input_format = PIPE_FORMAT_R32_USCALED;
  93.          key.element[nr].output_format = PIPE_FORMAT_R32_USCALED;
  94.          key.element[nr].output_offset = dst_offset;
  95.  
  96.          dst_offset += sizeof(uint);
  97.       } else if (util_format_is_pure_sint(draw->pt.vertex_element[i].src_format)) {
  98.          key.element[nr].type = TRANSLATE_ELEMENT_NORMAL;
  99.          key.element[nr].input_format = draw->pt.vertex_element[ei].src_format;
  100.          key.element[nr].input_buffer = draw->pt.vertex_element[ei].vertex_buffer_index;
  101.          key.element[nr].input_offset = draw->pt.vertex_element[ei].src_offset;
  102.          key.element[nr].instance_divisor = draw->pt.vertex_element[ei].instance_divisor;
  103.          key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_SINT;
  104.          key.element[nr].output_offset = dst_offset;
  105.  
  106.          ei++;
  107.          dst_offset += 4 * sizeof(int);
  108.       } else if (util_format_is_pure_uint(draw->pt.vertex_element[i].src_format)) {
  109.          key.element[nr].type = TRANSLATE_ELEMENT_NORMAL;
  110.          key.element[nr].input_format = draw->pt.vertex_element[ei].src_format;
  111.          key.element[nr].input_buffer = draw->pt.vertex_element[ei].vertex_buffer_index;
  112.          key.element[nr].input_offset = draw->pt.vertex_element[ei].src_offset;
  113.          key.element[nr].instance_divisor = draw->pt.vertex_element[ei].instance_divisor;
  114.          key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_UINT;
  115.          key.element[nr].output_offset = dst_offset;
  116.  
  117.          ei++;
  118.          dst_offset += 4 * sizeof(unsigned);
  119.       } else {
  120.          key.element[nr].type = TRANSLATE_ELEMENT_NORMAL;
  121.          key.element[nr].input_format = draw->pt.vertex_element[ei].src_format;
  122.          key.element[nr].input_buffer = draw->pt.vertex_element[ei].vertex_buffer_index;
  123.          key.element[nr].input_offset = draw->pt.vertex_element[ei].src_offset;
  124.          key.element[nr].instance_divisor = draw->pt.vertex_element[ei].instance_divisor;
  125.          key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  126.          key.element[nr].output_offset = dst_offset;
  127.  
  128.          ei++;
  129.          dst_offset += 4 * sizeof(float);
  130.       }
  131.  
  132.       nr++;
  133.    }
  134.  
  135.    assert(dst_offset <= vertex_size);
  136.  
  137.    key.nr_elements = nr;
  138.    key.output_stride = vertex_size;
  139.  
  140.    if (!fetch->translate ||
  141.        translate_key_compare(&fetch->translate->key, &key) != 0)
  142.    {
  143.       translate_key_sanitize(&key);
  144.       fetch->translate = translate_cache_find(fetch->cache, &key);
  145.    }
  146. }
  147.  
  148.  
  149. void
  150. draw_pt_fetch_run(struct pt_fetch *fetch,
  151.                   const unsigned *elts,
  152.                   unsigned count,
  153.                   char *verts)
  154. {
  155.    struct draw_context *draw = fetch->draw;
  156.    struct translate *translate = fetch->translate;
  157.    unsigned i;
  158.  
  159.    for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
  160.       translate->set_buffer(translate,
  161.                             i,
  162.                             ((char *)draw->pt.user.vbuffer[i].map +
  163.                              draw->pt.vertex_buffer[i].buffer_offset),
  164.                             draw->pt.vertex_buffer[i].stride,
  165.                             draw->pt.max_index);
  166.    }
  167.  
  168.    translate->run_elts( translate,
  169.                         elts,
  170.                         count,
  171.                         draw->start_instance,
  172.                         draw->instance_id,
  173.                         verts );
  174. }
  175.  
  176.  
  177. void
  178. draw_pt_fetch_run_linear(struct pt_fetch *fetch,
  179.                          unsigned start,
  180.                          unsigned count,
  181.                          char *verts)
  182. {
  183.    struct draw_context *draw = fetch->draw;
  184.    struct translate *translate = fetch->translate;
  185.    unsigned i;
  186.  
  187.    for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
  188.       translate->set_buffer(translate,
  189.                             i,
  190.                             ((char *)draw->pt.user.vbuffer[i].map +
  191.                              draw->pt.vertex_buffer[i].buffer_offset),
  192.                             draw->pt.vertex_buffer[i].stride,
  193.                             draw->pt.max_index);
  194.    }
  195.  
  196.    translate->run( translate,
  197.                    start,
  198.                    count,
  199.                    draw->start_instance,
  200.                    draw->instance_id,
  201.                    verts );
  202. }
  203.  
  204.  
  205. struct pt_fetch *
  206. draw_pt_fetch_create(struct draw_context *draw)
  207. {
  208.    struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch);
  209.    if (!fetch)
  210.       return NULL;
  211.  
  212.    fetch->draw = draw;
  213.    fetch->cache = translate_cache_create();
  214.    if (!fetch->cache) {
  215.       FREE(fetch);
  216.       return NULL;
  217.    }
  218.  
  219.    return fetch;
  220. }
  221.  
  222.  
  223. void
  224. draw_pt_fetch_destroy(struct pt_fetch *fetch)
  225. {
  226.    if (fetch->cache)
  227.       translate_cache_destroy(fetch->cache);
  228.  
  229.    FREE(fetch);
  230. }
  231.