diff options
Diffstat (limited to 'src/mesa')
37 files changed, 306 insertions, 185 deletions
diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 62a3269d17..85a6f03672 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -813,7 +813,7 @@ directfbgl_create_context( GLcontext *context, { struct dd_function_table functions; - _mesa_initialize_framebuffer( framebuffer, visual ); + _mesa_initialize_window_framebuffer( framebuffer, visual ); _mesa_init_driver_functions( &functions ); functions.GetString = dfbGetString; diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index e8cc202f88..c9ef1647a3 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -202,7 +202,7 @@ intelCreateBuffer(__DRIscreen * driScrnPriv, if (!fb) return GL_FALSE; - _mesa_initialize_framebuffer(fb, mesaVis); + _mesa_initialize_window_framebuffer(fb, mesaVis); if (mesaVis->redBits == 5) rgbFormat = MESA_FORMAT_RGB565; diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 249c0bbc11..aecba7f894 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -74,7 +74,7 @@ static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, GLvoid *data, int stride, int count) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - uint32_t *out; + GLfloat *out; int i; int size = 1; @@ -91,7 +91,7 @@ static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, aos->count = count; radeon_bo_map(aos->bo, 1); - out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); + out = (GLfloat*)((char*)aos->bo->ptr + aos->offset); for (i = 0; i < count; i++) { out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data ); out++; diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c index aa69b0fc72..928c15e1e4 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c @@ -297,7 +297,7 @@ void r300FragmentProgramDump(struct rX00_fragment_program_code *c) if (flags[0] != 0) { sprintf(tmp, "o%i.%s", (code->alu.inst[i]. - rgb_addr >> R300_ALU_DSTC_SHIFT) & 31, + rgb_addr >> 29) & 3, flags); strcat(dstc, tmp); } @@ -311,7 +311,7 @@ void r300FragmentProgramDump(struct rX00_fragment_program_code *c) if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_OUTPUT) { sprintf(tmp, "o%i.w ", (code->alu.inst[i]. - alpha_addr >> R300_ALU_DSTA_SHIFT) & 31); + alpha_addr >> 25) & 3); strcat(dsta, tmp); } if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_DEPTH) { diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c index 375838d98e..cc552aee17 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c @@ -176,7 +176,9 @@ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* i (inst->RGB.WriteMask << R300_ALU_DSTC_REG_MASK_SHIFT); } if (inst->RGB.OutputWriteMask) { - code->alu.inst[ip].rgb_addr |= (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT); + code->alu.inst[ip].rgb_addr |= + (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT) | + R300_RGB_TARGET(inst->RGB.Target); emit->node_flags |= R300_RGBA_OUT; } @@ -187,7 +189,8 @@ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* i R300_ALU_DSTA_REG; } if (inst->Alpha.OutputWriteMask) { - code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT; + code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT | + R300_ALPHA_TARGET(inst->Alpha.Target); emit->node_flags |= R300_RGBA_OUT; } if (inst->Alpha.DepthWriteMask) { diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index 5581f25352..c2d5dc27b4 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -35,7 +35,10 @@ static void dataflow_outputs_mark_use(void * userdata, void * data, void (*callback)(void *, unsigned int, unsigned int)) { struct r300_fragment_program_compiler * c = userdata; - callback(data, c->OutputColor, RC_MASK_XYZW); + callback(data, c->OutputColor[0], RC_MASK_XYZW); + callback(data, c->OutputColor[1], RC_MASK_XYZW); + callback(data, c->OutputColor[2], RC_MASK_XYZW); + callback(data, c->OutputColor[3], RC_MASK_XYZW); callback(data, c->OutputDepth, RC_MASK_W); } diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c index b1b14394b6..c2eb613b23 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c @@ -241,6 +241,9 @@ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT; + code->inst[ip].inst3 |= R500_ALU_RGB_TARGET(inst->RGB.Target); + code->inst[ip].inst4 |= R500_ALPHA_TARGET(inst->Alpha.Target); + if (inst->WriteALUResult) { code->inst[ip].inst3 |= R500_ALU_RGB_WMASK; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h index f27f858652..6bfda0574f 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h @@ -83,8 +83,10 @@ struct r300_fragment_program_compiler { struct rX00_fragment_program_code *code; struct r300_fragment_program_external_state state; unsigned is_r500; + /* Register corresponding to the depthbuffer. */ unsigned OutputDepth; - unsigned OutputColor; + /* Registers corresponding to the four colorbuffers. */ + unsigned OutputColor[4]; void * UserData; void (*AllocateHwInputs)( diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c index 7211768272..fff5b0c217 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c @@ -203,12 +203,21 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c, /* Destination handling */ if (inst->DstReg.File == RC_FILE_OUTPUT) { - if (inst->DstReg.Index == c->OutputColor) { - pair->RGB.OutputWriteMask |= inst->DstReg.WriteMask & RC_MASK_XYZ; - pair->Alpha.OutputWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); - } else if (inst->DstReg.Index == c->OutputDepth) { - pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); - } + if (inst->DstReg.Index == c->OutputDepth) { + pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); + } else { + for (i = 0; i < 4; i++) { + if (inst->DstReg.Index == c->OutputColor[i]) { + pair->RGB.Target = i; + pair->Alpha.Target = i; + pair->RGB.OutputWriteMask |= + inst->DstReg.WriteMask & RC_MASK_XYZ; + pair->Alpha.OutputWriteMask |= + GET_BIT(inst->DstReg.WriteMask, 3); + break; + } + } + } } else { if (needrgb) { pair->RGB.DestIndex = inst->DstReg.Index; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h index 6685ade3ea..511cc707a3 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h @@ -60,6 +60,7 @@ struct radeon_pair_instruction_rgb { unsigned int Opcode:8; unsigned int DestIndex:RC_REGISTER_INDEX_BITS; unsigned int WriteMask:3; + unsigned int Target:2; unsigned int OutputWriteMask:3; unsigned int Saturate:1; @@ -77,6 +78,7 @@ struct radeon_pair_instruction_alpha { unsigned int Opcode:8; unsigned int DestIndex:RC_REGISTER_INDEX_BITS; unsigned int WriteMask:1; + unsigned int Target:2; unsigned int OutputWriteMask:1; unsigned int DepthWriteMask:1; unsigned int Saturate:1; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c index d863b82d53..28fb9eae92 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c @@ -229,7 +229,7 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst (inst->RGB.WriteMask & 2) ? "y" : "", (inst->RGB.WriteMask & 4) ? "z" : ""); if (inst->RGB.OutputWriteMask) - fprintf(f, " color.%s%s%s", + fprintf(f, " color[%i].%s%s%s", inst->RGB.Target, (inst->RGB.OutputWriteMask & 1) ? "x" : "", (inst->RGB.OutputWriteMask & 2) ? "y" : "", (inst->RGB.OutputWriteMask & 4) ? "z" : ""); @@ -255,7 +255,7 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst if (inst->Alpha.WriteMask) fprintf(f, " temp[%i].w", inst->Alpha.DestIndex); if (inst->Alpha.OutputWriteMask) - fprintf(f, " color.w"); + fprintf(f, " color[%i].w", inst->Alpha.Target); if (inst->Alpha.DepthWriteMask) fprintf(f, " depth.w"); if (inst->WriteALUResult == RC_ALURESULT_W) diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index e24c7955d4..54ac2510e7 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -114,7 +114,7 @@ static void create_fragment_program(struct r300_context *r300) inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW; compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0); - compiler.OutputColor = FRAG_RESULT_COLOR; + compiler.OutputColor[0] = FRAG_RESULT_COLOR; compiler.OutputDepth = FRAG_RESULT_DEPTH; compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515); compiler.code = &r300->blit.fp_code; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c index e41aeff91a..a0e2dd3c09 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c @@ -221,7 +221,8 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog compiler.state = fp->state; compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE; compiler.OutputDepth = FRAG_RESULT_DEPTH; - compiler.OutputColor = FRAG_RESULT_COLOR; + memset(compiler.OutputColor, 0, 4 * sizeof(unsigned)); + compiler.OutputColor[0] = FRAG_RESULT_COLOR; compiler.AllocateHwInputs = &allocate_hw_inputs; if (compiler.Base.Debug) { diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 6fa1a0663b..93b6399a66 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1479,7 +1479,7 @@ radeonCreateBuffer( __DRIscreen *driScrnPriv, if (!rfb) return GL_FALSE; - _mesa_initialize_framebuffer(&rfb->base, mesaVis); + _mesa_initialize_window_framebuffer(&rfb->base, mesaVis); if (mesaVis->redBits == 5) rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV; diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c index 8340861aff..4e823669bf 100644 --- a/src/mesa/drivers/dri/swrast/swrast.c +++ b/src/mesa/drivers/dri/swrast/swrast.c @@ -368,7 +368,7 @@ driCreateNewDrawable(__DRIscreen *screen, buf->row = _mesa_malloc(MAX_WIDTH * 4); /* basic framebuffer setup */ - _mesa_initialize_framebuffer(&buf->Base, &config->modes); + _mesa_initialize_window_framebuffer(&buf->Base, &config->modes); /* add front renderbuffer */ frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE); diff --git a/src/mesa/drivers/fbdev/glfbdev.c b/src/mesa/drivers/fbdev/glfbdev.c index 531558dc4d..1a56b2395f 100644 --- a/src/mesa/drivers/fbdev/glfbdev.c +++ b/src/mesa/drivers/fbdev/glfbdev.c @@ -626,7 +626,7 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo, return NULL; /* basic framebuffer setup */ - _mesa_initialize_framebuffer(&buf->glframebuffer, &visual->glvisual); + _mesa_initialize_window_framebuffer(&buf->glframebuffer, &visual->glvisual); /* add front renderbuffer */ frontrb = new_glfbdev_renderbuffer(frontBuffer, visual); _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT, diff --git a/src/mesa/drivers/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile index fa8293d039..080fe475c1 100644 --- a/src/mesa/drivers/glslcompiler/Makefile +++ b/src/mesa/drivers/glslcompiler/Makefile @@ -10,6 +10,7 @@ PROGRAM = glslcompiler OBJECTS = \ glslcompiler.o \ ../../glapi/glapi.o \ + ../../glapi/glapi_nop.o \ ../../glapi/glthread.o \ ../../main/dispatch.o \ ../common/driverfuncs.o \ diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c index ceeafd5f90..b24b758cfb 100644 --- a/src/mesa/drivers/windows/gdi/wmesa.c +++ b/src/mesa/drivers/windows/gdi/wmesa.c @@ -35,7 +35,7 @@ wmesa_new_framebuffer(HDC hdc, GLvisual *visual) WMesaFramebuffer pwfb = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); if (pwfb) { - _mesa_initialize_framebuffer(&pwfb->Base, visual); + _mesa_initialize_window_framebuffer(&pwfb->Base, visual); pwfb->hDC = hdc; /* insert at head of list */ pwfb->next = FirstFramebuffer; diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index bf767bcedd..1a5456e1be 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -375,7 +375,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, b->type = type; b->cmap = cmap; - _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); + _mesa_initialize_window_framebuffer(&b->mesa_buffer, &vis->mesa_visual); b->mesa_buffer.Delete = xmesa_delete_framebuffer; /* diff --git a/src/mesa/main/bitset.h b/src/mesa/main/bitset.h index 8bd4526cb6..f2709abc9f 100644 --- a/src/mesa/main/bitset.h +++ b/src/mesa/main/bitset.h @@ -27,7 +27,12 @@ * \brief Bitset of arbitrary size definitions. * \author Michal Krol */ - + +#ifndef BITSET_H +#define BITSET_H + +#include "imports.h" + /**************************************************************************** * generic bitset implementation */ @@ -74,6 +79,23 @@ ((x)[BITSET_BITWORD(b)] &= ~BITSET_RANGE(b, e)) : \ (assert (!"BITSET_CLEAR_RANGE: bit range crosses word boundary"), 0)) +/* Get first bit set in a bitset. + */ +static INLINE int +__bitset_ffs(const BITSET_WORD *x, int n) +{ + int i; + + for (i = 0; i < n; i++) { + if (x[i]) + return _mesa_ffs(x[i]) + BITSET_WORDBITS * i; + } + + return 0; +} + +#define BITSET_FFS(x) __bitset_ffs(x, Elements(x)) + /**************************************************************************** * 64-bit bitset implementation */ @@ -120,3 +142,4 @@ ((x)[BITSET64_BITWORD(b)] &= ~BITSET64_RANGE(b, e)) : \ (assert (!"BITSET64_CLEAR_RANGE: bit range crosses word boundary"), 0)) +#endif diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index d958dbf7d4..96e5344383 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -88,7 +88,7 @@ _mesa_create_framebuffer(const GLvisual *visual) struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer); assert(visual); if (fb) { - _mesa_initialize_framebuffer(fb, visual); + _mesa_initialize_window_framebuffer(fb, visual); } return fb; } @@ -109,15 +109,7 @@ _mesa_new_framebuffer(GLcontext *ctx, GLuint name) assert(name != 0); fb = CALLOC_STRUCT(gl_framebuffer); if (fb) { - fb->Name = name; - fb->RefCount = 1; - fb->_NumColorDrawBuffers = 1; - fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT; - fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0; - fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; - fb->_ColorReadBufferIndex = BUFFER_COLOR0; - fb->Delete = _mesa_destroy_framebuffer; - _glthread_INIT_MUTEX(fb->Mutex); + _mesa_initialize_user_framebuffer(fb, name); } return fb; } @@ -126,10 +118,11 @@ _mesa_new_framebuffer(GLcontext *ctx, GLuint name) /** * Initialize a gl_framebuffer object. Typically used to initialize * window system-created framebuffers, not user-created framebuffers. - * \sa _mesa_create_framebuffer + * \sa _mesa_initialize_user_framebuffer */ void -_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) +_mesa_initialize_window_framebuffer(struct gl_framebuffer *fb, + const GLvisual *visual) { assert(fb); assert(visual); @@ -167,6 +160,30 @@ _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) /** + * Initialize a user-created gl_framebuffer object. + * \sa _mesa_initialize_window_framebuffer + */ +void +_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name) +{ + assert(fb); + assert(name); + + _mesa_bzero(fb, sizeof(struct gl_framebuffer)); + + fb->Name = name; + fb->RefCount = 1; + fb->_NumColorDrawBuffers = 1; + fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT; + fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0; + fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; + fb->_ColorReadBufferIndex = BUFFER_COLOR0; + fb->Delete = _mesa_destroy_framebuffer; + _glthread_INIT_MUTEX(fb->Mutex); +} + + +/** * Deallocate buffer and everything attached to it. * Typically called via the gl_framebuffer->Delete() method. */ diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h index ef21dd98e8..960513812c 100644 --- a/src/mesa/main/framebuffer.h +++ b/src/mesa/main/framebuffer.h @@ -34,7 +34,11 @@ extern struct gl_framebuffer * _mesa_new_framebuffer(GLcontext *ctx, GLuint name); extern void -_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual); +_mesa_initialize_window_framebuffer(struct gl_framebuffer *fb, + const GLvisual *visual); + +extern void +_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name); extern void _mesa_destroy_framebuffer(struct gl_framebuffer *buffer); diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 9f9789e010..54fd88ad4f 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -150,6 +150,10 @@ arb_input_attrib_string(GLint index, GLenum progType) "fragment.varying[7]" }; + /* sanity checks */ + assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0); + assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0); + if (progType == GL_VERTEX_PROGRAM_ARB) { assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0])); return vertAttribs[index]; @@ -162,6 +166,43 @@ arb_input_attrib_string(GLint index, GLenum progType) /** + * Print a vertex program's InputsRead field in human-readable format. + * For debugging. + */ +void +_mesa_print_vp_inputs(GLbitfield inputs) +{ + _mesa_printf("VP Inputs 0x%x: \n", inputs); + while (inputs) { + GLint attr = _mesa_ffs(inputs) - 1; + const char *name = arb_input_attrib_string(attr, + GL_VERTEX_PROGRAM_ARB); + _mesa_printf(" %d: %s\n", attr, name); + inputs &= ~(1 << attr); + } +} + + +/** + * Print a fragment program's InputsRead field in human-readable format. + * For debugging. + */ +void +_mesa_print_fp_inputs(GLbitfield inputs) +{ + _mesa_printf("FP Inputs 0x%x: \n", inputs); + while (inputs) { + GLint attr = _mesa_ffs(inputs) - 1; + const char *name = arb_input_attrib_string(attr, + GL_FRAGMENT_PROGRAM_ARB); + _mesa_printf(" %d: %s\n", attr, name); + inputs &= ~(1 << attr); + } +} + + + +/** * Return ARB_v/f_prog-style output attrib string. */ static const char * diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index fc286ded54..9ab7456016 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -37,6 +37,12 @@ typedef enum { } gl_prog_print_mode; +extern void +_mesa_print_vp_inputs(GLbitfield inputs); + +extern void +_mesa_print_fp_inputs(GLbitfield inputs); + extern const char * _mesa_condcode_string(GLuint condcode); diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 3e86d0adad..aaf5f96e2a 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -677,6 +677,8 @@ _mesa_combine_programs(GLcontext *ctx, const GLuint lenB = progB->NumInstructions; const GLuint numParamsA = _mesa_num_parameters(progA->Parameters); const GLuint newLength = lenA + lenB; + GLboolean usedTemps[MAX_PROGRAM_TEMPS]; + GLuint firstTemp = 0; GLbitfield inputsB; GLuint i; @@ -698,6 +700,10 @@ _mesa_combine_programs(GLcontext *ctx, newProg->Instructions = newInst; newProg->NumInstructions = newLength; + /* find used temp regs (we may need new temps below) */ + _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY, + usedTemps, MAX_PROGRAM_TEMPS); + if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprogA, *fprogB, *newFprog; GLbitfield progB_inputsRead = progB->InputsRead; @@ -741,12 +747,15 @@ _mesa_combine_programs(GLcontext *ctx, */ if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) && (progB_inputsRead & FRAG_BIT_COL0)) { - GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY); + GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS, + firstTemp); if (tempReg < 0) { _mesa_problem(ctx, "No free temp regs found in " "_mesa_combine_programs(), using 31"); tempReg = 31; } + firstTemp = tempReg + 1; + /* replace writes to result.color[0] with tempReg */ replace_registers(newInst, lenA, PROGRAM_OUTPUT, FRAG_RESULT_COLOR, @@ -784,53 +793,64 @@ _mesa_combine_programs(GLcontext *ctx, } - - /** - * Scan the given program to find a free register of the given type. - * \param regFile - PROGRAM_INPUT, PROGRAM_OUTPUT or PROGRAM_TEMPORARY + * Populate the 'used' array with flags indicating which registers (TEMPs, + * INPUTs, OUTPUTs, etc, are used by the given program. + * \param file type of register to scan for + * \param used returns true/false flags for in use / free + * \param usedSize size of the 'used' array */ -GLint -_mesa_find_free_register(const struct gl_program *prog, GLuint regFile) +void +_mesa_find_used_registers(const struct gl_program *prog, + gl_register_file file, + GLboolean used[], GLuint usedSize) { - GLboolean used[MAX_PROGRAM_TEMPS]; - GLuint i, k; - - assert(regFile == PROGRAM_INPUT || - regFile == PROGRAM_OUTPUT || - regFile == PROGRAM_TEMPORARY); + GLuint i, j; - _mesa_memset(used, 0, sizeof(used)); + _mesa_memset(used, 0, usedSize); for (i = 0; i < prog->NumInstructions; i++) { const struct prog_instruction *inst = prog->Instructions + i; const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); - /* check dst reg first */ - if (inst->DstReg.File == regFile) { + if (inst->DstReg.File == file) { used[inst->DstReg.Index] = GL_TRUE; } - else { - /* check src regs otherwise */ - for (k = 0; k < n; k++) { - if (inst->SrcReg[k].File == regFile) { - used[inst->SrcReg[k].Index] = GL_TRUE; - break; - } + + for (j = 0; j < n; j++) { + if (inst->SrcReg[j].File == file) { + used[inst->SrcReg[j].Index] = GL_TRUE; } } } +} - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { + +/** + * Scan the given 'used' register flag array for the first entry + * that's >= firstReg. + * \param used vector of flags indicating registers in use (as returned + * by _mesa_find_used_registers()) + * \param usedSize size of the 'used' array + * \param firstReg first register to start searching at + * \return index of unused register, or -1 if none. + */ +GLint +_mesa_find_free_register(const GLboolean used[], + GLuint usedSize, GLuint firstReg) +{ + GLuint i; + + assert(firstReg < usedSize); + + for (i = firstReg; i < usedSize; i++) if (!used[i]) return i; - } return -1; } - /** * "Post-process" a GPU program. This is intended to be used for debugging. * Example actions include no-op'ing instructions or changing instruction diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 56a4191f57..0187a2c55f 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -119,8 +119,14 @@ _mesa_combine_programs(GLcontext *ctx, const struct gl_program *progA, const struct gl_program *progB); +extern void +_mesa_find_used_registers(const struct gl_program *prog, + gl_register_file file, + GLboolean used[], GLuint usedSize); + extern GLint -_mesa_find_free_register(const struct gl_program *prog, GLuint regFile); +_mesa_find_free_register(const GLboolean used[], + GLuint maxRegs, GLuint firstReg); extern void _mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog); diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index 9514545709..fb2ebe6338 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -495,6 +495,11 @@ _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) GLuint i; GLint outputMap[VERT_RESULT_MAX]; GLuint numVaryingReads = 0; + GLboolean usedTemps[MAX_PROGRAM_TEMPS]; + GLuint firstTemp = 0; + + _mesa_find_used_registers(prog, PROGRAM_TEMPORARY, + usedTemps, MAX_PROGRAM_TEMPS); assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT); assert(prog->Target == GL_VERTEX_PROGRAM_ARB || type != PROGRAM_VARYING); @@ -513,8 +518,10 @@ _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) const GLuint var = inst->SrcReg[j].Index; if (outputMap[var] == -1) { numVaryingReads++; - outputMap[var] = _mesa_find_free_register(prog, - PROGRAM_TEMPORARY); + outputMap[var] = _mesa_find_free_register(usedTemps, + MAX_PROGRAM_TEMPS, + firstTemp); + firstTemp = outputMap[var] + 1; } inst->SrcReg[j].File = PROGRAM_TEMPORARY; inst->SrcReg[j].Index = outputMap[var]; diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index aa0508a41f..d9b508537d 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -60,26 +60,10 @@ static void translate_fp(struct st_context *st, struct st_fragment_program *stfp) { - const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead; - if (!stfp->state.tokens) { - GLuint inAttr, numIn = 0; - - for (inAttr = 0; inAttr < FRAG_ATTRIB_MAX; inAttr++) { - if (fragInputsRead & (1 << inAttr)) { - stfp->input_to_slot[inAttr] = numIn; - numIn++; - } - else { - stfp->input_to_slot[inAttr] = -1; - } - } - - stfp->num_input_slots = numIn; - assert(stfp->Base.Base.NumInstructions > 0); - st_translate_fragment_program(st, stfp, stfp->input_to_slot); + st_translate_fragment_program(st, stfp); } } diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c index 27ec2eb033..b82bbfe410 100644 --- a/src/mesa/state_tracker/st_atom_viewport.c +++ b/src/mesa/state_tracker/st_atom_viewport.c @@ -62,9 +62,9 @@ update_viewport( struct st_context *st ) GLfloat x = (GLfloat)ctx->Viewport.X; GLfloat y = (GLfloat)ctx->Viewport.Y; GLfloat z = ctx->Viewport.Near; - GLfloat half_width = (GLfloat)ctx->Viewport.Width / 2.0f; - GLfloat half_height = (GLfloat)ctx->Viewport.Height / 2.0f; - GLfloat half_depth = (GLfloat)(ctx->Viewport.Far - ctx->Viewport.Near) / 2.0f; + GLfloat half_width = (GLfloat)ctx->Viewport.Width * 0.5f; + GLfloat half_height = (GLfloat)ctx->Viewport.Height * 0.5f; + GLfloat half_depth = (GLfloat)(ctx->Viewport.Far - ctx->Viewport.Near) * 0.5f; st->state.viewport.scale[0] = half_width; st->state.viewport.scale[1] = half_height * yScale; diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index c70bbc880c..85420a950f 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -221,7 +221,7 @@ combined_bitmap_fragment_program(GLcontext *ctx) #endif /* translate to TGSI tokens */ - st_translate_fragment_program(st, stfp->bitmap_program, NULL); + st_translate_fragment_program(st, stfp->bitmap_program); } return stfp->bitmap_program; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 9b1d2103f1..2a084ca577 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -140,7 +140,7 @@ combined_drawpix_fragment_program(GLcontext *ctx) #endif /* translate to TGSI tokens */ - st_translate_fragment_program(st, stfp, NULL); + st_translate_fragment_program(st, stfp); /* save new program, update serial numbers */ st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo; @@ -221,7 +221,7 @@ make_fragment_shader_z(struct st_context *st) p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ st->drawpix.z_shader = (struct st_fragment_program *) p; - st_translate_fragment_program(st, st->drawpix.z_shader, NULL); + st_translate_fragment_program(st, st->drawpix.z_shader); return st->drawpix.z_shader; } diff --git a/src/mesa/state_tracker/st_cb_strings.c b/src/mesa/state_tracker/st_cb_strings.c index 996e065fed..0fcb427f30 100644 --- a/src/mesa/state_tracker/st_cb_strings.c +++ b/src/mesa/state_tracker/st_cb_strings.c @@ -39,7 +39,7 @@ #include "st_context.h" #include "st_cb_strings.h" -#define ST_VERSION_STRING "0.3" +#define ST_VERSION_STRING "0.4" static const GLubyte * st_get_string(GLcontext * ctx, GLenum name) diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 7c5664be1d..13f050900a 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -543,22 +543,15 @@ st_TexImage(GLcontext * ctx, _mesa_align_free(texImage->Data); } - if (width == 0 || height == 0 || depth == 0) { - /* stop after freeing old image */ - return; - } - - /* If this is the only mipmap level in the texture, could call - * bmBufferData with NULL data to free the old block and avoid - * waiting on any outstanding fences. + /* + * See if the new image is somehow incompatible with the existing + * mipmap. If so, free the old mipmap. */ if (stObj->pt) { if (stObj->teximage_realloc || level > (GLint) stObj->pt->last_level || - (stObj->pt->last_level == level && - stObj->pt->target != PIPE_TEXTURE_CUBE && - !st_texture_match_image(stObj->pt, &stImage->base, - stImage->face, stImage->level))) { + !st_texture_match_image(stObj->pt, &stImage->base, + stImage->face, stImage->level)) { DBG("release it\n"); pipe_texture_reference(&stObj->pt, NULL); assert(!stObj->pt); @@ -566,6 +559,11 @@ st_TexImage(GLcontext * ctx, } } + if (width == 0 || height == 0 || depth == 0) { + /* stop after freeing old image */ + return; + } + if (!stObj->pt) { guess_and_alloc_texture(ctx->st, stObj, stImage); if (!stObj->pt) { diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index ed9c0ff5b7..4e225a123c 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -54,7 +54,7 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->sampleBuffers) samples = visual->samples; - _mesa_initialize_framebuffer(&stfb->Base, visual); + _mesa_initialize_window_framebuffer(&stfb->Base, visual); if (visual->doubleBufferMode) { struct gl_renderbuffer *rb diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 5c87e47ca3..a639003dbd 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -269,24 +269,20 @@ fail: /** * Translate a Mesa fragment shader into a TGSI shader. - * \param inputMapping to map fragment program input registers to TGSI - * input slots * \return pointer to cached pipe_shader object. */ void st_translate_fragment_program(struct st_context *st, - struct st_fragment_program *stfp, - const GLuint inputMapping[]) + struct st_fragment_program *stfp ) { struct pipe_context *pipe = st->pipe; GLuint outputMapping[FRAG_RESULT_MAX]; - GLuint defaultInputMapping[FRAG_ATTRIB_MAX]; + GLuint inputMapping[FRAG_ATTRIB_MAX]; GLuint interpMode[16]; /* XXX size? */ GLuint attr; enum pipe_error error; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; struct ureg_program *ureg; - GLuint vslot = 0; uint fs_num_inputs = 0; @@ -294,24 +290,14 @@ st_translate_fragment_program(struct st_context *st, ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; uint fs_num_outputs = 0; - /* which vertex output goes to the first fragment input: */ - if (inputsRead & FRAG_BIT_WPOS) - vslot = 0; - else - vslot = 1; - /* * Convert Mesa program inputs to TGSI input register semantics. */ for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) { if (inputsRead & (1 << attr)) { - const GLuint slot = fs_num_inputs; - - defaultInputMapping[attr] = slot; - - stfp->input_map[slot] = vslot++; + const GLuint slot = fs_num_inputs++; - fs_num_inputs++; + inputMapping[attr] = slot; switch (attr) { case FRAG_ATTRIB_WPOS: @@ -376,6 +362,9 @@ st_translate_fragment_program(struct st_context *st, break; } } + else { + inputMapping[attr] = -1; + } } /* @@ -417,9 +406,6 @@ st_translate_fragment_program(struct st_context *st, } } - if (!inputMapping) - inputMapping = defaultInputMapping; - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); if (ureg == NULL) return; diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 6b9a9226df..d9822e50f5 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -52,12 +52,6 @@ struct st_fragment_program struct gl_fragment_program Base; GLuint serialNo; - GLuint input_to_slot[FRAG_ATTRIB_MAX]; /**< Maps FRAG_ATTRIB_x to slot */ - GLuint num_input_slots; - - /** map FP input back to VP output */ - GLuint input_map[PIPE_MAX_SHADER_INPUTS]; - ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; @@ -171,8 +165,7 @@ st_reference_fragprog(struct st_context *st, extern void st_translate_fragment_program(struct st_context *st, - struct st_fragment_program *fp, - const GLuint inputMapping[]); + struct st_fragment_program *fp); /* Called after program string change, discard all previous diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index da84eaa6ea..2fc866c577 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -30,12 +30,15 @@ #include "main/mtypes.h" #include "main/macros.h" #include "main/enums.h" +#include "main/image.h" #include "vbo_split.h" #define MAX_PRIM 32 -/* Used for splitting without copying. +/* Used for splitting without copying. No attempt is made to handle + * too large indexed vertex buffers: In general you need to copy to do + * that. */ struct split_context { GLcontext *ctx; @@ -48,6 +51,7 @@ struct split_context { vbo_draw_func draw; const struct split_limits *limits; + GLuint limit; struct _mesa_prim dstprim[MAX_PRIM]; GLuint dstprim_nr; @@ -58,38 +62,38 @@ struct split_context { static void flush_vertex( struct split_context *split ) { - GLuint min_index, max_index; + struct _mesa_index_buffer ib; GLuint i; if (!split->dstprim_nr) return; - min_index = split->dstprim[0].start; - max_index = min_index + split->dstprim[0].count - 1; + if (split->ib) { + ib = *split->ib; - for (i = 1; i < split->dstprim_nr; i++) { - GLuint tmp_min = split->dstprim[i].start; - GLuint tmp_max = tmp_min + split->dstprim[i].count - 1; + ib.count = split->max_index - split->min_index + 1; + ib.ptr = (const void *)((const char *)ib.ptr + + split->min_index * _mesa_sizeof_type(ib.type)); - if (tmp_min < min_index) - min_index = tmp_min; - - if (tmp_max > max_index) - max_index = tmp_max; + /* Rebase the primitives to save index buffer entries. */ + for (i = 0; i < split->dstprim_nr; i++) + split->dstprim[i].start -= split->min_index; } - assert(max_index >= min_index); + assert(split->max_index >= split->min_index); - split->draw( split->ctx, - split->array, - split->dstprim, - split->dstprim_nr, - NULL, - GL_TRUE, - min_index, - max_index); + split->draw(split->ctx, + split->array, + split->dstprim, + split->dstprim_nr, + split->ib ? &ib : NULL, + !split->ib, + split->min_index, + split->max_index); split->dstprim_nr = 0; + split->min_index = ~0; + split->max_index = 0; } @@ -106,62 +110,67 @@ static struct _mesa_prim *next_outprim( struct split_context *split ) } } -static int align(int value, int alignment) +static void update_index_bounds(struct split_context *split, + const struct _mesa_prim *prim) { - return (value + alignment - 1) & ~(alignment - 1); + split->min_index = MIN2(split->min_index, prim->start); + split->max_index = MAX2(split->max_index, prim->start + prim->count - 1); } - +/* Return the maximum amount of vertices that can be emitted for a + * primitive starting at 'prim->start', depending on the previous + * index bounds. + */ +static GLuint get_max_vertices(struct split_context *split, + const struct _mesa_prim *prim) +{ + if ((prim->start > split->min_index && + prim->start - split->min_index >= split->limit) || + (prim->start < split->max_index && + split->max_index - prim->start >= split->limit)) + /* "prim" starts too far away from the old range. */ + return 0; + + return MIN2(split->min_index, prim->start) + split->limit - prim->start; +} /* Break large primitives into smaller ones. If not possible, convert * the primitive to indexed and pass to split_elts(). */ static void split_prims( struct split_context *split) { - GLuint csr = 0; GLuint i; for (i = 0; i < split->nr_prims; i++) { const struct _mesa_prim *prim = &split->prim[i]; GLuint first, incr; GLboolean split_inplace = split_prim_inplace(prim->mode, &first, &incr); - GLuint count; - - /* Always wrap on an even numbered vertex to avoid problems with - * triangle strips. - */ - GLuint available = align(split->limits->max_verts - csr - 1, 2); - assert(split->limits->max_verts >= csr); + GLuint available = get_max_vertices(split, prim); + GLuint count = prim->count - (prim->count - first) % incr; if (prim->count < first) continue; - - count = prim->count - (prim->count - first) % incr; - - if ((available < count && !split_inplace) || + if ((available < count && !split_inplace) || (available < first && split_inplace)) { flush_vertex(split); - csr = 0; - available = align(split->limits->max_verts - csr - 1, 2); + available = get_max_vertices(split, prim); } if (available >= count) { struct _mesa_prim *outprim = next_outprim(split); + *outprim = *prim; - csr += prim->count; - available = align(split->limits->max_verts - csr - 1, 2); - } + update_index_bounds(split, outprim); + } else if (split_inplace) { GLuint j, nr; - for (j = 0 ; j < count ; ) { GLuint remaining = count - j; struct _mesa_prim *outprim = next_outprim(split); nr = MIN2( available, remaining ); - nr -= (nr - first) % incr; outprim->mode = prim->mode; @@ -169,21 +178,20 @@ static void split_prims( struct split_context *split) outprim->end = (nr == remaining && prim->end); outprim->start = prim->start + j; outprim->count = nr; - + + update_index_bounds(split, outprim); + if (nr == remaining) { /* Finished. */ - j += nr; - csr += nr; - available = align(split->limits->max_verts - csr - 1, 2); + j += nr; } else { /* Wrapped the primitive: */ j += nr - (first - incr); flush_vertex(split); - csr = 0; - available = align(split->limits->max_verts - csr - 1, 2); + available = get_max_vertices(split, prim); } } } @@ -260,10 +268,14 @@ void vbo_split_inplace( GLcontext *ctx, split.prim = prim; split.nr_prims = nr_prims; split.ib = ib; - split.min_index = min_index; - split.max_index = max_index; + + /* Empty interval, makes calculations simpler. */ + split.min_index = ~0; + split.max_index = 0; + split.draw = draw; split.limits = limits; + split.limit = ib ? limits->max_indices : limits->max_verts; split_prims( &split ); } |