Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2007  Brian Paul   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 "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Keith Whitwell <keith@tungstengraphics.com>
  26.  */
  27.  
  28. #include "main/glheader.h"
  29. #include "main/imports.h"
  30. #include "main/colormac.h"
  31. #include "tnl/tnl.h"
  32. #include "tnl/t_context.h"
  33. #include "tnl/t_pipeline.h"
  34. #include "tnl/t_vertex.h"
  35. #include "swrast_setup.h"
  36. #include "ss_context.h"
  37. #include "ss_triangle.h"
  38.  
  39.  
  40. /* Need to check lighting state and vertex program state to know
  41.  * if two-sided lighting is in effect.
  42.  */
  43. #define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT|_NEW_PROGRAM)
  44.  
  45.  
  46. #define VARYING_EMIT_STYLE  EMIT_4F
  47.  
  48.  
  49. GLboolean
  50. _swsetup_CreateContext( struct gl_context *ctx )
  51. {
  52.    SScontext *swsetup = calloc(1, sizeof(SScontext));
  53.  
  54.    if (!swsetup)
  55.       return GL_FALSE;
  56.  
  57.    ctx->swsetup_context = swsetup;
  58.  
  59.    swsetup->NewState = ~0;
  60.    _swsetup_trifuncs_init( ctx );
  61.  
  62.    _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
  63.                        sizeof(SWvertex) );
  64.  
  65.  
  66.    return GL_TRUE;
  67. }
  68.  
  69. void
  70. _swsetup_DestroyContext( struct gl_context *ctx )
  71. {
  72.    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
  73.  
  74.    if (swsetup) {
  75.       free(swsetup);
  76.       ctx->swsetup_context = 0;
  77.    }
  78.  
  79.    _tnl_free_vertices( ctx );
  80. }
  81.  
  82. static void
  83. _swsetup_RenderPrimitive( struct gl_context *ctx, GLenum mode )
  84. {
  85.    SWSETUP_CONTEXT(ctx)->render_prim = mode;
  86.    _swrast_render_primitive( ctx, mode );
  87. }
  88.  
  89.  
  90. /**
  91.  * Helper macros for setup_vertex_format()
  92.  */
  93. #define SWZ ((SWvertex *)0)
  94. #define SWOffset(MEMBER) (((char *)&(SWZ->MEMBER)) - ((char *)SWZ))
  95.  
  96. #define EMIT_ATTR( ATTR, STYLE, MEMBER )        \
  97. do {                                            \
  98.    map[e].attrib = (ATTR);                      \
  99.    map[e].format = (STYLE);                     \
  100.    map[e].offset = SWOffset(MEMBER);            \
  101.    e++;                                         \
  102. } while (0)
  103.  
  104.  
  105. /**
  106.  * Tell the tnl module how to build SWvertex objects for swrast.
  107.  * We'll build the map[] array with that info and pass it to
  108.  * _tnl_install_attrs().
  109.  */
  110. static void
  111. setup_vertex_format(struct gl_context *ctx)
  112. {
  113.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  114.    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
  115.    GLboolean intColors = !ctx->FragmentProgram._Current
  116.                       && !ctx->ATIFragmentShader._Enabled
  117.                       && ctx->RenderMode == GL_RENDER
  118.                       && CHAN_TYPE != GL_FLOAT;
  119.  
  120.    if (intColors != swsetup->intColors ||
  121.        tnl->render_inputs_bitset != swsetup->last_index_bitset) {
  122.       GLbitfield64 index_bitset = tnl->render_inputs_bitset;
  123.       struct tnl_attr_map map[_TNL_ATTRIB_MAX];
  124.       unsigned int i, e = 0;
  125.  
  126.       swsetup->intColors = intColors;
  127.  
  128.       EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[VARYING_SLOT_POS] );
  129.  
  130.       if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR0)) {
  131.          if (swsetup->intColors)
  132.             EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color );
  133.          else
  134.             EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F, attrib[VARYING_SLOT_COL0]);
  135.       }
  136.  
  137.       if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
  138.          EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F, attrib[VARYING_SLOT_COL1]);
  139.       }
  140.  
  141.       if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
  142.          const GLint emit = ctx->FragmentProgram._Current ? EMIT_4F : EMIT_1F;
  143.          EMIT_ATTR( _TNL_ATTRIB_FOG, emit, attrib[VARYING_SLOT_FOGC]);
  144.       }
  145.  
  146.       if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX))
  147.       {
  148.          for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
  149.             if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) {
  150.                EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F,
  151.                           attrib[VARYING_SLOT_TEX0 + i] );
  152.             }
  153.          }
  154.       }
  155.  
  156.       /* shader varying vars */
  157.       if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_GENERIC0, _TNL_NUM_GENERIC)) {
  158.          for (i = 0; i < ctx->Const.MaxVarying; i++) {
  159.             if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_GENERIC(i))) {
  160.                EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE,
  161.                           attrib[VARYING_SLOT_VAR0 + i] );
  162.             }
  163.          }
  164.       }
  165.  
  166.       if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE))
  167.          EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, pointSize );
  168.  
  169.       _tnl_install_attrs( ctx, map, e,
  170.                           ctx->Viewport._WindowMap.m,
  171.                           sizeof(SWvertex) );
  172.  
  173.       swsetup->last_index_bitset = index_bitset;
  174.    }
  175. }
  176.  
  177.  
  178. /**
  179.  * Prepare to render a vertex buffer.
  180.  * Called via tnl->Driver.Render.Start.
  181.  */
  182. static void
  183. _swsetup_RenderStart( struct gl_context *ctx )
  184. {
  185.    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
  186.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  187.    struct vertex_buffer *VB = &tnl->vb;
  188.  
  189.    if (swsetup->NewState & _SWSETUP_NEW_RENDERINDEX) {
  190.       _swsetup_choose_trifuncs(ctx);
  191.    }
  192.  
  193.    if (swsetup->NewState & _NEW_PROGRAM) {
  194.       swsetup->last_index_bitset = 0;
  195.    }
  196.  
  197.    swsetup->NewState = 0;
  198.  
  199.    /* This will change if drawing unfilled tris */
  200.    _swrast_SetFacing(ctx, 0);
  201.  
  202.    _swrast_render_start(ctx);
  203.  
  204.    /* Important */
  205.    VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
  206.  
  207.    setup_vertex_format(ctx);
  208. }
  209.  
  210.  
  211. /*
  212.  * We patch this function into tnl->Driver.Render.Finish.
  213.  * It's called when we finish rendering a vertex buffer.
  214.  */
  215. static void
  216. _swsetup_RenderFinish( struct gl_context *ctx )
  217. {
  218.    _swrast_render_finish( ctx );
  219. }
  220.  
  221. void
  222. _swsetup_InvalidateState( struct gl_context *ctx, GLuint new_state )
  223. {
  224.    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
  225.    swsetup->NewState |= new_state;
  226.    _tnl_invalidate_vertex_state( ctx, new_state );
  227. }
  228.  
  229.  
  230. void
  231. _swsetup_Wakeup( struct gl_context *ctx )
  232. {
  233.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  234.    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
  235.  
  236.    tnl->Driver.Render.Start = _swsetup_RenderStart;
  237.    tnl->Driver.Render.Finish = _swsetup_RenderFinish;
  238.    tnl->Driver.Render.PrimitiveNotify = _swsetup_RenderPrimitive;
  239.    tnl->Driver.Render.Interp = _tnl_interp;
  240.    tnl->Driver.Render.CopyPV = _tnl_copy_pv;
  241.    tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; /* new */
  242.    tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; /* new */
  243.    /* points */
  244.    /* line */
  245.    /* triangle */
  246.    /* quad */
  247.    tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
  248.    tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
  249.    tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
  250.    tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
  251.    tnl->Driver.Render.Multipass = 0;
  252.  
  253.    _tnl_invalidate_vertices( ctx, ~0 );
  254.    _tnl_need_projected_coords( ctx, GL_TRUE );
  255.    _swsetup_InvalidateState( ctx, ~0 );
  256.  
  257.    swsetup->verts = (SWvertex *)tnl->clipspace.vertex_buf;
  258.    swsetup->last_index_bitset = 0;
  259. }
  260.  
  261.  
  262. /**
  263.  * Populate a swrast SWvertex from an attrib-style vertex.
  264.  */
  265. void
  266. _swsetup_Translate( struct gl_context *ctx, const void *vertex, SWvertex *dest )
  267. {
  268.    const GLfloat *m = ctx->Viewport._WindowMap.m;
  269.    GLfloat tmp[4];
  270.    GLuint i;
  271.  
  272.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POS, tmp );
  273.  
  274.    dest->attrib[VARYING_SLOT_POS][0] = m[0]  * tmp[0] + m[12];
  275.    dest->attrib[VARYING_SLOT_POS][1] = m[5]  * tmp[1] + m[13];
  276.    dest->attrib[VARYING_SLOT_POS][2] = m[10] * tmp[2] + m[14];
  277.    dest->attrib[VARYING_SLOT_POS][3] =         tmp[3];
  278.  
  279.    /** XXX try to limit these loops someday */
  280.    for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
  281.       _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0 + i,
  282.                      dest->attrib[VARYING_SLOT_TEX0 + i] );
  283.  
  284.    for (i = 0 ; i < ctx->Const.MaxVarying ; i++)
  285.       _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_GENERIC0 + i,
  286.                      dest->attrib[VARYING_SLOT_VAR0 + i] );
  287.  
  288.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0,
  289.                   dest->attrib[VARYING_SLOT_COL0] );
  290.    UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp );
  291.  
  292.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1,
  293.                   dest->attrib[VARYING_SLOT_COL1]);
  294.  
  295.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp );
  296.    dest->attrib[VARYING_SLOT_FOGC][0] = tmp[0];
  297.  
  298.    /* XXX See _tnl_get_attr about pointsize ... */
  299.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp );
  300.    dest->pointSize = tmp[0];
  301. }
  302.  
  303.