Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2013 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. #include "draw_prim_assembler.h"
  29.  
  30. #include "util/u_debug.h"
  31. #include "util/u_memory.h"
  32. #include "util/u_prim.h"
  33.  
  34. #include "pipe/p_defines.h"
  35.  
  36. struct draw_assembler
  37. {
  38.    struct draw_context *draw;
  39.  
  40.    struct draw_prim_info *output_prims;
  41.    struct draw_vertex_info *output_verts;
  42.  
  43.    const struct draw_prim_info *input_prims;
  44.    const struct draw_vertex_info *input_verts;
  45. };
  46.  
  47. boolean
  48. draw_prim_assembler_is_required(const struct draw_context *draw,
  49.                                 const struct draw_prim_info *prim_info,
  50.                                 const struct draw_vertex_info *vert_info)
  51. {
  52.    switch (prim_info->prim) {
  53.    case PIPE_PRIM_LINES_ADJACENCY:
  54.    case PIPE_PRIM_LINE_STRIP_ADJACENCY:
  55.    case PIPE_PRIM_TRIANGLES_ADJACENCY:
  56.    case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
  57.       return TRUE;
  58.    default:
  59.       return FALSE;
  60.    }
  61. }
  62.  
  63. /*
  64.  * Copy the vertex header along with its data from the current
  65.  * vertex buffer into a buffer holding vertices arranged
  66.  * into decomposed primitives (i.e. buffer without the
  67.  * adjacency vertices)
  68.  */
  69. static void
  70. copy_verts(struct draw_assembler *asmblr,
  71.            unsigned *indices, unsigned num_indices)
  72. {
  73.    unsigned i;
  74.  
  75.    char *output = (char*)asmblr->output_verts->verts;
  76.    const char *input = (const char*)asmblr->input_verts->verts;
  77.  
  78.    for (i = 0; i < num_indices; ++i) {
  79.       unsigned idx = indices[i];
  80.       unsigned output_offset =
  81.          asmblr->output_verts->count * asmblr->output_verts->stride;
  82.       unsigned input_offset = asmblr->input_verts->stride * idx;
  83.       memcpy(output + output_offset, input + input_offset,
  84.              asmblr->input_verts->vertex_size);
  85.       asmblr->output_verts->count += 1;
  86.    }
  87. }
  88.  
  89. static void
  90. prim_point(struct draw_assembler *asmblr,
  91.            unsigned idx)
  92. {
  93.    unsigned indices[1];
  94.  
  95.    indices[0] = idx;
  96.  
  97.    copy_verts(asmblr, indices, 1);
  98. }
  99.  
  100. static void
  101. prim_line(struct draw_assembler *asmblr,
  102.           unsigned i0, unsigned i1)
  103. {
  104.    unsigned indices[2];
  105.  
  106.    indices[0] = i0;
  107.    indices[1] = i1;
  108.  
  109.    copy_verts(asmblr, indices, 2);
  110. }
  111.  
  112. static void
  113. prim_line_adj(struct draw_assembler *asmblr,
  114.               unsigned i0, unsigned i1, unsigned i2, unsigned i3)
  115. {
  116.    unsigned indices[2];
  117.  
  118.    indices[0] = i1;
  119.    indices[1] = i2;
  120.  
  121.    copy_verts(asmblr, indices, 2);
  122. }
  123.  
  124. static void
  125. prim_tri(struct draw_assembler *asmblr,
  126.          unsigned i0, unsigned i1, unsigned i2)
  127. {
  128.    unsigned indices[3];
  129.  
  130.    indices[0] = i0;
  131.    indices[1] = i1;
  132.    indices[2] = i2;
  133.  
  134.    copy_verts(asmblr, indices, 3);
  135. }
  136.  
  137. static void
  138. prim_tri_adj(struct draw_assembler *asmblr,
  139.              unsigned i0, unsigned i1, unsigned i2,
  140.              unsigned i3, unsigned i4, unsigned i5)
  141. {
  142.    unsigned indices[3];
  143.  
  144.    indices[0] = i0;
  145.    indices[1] = i2;
  146.    indices[2] = i4;
  147.  
  148.    copy_verts(asmblr, indices, 3);
  149. }
  150.  
  151.  
  152.  
  153. #define FUNC assembler_run_linear
  154. #define GET_ELT(idx) (start + (idx))
  155. #include "draw_prim_assembler_tmp.h"
  156.  
  157. #define FUNC assembler_run_elts
  158. #define LOCAL_VARS   const ushort *elts = input_prims->elts;
  159. #define GET_ELT(idx) (elts[start + (idx)])
  160. #include "draw_prim_assembler_tmp.h"
  161.  
  162.  
  163.  
  164. /*
  165.  * Primitive assembler breaks up adjacency primitives and assembles
  166.  * the base primitives they represent, e.g. vertices forming
  167.  * PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY
  168.  * become vertices forming PIPE_PRIM_TRIANGLES
  169.  * This is needed because specification says that the adjacency
  170.  * primitives are only visible in the geometry shader so we need
  171.  * to get rid of them so that the rest of the pipeline can
  172.  * process the inputs.
  173.  */
  174. void
  175. draw_prim_assembler_run(struct draw_context *draw,
  176.                         const struct draw_prim_info *input_prims,
  177.                         const struct draw_vertex_info *input_verts,
  178.                         struct draw_prim_info *output_prims,
  179.                         struct draw_vertex_info *output_verts)
  180. {
  181.    struct draw_assembler asmblr;
  182.    unsigned start, i;
  183.    unsigned assembled_prim = u_assembled_prim(input_prims->prim);
  184.    unsigned max_primitives = u_decomposed_prims_for_vertices(
  185.       input_prims->prim, input_prims->count);
  186.    unsigned max_verts = u_vertices_per_prim(assembled_prim) * max_primitives;
  187.  
  188.    asmblr.draw = draw;
  189.    asmblr.output_prims = output_prims;
  190.    asmblr.output_verts = output_verts;
  191.    asmblr.input_prims = input_prims;
  192.    asmblr.input_verts = input_verts;
  193.  
  194.    output_prims->linear = TRUE;
  195.    output_prims->elts = NULL;
  196.    output_prims->start = 0;
  197.    output_prims->prim = u_assembled_prim(input_prims->prim);
  198.    output_prims->flags = 0x0;
  199.    output_prims->primitive_lengths = MALLOC(sizeof(unsigned));
  200.    output_prims->primitive_lengths[0] = 0;
  201.    output_prims->primitive_count = 1;
  202.  
  203.    output_verts->vertex_size = input_verts->vertex_size;
  204.    output_verts->stride = input_verts->stride;
  205.    output_verts->verts = (struct vertex_header*)MALLOC(
  206.       input_verts->vertex_size * max_verts);
  207.    output_verts->count = 0;
  208.  
  209.  
  210.    for (start = i = 0; i < input_prims->primitive_count;
  211.         start += input_prims->primitive_lengths[i], i++)
  212.    {
  213.       unsigned count = input_prims->primitive_lengths[i];
  214.       if (input_prims->linear) {
  215.          assembler_run_linear(&asmblr, input_prims, input_verts,
  216.                               start, count);
  217.       } else {
  218.          assembler_run_elts(&asmblr, input_prims, input_verts,
  219.                             start, count);
  220.       }
  221.    }
  222.  
  223.    output_prims->primitive_lengths[0] = output_verts->count;
  224.    output_prims->count = output_verts->count;
  225. }
  226.