diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 44 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 13 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_clear.c | 4 | ||||
-rw-r--r-- | src/mesa/drivers/common/meta.c | 9 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_pixel_draw.c | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_common.c | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_debug.c | 10 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_debug.h | 60 | ||||
-rw-r--r-- | src/mesa/main/texenvprogram.c | 61 |
9 files changed, 154 insertions, 67 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 60ffa188df6..c79c56debd6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -2756,19 +2756,32 @@ exec_instruction( if (mach->ExecMask) { /* do the call */ - /* push the Cond, Loop, Cont stacks */ + /* First, record the depths of the execution stacks. + * This is important for deeply nested/looped return statements. + * We have to unwind the stacks by the correct amount. For a + * real code generator, we could determine the number of entries + * to pop off each stack with simple static analysis and avoid + * implementing this data structure at run time. + */ + mach->CallStack[mach->CallStackTop].CondStackTop = mach->CondStackTop; + mach->CallStack[mach->CallStackTop].LoopStackTop = mach->LoopStackTop; + mach->CallStack[mach->CallStackTop].ContStackTop = mach->ContStackTop; + /* note that PC was already incremented above */ + mach->CallStack[mach->CallStackTop].ReturnAddr = *pc; + + mach->CallStackTop++; + + /* Second, push the Cond, Loop, Cont, Func stacks */ assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); mach->CondStack[mach->CondStackTop++] = mach->CondMask; assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); mach->ContStack[mach->ContStackTop++] = mach->ContMask; - assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING); mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask; - /* note that PC was already incremented above */ - mach->CallStack[mach->CallStackTop++] = *pc; + /* Finally, jump to the subroutine */ *pc = inst->InstructionExtLabel.Label; } break; @@ -2785,18 +2798,24 @@ exec_instruction( *pc = -1; return; } - *pc = mach->CallStack[--mach->CallStackTop]; - /* pop the Cond, Loop, Cont stacks */ - assert(mach->CondStackTop > 0); - mach->CondMask = mach->CondStack[--mach->CondStackTop]; - assert(mach->LoopStackTop > 0); - mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; - assert(mach->ContStackTop > 0); - mach->ContMask = mach->ContStack[--mach->ContStackTop]; + assert(mach->CallStackTop > 0); + mach->CallStackTop--; + + mach->CondStackTop = mach->CallStack[mach->CallStackTop].CondStackTop; + mach->CondMask = mach->CondStack[mach->CondStackTop]; + + mach->LoopStackTop = mach->CallStack[mach->CallStackTop].LoopStackTop; + mach->LoopMask = mach->LoopStack[mach->LoopStackTop]; + + mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop; + mach->ContMask = mach->ContStack[mach->ContStackTop]; + assert(mach->FuncStackTop > 0); mach->FuncMask = mach->FuncStack[--mach->FuncStackTop]; + *pc = mach->CallStack[mach->CallStackTop].ReturnAddr; + UPDATE_EXEC_MASK(mach); } break; @@ -3245,7 +3264,6 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) mach->FuncMask = 0xf; mach->ExecMask = 0xf; - mach->CondStackTop = 0; /* temporarily subvert this assertion */ assert(mach->CondStackTop == 0); assert(mach->LoopStackTop == 0); assert(mach->ContStackTop == 0); diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 3baa94dbdde..c72f76809d4 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -186,6 +186,17 @@ struct tgsi_exec_labels */ #define TGSI_EXEC_MAX_CONST_BUFFER 4096 + +/** function call/activation record */ +struct tgsi_call_record +{ + uint CondStackTop; + uint LoopStackTop; + uint ContStackTop; + uint ReturnAddr; +}; + + /** * Run-time virtual machine state for executing TGSI shader. */ @@ -249,7 +260,7 @@ struct tgsi_exec_machine int FuncStackTop; /** Function call stack for saving/restoring the program counter */ - uint CallStack[TGSI_EXEC_MAX_CALL_NESTING]; + struct tgsi_call_record CallStack[TGSI_EXEC_MAX_CALL_NESTING]; int CallStackTop; struct tgsi_full_instruction *Instructions; diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index fa59277438c..d3af18e162b 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -85,5 +85,7 @@ softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, /* non-cached surface */ pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); #endif - } + } + + softpipe->dirty_render_cache = TRUE; } diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 276e981a94c..0b9781027e7 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -1522,6 +1522,8 @@ _mesa_meta_draw_pixels(GLcontext *ctx, } else if (_mesa_is_stencil_format(format)) { if (ctx->Extensions.ARB_fragment_program && + ctx->Pixel.IndexShift == 0 && + ctx->Pixel.IndexOffset == 0 && type == GL_UNSIGNED_BYTE) { /* We'll store stencil as alpha. This only works for GLubyte * image data because of how incoming values are mapped to alpha @@ -1656,6 +1658,13 @@ _mesa_meta_draw_pixels(GLcontext *ctx, _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); + + /* set all stencil bits to 0 */ + _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + _mesa_StencilFunc(GL_ALWAYS, 0, 255); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + + /* set stencil bits to 1 where needed */ _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index 8c113881d6b..7fbb89fd6aa 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -42,6 +42,7 @@ #include "main/depth.h" #include "main/hash.h" #include "main/blend.h" +#include "swrast/swrast.h" #include "drivers/common/meta.h" #include "intel_context.h" @@ -260,9 +261,24 @@ intelDrawPixels(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, const GLvoid * pixels) { +#if 0 + /* XXX this function doesn't seem to work reliably even when all + * the pre-requisite conditions are met. + * Note that this function is never hit with conform. + * Fall back to swrast because even the _mesa_meta_draw_pixels() approach + * isn't working because of an apparent stencil bug. + */ if (intel_stencil_drawpixels(ctx, x, y, width, height, format, type, unpack, pixels)) return; +#else + (void) intel_stencil_drawpixels; /* silence warning */ + if (format == GL_STENCIL_INDEX) { + _swrast_DrawPixels(ctx, x, y, width, height, format, type, + unpack, pixels); + return; + } +#endif _mesa_meta_draw_pixels(ctx, x, y, width, height, format, type, unpack, pixels); diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index e53eb0904d2..a4c7b40798a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -1234,7 +1234,9 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) UNLOCK_HARDWARE(rmesa); if (ret) { - fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); + fprintf(stderr, "drmRadeonCmdBuffer: %d. Kernel failed to " + "parse or rejected command stream. See dmesg " + "for more info.\n", ret); _mesa_exit(ret); } diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.c b/src/mesa/drivers/dri/radeon/radeon_debug.c index a1ed39683f1..3b6f0038037 100644 --- a/src/mesa/drivers/dri/radeon/radeon_debug.c +++ b/src/mesa/drivers/dri/radeon/radeon_debug.c @@ -32,6 +32,9 @@ #include "radeon_debug.h" #include "radeon_common_context.h" +#include <stdarg.h> +#include <stdio.h> + static const struct dri_debug_control debug_control[] = { {"fall", RADEON_FALLBACKS}, {"tex", RADEON_TEXTURE}, @@ -85,10 +88,10 @@ void _radeon_debug_remove_indent(void) } } -extern void _radeon_print(const radeon_debug_type_t type, +void _radeon_print(const radeon_debug_type_t type, const radeon_debug_level_t level, const char* message, - va_list values) + ...) { GET_CURRENT_CONTEXT(ctx); if (ctx) { @@ -97,5 +100,8 @@ extern void _radeon_print(const radeon_debug_type_t type, if (radeon->debug.indent_depth) fprintf(stderr, "%s", radeon->debug.indent); } + va_list values; + va_start( values, message ); vfprintf(stderr, message, values); + va_end( values ); } diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.h b/src/mesa/drivers/dri/radeon/radeon_debug.h index 132e27351da..2a8302293b2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_debug.h +++ b/src/mesa/drivers/dri/radeon/radeon_debug.h @@ -30,8 +30,7 @@ #ifndef RADEON_DEBUG_H_INCLUDED #define RADEON_DEBUG_H_INCLUDED -#include <stdarg.h> -#include <stdio.h> +#include <stdlib.h> typedef enum radeon_debug_levels { RADEON_CRITICAL = 0, /* Only errors */ @@ -102,57 +101,36 @@ static inline int radeon_is_debug_enabled(const radeon_debug_type_t type, extern void _radeon_print(const radeon_debug_type_t type, const radeon_debug_level_t level, const char* message, - va_list values); -/** - * Format attribute requires declaration for setting it. Don't ask me why! - */ -static inline void radeon_print(const radeon_debug_type_t type, - const radeon_debug_level_t level, - const char* message, - ...) __attribute__((format(printf,3,4))); - + ...) __attribute__((format(printf,3,4))); /** * Print out debug message if channel specified by type is enabled * and compile time debugging level is at least as high as level parameter */ -static inline void radeon_print(const radeon_debug_type_t type, - const radeon_debug_level_t level, - const char* message, - ...) -{ - /* Compile out if level of message is too high */ - if (radeon_is_debug_enabled(type, level)) { - - va_list values; - va_start( values, message ); - _radeon_print(type, level, message, values); - va_end( values ); - } -} +#define radeon_print(type, level, message, ...) do { \ + const radeon_debug_level_t _debug_level = (level); \ + const radeon_debug_type_t _debug_type = (type); \ + /* Compile out if level of message is too high */ \ + if (radeon_is_debug_enabled(type, level)) { \ + _radeon_print(_debug_type, _debug_level, \ + (message), ## __VA_ARGS__); \ + } \ +} while(0) -static inline void radeon_error(const char* message, ...) __attribute__((format(printf,1,2))); /** * printf style function for writing error messages. */ -static inline void radeon_error(const char* message, ...) -{ - va_list values; - va_start( values, message ); - radeon_print(RADEON_GENERAL, RADEON_CRITICAL, message, values); - va_end( values ); -} +#define radeon_error(message, ...) do { \ + radeon_print(RADEON_GENERAL, RADEON_CRITICAL, \ + (message), ## __VA_ARGS__); \ +} while(0) -static inline void radeon_warning(const char* message, ...) __attribute__((format(printf,1,2))); /** * printf style function for writing warnings. */ -static inline void radeon_warning(const char* message, ...) -{ - va_list values; - va_start( values, message ); - radeon_print(RADEON_GENERAL, RADEON_IMPORTANT, message, values); - va_end( values ); -} +#define radeon_warning(message, ...) do { \ + radeon_print(RADEON_GENERAL, RADEON_IMPORTANT, \ + (message), ## __VA_ARGS__); \ +} while(0) extern void radeon_init_debug(void); extern void _radeon_debug_add_indent(void); diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 870970a3554..2f3e47e69ec 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -248,6 +248,40 @@ static GLuint translate_mode( GLenum envMode, GLenum mode ) /** + * Do we need to clamp the results of the given texture env/combine mode? + * If the inputs to the mode are in [0,1] we don't always have to clamp + * the results. + */ +static GLboolean +need_saturate( GLuint mode ) +{ + switch (mode) { + case MODE_REPLACE: + case MODE_MODULATE: + case MODE_INTERPOLATE: + return GL_FALSE; + case MODE_ADD: + case MODE_ADD_SIGNED: + case MODE_SUBTRACT: + case MODE_DOT3_RGB: + case MODE_DOT3_RGB_EXT: + case MODE_DOT3_RGBA: + case MODE_DOT3_RGBA_EXT: + case MODE_MODULATE_ADD_ATI: + case MODE_MODULATE_SIGNED_ADD_ATI: + case MODE_MODULATE_SUBTRACT_ATI: + case MODE_ADD_PRODUCTS: + case MODE_ADD_PRODUCTS_SIGNED: + case MODE_BUMP_ENVMAP_ATI: + return GL_TRUE; + default: + assert(0); + } +} + + + +/** * Translate TEXTURE_x_BIT to TEXTURE_x_INDEX. */ static GLuint translate_tex_src_bit( GLbitfield bit ) @@ -1116,7 +1150,7 @@ static struct ureg emit_texenv(struct texenv_fragment_program *p, GLuint unit) { const struct state_key *key = p->state; - GLboolean saturate; + GLboolean rgb_saturate, alpha_saturate; GLuint rgb_shift, alpha_shift; struct ureg out, dest; @@ -1146,7 +1180,19 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) /* If we'll do rgb/alpha shifting don't saturate in emit_combine(). * We don't want to clamp twice. */ - saturate = !(rgb_shift || alpha_shift); + if (rgb_shift) + rgb_saturate = GL_FALSE; /* saturate after rgb shift */ + else if (need_saturate(key->unit[unit].ModeRGB)) + rgb_saturate = GL_TRUE; + else + rgb_saturate = GL_FALSE; + + if (alpha_shift) + alpha_saturate = GL_FALSE; /* saturate after alpha shift */ + else if (need_saturate(key->unit[unit].ModeA)) + alpha_saturate = GL_TRUE; + else + alpha_saturate = GL_FALSE; /* If this is the very last calculation, emit direct to output reg: */ @@ -1162,7 +1208,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) */ if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && args_match(key, unit)) { - out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, + out = emit_combine( p, dest, WRITEMASK_XYZW, rgb_saturate, unit, key->unit[unit].NumArgsRGB, key->unit[unit].ModeRGB, @@ -1170,7 +1216,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) } else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT || key->unit[unit].ModeRGB == MODE_DOT3_RGBA) { - out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, + out = emit_combine( p, dest, WRITEMASK_XYZW, rgb_saturate, unit, key->unit[unit].NumArgsRGB, key->unit[unit].ModeRGB, @@ -1180,12 +1226,12 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) /* Need to do something to stop from re-emitting identical * argument calculations here: */ - out = emit_combine( p, dest, WRITEMASK_XYZ, saturate, + out = emit_combine( p, dest, WRITEMASK_XYZ, rgb_saturate, unit, key->unit[unit].NumArgsRGB, key->unit[unit].ModeRGB, key->unit[unit].OptRGB); - out = emit_combine( p, dest, WRITEMASK_W, saturate, + out = emit_combine( p, dest, WRITEMASK_W, alpha_saturate, unit, key->unit[unit].NumArgsA, key->unit[unit].ModeA, @@ -1196,8 +1242,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) */ if (alpha_shift || rgb_shift) { struct ureg shift; - - saturate = GL_TRUE; /* always saturate at this point */ + GLboolean saturate = GL_TRUE; /* always saturate at this point */ if (rgb_shift == alpha_shift) { shift = register_scalar_const(p, (GLfloat)(1<<rgb_shift)); |