/* * Mesa 3-D graphics library * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /** * \file swrast/s_context.h * \brief Software rasterization context and private types. * \author Keith Whitwell */ /** * \mainpage swrast module * * This module, software rasterization, contains the software fallback * routines for drawing points, lines, triangles, bitmaps and images. * All rendering boils down to writing spans (arrays) of pixels with * particular colors. The span-writing routines must be implemented * by the device driver. */ #ifndef S_CONTEXT_H #define S_CONTEXT_H #include "main/mtypes.h" #include "main/texcompress.h" #include "program/prog_execute.h" #include "swrast.h" #include "s_fragprog.h" #include "s_span.h" typedef void (*texture_sample_func)(struct gl_context *ctx, const struct gl_sampler_object *samp, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], GLfloat rgba[][4]); typedef void (*swrast_blend_func)(struct gl_context *ctx, GLuint n, const GLubyte mask[], GLvoid *src, const GLvoid *dst, GLenum chanType); typedef void (*swrast_point_func)( struct gl_context *ctx, const SWvertex *); typedef void (*swrast_line_func)( struct gl_context *ctx, const SWvertex *, const SWvertex *); typedef void (*swrast_tri_func)( struct gl_context *ctx, const SWvertex *, const SWvertex *, const SWvertex *); typedef void (*validate_texture_image_func)(struct gl_context *ctx, struct gl_texture_object *texObj, GLuint face, GLuint level); /** * \defgroup Bitmasks * Bitmasks to indicate which rasterization options are enabled * (RasterMask) */ /*@{*/ #define ALPHATEST_BIT 0x001 /**< Alpha-test pixels */ #define BLEND_BIT 0x002 /**< Blend pixels */ #define DEPTH_BIT 0x004 /**< Depth-test pixels */ #define FOG_BIT 0x008 /**< Fog pixels */ #define LOGIC_OP_BIT 0x010 /**< Apply logic op in software */ #define CLIP_BIT 0x020 /**< Scissor or window clip pixels */ #define STENCIL_BIT 0x040 /**< Stencil pixels */ #define MASKING_BIT 0x080 /**< Do glColorMask or glIndexMask */ #define MULTI_DRAW_BIT 0x400 /**< Write to more than one color- */ /**< buffer or no buffers. */ #define OCCLUSION_BIT 0x800 /**< GL_HP_occlusion_test enabled */ #define TEXTURE_BIT 0x1000 /**< Texturing really enabled */ #define FRAGPROG_BIT 0x2000 /**< Fragment program enabled */ #define ATIFRAGSHADER_BIT 0x4000 /**< ATI Fragment shader enabled */ #define CLAMPING_BIT 0x8000 /**< Clamp colors to [0,1] */ /*@}*/ #define _SWRAST_NEW_RASTERMASK (_NEW_BUFFERS| \ _NEW_SCISSOR| \ _NEW_COLOR| \ _NEW_DEPTH| \ _NEW_FOG| \ _NEW_PROGRAM| \ _NEW_STENCIL| \ _NEW_TEXTURE| \ _NEW_VIEWPORT| \ _NEW_DEPTH) struct swrast_texture_image; /** * Fetch a texel from texture image at given position. */ typedef void (*FetchTexelFunc)(const struct swrast_texture_image *texImage, GLint col, GLint row, GLint img, GLfloat *texelOut); /** * Subclass of gl_texture_image. * We need extra fields/info to keep tracking of mapped texture buffers, * strides and Fetch functions. */ struct swrast_texture_image { struct gl_texture_image Base; GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */ /** used for mipmap LOD computation */ GLfloat WidthScale, HeightScale, DepthScale; /** * Byte stride between rows in ImageSlices. * * For compressed textures, this is the byte stride between one row of * blocks and the next row of blocks. * * Only valid while one of the ImageSlices is mapped, and must be the same * between all slices. */ GLint RowStride; /** * When a texture image is mapped for swrast, this array contains pointers * to the beginning of each slice. * * For swrast-allocated textures, these pointers will always stay * initialized to point within Buffer. */ void **ImageSlices; /** Malloc'd texture memory */ GLubyte *Buffer; FetchTexelFunc FetchTexel; /** For fetching texels from compressed textures */ compressed_fetch_func FetchCompressedTexel; }; /** cast wrapper */ static inline struct swrast_texture_image * swrast_texture_image(struct gl_texture_image *img) { return (struct swrast_texture_image *) img; } /** cast wrapper */ static inline const struct swrast_texture_image * swrast_texture_image_const(const struct gl_texture_image *img) { return (const struct swrast_texture_image *) img; } /** * Subclass of gl_renderbuffer with extra fields needed for software * rendering. */ struct swrast_renderbuffer { struct gl_renderbuffer Base; GLubyte *Buffer; /**< The malloc'd memory for buffer */ /** These fields are only valid while buffer is mapped for rendering */ GLubyte *Map; GLint RowStride; /**< in bytes */ /** For span rendering */ GLenum ColorType; }; /** cast wrapper */ static inline struct swrast_renderbuffer * swrast_renderbuffer(struct gl_renderbuffer *img) { return (struct swrast_renderbuffer *) img; } /** * \struct SWcontext * \brief Per-context state that's private to the software rasterizer module. */ typedef struct { /** Driver interface: */ struct swrast_device_driver Driver; /** Configuration mechanisms to make software rasterizer match * characteristics of the hardware rasterizer (if present): */ GLboolean AllowVertexFog; GLboolean AllowPixelFog; /** Derived values, invalidated on statechanges, updated from * _swrast_validate_derived(): */ GLbitfield _RasterMask; GLfloat _BackfaceSign; /** +1 or -1 */ GLfloat _BackfaceCullSign; /** +1, 0, or -1 */ GLboolean _PreferPixelFog; /* Compute fog blend factor per fragment? */ GLboolean _TextureCombinePrimary; GLboolean _FogEnabled; GLboolean _DeferredTexture; /** List/array of the fragment attributes to interpolate */ GLuint _ActiveAttribs[VARYING_SLOT_MAX]; /** Same info, but as a bitmask of VARYING_BIT_x bits */ GLbitfield64 _ActiveAttribMask; /** Number of fragment attributes to interpolate */ GLuint _NumActiveAttribs; /** Indicates how each attrib is to be interpolated (lines/tris) */ GLenum _InterpMode[VARYING_SLOT_MAX]; /* GL_FLAT or GL_SMOOTH (for now) */ /* Working values: */ GLuint StippleCounter; /**< Line stipple counter */ GLuint PointLineFacing; GLbitfield NewState; GLuint StateChanges; GLenum Primitive; /* current primitive being drawn (ala glBegin) */ GLboolean SpecularVertexAdd; /**< Add specular/secondary color per vertex */ void (*InvalidateState)( struct gl_context *ctx, GLbitfield new_state ); /** * When the NewState mask intersects these masks, we invalidate the * Point/Line/Triangle function pointers below. */ /*@{*/ GLbitfield InvalidatePointMask; GLbitfield InvalidateLineMask; GLbitfield InvalidateTriangleMask; /*@}*/ /** * Device drivers plug in functions for these callbacks. * Will be called when the GL state change mask intersects the above masks. */ /*@{*/ void (*choose_point)( struct gl_context * ); void (*choose_line)( struct gl_context * ); void (*choose_triangle)( struct gl_context * ); /*@}*/ /** * Current point, line and triangle drawing functions. */ /*@{*/ swrast_point_func Point; swrast_line_func Line; swrast_tri_func Triangle; /*@}*/ /** * Placeholders for when separate specular (or secondary color) is * enabled but texturing is not. */ /*@{*/ swrast_point_func SpecPoint; swrast_line_func SpecLine; swrast_tri_func SpecTriangle; /*@}*/ /** * Typically, we'll allocate a sw_span structure as a local variable * and set its 'array' pointer to point to this object. The reason is * this object is big and causes problems when allocated on the stack * on some systems. */ SWspanarrays *SpanArrays; SWspanarrays *ZoomedArrays; /**< For pixel zooming */ /** * Used to buffer N GL_POINTS, instead of rendering one by one. */ SWspan PointSpan; /** Internal hooks, kept up to date by the same mechanism as above. */ swrast_blend_func BlendFunc; texture_sample_func TextureSample[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; /** Buffer for saving the sampled texture colors. * Needed for GL_ARB_texture_env_crossbar implementation. */ GLfloat *TexelBuffer; validate_texture_image_func ValidateTextureImage; /** State used during execution of fragment programs */ struct gl_program_machine FragProgMachine; /** Temporary arrays for stencil operations. To avoid large stack * allocations. */ struct { GLubyte *buf1, *buf2, *buf3, *buf4; } stencil_temp; } SWcontext; extern void _swrast_validate_derived( struct gl_context *ctx ); extern void _swrast_update_texture_samplers(struct gl_context *ctx); /** Return SWcontext for the given struct gl_context */ static inline SWcontext * SWRAST_CONTEXT(struct gl_context *ctx) { return (SWcontext *) ctx->swrast_context; } /** const version of above */ static inline const SWcontext * CONST_SWRAST_CONTEXT(const struct gl_context *ctx) { return (const SWcontext *) ctx->swrast_context; } /** * Called prior to framebuffer reading/writing. * For drivers that rely on swrast for fallback rendering, this is the * driver's opportunity to map renderbuffers and textures. */ static inline void swrast_render_start(struct gl_context *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); if (swrast->Driver.SpanRenderStart) swrast->Driver.SpanRenderStart(ctx); } /** Called after framebuffer reading/writing */ static inline void swrast_render_finish(struct gl_context *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); if (swrast->Driver.SpanRenderFinish) swrast->Driver.SpanRenderFinish(ctx); } extern void _swrast_span_render_start(struct gl_context *ctx); extern void _swrast_span_render_finish(struct gl_context *ctx); extern void _swrast_map_textures(struct gl_context *ctx); extern void _swrast_unmap_textures(struct gl_context *ctx); extern unsigned int _swrast_teximage_slice_height(struct gl_texture_image *texImage); extern void _swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj); extern void _swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj); extern void _swrast_map_renderbuffers(struct gl_context *ctx); extern void _swrast_unmap_renderbuffers(struct gl_context *ctx); /** * Size of an RGBA pixel, in bytes, for given datatype. */ #define RGBA_PIXEL_SIZE(TYPE) \ ((TYPE == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) : \ ((TYPE == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort) \ : 4 * sizeof(GLfloat))) /* * Fixed point arithmetic macros */ #ifndef FIXED_FRAC_BITS #define FIXED_FRAC_BITS 11 #endif #define FIXED_SHIFT FIXED_FRAC_BITS #define FIXED_ONE (1 << FIXED_SHIFT) #define FIXED_HALF (1 << (FIXED_SHIFT-1)) #define FIXED_FRAC_MASK (FIXED_ONE - 1) #define FIXED_INT_MASK (~FIXED_FRAC_MASK) #define FIXED_EPSILON 1 #define FIXED_SCALE ((float) FIXED_ONE) #define FIXED_DBL_SCALE ((double) FIXED_ONE) #define FloatToFixed(X) (IROUND((X) * FIXED_SCALE)) #define FixedToDouble(X) ((X) * (1.0 / FIXED_DBL_SCALE)) #define IntToFixed(I) ((I) << FIXED_SHIFT) #define FixedToInt(X) ((X) >> FIXED_SHIFT) #define FixedToUns(X) (((unsigned int)(X)) >> FIXED_SHIFT) #define FixedCeil(X) (((X) + FIXED_ONE - FIXED_EPSILON) & FIXED_INT_MASK) #define FixedFloor(X) ((X) & FIXED_INT_MASK) #define FixedToFloat(X) ((X) * (1.0F / FIXED_SCALE)) #define PosFloatToFixed(X) FloatToFixed(X) #define SignedFloatToFixed(X) FloatToFixed(X) /* * XXX these macros are just bandages for now in order to make * CHAN_BITS==32 compile cleanly. * These should probably go elsewhere at some point. */ #if CHAN_TYPE == GL_FLOAT #define ChanToFixed(X) (X) #define FixedToChan(X) (X) #else #define ChanToFixed(X) IntToFixed(X) #define FixedToChan(X) FixedToInt(X) #endif /** * For looping over fragment attributes in the pointe, line * triangle rasterizers. */ #define ATTRIB_LOOP_BEGIN \ { \ GLuint a; \ for (a = 0; a < swrast->_NumActiveAttribs; a++) { \ const GLuint attr = swrast->_ActiveAttribs[a]; #define ATTRIB_LOOP_END } } /** * Return the address of a pixel value in a mapped renderbuffer. */ static inline GLubyte * _swrast_pixel_address(struct gl_renderbuffer *rb, GLint x, GLint y) { struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); const GLint bpp = _mesa_get_format_bytes(rb->Format); const GLint rowStride = srb->RowStride; assert(x >= 0); assert(y >= 0); /* NOTE: using <= only because of s_tritemp.h which gets a pixel * address but doesn't necessarily access it. */ assert(x <= (GLint) rb->Width); assert(y <= (GLint) rb->Height); assert(srb->Map); return (GLubyte *) srb->Map + y * rowStride + x * bpp; } #endif