diff options
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_quad_stipple.c | 18 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_setup.c | 13 | ||||
| -rw-r--r-- | src/mesa/state_tracker/st_atom_rasterizer.c | 1 | ||||
| -rw-r--r-- | src/mesa/state_tracker/st_atom_stipple.c | 38 | ||||
| -rw-r--r-- | src/mesa/state_tracker/st_context.h | 3 | ||||
| -rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.c | 179 | 
6 files changed, 203 insertions, 49 deletions
| diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c index 05e862f097..07162db7b6 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stipple.c +++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c @@ -22,21 +22,11 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad)     if (quad->input.prim == QUAD_PRIM_TRI) {        struct softpipe_context *softpipe = qs->softpipe;        /* need to invert Y to index into OpenGL's stipple pattern */ -      int y0, y1; -      uint stipple0, stipple1;        const int col0 = quad->input.x0 % 32; - -      if (softpipe->rasterizer->origin_lower_left) { -         y0 = softpipe->framebuffer.height - 1 - quad->input.y0; -         y1 = y0 - 1; -      } -      else { -         y0 = quad->input.y0; -         y1 = y0 + 1; -      } - -      stipple0 = softpipe->poly_stipple.stipple[y0 % 32]; -      stipple1 = softpipe->poly_stipple.stipple[y1 % 32]; +      const int y0 = quad->input.y0; +      const int y1 = y0 + 1; +      const uint stipple0 = softpipe->poly_stipple.stipple[y0 % 32]; +      const uint stipple1 = softpipe->poly_stipple.stipple[y1 % 32];        /* turn off quad mask bits that fail the stipple test */        if ((stipple0 & (bit31 >> col0)) == 0) diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 0925653b5d..96cb09b905 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -732,18 +732,9 @@ setup_fragcoord_coeff(struct setup_context *setup, uint slot)     setup->coef[slot].dadx[0] = 1.0;     setup->coef[slot].dady[0] = 0.0;     /*Y*/ -   if (setup->softpipe->rasterizer->origin_lower_left) { -      /* y=0=bottom */ -      const int winHeight = setup->softpipe->framebuffer.height; -      setup->coef[slot].a0[1] = (float) (winHeight - 1); -      setup->coef[slot].dady[1] = -1.0; -   } -   else { -      /* y=0=top */ -      setup->coef[slot].a0[1] = 0.0; -      setup->coef[slot].dady[1] = 1.0; -   } +   setup->coef[slot].a0[1] = 0.0;     setup->coef[slot].dadx[1] = 0.0; +   setup->coef[slot].dady[1] = 1.0;     /*Z*/     setup->coef[slot].a0[2] = setup->posCoef.a0[2];     setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index ea76487bcf..5bdcaa4a01 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -79,6 +79,7 @@ static void update_raster_state( struct st_context *st )     memset(raster, 0, sizeof(*raster)); +   /* XXX obsolete field, remove someday */     raster->origin_lower_left = 1; /* Always true for OpenGL */     /* _NEW_POLYGON, _NEW_BUFFERS diff --git a/src/mesa/state_tracker/st_atom_stipple.c b/src/mesa/state_tracker/st_atom_stipple.c index f395930ab4..31e124b329 100644 --- a/src/mesa/state_tracker/st_atom_stipple.c +++ b/src/mesa/state_tracker/st_atom_stipple.c @@ -39,24 +39,52 @@  #include "pipe/p_defines.h" +/** + * OpenGL's polygon stipple is indexed with window coordinates in which + * the origin (0,0) is the lower-left corner of the window. + * With Gallium, the origin is the upper-left corner of the window. + * To convert GL's polygon stipple to what gallium expects we need to + * invert the pattern vertically and rotate the stipple rows according + * to the window height. + */ +static void +invert_stipple(GLuint dest[32], const GLuint src[32], GLuint winHeight) +{ +   GLuint i; + +   for (i = 0; i < 32; i++) { +      dest[i] = src[(winHeight - 1 - i) & 0x1f]; +   } +} + + +  static void   update_stipple( struct st_context *st )  { -   const GLuint sz = sizeof(st->state.poly_stipple.stipple); +   const GLuint sz = sizeof(st->state.poly_stipple);     assert(sz == sizeof(st->ctx->PolygonStipple)); -   if (memcmp(&st->state.poly_stipple.stipple, st->ctx->PolygonStipple, sz)) { +   if (memcmp(st->state.poly_stipple, st->ctx->PolygonStipple, sz)) {        /* state has changed */ -      memcpy(st->state.poly_stipple.stipple, st->ctx->PolygonStipple, sz); -      st->pipe->set_polygon_stipple(st->pipe, &st->state.poly_stipple); +      struct pipe_poly_stipple newStipple; + +      memcpy(st->state.poly_stipple, st->ctx->PolygonStipple, sz); + +      invert_stipple(newStipple.stipple, st->ctx->PolygonStipple, +                     st->ctx->DrawBuffer->Height); + +      st->pipe->set_polygon_stipple(st->pipe, &newStipple);     }  } +/** Update the stipple when the pattern or window height changes */  const struct st_tracked_state st_update_polygon_stipple = {     "st_update_polygon_stipple",				/* name */     {							/* dirty */ -      (_NEW_POLYGONSTIPPLE),				/* mesa */ +      (_NEW_POLYGONSTIPPLE | +       _NEW_BUFFERS),					/* mesa */        0,						/* st */     },     update_stipple					/* update */ diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index d7518ab689..ae8c2978bf 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -93,12 +93,13 @@ struct st_context        struct pipe_constant_buffer constants[2];        struct pipe_framebuffer_state framebuffer;        struct pipe_texture *sampler_texture[PIPE_MAX_SAMPLERS]; -      struct pipe_poly_stipple poly_stipple;        struct pipe_scissor_state scissor;        struct pipe_viewport_state viewport;        GLuint num_samplers;        GLuint num_textures; + +      GLuint poly_stipple[32];  /**< In OpenGL's bottom-to-top order */     } state;     struct { diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index cbf3f334c0..ffa607dd87 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -219,8 +219,9 @@ compile_instruction(     const GLuint immediateMapping[],     GLboolean indirectAccess,     GLuint preamble_size, -   GLuint processor, -   GLboolean *insideSubroutine) +   GLuint procType, +   GLboolean *insideSubroutine, +   GLint wposTemp)  {     GLuint i;     struct tgsi_full_dst_register *fulldst; @@ -247,19 +248,29 @@ compile_instruction(        GLuint j;        fullsrc = &fullinst->FullSrcRegisters[i]; -      fullsrc->SrcRegister.File = map_register_file( -         inst->SrcReg[i].File, -         inst->SrcReg[i].Index, -         immediateMapping, -         indirectAccess ); -      fullsrc->SrcRegister.Index = map_register_file_index( -         fullsrc->SrcRegister.File, -         inst->SrcReg[i].Index, -         inputMapping, -         outputMapping, -         immediateMapping, -         indirectAccess ); +      if (procType == TGSI_PROCESSOR_FRAGMENT && +          inst->SrcReg[i].File == PROGRAM_INPUT && +          inst->SrcReg[i].Index == FRAG_ATTRIB_WPOS) { +         /* special case of INPUT[WPOS] */ +         fullsrc->SrcRegister.File = TGSI_FILE_TEMPORARY; +         fullsrc->SrcRegister.Index = wposTemp; +      } +      else { +         /* any other src register */ +         fullsrc->SrcRegister.File = map_register_file( +            inst->SrcReg[i].File, +            inst->SrcReg[i].Index, +            immediateMapping, +            indirectAccess ); +         fullsrc->SrcRegister.Index = map_register_file_index( +            fullsrc->SrcRegister.File, +            inst->SrcReg[i].Index, +            inputMapping, +            outputMapping, +            immediateMapping, +            indirectAccess ); +      }        /* swizzle (ext swizzle also depends on negation) */        { @@ -733,6 +744,111 @@ find_temporaries(const struct gl_program *program,  } +/** + * Find an unused temporary in the tempsUsed array. + */ +static int +find_free_temporary(GLboolean tempsUsed[MAX_PROGRAM_TEMPS]) +{ +   int i; +   for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { +      if (!tempsUsed[i]) { +         tempsUsed[i] = GL_TRUE; +         return i; +      } +   } +   return -1; +} + + +/** helper for building simple TGSI instruction, one src register */ +static void +build_tgsi_instruction1(struct tgsi_full_instruction *inst, +                        int opcode, +                        int dstFile, int dstIndex, int writemask, +                        int srcFile1, int srcIndex1) +{ +   *inst = tgsi_default_full_instruction(); + +   inst->Instruction.Opcode = opcode; + +   inst->Instruction.NumDstRegs = 1; +   inst->FullDstRegisters[0].DstRegister.File = dstFile; +   inst->FullDstRegisters[0].DstRegister.Index = dstIndex; +   inst->FullDstRegisters[0].DstRegister.WriteMask = writemask; + +   inst->Instruction.NumSrcRegs = 1; +   inst->FullSrcRegisters[0].SrcRegister.File = srcFile1; +   inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1; +} + + +/** helper for building simple TGSI instruction, two src registers */ +static void +build_tgsi_instruction2(struct tgsi_full_instruction *inst, +                        int opcode, +                        int dstFile, int dstIndex, int writemask, +                        int srcFile1, int srcIndex1, +                        int srcFile2, int srcIndex2) +{ +   *inst = tgsi_default_full_instruction(); + +   inst->Instruction.Opcode = opcode; + +   inst->Instruction.NumDstRegs = 1; +   inst->FullDstRegisters[0].DstRegister.File = dstFile; +   inst->FullDstRegisters[0].DstRegister.Index = dstIndex; +   inst->FullDstRegisters[0].DstRegister.WriteMask = writemask; + +   inst->Instruction.NumSrcRegs = 2; +   inst->FullSrcRegisters[0].SrcRegister.File = srcFile1; +   inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1; +   inst->FullSrcRegisters[1].SrcRegister.File = srcFile2; +   inst->FullSrcRegisters[1].SrcRegister.Index = srcIndex2; +} + + + +/** + * Emit the TGSI instructions for inverting the WPOS y coordinate. + */ +static int +emit_inverted_wpos(struct tgsi_token *tokens, +                   int wpos_temp, +                   int winsize_const, +                   int wpos_input, +                   struct tgsi_header *header, int maxTokens) +{ +   struct tgsi_full_instruction fullinst; +   int ti = 0; + +   /* MOV wpos_temp.xzw, input[wpos]; */ +   build_tgsi_instruction1(&fullinst, +                           TGSI_OPCODE_MOV, +                           TGSI_FILE_TEMPORARY, wpos_temp, WRITEMASK_XZW, +                           TGSI_FILE_INPUT, 0); + +   ti += tgsi_build_full_instruction(&fullinst, +                                     &tokens[ti], +                                     header, +                                     maxTokens - ti); + +   /* SUB wpos_temp.y, const[winsize_const] - input[wpos_input]; */ +   build_tgsi_instruction2(&fullinst, +                           TGSI_OPCODE_SUB, +                           TGSI_FILE_TEMPORARY, wpos_temp, WRITEMASK_Y, +                           TGSI_FILE_CONSTANT, winsize_const, +                           TGSI_FILE_INPUT, wpos_input); + +   ti += tgsi_build_full_instruction(&fullinst, +                                     &tokens[ti], +                                     header, +                                     maxTokens - ti); + +   return ti; +} + +  /** @@ -778,16 +894,34 @@ st_translate_mesa_program(     GLuint ti;  /* token index */     struct tgsi_header *header;     struct tgsi_processor *processor; -   struct tgsi_full_instruction fullinst;     GLuint preamble_size = 0;     GLuint immediates[1000];     GLuint numImmediates = 0;     GLboolean insideSubroutine = GL_FALSE;     GLboolean indirectAccess = GL_FALSE; +   GLboolean tempsUsed[MAX_PROGRAM_TEMPS + 1]; +   GLint wposTemp = -1, winHeightConst = -1;     assert(procType == TGSI_PROCESSOR_FRAGMENT ||            procType == TGSI_PROCESSOR_VERTEX); +   find_temporaries(program, tempsUsed); + +   if (procType == TGSI_PROCESSOR_FRAGMENT) { +      if (program->InputsRead & FRAG_BIT_WPOS) { +         /* Fragment program uses fragment position input. +          * Need to replace instances of INPUT[WPOS] with temp T +          * where T = INPUT[WPOS] by y is inverted. +          */ +         static const gl_state_index winSizeState[STATE_LENGTH] +            = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 }; +         winHeightConst = _mesa_add_state_reference(program->Parameters, +                                                    winSizeState); +         wposTemp = find_free_temporary(tempsUsed); +      } +   } + +     *(struct tgsi_version *) &tokens[0] = tgsi_build_version();     header = (struct tgsi_header *) &tokens[1]; @@ -884,11 +1018,9 @@ st_translate_mesa_program(     /* temporary decls */     { -      GLboolean tempsUsed[MAX_PROGRAM_TEMPS + 1];        GLboolean inside_range = GL_FALSE;        GLuint start_range = 0; -      find_temporaries(program, tempsUsed);        tempsUsed[MAX_PROGRAM_TEMPS] = GL_FALSE;        for (i = 0; i < MAX_PROGRAM_TEMPS + 1; i++) {           if (tempsUsed[i] && !inside_range) { @@ -1018,7 +1150,17 @@ st_translate_mesa_program(        }     } +   /* invert WPOS fragment input */ +   if (wposTemp >= 0) { +      ti += emit_inverted_wpos(&tokens[ti], wposTemp, winHeightConst, +                               inputMapping[FRAG_ATTRIB_WPOS], +                               header, maxTokens - ti); +      preamble_size = 2; /* two instructions added */ +   } +     for (i = 0; i < program->NumInstructions; i++) { +      struct tgsi_full_instruction fullinst; +        compile_instruction(           &program->Instructions[i],           &fullinst, @@ -1028,7 +1170,8 @@ st_translate_mesa_program(           indirectAccess,           preamble_size,           procType, -         &insideSubroutine ); +         &insideSubroutine, +         wposTemp);        ti += tgsi_build_full_instruction(           &fullinst, | 
