Beispiel #1
0
/**
 * Scan program instructions to update the program's InputsRead and
 * OutputsWritten fields.
 */
static void
_slang_update_inputs_outputs(struct gl_program *prog)
{
   GLuint i, j;
   GLuint maxAddrReg = 0;

   prog->InputsRead = 0x0;
   prog->OutputsWritten = 0x0;

   for (i = 0; i < prog->NumInstructions; i++) {
      const struct prog_instruction *inst = prog->Instructions + i;
      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
      for (j = 0; j < numSrc; j++) {
         if (inst->SrcReg[j].File == PROGRAM_INPUT) {
            prog->InputsRead |= 1 << inst->SrcReg[j].Index;
         }
         else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
            maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
         }
      }

      if (inst->DstReg.File == PROGRAM_OUTPUT) {
         prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
         if (inst->DstReg.RelAddr) {
            /* If the output attribute is indexed with relative addressing
             * we know that it must be a varying or texcoord such as
             * gl_TexCoord[i] = v;  In this case, mark all the texcoords
             * or varying outputs as being written.  It's not an error if
             * a vertex shader writes varying vars that aren't used by the
             * fragment shader.  But it is an error for a fragment shader
             * to use varyings that are not written by the vertex shader.
             */
            if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
               if (inst->DstReg.Index == VERT_RESULT_TEX0) {
                  /* mark all texcoord outputs as written */
                  const GLbitfield64 mask =
		     BITFIELD64_RANGE(VERT_RESULT_TEX0,
				      (VERT_RESULT_TEX0
				       + MAX_TEXTURE_COORD_UNITS - 1));
                  prog->OutputsWritten |= mask;
               }
               else if (inst->DstReg.Index == VERT_RESULT_VAR0) {
                  /* mark all generic varying outputs as written */
                  const GLbitfield64 mask =
		     BITFIELD64_RANGE(VERT_RESULT_VAR0,
				      (VERT_RESULT_VAR0 + MAX_VARYING - 1));
                  prog->OutputsWritten |= mask;
               }
            }
         }
      }
      else if (inst->DstReg.File == PROGRAM_ADDRESS) {
         maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);
      }
   }
   prog->NumAddressRegs = maxAddrReg;
}
Beispiel #2
0
/**
 * Set vertex state for SW TCL.  The primary purpose of this function is to
 * determine in advance whether or not the hardware can / should do the
 * projection divide or Mesa should do it.
 */
void radeonChooseVertexState( struct gl_context *ctx )
{
   r100ContextPtr rmesa = R100_CONTEXT( ctx );
   TNLcontext *tnl = TNL_CONTEXT(ctx);

   GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
   GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
                         ctx->Polygon.BackMode != GL_FILL);
   GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
   
   se_coord_fmt &= ~(RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
		     RADEON_VTX_Z_PRE_MULT_1_OVER_W0 |
		     RADEON_VTX_W0_IS_NOT_1_OVER_W0);

   /* We must ensure that we don't do _tnl_need_projected_coords while in a
    * rasterization fallback.  As this function will be called again when we
    * leave a rasterization fallback, we can just skip it for now.
    */
   if (rmesa->radeon.Fallback != 0)
      return;

   /* HW perspective divide is a win, but tiny vertex formats are a
    * bigger one.
    */

   if ((0 == (tnl->render_inputs_bitset & 
        (BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)
         | BITFIELD64_BIT(_TNL_ATTRIB_COLOR1))))
       || twosided
       || unfilled) {
      rmesa->swtcl.needproj = GL_TRUE;
      se_coord_fmt |= (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
		      RADEON_VTX_Z_PRE_MULT_1_OVER_W0);
   }
   else {
      rmesa->swtcl.needproj = GL_FALSE;
      se_coord_fmt |= (RADEON_VTX_W0_IS_NOT_1_OVER_W0);
   }

   _tnl_need_projected_coords( ctx, rmesa->swtcl.needproj );

   if ( se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT] ) {
      RADEON_STATECHANGE( rmesa, set );
      rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
   }
}
Beispiel #3
0
/**
 * Tell the tnl module how to build SWvertex objects for swrast.
 * We'll build the map[] array with that info and pass it to
 * _tnl_install_attrs().
 */
static void
setup_vertex_format(struct gl_context *ctx)
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   SScontext *swsetup = SWSETUP_CONTEXT(ctx);
   GLboolean intColors = !ctx->FragmentProgram._Current
                      && !ctx->ATIFragmentShader._Enabled
                      && ctx->RenderMode == GL_RENDER
                      && CHAN_TYPE != GL_FLOAT;

   if (intColors != swsetup->intColors ||
       tnl->render_inputs_bitset != swsetup->last_index_bitset) {
      GLbitfield64 index_bitset = tnl->render_inputs_bitset;
      struct tnl_attr_map map[_TNL_ATTRIB_MAX];
      unsigned int i, e = 0;

      swsetup->intColors = intColors;

      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[VARYING_SLOT_POS] );

      if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR0)) {
         if (swsetup->intColors)
            EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color );
         else
            EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F, attrib[VARYING_SLOT_COL0]);
      }

      if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
         EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F, attrib[VARYING_SLOT_COL1]);
      }

      if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
         const GLint emit = ctx->FragmentProgram._Current ? EMIT_4F : EMIT_1F;
         EMIT_ATTR( _TNL_ATTRIB_FOG, emit, attrib[VARYING_SLOT_FOGC]);
      }

      if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX))
      {
         for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
            if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) {
               EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F,
                          attrib[VARYING_SLOT_TEX0 + i] );
            }
         }
      }

      /* shader varying vars */
      if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_GENERIC0, _TNL_NUM_GENERIC)) {
         for (i = 0; i < ctx->Const.MaxVarying; i++) {
            if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_GENERIC(i))) {
               EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE,
                          attrib[VARYING_SLOT_VAR0 + i] );
            }
         }
      }

      if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE))
         EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, pointSize );

      _tnl_install_attrs( ctx, map, e,
                          ctx->Viewport._WindowMap.m,
                          sizeof(SWvertex) );

      swsetup->last_index_bitset = index_bitset;
   }
}
Beispiel #4
0
static void radeonSetVertexFormat( struct gl_context *ctx )
{
   r100ContextPtr rmesa = R100_CONTEXT( ctx );
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct vertex_buffer *VB = &tnl->vb;
   GLbitfield64 index_bitset = tnl->render_inputs_bitset;
   int fmt_0 = 0;
   int offset = 0;

   /* Important:
    */
   if ( VB->NdcPtr != NULL ) {
      VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
   }
   else {
      VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
   }

   assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL );
   rmesa->radeon.swtcl.vertex_attr_count = 0;

   /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
    * build up a hardware vertex.
    */
   if ( !rmesa->swtcl.needproj ||
        (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX))) {
      /* for projtex */
      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F, 
		 RADEON_CP_VC_FRMT_XY |	RADEON_CP_VC_FRMT_Z | RADEON_CP_VC_FRMT_W0 );
      offset = 4;
   }
   else {
      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F, 
		 RADEON_CP_VC_FRMT_XY |	RADEON_CP_VC_FRMT_Z );
      offset = 3;
   }

   rmesa->swtcl.coloroffset = offset;
#if MESA_LITTLE_ENDIAN 
   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, 
	      RADEON_CP_VC_FRMT_PKCOLOR );
#else
   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR,
	      RADEON_CP_VC_FRMT_PKCOLOR );
#endif
   offset += 1;

   rmesa->swtcl.specoffset = 0;
   if (index_bitset &
       (BITFIELD64_BIT(_TNL_ATTRIB_COLOR1) | BITFIELD64_BIT(_TNL_ATTRIB_FOG))) {

#if MESA_LITTLE_ENDIAN 
      if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
	 rmesa->swtcl.specoffset = offset;
	 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB,
	 	    RADEON_CP_VC_FRMT_PKSPEC );
      }
      else {
	 EMIT_PAD( 3 );
      }

      if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
	 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F,
	 	    RADEON_CP_VC_FRMT_PKSPEC );
      }
      else {
	 EMIT_PAD( 1 );
      }
#else
      if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
	 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F,
	 	    RADEON_CP_VC_FRMT_PKSPEC );
      }
      else {
	 EMIT_PAD( 1 );
      }

      if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
	 rmesa->swtcl.specoffset = offset;
	 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR,
	 	    RADEON_CP_VC_FRMT_PKSPEC );
      }
      else {
	 EMIT_PAD( 3 );
      }
#endif
   }

   if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) {
      int i;

      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
	 if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) {
	    GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;

	    switch (sz) {
	    case 1:
	    case 2:
	       EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_2F,
			  radeon_cp_vc_frmts[i][0] );
	       break;
	    case 3:
	       if (ctx->Texture.Unit[i]._Current &&
                   ctx->Texture.Unit[i]._Current->Target == GL_TEXTURE_CUBE_MAP) {
	           EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F,
			      radeon_cp_vc_frmts[i][1] );
               } else {
	           EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_2F,
			      radeon_cp_vc_frmts[i][0] );
               }
               break;
	    case 4:
	       if (ctx->Texture.Unit[i]._Current &&
                   ctx->Texture.Unit[i]._Current->Target == GL_TEXTURE_CUBE_MAP) {
		  EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F,
			     radeon_cp_vc_frmts[i][1] );
	       } else {
		  EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F_XYW,
			     radeon_cp_vc_frmts[i][1] );
	       }
	       break;
	    default:
	       continue;
	    };
	 }
      }
   }

   if (rmesa->radeon.tnl_index_bitset != index_bitset ||
       fmt_0 != rmesa->swtcl.vertex_format) {
      RADEON_NEWPRIM(rmesa);
      rmesa->swtcl.vertex_format = fmt_0;
      rmesa->radeon.swtcl.vertex_size =
	  _tnl_install_attrs( ctx,
			      rmesa->radeon.swtcl.vertex_attrs, 
			      rmesa->radeon.swtcl.vertex_attr_count,
			      NULL, 0 );
      rmesa->radeon.swtcl.vertex_size /= 4;
      rmesa->radeon.tnl_index_bitset = index_bitset;
      radeon_print(RADEON_SWRENDER, RADEON_VERBOSE,
	  "%s: vertex_size= %d floats\n",  __func__, rmesa->radeon.swtcl.vertex_size);
   }
}
Beispiel #5
0
static void
i830_render_start(struct intel_context *intel)
{
    struct gl_context *ctx = &intel->ctx;
    struct i830_context *i830 = i830_context(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
    GLbitfield64 index_bitset = tnl->render_inputs_bitset;
    GLuint v0 = _3DSTATE_VFT0_CMD;
    GLuint v2 = _3DSTATE_VFT1_CMD;
    GLuint mcsb1 = 0;

    /* Important:
     */
    VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
    intel->vertex_attr_count = 0;

    /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
     * build up a hardware vertex.
     */
    if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) {
        EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW);
        intel->coloroffset = 4;
    }
    else {
        EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ);
        intel->coloroffset = 3;
    }

    if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE)) {
        EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH);
    }

    EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE);

    intel->specoffset = 0;
    if (index_bitset & (BITFIELD64_BIT(_TNL_ATTRIB_COLOR1) |
                        BITFIELD64_BIT(_TNL_ATTRIB_FOG))) {
        if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
            intel->specoffset = intel->coloroffset + 1;
            EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC);
        }
        else
            EMIT_PAD(3);

        if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG))
            EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC);
        else
            EMIT_PAD(1);
    }

    if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) {
        int i, count = 0;

        for (i = 0; i < I830_TEX_UNITS; i++) {
            if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) {
                GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
                GLuint emit;
                GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] &
                              ~TEXCOORDTYPE_MASK);

                switch (sz) {
                case 1:
                case 2:
                    emit = EMIT_2F;
                    sz = 2;
                    mcs |= TEXCOORDTYPE_CARTESIAN;
                    break;
                case 3:
                    emit = EMIT_3F;
                    sz = 3;
                    mcs |= TEXCOORDTYPE_VECTOR;
                    break;
                case 4:
                    emit = EMIT_3F_XYW;
                    sz = 3;
                    mcs |= TEXCOORDTYPE_HOMOGENEOUS;
                    break;
                default:
                    continue;
                };


                EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, emit, 0);
                v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz));
                mcsb1 |= (count + 8) << (i * 4);

                if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) {
                    I830_STATECHANGE(i830, I830_UPLOAD_TEX(i));
                    i830->state.Tex[i][I830_TEXREG_MCS] = mcs;
                }

                count++;
            }
        }

        v0 |= VFT0_TEX_COUNT(count);
    }

    /* Only need to change the vertex emit code if there has been a
     * statechange to a new hardware vertex format:
     */
    if (v0 != i830->state.Ctx[I830_CTXREG_VF] ||
            v2 != i830->state.Ctx[I830_CTXREG_VF2] ||
            mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] ||
            index_bitset != i830->last_index_bitset) {
        I830_STATECHANGE(i830, I830_UPLOAD_CTX);

        /* Must do this *after* statechange, so as not to affect
         * buffered vertices reliant on the old state:
         */
        intel->vertex_size =
            _tnl_install_attrs(ctx,
                               intel->vertex_attrs,
                               intel->vertex_attr_count,
                               intel->ViewportMatrix.m, 0);

        intel->vertex_size >>= 2;

        i830->state.Ctx[I830_CTXREG_VF] = v0;
        i830->state.Ctx[I830_CTXREG_VF2] = v2;
        i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1;
        i830->last_index_bitset = index_bitset;

        assert(i830_check_vertex_size(intel, intel->vertex_size));
    }