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.1
  4.  *
  5.  * Copyright (C) 1999-2007  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.  * 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 = (SScontext *)CALLOC(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.        !RENDERINPUTS_EQUAL(tnl->render_inputs_bitset,
  122.                            swsetup->last_index_bitset)) {
  123.       DECLARE_RENDERINPUTS(index_bitset);
  124.       struct tnl_attr_map map[_TNL_ATTRIB_MAX];
  125.       unsigned int i, e = 0;
  126.  
  127.       swsetup->intColors = intColors;
  128.  
  129.       RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
  130.  
  131.       EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[FRAG_ATTRIB_WPOS] );
  132.  
  133.       if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR0 )) {
  134.          if (swsetup->intColors)
  135.             EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color );
  136.          else
  137.             EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F, attrib[FRAG_ATTRIB_COL0]);
  138.       }
  139.  
  140.       if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
  141.          EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F, attrib[FRAG_ATTRIB_COL1]);
  142.       }
  143.  
  144.       if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
  145.          const GLint emit = ctx->FragmentProgram._Current ? EMIT_4F : EMIT_1F;
  146.          EMIT_ATTR( _TNL_ATTRIB_FOG, emit, attrib[FRAG_ATTRIB_FOGC]);
  147.       }
  148.  
  149.       if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX))
  150.       {
  151.          for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
  152.             if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
  153.                EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F,
  154.                           attrib[FRAG_ATTRIB_TEX0 + i] );
  155.             }
  156.          }
  157.       }
  158.  
  159.       /* shader varying vars */
  160.       if (RENDERINPUTS_TEST_RANGE( index_bitset,
  161.                                    _TNL_FIRST_GENERIC, _TNL_LAST_GENERIC )) {
  162.          for (i = 0; i < ctx->Const.MaxVarying; i++) {
  163.             if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_GENERIC(i) )) {
  164.                EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE,
  165.                           attrib[FRAG_ATTRIB_VAR0 + i] );
  166.             }
  167.          }
  168.       }
  169.  
  170.       if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE ))
  171.          EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, pointSize );
  172.  
  173.       _tnl_install_attrs( ctx, map, e,
  174.                           ctx->Viewport._WindowMap.m,
  175.                           sizeof(SWvertex) );
  176.  
  177.       RENDERINPUTS_COPY( swsetup->last_index_bitset, index_bitset );
  178.    }
  179. }
  180.  
  181.  
  182. /**
  183.  * Prepare to render a vertex buffer.
  184.  * Called via tnl->Driver.Render.Start.
  185.  */
  186. static void
  187. _swsetup_RenderStart( struct gl_context *ctx )
  188. {
  189.    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
  190.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  191.    struct vertex_buffer *VB = &tnl->vb;
  192.  
  193.    if (swsetup->NewState & _SWSETUP_NEW_RENDERINDEX) {
  194.       _swsetup_choose_trifuncs(ctx);
  195.    }
  196.  
  197.    if (swsetup->NewState & _NEW_PROGRAM) {
  198.       RENDERINPUTS_ZERO( swsetup->last_index_bitset );
  199.    }
  200.  
  201.    swsetup->NewState = 0;
  202.  
  203.    /* This will change if drawing unfilled tris */
  204.    _swrast_SetFacing(ctx, 0);
  205.  
  206.    _swrast_render_start(ctx);
  207.  
  208.    /* Important */
  209.    VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
  210.  
  211.    setup_vertex_format(ctx);
  212. }
  213.  
  214.  
  215. /*
  216.  * We patch this function into tnl->Driver.Render.Finish.
  217.  * It's called when we finish rendering a vertex buffer.
  218.  */
  219. static void
  220. _swsetup_RenderFinish( struct gl_context *ctx )
  221. {
  222.    _swrast_render_finish( ctx );
  223. }
  224.  
  225. void
  226. _swsetup_InvalidateState( struct gl_context *ctx, GLuint new_state )
  227. {
  228.    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
  229.    swsetup->NewState |= new_state;
  230.    _tnl_invalidate_vertex_state( ctx, new_state );
  231. }
  232.  
  233.  
  234. void
  235. _swsetup_Wakeup( struct gl_context *ctx )
  236. {
  237.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  238.    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
  239.  
  240.    tnl->Driver.Render.Start = _swsetup_RenderStart;
  241.    tnl->Driver.Render.Finish = _swsetup_RenderFinish;
  242.    tnl->Driver.Render.PrimitiveNotify = _swsetup_RenderPrimitive;
  243.    tnl->Driver.Render.Interp = _tnl_interp;
  244.    tnl->Driver.Render.CopyPV = _tnl_copy_pv;
  245.    tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; /* new */
  246.    tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; /* new */
  247.    /* points */
  248.    /* line */
  249.    /* triangle */
  250.    /* quad */
  251.    tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
  252.    tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
  253.    tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
  254.    tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
  255.    tnl->Driver.Render.Multipass = 0;
  256.  
  257.    _tnl_invalidate_vertices( ctx, ~0 );
  258.    _tnl_need_projected_coords( ctx, GL_TRUE );
  259.    _swsetup_InvalidateState( ctx, ~0 );
  260.  
  261.    swsetup->verts = (SWvertex *)tnl->clipspace.vertex_buf;
  262.    RENDERINPUTS_ZERO( swsetup->last_index_bitset );
  263. }
  264.  
  265.  
  266. /**
  267.  * Populate a swrast SWvertex from an attrib-style vertex.
  268.  */
  269. void
  270. _swsetup_Translate( struct gl_context *ctx, const void *vertex, SWvertex *dest )
  271. {
  272.    const GLfloat *m = ctx->Viewport._WindowMap.m;
  273.    GLfloat tmp[4];
  274.    GLuint i;
  275.  
  276.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POS, tmp );
  277.  
  278.    dest->attrib[FRAG_ATTRIB_WPOS][0] = m[0]  * tmp[0] + m[12];
  279.    dest->attrib[FRAG_ATTRIB_WPOS][1] = m[5]  * tmp[1] + m[13];
  280.    dest->attrib[FRAG_ATTRIB_WPOS][2] = m[10] * tmp[2] + m[14];
  281.    dest->attrib[FRAG_ATTRIB_WPOS][3] =         tmp[3];
  282.  
  283.    /** XXX try to limit these loops someday */
  284.    for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
  285.       _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0 + i,
  286.                      dest->attrib[FRAG_ATTRIB_TEX0 + i] );
  287.  
  288.    for (i = 0 ; i < ctx->Const.MaxVarying ; i++)
  289.       _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_GENERIC0 + i,
  290.                      dest->attrib[FRAG_ATTRIB_VAR0 + i] );
  291.  
  292.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0,
  293.                   dest->attrib[FRAG_ATTRIB_COL0] );
  294.    UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp );
  295.  
  296.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1,
  297.                   dest->attrib[FRAG_ATTRIB_COL1]);
  298.  
  299.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp );
  300.    dest->attrib[FRAG_ATTRIB_FOGC][0] = tmp[0];
  301.  
  302.    /* XXX See _tnl_get_attr about pointsize ... */
  303.    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp );
  304.    dest->pointSize = tmp[0];
  305. }
  306.  
  307.