Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  7.2
  4.  *
  5.  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. /* Author:
  26.  *    Keith Whitwell <keith@tungstengraphics.com>
  27.  */
  28.  
  29. #include "main/glheader.h"
  30. #include "main/bufferobj.h"
  31. #include "main/context.h"
  32. #include "main/imports.h"
  33. #include "main/mtypes.h"
  34. #include "main/macros.h"
  35. #include "main/light.h"
  36. #include "main/state.h"
  37.  
  38. #include "vbo_context.h"
  39.  
  40.  
  41. #if FEATURE_dlist
  42.  
  43.  
  44. /**
  45.  * After playback, copy everything but the position from the
  46.  * last vertex to the saved state
  47.  */
  48. static void
  49. _playback_copy_to_current(struct gl_context *ctx,
  50.                           const struct vbo_save_vertex_list *node)
  51. {
  52.    struct vbo_context *vbo = vbo_context(ctx);
  53.    GLfloat vertex[VBO_ATTRIB_MAX * 4];
  54.    GLfloat *data;
  55.    GLuint i, offset;
  56.  
  57.    if (node->current_size == 0)
  58.       return;
  59.  
  60.    if (node->current_data) {
  61.       data = node->current_data;
  62.    }
  63.    else {
  64.       data = vertex;
  65.  
  66.       if (node->count)
  67.          offset = (node->buffer_offset +
  68.                    (node->count-1) * node->vertex_size * sizeof(GLfloat));
  69.       else
  70.          offset = node->buffer_offset;
  71.  
  72.       ctx->Driver.GetBufferSubData( ctx, 0, offset,
  73.                                     node->vertex_size * sizeof(GLfloat),
  74.                                     data, node->vertex_store->bufferobj );
  75.  
  76.       data += node->attrsz[0]; /* skip vertex position */
  77.    }
  78.  
  79.    for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
  80.       if (node->attrsz[i]) {
  81.          GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
  82.          GLfloat tmp[4];
  83.  
  84.          COPY_CLEAN_4V(tmp,
  85.                        node->attrsz[i],
  86.                        data);
  87.          
  88.          if (memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
  89.             memcpy(current, tmp, 4 * sizeof(GLfloat));
  90.  
  91.             vbo->currval[i].Size = node->attrsz[i];
  92.  
  93.             if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
  94.                 i <= VBO_ATTRIB_LAST_MATERIAL)
  95.                ctx->NewState |= _NEW_LIGHT;
  96.  
  97.             ctx->NewState |= _NEW_CURRENT_ATTRIB;
  98.          }
  99.  
  100.          data += node->attrsz[i];
  101.       }
  102.    }
  103.  
  104.    /* Colormaterial -- this kindof sucks.
  105.     */
  106.    if (ctx->Light.ColorMaterialEnabled) {
  107.       _mesa_update_color_material(ctx, ctx->Current.Attrib[VBO_ATTRIB_COLOR0]);
  108.    }
  109.  
  110.    /* CurrentExecPrimitive
  111.     */
  112.    if (node->prim_count) {
  113.       const struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
  114.       if (prim->end)
  115.          ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
  116.       else
  117.          ctx->Driver.CurrentExecPrimitive = prim->mode;
  118.    }
  119. }
  120.  
  121.  
  122.  
  123. /**
  124.  * Treat the vertex storage as a VBO, define vertex arrays pointing
  125.  * into it:
  126.  */
  127. static void vbo_bind_vertex_list(struct gl_context *ctx,
  128.                                  const struct vbo_save_vertex_list *node)
  129. {
  130.    struct vbo_context *vbo = vbo_context(ctx);
  131.    struct vbo_save_context *save = &vbo->save;
  132.    struct gl_client_array *arrays = save->arrays;
  133.    GLuint buffer_offset = node->buffer_offset;
  134.    const GLuint *map;
  135.    GLuint attr;
  136.    GLubyte node_attrsz[VBO_ATTRIB_MAX];  /* copy of node->attrsz[] */
  137.    GLbitfield varying_inputs = 0x0;
  138.  
  139.    memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz));
  140.  
  141.    /* Install the default (ie Current) attributes first, then overlay
  142.     * all active ones.
  143.     */
  144.    switch (get_program_mode(ctx)) {
  145.    case VP_NONE:
  146.       for (attr = 0; attr < 16; attr++) {
  147.          save->inputs[attr] = &vbo->legacy_currval[attr];
  148.       }
  149.       for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) {
  150.          save->inputs[attr + 16] = &vbo->mat_currval[attr];
  151.       }
  152.       map = vbo->map_vp_none;
  153.       break;
  154.    case VP_NV:
  155.    case VP_ARB:
  156.       /* The aliasing of attributes for NV vertex programs has already
  157.        * occurred.  NV vertex programs cannot access material values,
  158.        * nor attributes greater than VERT_ATTRIB_TEX7.  
  159.        */
  160.       for (attr = 0; attr < 16; attr++) {
  161.          save->inputs[attr] = &vbo->legacy_currval[attr];
  162.          save->inputs[attr + 16] = &vbo->generic_currval[attr];
  163.       }
  164.       map = vbo->map_vp_arb;
  165.  
  166.       /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read.
  167.        * In that case we effectively need to route the data from
  168.        * glVertexAttrib(0, val) calls to feed into the GENERIC0 input.
  169.        */
  170.       if ((ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_POS) == 0 &&
  171.           (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) {
  172.          save->inputs[16] = save->inputs[0];
  173.          node_attrsz[16] = node_attrsz[0];
  174.          node_attrsz[0] = 0;
  175.       }
  176.       break;
  177.    default:
  178.       assert(0);
  179.    }
  180.  
  181.    for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
  182.       const GLuint src = map[attr];
  183.  
  184.       if (node_attrsz[src]) {
  185.          /* override the default array set above */
  186.          save->inputs[attr] = &arrays[attr];
  187.  
  188.          arrays[attr].Ptr = (const GLubyte *) NULL + buffer_offset;
  189.          arrays[attr].Size = node->attrsz[src];
  190.          arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat);
  191.          arrays[attr].Stride = node->vertex_size * sizeof(GLfloat);
  192.          arrays[attr].Type = GL_FLOAT;
  193.          arrays[attr].Format = GL_RGBA;
  194.          arrays[attr].Enabled = 1;
  195.          _mesa_reference_buffer_object(ctx,
  196.                                        &arrays[attr].BufferObj,
  197.                                        node->vertex_store->bufferobj);
  198.          arrays[attr]._MaxElement = node->count; /* ??? */
  199.          
  200.          assert(arrays[attr].BufferObj->Name);
  201.  
  202.          buffer_offset += node->attrsz[src] * sizeof(GLfloat);
  203.          varying_inputs |= 1<<attr;
  204.       }
  205.    }
  206.  
  207.    _mesa_set_varying_vp_inputs( ctx, varying_inputs );
  208. }
  209.  
  210.  
  211. static void
  212. vbo_save_loopback_vertex_list(struct gl_context *ctx,
  213.                               const struct vbo_save_vertex_list *list)
  214. {
  215.    const char *buffer = ctx->Driver.MapBuffer(ctx,
  216.                                               GL_ARRAY_BUFFER_ARB,
  217.                                               GL_READ_ONLY, /* ? */
  218.                                               list->vertex_store->bufferobj);
  219.  
  220.    vbo_loopback_vertex_list(ctx,
  221.                             (const GLfloat *)(buffer + list->buffer_offset),
  222.                             list->attrsz,
  223.                             list->prim,
  224.                             list->prim_count,
  225.                             list->wrap_count,
  226.                             list->vertex_size);
  227.  
  228.    ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB,
  229.                            list->vertex_store->bufferobj);
  230. }
  231.  
  232.  
  233. /**
  234.  * Execute the buffer and save copied verts.
  235.  * This is called from the display list code when executing
  236.  * a drawing command.
  237.  */
  238. void
  239. vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
  240. {
  241.    const struct vbo_save_vertex_list *node =
  242.       (const struct vbo_save_vertex_list *) data;
  243.    struct vbo_save_context *save = &vbo_context(ctx)->save;
  244.  
  245.    FLUSH_CURRENT(ctx, 0);
  246.  
  247.    if (node->prim_count > 0 && node->count > 0) {
  248.  
  249.       if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
  250.           node->prim[0].begin) {
  251.  
  252.          /* Degenerate case: list is called inside begin/end pair and
  253.           * includes operations such as glBegin or glDrawArrays.
  254.           */
  255.          if (0)
  256.             printf("displaylist recursive begin");
  257.  
  258.          vbo_save_loopback_vertex_list( ctx, node );
  259.          return;
  260.       }
  261.       else if (save->replay_flags) {
  262.          /* Various degnerate cases: translate into immediate mode
  263.           * calls rather than trying to execute in place.
  264.           */
  265.          vbo_save_loopback_vertex_list( ctx, node );
  266.          return;
  267.       }
  268.      
  269.       if (ctx->NewState)
  270.          _mesa_update_state( ctx );
  271.  
  272.       /* XXX also need to check if shader enabled, but invalid */
  273.       if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
  274.           (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
  275.          _mesa_error(ctx, GL_INVALID_OPERATION,
  276.                      "glBegin (invalid vertex/fragment program)");
  277.          return;
  278.       }
  279.  
  280.       vbo_bind_vertex_list( ctx, node );
  281.  
  282.       /* Again...
  283.        */
  284.       if (ctx->NewState)
  285.          _mesa_update_state( ctx );
  286.  
  287.       vbo_context(ctx)->draw_prims(ctx,
  288.                                    save->inputs,
  289.                                    node->prim,
  290.                                    node->prim_count,
  291.                                    NULL,
  292.                                    GL_TRUE,
  293.                                    0,   /* Node is a VBO, so this is ok */
  294.                                    node->count - 1);
  295.    }
  296.  
  297.    /* Copy to current?
  298.     */
  299.    _playback_copy_to_current( ctx, node );
  300. }
  301.  
  302.  
  303. #endif /* FEATURE_dlist */
  304.