Removed knowledge of swrast Clear/Bitmap/Accum/Draw/Read/CopyPixels

functions from core mesa -- if drivers need these fallbacks they
must now call them themselves.

Introduced hooks for clip-vertex-interpolation and the rendering
of clipped lines and polygons.  Allows drivers to interpolate
their hardware-format vertices directly.  Used in dri drivers to
replace fastpath code.

Slight optimizations to pipeline build/run routines.
This commit is contained in:
Keith Whitwell
2001-01-29 20:47:39 +00:00
parent 4b90e68ac6
commit 5c1e7fa6ee
23 changed files with 658 additions and 881 deletions

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.X11,v 1.40 2001/01/24 00:04:58 brianp Exp $
# $Id: Makefile.X11,v 1.41 2001/01/29 20:47:39 keithw Exp $
# Mesa 3-D graphics library
# Version: 3.5
@@ -21,6 +21,32 @@ LIBDIR = ../lib
CORE_SOURCES = \
tnl/t_array_api.c \
tnl/t_array_import.c \
tnl/t_context.c \
tnl/t_eval_api.c \
tnl/t_imm_alloc.c \
tnl/t_imm_api.c \
tnl/t_imm_debug.c \
tnl/t_imm_dlist.c \
tnl/t_imm_elt.c \
tnl/t_imm_eval.c \
tnl/t_imm_exec.c \
tnl/t_imm_fixup.c \
tnl/t_pipeline.c \
tnl/t_vb_fog.c \
tnl/t_vb_light.c \
tnl/t_vb_material.c \
tnl/t_vb_normals.c \
tnl/t_vb_points.c \
tnl/t_vb_render.c \
tnl/t_vb_texgen.c \
tnl/t_vb_texmat.c \
tnl/t_vb_vertex.c \
swrast_setup/ss_context.c \
swrast_setup/ss_triangle.c \
swrast_setup/ss_vb.c \
swrast_setup/ss_interp.c \
api_loopback.c \
api_noop.c \
api_validate.c \
@@ -86,6 +112,15 @@ CORE_SOURCES = \
X86/common_x86.c \
X86/3dnow.c \
X86/katmai.c \
math/m_debug_xform.c \
math/m_eval.c \
math/m_matrix.c \
math/m_translate.c \
math/m_vector.c \
math/m_vertices.c \
math/m_xform.c \
array_cache/ac_context.c \
array_cache/ac_import.c \
swrast/s_aaline.c \
swrast/s_aatriangle.c \
swrast/s_accum.c \
@@ -114,41 +149,7 @@ CORE_SOURCES = \
swrast/s_stencil.c \
swrast/s_texture.c \
swrast/s_triangle.c \
swrast/s_zoom.c \
swrast_setup/ss_context.c \
swrast_setup/ss_triangle.c \
swrast_setup/ss_vb.c \
math/m_debug_xform.c \
math/m_eval.c \
math/m_matrix.c \
math/m_translate.c \
math/m_vector.c \
math/m_vertices.c \
math/m_xform.c \
array_cache/ac_context.c \
array_cache/ac_import.c \
tnl/t_array_api.c \
tnl/t_array_import.c \
tnl/t_context.c \
tnl/t_eval_api.c \
tnl/t_imm_alloc.c \
tnl/t_imm_api.c \
tnl/t_imm_debug.c \
tnl/t_imm_dlist.c \
tnl/t_imm_elt.c \
tnl/t_imm_eval.c \
tnl/t_imm_exec.c \
tnl/t_imm_fixup.c \
tnl/t_pipeline.c \
tnl/t_vb_fog.c \
tnl/t_vb_light.c \
tnl/t_vb_material.c \
tnl/t_vb_normals.c \
tnl/t_vb_points.c \
tnl/t_vb_render.c \
tnl/t_vb_texgen.c \
tnl/t_vb_texmat.c \
tnl/t_vb_vertex.c
swrast/s_zoom.c
DRIVER_SOURCES = \

View File

@@ -145,7 +145,7 @@ static void fxDDClearColor(GLcontext *ctx, const GLchan color[4])
/* Clear the color and/or depth buffers */
static GLbitfield fxDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
static void fxDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
@@ -255,7 +255,10 @@ static GLbitfield fxDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
;
}
return softwareMask;
/* Clear any remaining buffers:
*/
if (softwareMask)
_swrast_Clear( ctx, softwareMask, all, x, y, width, height );
}
@@ -313,7 +316,7 @@ static void fxDDSetReadBuffer(GLcontext *ctx, GLframebuffer *buffer,
static GLboolean fxDDDrawBitmap(GLcontext *ctx, GLint px, GLint py,
static void fxDDDrawBitmap(GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap)
@@ -335,7 +338,10 @@ static GLboolean fxDDDrawBitmap(GLcontext *ctx, GLint px, GLint py,
( ctx->DrawBuffer->UseSoftwareAlphaBuffers &&
ctx->Color.ColorMask[ACOMP]) ||
ctx->Color.MultiDrawBuffer)
return GL_FALSE;
{
_swrast_Bitmap( ctx, px, py, width, height, unpack, bitmap );
return;
}
if (ctx->Scissor.Enabled) {
@@ -374,7 +380,7 @@ static GLboolean fxDDDrawBitmap(GLcontext *ctx, GLint px, GLint py,
}
if (width <= 0 || height <= 0)
return GL_TRUE; /* totally scissored away */
return;
}
else {
finalUnpack = unpack;
@@ -408,7 +414,7 @@ static GLboolean fxDDDrawBitmap(GLcontext *ctx, GLint px, GLint py,
#ifndef FX_SILENT
fprintf(stderr,"fx Driver: error locking the linear frame buffer\n");
#endif
return GL_TRUE;
return;
}
{
@@ -472,23 +478,23 @@ static GLboolean fxDDDrawBitmap(GLcontext *ctx, GLint px, GLint py,
}
FX_grLfbUnlock(GR_LFB_WRITE_ONLY,fxMesa->currentFB);
return GL_TRUE;
}
static GLboolean fxDDReadPixels( GLcontext *ctx, GLint x, GLint y,
static void fxDDReadPixels( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *packing,
GLvoid *dstImage )
{
if (ctx->_ImageTransferState) {
return GL_FALSE; /* can't do this */
_swrast_ReadPixels( ctx, x, y, width, height, format, type,
packing, dstImage );
return;
}
else {
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
GrLfbInfo_t info;
GLboolean result = GL_FALSE;
BEGIN_BOARD_LOCK();
if (grLfbLock(GR_LFB_READ_ONLY,
@@ -533,7 +539,6 @@ static GLboolean fxDDReadPixels( GLcontext *ctx, GLint x, GLint y,
dst += dstStride;
src -= srcStride;
}
result = GL_TRUE;
}
else if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
/* convert 5R6G5B into 8R8G8B8A */
@@ -565,7 +570,6 @@ static GLboolean fxDDReadPixels( GLcontext *ctx, GLint x, GLint y,
dst += dstStride;
src -= srcStride;
}
result = GL_TRUE;
}
else if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
/* directly memcpy 5R6G5B pixels into client's buffer */
@@ -576,16 +580,18 @@ static GLboolean fxDDReadPixels( GLcontext *ctx, GLint x, GLint y,
dst += dstStride;
src -= srcStride;
}
result = GL_TRUE;
}
else {
result = GL_FALSE;
grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
END_BOARD_LOCK();
_swrast_ReadPixels( ctx, x, y, width, height, format, type,
packing, dstImage );
return;
}
grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
}
END_BOARD_LOCK();
return result;
}
}
@@ -1037,10 +1043,9 @@ static void fxDDRenderStart( GLcontext *ctx )
{
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
if (!fxMesa->is_in_hardware) {
_swsetup_RenderStart( ctx );
}
else if (fxMesa->new_state) {
if (fxMesa->new_state) {
fxSetupFXUnits( ctx );
}
}
@@ -1079,9 +1084,12 @@ void fxSetupDDPointers(GLcontext *ctx)
ctx->Driver.SetReadBuffer=fxDDSetReadBuffer;
ctx->Driver.GetBufferSize=fxDDBufferSize;
ctx->Driver.Accum = _swrast_Accum;
ctx->Driver.Bitmap = fxDDDrawBitmap;
ctx->Driver.DrawPixels=NULL;
ctx->Driver.CopyPixels = _swrast_CopyPixels;
ctx->Driver.DrawPixels = _swrast_DrawPixels;
ctx->Driver.ReadPixels = fxDDReadPixels;
ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
ctx->Driver.Finish=fxDDFinish;
ctx->Driver.Flush=NULL;
@@ -1091,6 +1099,13 @@ void fxSetupDDPointers(GLcontext *ctx)
ctx->Driver.ResetLineStipple=_swrast_ResetLineStipple;
ctx->Driver.RenderPrimitive=fxDDRenderPrimitive;
/* Install the oldstyle interp functions:
*/
ctx->Driver.RenderInterp = _swsetup_RenderInterp;
ctx->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
ctx->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
ctx->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
ctx->Driver.TexImage2D = fxDDTexImage2D;
ctx->Driver.TexSubImage2D = fxDDTexSubImage2D;
ctx->Driver.GetTexImage = fxDDGetTexImage;

View File

@@ -1,4 +1,4 @@
/* $Id: osmesa.c,v 1.41 2001/01/24 00:04:58 brianp Exp $ */
/* $Id: osmesa.c,v 1.42 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -1775,7 +1775,13 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
ctx->Driver.SetDrawBuffer = set_draw_buffer;
ctx->Driver.SetReadBuffer = set_read_buffer;
ctx->Driver.Accum = _swrast_Accum;
ctx->Driver.Bitmap = _swrast_Bitmap;
ctx->Driver.Clear = clear;
ctx->Driver.CopyPixels = _swrast_CopyPixels;
ctx->Driver.DrawPixels = _swrast_DrawPixels;
ctx->Driver.ReadPixels = _swrast_ReadPixels;
ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
ctx->Driver.GetBufferSize = buffer_size;
@@ -1787,6 +1793,10 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
ctx->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
ctx->Driver.RenderStart = _swsetup_RenderStart;
ctx->Driver.RenderFinish = _swsetup_RenderFinish;
ctx->Driver.RenderInterp = _swsetup_RenderInterp;
ctx->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
ctx->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
ctx->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
/* RGB(A) span/pixel functions */
if (osmesa->format == OSMESA_RGB) {

View File

@@ -1,4 +1,4 @@
/* $Id: xm_dd.c,v 1.11 2001/01/24 00:04:59 brianp Exp $ */
/* $Id: xm_dd.c,v 1.12 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -755,15 +755,23 @@ clear_buffers( GLcontext *ctx, GLbitfield mask,
if (mask & DD_FRONT_LEFT_BIT) {
ASSERT(xmesa->xm_buffer->front_clear_func);
(*xmesa->xm_buffer->front_clear_func)( ctx, all, x, y, width, height );
mask &= ~DD_FRONT_LEFT_BIT;
}
if (mask & DD_BACK_LEFT_BIT) {
ASSERT(xmesa->xm_buffer->back_clear_func);
(*xmesa->xm_buffer->back_clear_func)( ctx, all, x, y, width, height );
mask &= ~DD_BACK_LEFT_BIT;
}
return mask & (~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
if (mask)
_swrast_Clear( ctx, mask, all, x, y, width, height );
}
static void
resize_buffers( GLcontext *ctx )
{
_swrast_alloc_buffers( ctx );
}
#if 0
/*
@@ -923,7 +931,10 @@ void xmesa_init_pointers( GLcontext *ctx )
ctx->Driver.Flush = flush;
ctx->Driver.Finish = finish;
/* Hooks for t_vb_render.c:
*/
ctx->Driver.RenderStart = _swsetup_RenderStart;
ctx->Driver.RenderFinish = _swsetup_RenderFinish;
ctx->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
ctx->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
ctx->Driver.PointsFunc = _swsetup_Points;
@@ -931,15 +942,28 @@ void xmesa_init_pointers( GLcontext *ctx )
ctx->Driver.TriangleFunc = _swsetup_Triangle;
ctx->Driver.QuadFunc = _swsetup_Quad;
ctx->Driver.ResetLineStipple = _swrast_ResetLineStipple;
ctx->Driver.RenderFinish = _swsetup_RenderFinish;
ctx->Driver.RenderInterp = _swsetup_RenderInterp;
ctx->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
ctx->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
ctx->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
/* Software rasterizer pixel paths:
*/
ctx->Driver.Accum = _swrast_Accum;
ctx->Driver.Bitmap = _swrast_Bitmap;
ctx->Driver.Clear = clear_buffers;
ctx->Driver.ResizeBuffersMESA = resize_buffers;
ctx->Driver.CopyPixels = _swrast_CopyPixels;
ctx->Driver.DrawPixels = _swrast_DrawPixels;
ctx->Driver.ReadPixels = _swrast_ReadPixels;
/*
*/
ctx->Driver.SetDrawBuffer = set_draw_buffer;
ctx->Driver.SetReadBuffer = set_read_buffer;
ctx->Driver.ClearIndex = clear_index;
ctx->Driver.ClearColor = clear_color;
ctx->Driver.Clear = clear_buffers;
ctx->Driver.IndexMask = index_mask;
ctx->Driver.ColorMask = color_mask;
ctx->Driver.Enable = enable;

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.X11,v 1.40 2001/01/24 00:04:58 brianp Exp $
# $Id: Makefile.X11,v 1.41 2001/01/29 20:47:39 keithw Exp $
# Mesa 3-D graphics library
# Version: 3.5
@@ -21,6 +21,32 @@ LIBDIR = ../lib
CORE_SOURCES = \
tnl/t_array_api.c \
tnl/t_array_import.c \
tnl/t_context.c \
tnl/t_eval_api.c \
tnl/t_imm_alloc.c \
tnl/t_imm_api.c \
tnl/t_imm_debug.c \
tnl/t_imm_dlist.c \
tnl/t_imm_elt.c \
tnl/t_imm_eval.c \
tnl/t_imm_exec.c \
tnl/t_imm_fixup.c \
tnl/t_pipeline.c \
tnl/t_vb_fog.c \
tnl/t_vb_light.c \
tnl/t_vb_material.c \
tnl/t_vb_normals.c \
tnl/t_vb_points.c \
tnl/t_vb_render.c \
tnl/t_vb_texgen.c \
tnl/t_vb_texmat.c \
tnl/t_vb_vertex.c \
swrast_setup/ss_context.c \
swrast_setup/ss_triangle.c \
swrast_setup/ss_vb.c \
swrast_setup/ss_interp.c \
api_loopback.c \
api_noop.c \
api_validate.c \
@@ -86,6 +112,15 @@ CORE_SOURCES = \
X86/common_x86.c \
X86/3dnow.c \
X86/katmai.c \
math/m_debug_xform.c \
math/m_eval.c \
math/m_matrix.c \
math/m_translate.c \
math/m_vector.c \
math/m_vertices.c \
math/m_xform.c \
array_cache/ac_context.c \
array_cache/ac_import.c \
swrast/s_aaline.c \
swrast/s_aatriangle.c \
swrast/s_accum.c \
@@ -114,41 +149,7 @@ CORE_SOURCES = \
swrast/s_stencil.c \
swrast/s_texture.c \
swrast/s_triangle.c \
swrast/s_zoom.c \
swrast_setup/ss_context.c \
swrast_setup/ss_triangle.c \
swrast_setup/ss_vb.c \
math/m_debug_xform.c \
math/m_eval.c \
math/m_matrix.c \
math/m_translate.c \
math/m_vector.c \
math/m_vertices.c \
math/m_xform.c \
array_cache/ac_context.c \
array_cache/ac_import.c \
tnl/t_array_api.c \
tnl/t_array_import.c \
tnl/t_context.c \
tnl/t_eval_api.c \
tnl/t_imm_alloc.c \
tnl/t_imm_api.c \
tnl/t_imm_debug.c \
tnl/t_imm_dlist.c \
tnl/t_imm_elt.c \
tnl/t_imm_eval.c \
tnl/t_imm_exec.c \
tnl/t_imm_fixup.c \
tnl/t_pipeline.c \
tnl/t_vb_fog.c \
tnl/t_vb_light.c \
tnl/t_vb_material.c \
tnl/t_vb_normals.c \
tnl/t_vb_points.c \
tnl/t_vb_render.c \
tnl/t_vb_texgen.c \
tnl/t_vb_texmat.c \
tnl/t_vb_vertex.c
swrast/s_zoom.c
DRIVER_SOURCES = \

View File

@@ -1,4 +1,4 @@
/* $Id: accum.c,v 1.34 2001/01/23 23:39:36 brianp Exp $ */
/* $Id: accum.c,v 1.35 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -35,7 +35,6 @@
#include "mem.h"
#include "state.h"
#include "mtypes.h"
#include "swrast/swrast.h"
#endif
@@ -92,7 +91,5 @@ _mesa_Accum( GLenum op, GLfloat value )
height = ctx->DrawBuffer->Height;
}
if (!ctx->Driver.Accum ||
!ctx->Driver.Accum( ctx, op, value, xpos, ypos, width, height ))
_swrast_Accum( ctx, op, value, xpos, ypos, width, height );
ctx->Driver.Accum( ctx, op, value, xpos, ypos, width, height );
}

View File

@@ -1,4 +1,4 @@
/* $Id: buffers.c,v 1.24 2001/01/24 00:04:58 brianp Exp $ */
/* $Id: buffers.c,v 1.25 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -41,7 +41,6 @@
#include "stencil.h"
#include "state.h"
#include "mtypes.h"
#include "swrast/swrast.h"
#endif
@@ -126,24 +125,7 @@ _mesa_Clear( GLbitfield mask )
}
ASSERT(ctx->Driver.Clear);
newMask = (*ctx->Driver.Clear)( ctx, ddMask, !ctx->Scissor.Enabled,
x, y, width, height );
#ifdef DEBUG
{
GLbitfield legalBits = DD_FRONT_LEFT_BIT |
DD_FRONT_RIGHT_BIT |
DD_BACK_LEFT_BIT |
DD_BACK_RIGHT_BIT |
DD_DEPTH_BIT |
DD_STENCIL_BIT |
DD_ACCUM_BIT;
assert((newMask & (~legalBits)) == 0);
}
#endif
if (newMask)
_swrast_Clear( ctx, newMask, !ctx->Scissor.Enabled,
ctx->Driver.Clear( ctx, ddMask, !ctx->Scissor.Enabled,
x, y, width, height );
}
}
@@ -387,5 +369,5 @@ _mesa_ResizeBuffersMESA( void )
ctx->DrawBuffer->Width = buf_width;
ctx->DrawBuffer->Height = buf_height;
_swrast_alloc_buffers( ctx );
ctx->Driver.ResizeBuffersMESA( ctx );
}

View File

@@ -1,4 +1,4 @@
/* $Id: dd.h,v 1.48 2001/01/24 00:04:58 brianp Exp $ */
/* $Id: dd.h,v 1.49 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -137,6 +137,12 @@ typedef void (*quad_func)( GLcontext *ctx, GLuint v1, GLuint v2,
typedef void (*render_func)( GLcontext *ctx, GLuint start, GLuint count,
GLuint flags );
typedef void (*interp_func)( GLcontext *ctx,
GLfloat t, GLuint dst, GLuint in, GLuint out,
GLboolean force_boundary );
typedef void (*copy_pv_func)( GLcontext *ctx, GLuint dst, GLuint src );
/*
* Device Driver function table.
@@ -161,13 +167,11 @@ struct dd_function_table {
* LineFunc, or TriangleFunc).
*/
GLbitfield (*Clear)( GLcontext *ctx, GLbitfield mask, GLboolean all,
void (*Clear)( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint x, GLint y, GLint width, GLint height );
/* Clear the color/depth/stencil/accum buffer(s).
* 'mask' is a bitmask of the DD_*_BIT values defined above that indicates
* which buffers need to be cleared. The driver should clear those
* buffers then return a new bitmask indicating which buffers should be
* cleared by software Mesa.
* which buffers need to be cleared.
* If 'all' is true then the clear the whole buffer, else clear only the
* region defined by (x,y,width,height).
* This function must obey the glColorMask, glIndexMask and glStencilMask
@@ -395,7 +399,7 @@ struct dd_function_table {
/***
*** For hardware accumulation buffer:
***/
GLboolean (*Accum)( GLcontext *ctx, GLenum op, GLfloat value,
void (*Accum)( GLcontext *ctx, GLenum op, GLfloat value,
GLint xpos, GLint ypos, GLint width, GLint height );
/* Execute glAccum command within the given scissor region.
*/
@@ -405,48 +409,44 @@ struct dd_function_table {
*** glDraw/Read/CopyPixels and glBitmap functions:
***/
GLboolean (*DrawPixels)( GLcontext *ctx,
void (*DrawPixels)( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels );
/* This is called by glDrawPixels.
* 'unpack' describes how to unpack the source image data.
* Return GL_TRUE if the driver succeeds, return GL_FALSE if core Mesa
* must do the job.
*/
GLboolean (*ReadPixels)( GLcontext *ctx,
void (*ReadPixels)( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
GLvoid *dest );
/* Called by glReadPixels.
* Return GL_TRUE if operation completed, else return GL_FALSE.
* This function must respect all glPixelTransfer settings.
*/
GLboolean (*CopyPixels)( GLcontext *ctx,
void (*CopyPixels)( GLcontext *ctx,
GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint dstx, GLint dsty, GLenum type );
/* Do a glCopyPixels. Return GL_TRUE if operation completed, else
* return GL_FALSE. This function must respect all rasterization
/* Do a glCopyPixels. This function must respect all rasterization
* state, glPixelTransfer, glPixelZoom, etc.
*/
GLboolean (*Bitmap)( GLcontext *ctx,
void (*Bitmap)( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap );
/* This is called by glBitmap. Works the same as DrawPixels, above.
*/
void (*ResizeBuffersMESA)( GLcontext *ctx );
/***
*** Texture image functions:
***/
GLboolean (*TexImage1D)( GLcontext *ctx, GLenum target, GLint level,
GLenum format, GLenum type, const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
@@ -701,6 +701,10 @@ struct dd_function_table {
/* Called by glBindTexture().
*/
void (*CreateTexture)( GLcontext *ctx, struct gl_texture_object *tObj );
/* Called when a texture object is created.
*/
void (*DeleteTexture)( GLcontext *ctx, struct gl_texture_object *tObj );
/* Called when a texture object is about to be deallocated. Driver
* should free anything attached to the DriverData pointers.
@@ -836,6 +840,13 @@ struct dd_function_table {
* modes accepted by glBegin().
*/
interp_func RenderInterp;
copy_pv_func RenderCopyPV;
void (*RenderClippedPolygon)( GLcontext *ctx, const GLuint *elts, GLuint n );
void (*RenderClippedLine)( GLcontext *ctx, GLuint v0, GLuint v1 );
/* Functions to interpolate between prebuilt vertices, copy flat-shade
* provoking color, and to render clipped primitives.
*/
/***
*** Parameters for _tnl_render_stage

View File

@@ -1,4 +1,4 @@
/* $Id: drawpix.c,v 1.47 2000/12/26 05:09:28 keithw Exp $ */
/* $Id: drawpix.c,v 1.48 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -38,7 +38,6 @@
#include "mmath.h"
#include "state.h"
#include "mtypes.h"
#include "swrast/swrast.h"
#endif
@@ -72,15 +71,8 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
/* see if device driver can do the drawpix */
RENDER_START(ctx);
if (ctx->Driver.DrawPixels
&& (*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type,
&ctx->Unpack, pixels)) {
/* finished */
} else
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type,
&ctx->Unpack, pixels);
RENDER_FINISH(ctx);
}
else if (ctx->RenderMode==GL_FEEDBACK) {

View File

@@ -1,4 +1,4 @@
/* $Id: mtypes.h,v 1.16 2001/01/24 04:56:20 brianp Exp $ */
/* $Id: mtypes.h,v 1.17 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -498,9 +498,9 @@ struct gl_light_attrib {
};
#define LIGHT_SPOT 0x1
#define LIGHT_LOCAL_VIEWER 0x2
#define LIGHT_POSITIONAL 0x4
#define LIGHT_SPOT 0x10
#define LIGHT_LOCAL_VIEWER 0x20
#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER)

View File

@@ -1,4 +1,4 @@
/* $Id: texobj.c,v 1.37 2000/12/26 05:09:29 keithw Exp $ */
/* $Id: texobj.c,v 1.38 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -54,8 +54,8 @@
* Return: pointer to new texture object
*/
struct gl_texture_object *
_mesa_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
GLuint dimensions)
_mesa_alloc_texture_object( struct gl_shared_state *shared,
GLuint name, GLuint dimensions )
{
struct gl_texture_object *obj;
@@ -177,7 +177,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
struct gl_texture_object *t )
{
const GLint baseLevel = t->BaseLevel;
GLint maxLog2;
GLint maxLog2 = 0;
t->Complete = GL_TRUE; /* be optimistic */
@@ -522,7 +522,7 @@ _mesa_BindTexture( GLenum target, GLuint texName )
GLuint unit = ctx->Texture.CurrentUnit;
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *oldTexObj;
struct gl_texture_object *newTexObj;
struct gl_texture_object *newTexObj = 0;
GLuint targetDim;
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -594,7 +594,8 @@ _mesa_BindTexture( GLenum target, GLuint texName )
}
else {
/* if this is a new texture id, allocate a texture object now */
newTexObj = _mesa_alloc_texture_object(ctx->Shared, texName, targetDim);
newTexObj = _mesa_alloc_texture_object( ctx->Shared, texName,
targetDim);
if (!newTexObj) {
gl_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
return;

View File

@@ -1,4 +1,4 @@
/* $Id: texstate.c,v 1.28 2001/01/24 00:04:58 brianp Exp $ */
/* $Id: texstate.c,v 1.29 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -41,7 +41,6 @@
#include "mtypes.h"
#include "math/m_xform.h"
#include "math/m_matrix.h"
#include "swrast/swrast.h"
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: ss_context.c,v 1.8 2001/01/16 05:29:43 keithw Exp $ */
/* $Id: ss_context.c,v 1.9 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -32,6 +32,7 @@
#include "ss_context.h"
#include "ss_triangle.h"
#include "ss_vb.h"
#include "ss_interp.h"
#include "swrast_setup.h"
#include "tnl/t_context.h"
@@ -107,6 +108,7 @@ _swsetup_CreateContext( GLcontext *ctx )
swsetup->NewState = ~0;
_swsetup_vb_init( ctx );
_swsetup_interp_init( ctx );
_swsetup_trifuncs_init( ctx );
return GL_TRUE;
@@ -134,6 +136,7 @@ void
_swsetup_RenderStart( GLcontext *ctx )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLuint new_state = swsetup->NewState;
if (new_state & _SWSETUP_NEW_RENDERINDEX) {
@@ -145,6 +148,11 @@ _swsetup_RenderStart( GLcontext *ctx )
}
swsetup->NewState = 0;
if (VB->ClipMask && VB->importable_data)
VB->import_data( ctx,
VB->importable_data,
VEC_NOT_WRITEABLE|VEC_BAD_STRIDE);
}
void
@@ -156,6 +164,26 @@ _swsetup_RenderFinish( GLcontext *ctx )
void
_swsetup_InvalidateState( GLcontext *ctx, GLuint new_state )
{
SWSETUP_CONTEXT(ctx)->NewState |= new_state;
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
swsetup->NewState |= new_state;
if (new_state & _SWSETUP_NEW_INTERP) {
swsetup->RenderInterp = _swsetup_validate_interp;
swsetup->RenderCopyPV = _swsetup_validate_copypv;
}
}
void
_swsetup_RenderInterp( GLcontext *ctx, GLfloat t,
GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary )
{
SWSETUP_CONTEXT(ctx)->RenderInterp( ctx, t, dst, out, in, force_boundary );
}
void
_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src )
{
SWSETUP_CONTEXT(ctx)->RenderCopyPV( ctx, dst, src );
}

View File

@@ -53,6 +53,13 @@ typedef struct {
void (*Points)( GLcontext *ctx, GLuint first, GLuint last );
void (*RenderCopyPV)( GLcontext *ctx, GLuint dst, GLuint src );
void (*RenderInterp)( GLcontext *ctx, GLfloat t,
GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary );
SWvertex *verts;
GLenum render_prim;

View File

@@ -49,7 +49,10 @@ static void TAG(rs)(GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs )
const GLfloat tz = m[14];
GLuint maxtex = 0;
/* fprintf(stderr, "%s\n", __FUNCTION__); */
if (!newinputs) {
fprintf(stderr, "no new inputs\n");
return;
}
/* TODO: Get import_client_data to pad vectors out to 4 cleanly.
*/

View File

@@ -69,4 +69,22 @@ _swsetup_RenderStart( GLcontext *ctx );
extern void
_swsetup_RenderFinish( GLcontext *ctx );
extern void
_swsetup_RenderProjectInterpVerts( GLcontext *ctx );
extern void
_swsetup_RenderInterp( GLcontext *ctx, GLfloat t,
GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary );
extern void
_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src );
extern void
_swsetup_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n );
extern void
_swsetup_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj );
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: t_context.h,v 1.12 2001/01/24 00:04:59 brianp Exp $ */
/* $Id: t_context.h,v 1.13 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -234,12 +234,6 @@ struct vertex_arrays
typedef struct gl_material GLmaterial;
typedef void (*interp_func)( GLcontext *ctx,
GLfloat t, GLuint dst, GLuint in, GLuint out,
GLboolean force_boundary );
typedef void (*copy_pv_func)( GLcontext *ctx, GLuint dst, GLuint src );
/* Contains the current state of a running pipeline.
*/
typedef struct vertex_buffer
@@ -299,8 +293,6 @@ typedef struct vertex_buffer
*/
GLuint LastClipped;
interp_func interpfunc;
copy_pv_func copypvfunc;
/* Private data from _tnl_render_stage that has no business being
* in this struct.
*/

View File

@@ -1,4 +1,4 @@
/* $Id: t_imm_dlist.c,v 1.5 2001/01/08 21:56:00 keithw Exp $ */
/* $Id: t_imm_dlist.c,v 1.6 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -156,6 +156,9 @@ _tnl_compile_cassette( GLcontext *ctx, struct immediate *IM )
#if 0
/* Drivers to turn this on?
*/
static void calc_normal_lengths( GLfloat *dest,
CONST GLfloat (*data)[3],
GLuint *flags,
@@ -177,7 +180,7 @@ static void calc_normal_lengths( GLfloat *dest,
flags[0] = tmpflag;
}
#endif
static void

View File

@@ -1,4 +1,4 @@
/* $Id: t_pipeline.c,v 1.10 2001/01/17 02:49:39 keithw Exp $ */
/* $Id: t_pipeline.c,v 1.11 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -77,40 +77,50 @@ void _tnl_destroy_pipeline( GLcontext *ctx )
tnl->pipeline.nr_stages = 0;
}
/* TODO: merge validate with run.
*/
void _tnl_validate_pipeline( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct gl_pipeline *pipe = &tnl->pipeline;
struct gl_pipeline_stage *stage = pipe->stages;
struct gl_pipeline_stage *s = pipe->stages;
GLuint newstate = pipe->build_state_changes;
GLuint generated = 0;
GLuint i;
GLuint changed_inputs = 0;
pipe->inputs = 0;
pipe->build_state_changes = 0;
for (i = 0 ; i < pipe->nr_stages ; i++) {
if (stage[i].check_state & newstate) {
stage[i].check(ctx, &stage[i]);
for (i = pipe->nr_stages+1 ; --i ; s++) {
s->changed_inputs |= s->inputs & changed_inputs;
if (s->check_state & newstate) {
if (s->active) {
GLuint old_outputs = s->outputs;
s->check(ctx, s);
if (!s->active)
changed_inputs |= old_outputs;
}
else
s->check(ctx, s);
}
if (stage[i].active) {
pipe->inputs |= stage[i].inputs & ~generated;
generated |= stage[i].outputs;
if (s->active) {
pipe->inputs |= s->inputs & ~generated;
generated |= s->outputs;
}
}
}
void _tnl_run_pipeline( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct gl_pipeline *pipe = &tnl->pipeline;
struct gl_pipeline_stage *stage = pipe->stages;
struct gl_pipeline_stage *s = pipe->stages;
GLuint changed_state = pipe->run_state_changes;
GLuint changed_inputs = pipe->run_input_changes;
GLboolean running = GL_TRUE;
@@ -129,21 +139,21 @@ void _tnl_run_pipeline( GLcontext *ctx )
* Even inactive stages have their state and inputs examined to try
* to keep cached data alive over state-changes.
*/
for (i = 0 ; i < pipe->nr_stages ; i++) {
for (i = pipe->nr_stages+1 ; --i ; s++) {
s->changed_inputs |= s->inputs & changed_inputs;
stage[i].changed_inputs |= stage[i].inputs & changed_inputs;
if (stage[i].run_state & changed_state) {
stage[i].changed_inputs = stage[i].inputs;
if (s->run_state & changed_state) {
/* changed_inputs |= s->check(ctx, s); */
s->changed_inputs = s->inputs;
}
if (stage[i].active) {
if (stage[i].changed_inputs)
changed_inputs |= stage[i].outputs;
if (s->active) {
if (running) {
running = stage[i].run( ctx, &stage[i] );
stage[i].changed_inputs = 0;
if (s->changed_inputs)
changed_inputs |= s->outputs;
/* fprintf(stderr, "run %s\n", s->name); */
running = s->run( ctx, s );
}
}
}

View File

@@ -1,4 +1,4 @@
/* $Id: t_vb_cliptmp.h,v 1.7 2001/01/17 02:49:39 keithw Exp $ */
/* $Id: t_vb_cliptmp.h,v 1.8 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -58,13 +58,13 @@ do { \
* know dp != dpPrev from DIFFERENT_SIGNS, above. \
*/ \
GLfloat t = dp / (dp - dpPrev); \
LINTERP_SZ( t, coord, newvert, idx, idxPrev, SIZE ); \
LINTERP_4F( t, coord, newvert, idx, idxPrev, SIZE ); \
interp( ctx, t, newvert, idx, idxPrev, GL_TRUE ); \
} else { \
/* Coming back in. \
*/ \
GLfloat t = dpPrev / (dpPrev - dp); \
LINTERP_SZ( t, coord, newvert, idxPrev, idx, SIZE ); \
LINTERP_4F( t, coord, newvert, idxPrev, idx, SIZE ); \
interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \
} \
} \
@@ -98,13 +98,13 @@ do { \
if (NEGATIVE(dpJ)) { \
GLfloat t = dpI / (dpI - dpJ); \
VB->ClipMask[jj] |= PLANE; \
LINTERP_SZ( t, coord, newvert, ii, jj, SIZE ); \
LINTERP_4F( t, coord, newvert, ii, jj, SIZE ); \
interp( ctx, t, newvert, ii, jj, GL_FALSE ); \
jj = newvert; \
} else { \
GLfloat t = dpJ / (dpJ - dpI); \
VB->ClipMask[ii] |= PLANE; \
LINTERP_SZ( t, coord, newvert, jj, ii, SIZE ); \
LINTERP_4F( t, coord, newvert, jj, ii, SIZE ); \
interp( ctx, t, newvert, jj, ii, GL_FALSE ); \
ii = newvert; \
} \
@@ -115,50 +115,15 @@ do { \
} while (0)
static void TAG(build_proj_verts)( GLcontext *ctx )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
/* Project if necessary.
*/
if (VB->ProjectedClipPtr) {
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLfloat (*proj)[4] = VB->ProjectedClipPtr->data;
GLuint last = VB->LastClipped;
GLuint i;
for (i = VB->FirstClipped; i < last; i++) {
if (VB->ClipMask[i] == 0) {
if (SIZE == 4 && W(i) != 0.0F) {
GLfloat wInv = 1.0F / W(i);
proj[i][0] = X(i) * wInv;
proj[i][1] = Y(i) * wInv;
proj[i][2] = Z(i) * wInv;
proj[i][3] = wInv;
} else {
proj[i][0] = X(i);
proj[i][1] = Y(i);
proj[i][2] = Z(i);
proj[i][3] = W(i);
}
}
}
}
ctx->Driver.BuildProjectedVertices(ctx,
VB->FirstClipped,
VB->LastClipped,
~0);
}
/* Clip a line against the viewport and user clip planes.
*/
static void TAG(clip_line)( GLcontext *ctx,
static __inline void TAG(clip_line)( GLcontext *ctx,
GLuint i, GLuint j,
GLubyte mask )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
interp_func interp = (interp_func) VB->interpfunc;
interp_func interp = ctx->Driver.RenderInterp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint ii = i, jj = j, p;
@@ -186,31 +151,29 @@ static void TAG(clip_line)( GLcontext *ctx,
}
if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj)
VB->copypvfunc( ctx, jj, j );
TAG(build_proj_verts)( ctx );
/* Render the new line.
*/
ctx->Driver.LineFunc( ctx, ii, jj );
ctx->Driver.RenderCopyPV( ctx, jj, j );
ctx->Driver.RenderClippedLine( ctx, ii, jj );
}
/* Clip a triangle or quad against the viewport and user clip planes.
/* Clip a triangle against the viewport and user clip planes.
*/
static void TAG(clip_polygon)( GLcontext *ctx,
GLuint n, GLuint vlist[],
static __inline void TAG(clip_tri)( GLcontext *ctx,
GLuint v0, GLuint v1, GLuint v2,
GLubyte mask )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
interp_func interp = (interp_func) VB->interpfunc;
interp_func interp = ctx->Driver.RenderInterp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint pv = vlist[0];
GLuint vlist2[MAX_CLIPPED_VERTICES];
GLuint *inlist = vlist, *outlist = vlist2;
GLuint pv = v0;
GLuint vlist[2][MAX_CLIPPED_VERTICES];
GLuint *inlist = vlist[0], *outlist = vlist[1];
GLuint p;
GLubyte *clipmask = VB->ClipMask;
GLuint n = 3;
ASSIGN_3V(inlist, v0, v1, v2 );
VB->LastClipped = VB->FirstClipped;
@@ -238,25 +201,64 @@ static void TAG(clip_polygon)( GLcontext *ctx,
if (ctx->_TriangleCaps & DD_FLATSHADE) {
if (pv != inlist[0]) {
ASSERT( inlist[0] >= VB->FirstClipped );
VB->copypvfunc( ctx, inlist[0], pv );
ctx->Driver.RenderCopyPV( ctx, inlist[0], pv );
}
}
TAG(build_proj_verts)( ctx );
ctx->Driver.RenderClippedPolygon( ctx, inlist, n );
}
/* Render the new vertices as an unclipped polygon.
/* Clip a quad against the viewport and user clip planes.
*/
static __inline void TAG(clip_quad)( GLcontext *ctx,
GLuint v0, GLuint v1, GLuint v2, GLuint v3,
GLubyte mask )
{
GLuint *tmp = VB->Elts;
VB->Elts = inlist;
ctx->Driver.RenderTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
VB->Elts = tmp;
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
interp_func interp = ctx->Driver.RenderInterp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint pv = v0;
GLuint vlist[2][MAX_CLIPPED_VERTICES];
GLuint *inlist = vlist[0], *outlist = vlist[1];
GLuint p;
GLubyte *clipmask = VB->ClipMask;
GLuint n = 4;
ASSIGN_4V(inlist, v0, v1, v2, v3 );
VB->LastClipped = VB->FirstClipped;
if (mask & 0x3f) {
POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 );
POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 );
POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 );
POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 );
POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 );
}
if (mask & CLIP_USER_BIT) {
for (p=0;p<MAX_CLIP_PLANES;p++) {
if (ctx->Transform.ClipEnabled[p]) {
GLfloat a = ctx->Transform._ClipUserPlane[p][0];
GLfloat b = ctx->Transform._ClipUserPlane[p][1];
GLfloat c = ctx->Transform._ClipUserPlane[p][2];
GLfloat d = ctx->Transform._ClipUserPlane[p][3];
POLY_CLIP( CLIP_USER_BIT, a, b, c, d );
}
}
}
if (ctx->_TriangleCaps & DD_FLATSHADE) {
if (pv != inlist[0]) {
ASSERT( inlist[0] >= VB->FirstClipped );
ctx->Driver.RenderCopyPV( ctx, inlist[0], pv );
}
}
ctx->Driver.RenderClippedPolygon( ctx, inlist, n );
}
#undef W
#undef Z

View File

@@ -1,4 +1,4 @@
/* $Id: t_vb_render.c,v 1.11 2001/01/23 23:39:37 brianp Exp $ */
/* $Id: t_vb_render.c,v 1.12 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -51,7 +51,6 @@
#include "glheader.h"
#include "context.h"
#include "colormac.h"
#include "macros.h"
#include "mem.h"
#include "mtypes.h"
@@ -75,296 +74,6 @@ typedef void (*clip_poly_func)( GLcontext *ctx,
struct render_stage_data {
/* Clipping functions for current state.
*/
interp_func interp; /* Clip interpolation function */
copy_pv_func copypv; /* Flatshade fixup function */
GLuint _ClipInputs; /* Inputs referenced by interpfunc */
};
#define RENDER_STAGE_DATA(stage) ((struct render_stage_data *)stage->private)
/**********************************************************************/
/* Interpolate between pairs of vertices */
/**********************************************************************/
#define LINTERP_SZ( t, vec, to, a, b, sz ) \
do { \
switch (sz) { \
case 4: vec[to][3] = LINTERP( t, vec[a][3], vec[b][3] ); \
case 3: vec[to][2] = LINTERP( t, vec[a][2], vec[b][2] ); \
case 2: vec[to][1] = LINTERP( t, vec[a][1], vec[b][1] ); \
case 1: vec[to][0] = LINTERP( t, vec[a][0], vec[b][0] ); \
} \
} while(0)
#if 1
#define LINTERP_RGBA(nr, t, out, a, b) { \
int i; \
for (i = 0; i < nr; i++) { \
GLfloat fa = CHAN_TO_FLOAT(a[i]); \
GLfloat fb = CHAN_TO_FLOAT(b[i]); \
GLfloat fo = LINTERP(t, fa, fb); \
CLAMPED_FLOAT_TO_CHAN(out[i], fo); \
} \
}
#else
#define LINTERP_RGBA(nr, t, out, a, b) { \
int n; \
const GLuint ti = FloatToInt(t*256.0F); \
const GLubyte *Ib = (const GLubyte *)&a[0]; \
const GLubyte *Jb = (const GLubyte *)&b[0]; \
GLubyte *Ob = (GLubyte *)&out[0]; \
\
for (n = 0 ; n < nr ; n++) \
Ob[n] = (GLubyte) (Ib[n] + ((ti * (Jb[n] - Ib[n]))/256)); \
}
#endif
#define INTERP_RGBA 0x1
#define INTERP_TEX 0x2
#define INTERP_INDEX 0x4
#define INTERP_SPEC 0x8
#define INTERP_FOG 0x10
#define INTERP_EDGE 0x20
#define MAX_INTERP 0x40
static interp_func interp_tab[MAX_INTERP];
static copy_pv_func copy_tab[MAX_INTERP];
#define IND (0)
#define NAME interp_none
#include "t_vb_interptmp.h"
#define IND (INTERP_FOG)
#define NAME interp_FOG
#include "t_vb_interptmp.h"
#define IND (INTERP_TEX)
#define NAME interp_TEX
#include "t_vb_interptmp.h"
#define IND (INTERP_FOG|INTERP_TEX)
#define NAME interp_FOG_TEX
#include "t_vb_interptmp.h"
#define IND (INTERP_EDGE)
#define NAME interp_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_FOG|INTERP_EDGE)
#define NAME interp_FOG_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_TEX|INTERP_EDGE)
#define NAME interp_TEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_FOG|INTERP_TEX|INTERP_EDGE)
#define NAME interp_FOG_TEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA)
#define NAME interp_RGBA
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC)
#define NAME interp_RGBA_SPEC
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_FOG)
#define NAME interp_RGBA_FOG
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_FOG)
#define NAME interp_RGBA_SPEC_FOG
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_TEX)
#define NAME interp_RGBA_TEX
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_TEX)
#define NAME interp_RGBA_SPEC_TEX
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_FOG|INTERP_TEX)
#define NAME interp_RGBA_FOG_TEX
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX)
#define NAME interp_RGBA_SPEC_FOG_TEX
#include "t_vb_interptmp.h"
#define IND (INTERP_INDEX)
#define NAME interp_INDEX
#include "t_vb_interptmp.h"
#define IND (INTERP_FOG|INTERP_INDEX)
#define NAME interp_FOG_INDEX
#include "t_vb_interptmp.h"
#define IND (INTERP_TEX|INTERP_INDEX)
#define NAME interp_TEX_INDEX
#include "t_vb_interptmp.h"
#define IND (INTERP_FOG|INTERP_TEX|INTERP_INDEX)
#define NAME interp_FOG_TEX_INDEX
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_EDGE)
#define NAME interp_RGBA_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_EDGE)
#define NAME interp_RGBA_SPEC_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_FOG|INTERP_EDGE)
#define NAME interp_RGBA_FOG_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_EDGE)
#define NAME interp_RGBA_SPEC_FOG_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_TEX|INTERP_EDGE)
#define NAME interp_RGBA_TEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_TEX|INTERP_EDGE)
#define NAME interp_RGBA_SPEC_TEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_FOG|INTERP_TEX|INTERP_EDGE)
#define NAME interp_RGBA_FOG_TEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX|INTERP_EDGE)
#define NAME interp_RGBA_SPEC_FOG_TEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_INDEX|INTERP_EDGE)
#define NAME interp_INDEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_FOG|INTERP_INDEX|INTERP_EDGE)
#define NAME interp_FOG_INDEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_TEX|INTERP_INDEX|INTERP_EDGE)
#define NAME interp_TEX_INDEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_FOG|INTERP_TEX|INTERP_INDEX|INTERP_EDGE)
#define NAME interp_FOG_TEX_INDEX_EDGE
#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA)
#define NAME copy_RGBA
#include "t_vb_flattmp.h"
#define IND (INTERP_RGBA|INTERP_SPEC)
#define NAME copy_RGBA_SPEC
#include "t_vb_flattmp.h"
#define IND (INTERP_INDEX)
#define NAME copy_INDEX
#include "t_vb_flattmp.h"
static void interp_invalid( GLcontext *ctx,
GLfloat t,
GLuint dst, GLuint in, GLuint out,
GLboolean boundary )
{
(void)(ctx && t && in && out && boundary);
fprintf(stderr, "Invalid interpolation function in t_vbrender.c\n");
}
static void copy_invalid( GLcontext *ctx, GLuint dst, GLuint src )
{
(void)(ctx && dst && src);
fprintf(stderr, "Invalid copy function in t_vbrender.c\n");
}
static void interp_init( void )
{
GLuint i;
/* Use the maximal function as the default. I don't believe any of
* the non-implemented combinations are reachable, but this gives
* some safety from crashes.
*/
for (i = 0 ; i < Elements(interp_tab) ; i++) {
interp_tab[i] = interp_invalid;
copy_tab[i] = copy_invalid;
}
interp_tab[0] = interp_none;
interp_tab[INTERP_FOG] = interp_FOG;
interp_tab[INTERP_TEX] = interp_TEX;
interp_tab[INTERP_FOG|INTERP_TEX] = interp_FOG_TEX;
interp_tab[INTERP_EDGE] = interp_EDGE;
interp_tab[INTERP_FOG|INTERP_EDGE] = interp_FOG_EDGE;
interp_tab[INTERP_TEX|INTERP_EDGE] = interp_TEX_EDGE;
interp_tab[INTERP_FOG|INTERP_TEX|INTERP_EDGE] = interp_FOG_TEX_EDGE;
interp_tab[INTERP_RGBA] = interp_RGBA;
interp_tab[INTERP_RGBA|INTERP_SPEC] = interp_RGBA_SPEC;
interp_tab[INTERP_RGBA|INTERP_FOG] = interp_RGBA_FOG;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG] = interp_RGBA_SPEC_FOG;
interp_tab[INTERP_RGBA|INTERP_TEX] = interp_RGBA_TEX;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_TEX] = interp_RGBA_SPEC_TEX;
interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_TEX] = interp_RGBA_FOG_TEX;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX] =
interp_RGBA_SPEC_FOG_TEX;
interp_tab[INTERP_INDEX] = interp_INDEX;
interp_tab[INTERP_FOG|INTERP_INDEX] = interp_FOG_INDEX;
interp_tab[INTERP_TEX|INTERP_INDEX] = interp_TEX_INDEX;
interp_tab[INTERP_FOG|INTERP_TEX|INTERP_INDEX] = interp_FOG_TEX_INDEX;
interp_tab[INTERP_RGBA|INTERP_EDGE] = interp_RGBA_EDGE;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_EDGE] = interp_RGBA_SPEC_EDGE;
interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_EDGE] = interp_RGBA_FOG_EDGE;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_EDGE] =
interp_RGBA_SPEC_FOG_EDGE;
interp_tab[INTERP_RGBA|INTERP_TEX|INTERP_EDGE] = interp_RGBA_TEX_EDGE;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_TEX|INTERP_EDGE] =
interp_RGBA_SPEC_TEX_EDGE;
interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_TEX|INTERP_EDGE] =
interp_RGBA_FOG_TEX_EDGE;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX|INTERP_EDGE] =
interp_RGBA_SPEC_FOG_TEX_EDGE;
interp_tab[INTERP_INDEX|INTERP_EDGE] = interp_INDEX_EDGE;
interp_tab[INTERP_FOG|INTERP_INDEX|INTERP_EDGE] = interp_FOG_INDEX_EDGE;
interp_tab[INTERP_TEX|INTERP_INDEX|INTERP_EDGE] = interp_TEX_INDEX_EDGE;
interp_tab[INTERP_FOG|INTERP_TEX|INTERP_INDEX|INTERP_EDGE] =
interp_FOG_TEX_INDEX_EDGE;
copy_tab[INTERP_RGBA] = copy_RGBA;
copy_tab[INTERP_RGBA|INTERP_SPEC] = copy_RGBA_SPEC;
copy_tab[INTERP_INDEX] = copy_INDEX;
}
/**********************************************************************/
/* Clip single primitives */
@@ -382,6 +91,28 @@ static void interp_init( void )
*/
#endif
#define LINTERP_SZ( t, vec, to, a, b, sz ) \
do { \
switch (sz) { \
case 2: vec[to][2] = 0.0; \
case 3: vec[to][3] = 1.0; \
} \
switch (sz) { \
case 4: vec[to][3] = LINTERP( t, vec[a][3], vec[b][3] ); \
case 3: vec[to][2] = LINTERP( t, vec[a][2], vec[b][2] ); \
case 2: vec[to][1] = LINTERP( t, vec[a][1], vec[b][1] ); \
vec[to][0] = LINTERP( t, vec[a][0], vec[b][0] ); \
} \
} while(0)
#define LINTERP_4F( t, vec, to, a, b, sz ) \
do { \
vec[to][3] = LINTERP( t, vec[a][3], vec[b][3] ); \
vec[to][2] = LINTERP( t, vec[a][2], vec[b][2] ); \
vec[to][1] = LINTERP( t, vec[a][1], vec[b][1] ); \
vec[to][0] = LINTERP( t, vec[a][0], vec[b][0] ); \
} while (0)
#define W(i) coord[i][3]
#define Z(i) coord[i][2]
#define Y(i) coord[i][1]
@@ -390,37 +121,6 @@ static void interp_init( void )
#define TAG(x) x##_4
#include "t_vb_cliptmp.h"
#define W(i) 1.0
#define Z(i) coord[i][2]
#define Y(i) coord[i][1]
#define X(i) coord[i][0]
#define SIZE 3
#define TAG(x) x##_3
#include "t_vb_cliptmp.h"
#define W(i) 1.0
#define Z(i) 0.0
#define Y(i) coord[i][1]
#define X(i) coord[i][0]
#define SIZE 2
#define TAG(x) x##_2
#include "t_vb_cliptmp.h"
static clip_poly_func clip_poly_tab[5] = {
0,
0,
clip_polygon_2,
clip_polygon_3,
clip_polygon_4
};
static clip_line_func clip_line_tab[5] = {
0,
0,
clip_line_2,
clip_line_3,
clip_line_4
};
/**********************************************************************/
@@ -444,7 +144,7 @@ do { \
if (!ormask) \
LineFunc( ctx, v1, v2 ); \
else if (!(c1 & c2 & 0x3f)) \
clip_line_tab[sz]( ctx, v1, v2, ormask ); \
clip_line_4( ctx, v1, v2, ormask ); \
} while (0)
#define RENDER_TRI( v1, v2, v3 ) \
@@ -453,11 +153,8 @@ do { \
GLubyte ormask = c1|c2|c3; \
if (!ormask) \
TriangleFunc( ctx, v1, v2, v3 ); \
else if (!(c1 & c2 & c3 & 0x3f)) { \
GLuint vlist[MAX_CLIPPED_VERTICES]; \
ASSIGN_3V(vlist, v3, v1, v2 ); \
clip_poly_tab[sz]( ctx, 3, vlist, ormask ); \
} \
else if (!(c1 & c2 & c3 & 0x3f)) \
clip_tri_4( ctx, v1, v2, v3, ormask ); \
} while (0)
#define RENDER_QUAD( v1, v2, v3, v4 ) \
@@ -467,11 +164,8 @@ do { \
GLubyte ormask = c1|c2|c3|c4; \
if (!ormask) \
QuadFunc( ctx, v1, v2, v3, v4 ); \
else if (!(c1 & c2 & c3 & c4 & 0x3f)) { \
GLuint vlist[MAX_CLIPPED_VERTICES]; \
ASSIGN_4V(vlist, v4, v1, v2, v3 ); \
clip_poly_tab[sz]( ctx, 4, vlist, ormask ); \
} \
else if (!(c1 & c2 & c3 & c4 & 0x3f)) \
clip_quad_4( ctx, v1, v2, v3, v4, ormask ); \
} while (0)
@@ -483,12 +177,13 @@ do { \
const line_func LineFunc = ctx->Driver.LineFunc; \
const triangle_func TriangleFunc = ctx->Driver.TriangleFunc; \
const quad_func QuadFunc = ctx->Driver.QuadFunc; \
const GLboolean stipple = ctx->Line.StippleFlag; \
(void) (LineFunc && TriangleFunc && QuadFunc); \
(void) elt; (void) mask; (void) sz;
(void) elt; (void) mask; (void) sz; (void) stipple;
#define TAG(x) clip_##x##_verts
#define INIT(x) ctx->Driver.RenderPrimitive( ctx, x )
#define RESET_STIPPLE ctx->Driver.ResetLineStipple( ctx )
#define RESET_STIPPLE if (stipple) ctx->Driver.ResetLineStipple( ctx )
#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE;
#define PRESERVE_VB_DEFS
#include "t_vb_rendertmp.h"
@@ -503,6 +198,40 @@ do { \
#define TAG(x) clip_##x##_elts
#include "t_vb_rendertmp.h"
/* TODO: do this for all primitives, verts and elts:
*/
static void clip_elt_triangles( GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags )
{
GLuint j;
GLuint last = count-2;
render_func render_tris = ctx->Driver.RenderTabElts[GL_TRIANGLES];
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
const GLuint * const elt = VB->Elts;
GLubyte *mask = VB->ClipMask;
(void) flags;
ctx->Driver.RenderPrimitive( ctx, GL_TRIANGLES );
for (j=start; j < last; j+=3 ) {
GLubyte c1 = mask[elt[j]];
GLubyte c2 = mask[elt[j+1]];
GLubyte c3 = mask[elt[j+2]];
GLubyte ormask = c1|c2|c3;
if (ormask) {
if (start < j)
render_tris( ctx, start, j, 0 );
if (!(c1&c2&c3&0x3f))
clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask );
start = j+3;
}
}
if (start < j)
render_tris( ctx, start, j, 0 );
}
/**********************************************************************/
/* Render whole begin/end objects */
@@ -570,29 +299,21 @@ static GLboolean run_render( GLcontext *ctx,
render_func *tab;
GLint pass = 0;
VB->interpfunc = RENDER_STAGE_DATA(stage)->interp;
VB->copypvfunc = RENDER_STAGE_DATA(stage)->copypv;
/* Allow the drivers to lock before projected verts are built so
* that window coordinates are guarenteed not to change before
* rendering.
*/
ctx->Driver.RenderStart( ctx );
ctx->Driver.BuildProjectedVertices( ctx, 0, VB->Count, new_inputs );
if (VB->ClipOrMask) {
tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
if (new_inputs & VB->importable_data)
VB->import_data( ctx,
new_inputs & VB->importable_data,
VEC_NOT_WRITEABLE|VEC_BAD_STRIDE);
clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles;
}
else {
tab = VB->Elts ? ctx->Driver.RenderTabElts : ctx->Driver.RenderTabVerts;
}
ctx->Driver.BuildProjectedVertices( ctx, 0, VB->Count, new_inputs );
do
{
GLuint i, length, flags = 0;
@@ -623,30 +344,21 @@ static GLboolean run_render( GLcontext *ctx,
/* Quite a bit of work involved in finding out the inputs for the
* render stage. This function also identifies which vertex
* interpolation function to use, as these are essentially the same
* question.
* render stage.
*/
static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
{
struct render_stage_data *store = RENDER_STAGE_DATA(stage);
GLuint interp = 0;
GLuint copy = 0;
GLuint inputs = VERT_CLIP;
GLuint i;
if (ctx->Visual.rgbMode) {
interp |= INTERP_RGBA;
inputs |= VERT_RGBA;
if (ctx->_TriangleCaps & DD_SEPERATE_SPECULAR) {
interp |= INTERP_SPEC;
inputs |= VERT_SPEC_RGB;
}
if (ctx->Texture._ReallyEnabled) {
interp |= INTERP_TEX;
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled)
inputs |= VERT_TEX(i);
@@ -655,7 +367,6 @@ static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
}
else
{
interp |= INTERP_INDEX;
inputs |= VERT_INDEX;
}
@@ -665,63 +376,25 @@ static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
/* How do drivers turn this off?
*/
if (ctx->Fog.Enabled) {
interp |= INTERP_FOG;
inputs |= VERT_FOG_COORD;
}
if (ctx->_TriangleCaps & DD_TRI_UNFILLED) {
inputs |= VERT_EDGE;
interp |= INTERP_EDGE;
}
if (ctx->RenderMode==GL_FEEDBACK) {
interp |= INTERP_TEX;
inputs |= VERT_TEX_ANY;
}
if (ctx->_TriangleCaps & DD_FLATSHADE) {
copy = interp & (INTERP_RGBA|INTERP_SPEC|INTERP_INDEX);
interp &= ~copy;
}
store->copypv = copy_tab[copy];
store->interp = interp_tab[interp];
stage->inputs = inputs;
}
/* Called the first time stage->check() is invoked.
*/
static void alloc_render_data( GLcontext *ctx,
struct gl_pipeline_stage *stage )
{
struct render_stage_data *store;
static GLboolean first_time = 1;
if (first_time) {
interp_init();
first_time = 0;
}
stage->private = MALLOC(sizeof(*store));
if (!stage->private)
return;
/* Now do the check.
*/
stage->check = check_render;
stage->check( ctx, stage );
}
static void dtr( struct gl_pipeline_stage *stage )
{
struct render_stage_data *store = RENDER_STAGE_DATA(stage);
if (store) {
FREE( store );
stage->private = 0;
}
}
@@ -742,6 +415,6 @@ const struct gl_pipeline_stage _tnl_render_stage =
0, 0, /* inputs (set in check_render), outputs */
0, 0, /* changed_inputs, private */
dtr, /* destructor */
alloc_render_data, /* check - initially set to alloc data */
check_render, /* check */
run_render /* run */
};

View File

@@ -1,4 +1,4 @@
/* $Id: t_vb_texgen.c,v 1.1 2000/12/26 05:09:33 keithw Exp $ */
/* $Id: t_vb_texgen.c,v 1.2 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -372,6 +372,7 @@ static void texgen( GLcontext *ctx,
GLuint count = VB->Count;
GLfloat (*f)[3] = store->tmp_f;
GLfloat *m = store->tmp_m;
GLuint holes = 0;
if (texUnit->_GenFlags & TEXGEN_NEED_M) {
@@ -380,25 +381,33 @@ static void texgen( GLcontext *ctx,
build_f_tab[in->size]( (GLfloat *)store->tmp_f, 3, normal, eye );
}
if (in != out) {
if (!in) {
ASSERT(0);
in = out;
in->count = VB->Count;
out->size = store->TexgenSize[unit];
out->flags |= texUnit->TexGenEnabled;
out->count = VB->Count;
holes = store->TexgenHoles[unit];
}
else {
GLuint copy = (all_bits[in->size] & ~texUnit->TexGenEnabled);
if (copy)
gl_copy_tab[0][copy](out, in, 0);
out->size = MAX2(in->size, store->TexgenSize[unit]);
out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled;
out->count = in->count;
holes = ~all_bits[in->size] & store->TexgenHoles[unit];
}
if (store->TexgenHoles[unit])
{
GLuint holes = (~all_bits[in->size] & store->TexgenHoles[unit]);
if (holes) {
if (holes & VEC_DIRTY_2) gl_vector4f_clean_elem(out, count, 2);
if (holes & VEC_DIRTY_1) gl_vector4f_clean_elem(out, count, 1);
if (holes & VEC_DIRTY_0) gl_vector4f_clean_elem(out, count, 0);
}
}
out->size = MAX2(in->size, store->TexgenSize[unit]);
out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled;
out->count = in->count;
if (texUnit->TexGenEnabled & S_BIT) {
GLuint i;
@@ -604,8 +613,8 @@ static void check_texgen( GLcontext *ctx, struct gl_pipeline_stage *stage )
/* Need the original input in case it contains a Q coord:
* (sigh)
*/
if ((ctx->Texture.Unit[i]._ReallyEnabled|Q_BIT) &
~ctx->Texture.Unit[i].TexGenEnabled)
/* if ((ctx->Texture.Unit[i]._ReallyEnabled|Q_BIT) & */
/* ~ctx->Texture.Unit[i].TexGenEnabled) */
inputs |= VERT_TEX(i);
/* Something for Feedback? */

View File

@@ -1,4 +1,4 @@
/* $Id: t_vb_vertex.c,v 1.2 2001/01/13 05:48:26 keithw Exp $ */
/* $Id: t_vb_vertex.c,v 1.3 2001/01/29 20:47:39 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -167,6 +167,19 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
VB->ObjPtr );
}
/* Drivers expect this to be clean to element 4...
*/
if (VB->ClipPtr->size < 4) {
if (VB->ClipPtr->flags & VEC_NOT_WRITEABLE) {
ASSERT(VB->ClipPtr == VB->ObjPtr);
VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE );
VB->ClipPtr = VB->ObjPtr;
}
if (VB->ClipPtr->size == 2)
gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
}
/* Cliptest and perspective divide. Clip functions must clear
* the clipmask.
*/
@@ -181,20 +194,6 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
&store->ormask,
&store->andmask );
/* Drivers expect this to be size 4...
*/
if (VB->ProjectedClipPtr->size < 4) {
ASSERT(VB->ProjectedClipPtr == VB->ClipPtr);
if (VB->ProjectedClipPtr->flags & VEC_NOT_WRITEABLE) {
ASSERT(VB->ProjectedClipPtr == VB->ObjPtr);
VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE );
VB->ProjectedClipPtr = VB->ClipPtr = VB->ObjPtr;
}
if (VB->ClipPtr->size == 2)
gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
VB->ClipPtr->size = 4;
}
} else {
VB->ProjectedClipPtr = 0;
gl_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,