Ejemplo n.º 1
0
/**
 * Apply stencil test to an array of stencil values (before depth buffering).
 * For the values that fail, we'll apply the GL_STENCIL_FAIL operator to
 * the stencil values.
 *
 * @param face  0 or 1 for front or back-face polygons
 * @param n  number of pixels in the array
 * @param stencil  array of [n] stencil values (in/out)
 * @param mask  array [n] of flag:  0=skip the pixel, 1=stencil the pixel,
 *              values are set to zero where the stencil test fails.
 * @param stride  stride between stencil values
 * @return GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
 */
static GLboolean
do_stencil_test(struct gl_context *ctx, GLuint face, GLuint n,
                GLubyte stencil[], GLubyte mask[], GLint stride)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLubyte *fail = swrast->stencil_temp.buf2;
   GLboolean allfail = GL_FALSE;
   GLuint i, j;
   const GLuint valueMask = ctx->Stencil.ValueMask[face];
   const GLubyte ref = (GLubyte) (_mesa_get_stencil_ref(ctx, face) & valueMask);
   GLubyte s;

   /*
    * Perform stencil test.  The results of this operation are stored
    * in the fail[] array:
    *   IF fail[i] is non-zero THEN
    *       the stencil fail operator is to be applied
    *   ELSE
    *       the stencil fail operator is not to be applied
    *   ENDIF
    */
   switch (ctx->Stencil.Function[face]) {
   case GL_NEVER:
      STENCIL_TEST(0);
      allfail = GL_TRUE;
      break;
   case GL_LESS:
      STENCIL_TEST(ref < s);
      break;
   case GL_LEQUAL:
      STENCIL_TEST(ref <= s);
      break;
   case GL_GREATER:
      STENCIL_TEST(ref > s);
      break;
   case GL_GEQUAL:
      STENCIL_TEST(ref >= s);
      break;
   case GL_EQUAL:
      STENCIL_TEST(ref == s);
      break;
   case GL_NOTEQUAL:
      STENCIL_TEST(ref != s);
      break;
   case GL_ALWAYS:
      STENCIL_TEST(1);
      break;
   default:
      _mesa_problem(ctx, "Bad stencil func in gl_stencil_span");
      return 0;
   }

   if (ctx->Stencil.FailFunc[face] != GL_KEEP) {
      apply_stencil_op(ctx, ctx->Stencil.FailFunc[face], face, n, stencil,
                       fail, stride);
   }

   return !allfail;
}
Ejemplo n.º 2
0
static void
gen6_upload_color_calc_state(struct brw_context *brw)
{
   struct gl_context *ctx = &brw->ctx;
   struct gen6_color_calc_state *cc;

   cc = brw_state_batch(brw, AUB_TRACE_CC_STATE,
			sizeof(*cc), 64, &brw->cc.state_offset);
   memset(cc, 0, sizeof(*cc));

   /* _NEW_COLOR */
   cc->cc0.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
   UNCLAMPED_FLOAT_TO_UBYTE(cc->cc1.alpha_ref_fi.ui, ctx->Color.AlphaRef);

   if (brw->gen < 9) {
      /* _NEW_STENCIL */
      cc->cc0.stencil_ref = _mesa_get_stencil_ref(ctx, 0);
      cc->cc0.bf_stencil_ref =
         _mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace);
   }

   /* _NEW_COLOR */
   cc->constant_r = ctx->Color.BlendColorUnclamped[0];
   cc->constant_g = ctx->Color.BlendColorUnclamped[1];
   cc->constant_b = ctx->Color.BlendColorUnclamped[2];
   cc->constant_a = ctx->Color.BlendColorUnclamped[3];

   /* Point the GPU at the new indirect state. */
   if (brw->gen == 6) {
      BEGIN_BATCH(4);
      OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2));
      OUT_BATCH(0);
      OUT_BATCH(0);
      OUT_BATCH(brw->cc.state_offset | 1);
      ADVANCE_BATCH();
   } else {
      BEGIN_BATCH(2);
      OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (2 - 2));
      OUT_BATCH(brw->cc.state_offset | 1);
      ADVANCE_BATCH();
   }
}
Ejemplo n.º 3
0
/**
 * Apply the given stencil operator to the array of stencil values.
 * Don't touch stencil[i] if mask[i] is zero.
 * @param n   number of stencil values
 * @param oper  the stencil buffer operator
 * @param face  0 or 1 for front or back face operation
 * @param stencil  array of stencil values (in/out)
 * @param mask  array [n] of flag:  1=apply operator, 0=don't apply operator
 * @param stride  stride between stencil values
 */
static void
apply_stencil_op(const struct gl_context *ctx, GLenum oper, GLuint face,
                 GLuint n, GLubyte stencil[], const GLubyte mask[],
                 GLint stride)
{
   const GLubyte ref = _mesa_get_stencil_ref(ctx, face);
   const GLubyte wrtmask = ctx->Stencil.WriteMask[face];
   const GLubyte invmask = (GLubyte) (~wrtmask);
   GLuint i, j;

   switch (oper) {
   case GL_KEEP:
      /* do nothing */
      break;
   case GL_ZERO:
      /* replace stencil buf values with zero */
      STENCIL_OP(0);
      break;
   case GL_REPLACE:
      /* replace stencil buf values with ref value */
      STENCIL_OP(ref);
      break;
   case GL_INCR:
      /* increment stencil buf values, with clamping */
      STENCIL_OP(clamp(s + 1));
      break;
   case GL_DECR:
      /* increment stencil buf values, with clamping */
      STENCIL_OP(clamp(s - 1));
      break;
   case GL_INCR_WRAP_EXT:
      /* increment stencil buf values, without clamping */
      STENCIL_OP(s + 1);
      break;
   case GL_DECR_WRAP_EXT:
      /* increment stencil buf values, without clamping */
      STENCIL_OP(s - 1);
      break;
   case GL_INVERT:
      /* replace stencil buf values with inverted value */
      STENCIL_OP(~s);
      break;
   default:
      _mesa_problem(ctx, "Bad stencil op in apply_stencil_op");
   }
}
void
nv04_emit_control(struct gl_context *ctx, int emit)
{
	struct nv04_context *nv04 = to_nv04_context(ctx);
	struct gl_framebuffer *fb = ctx->DrawBuffer;
	int cull = ctx->Polygon.CullFaceMode;
	int front = ctx->Polygon.FrontFace;

	nv04->ctrl[0] = NV04_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_FIXED |
			NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN_CORNER;
	nv04->ctrl[1] = 0;
	nv04->ctrl[2] = 0;

	/* Dithering. */
	if (ctx->Color.DitherFlag)
		nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE;

	/* Cull mode. */
	if (!ctx->Polygon.CullFlag)
		nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE;
	else if (cull == GL_FRONT_AND_BACK)
		nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH;
	else
		nv04->ctrl[0] |= (cull == GL_FRONT) ^ (front == GL_CCW) ?
				 NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW :
				 NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW;

	/* Depth test. */
	if (ctx->Depth.Test && fb->Visual.depthBits > 0)
		nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE;
	if (ctx->Depth.Mask && fb->Visual.depthBits > 0)
		nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE;

	nv04->ctrl[0] |= get_comparison_op(ctx->Depth.Func) << 16;

	/* Alpha test. */
	if (ctx->Color.AlphaEnabled)
		nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE;

	nv04->ctrl[0] |= get_comparison_op(ctx->Color.AlphaFunc) << 8 |
			 FLOAT_TO_UBYTE(ctx->Color.AlphaRef);

	/* Color mask. */
	if (ctx->Color.ColorMask[0][RCOMP])
		nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE;
	if (ctx->Color.ColorMask[0][GCOMP])
		nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE;
	if (ctx->Color.ColorMask[0][BCOMP])
		nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE;
	if (ctx->Color.ColorMask[0][ACOMP])
		nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE;

	/* Stencil test. */
	if (ctx->Stencil.WriteMask[0])
		nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE;

	if (_mesa_stencil_is_enabled(ctx))
		nv04->ctrl[1] |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE;

	nv04->ctrl[1] |= get_comparison_op(ctx->Stencil.Function[0]) << 4 |
			 _mesa_get_stencil_ref(ctx, 0) << 8 |
			 ctx->Stencil.ValueMask[0] << 16 |
			 ctx->Stencil.WriteMask[0] << 24;

	nv04->ctrl[2] |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 |
			 get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 |
			 get_stencil_op(ctx->Stencil.FailFunc[0]);
}
Ejemplo n.º 5
0
/**
 * Creates the state cache entry for the given CC unit key.
 */
static void upload_cc_unit(struct brw_context *brw)
{
   struct gl_context *ctx = &brw->ctx;
   struct brw_cc_unit_state *cc;

   cc = brw_state_batch(brw, AUB_TRACE_CC_STATE,
			sizeof(*cc), 64, &brw->cc.state_offset);
   memset(cc, 0, sizeof(*cc));

   /* _NEW_STENCIL | _NEW_BUFFERS */
   if (ctx->Stencil._Enabled) {
      const unsigned back = ctx->Stencil._BackFace;

      cc->cc0.stencil_enable = 1;
      cc->cc0.stencil_func =
	 intel_translate_compare_func(ctx->Stencil.Function[0]);
      cc->cc0.stencil_fail_op =
	 intel_translate_stencil_op(ctx->Stencil.FailFunc[0]);
      cc->cc0.stencil_pass_depth_fail_op =
	 intel_translate_stencil_op(ctx->Stencil.ZFailFunc[0]);
      cc->cc0.stencil_pass_depth_pass_op =
	 intel_translate_stencil_op(ctx->Stencil.ZPassFunc[0]);
      cc->cc1.stencil_ref = _mesa_get_stencil_ref(ctx, 0);
      cc->cc1.stencil_write_mask = ctx->Stencil.WriteMask[0];
      cc->cc1.stencil_test_mask = ctx->Stencil.ValueMask[0];

      if (ctx->Stencil._TestTwoSide) {
	 cc->cc0.bf_stencil_enable = 1;
	 cc->cc0.bf_stencil_func =
	    intel_translate_compare_func(ctx->Stencil.Function[back]);
	 cc->cc0.bf_stencil_fail_op =
	    intel_translate_stencil_op(ctx->Stencil.FailFunc[back]);
	 cc->cc0.bf_stencil_pass_depth_fail_op =
	    intel_translate_stencil_op(ctx->Stencil.ZFailFunc[back]);
	 cc->cc0.bf_stencil_pass_depth_pass_op =
	    intel_translate_stencil_op(ctx->Stencil.ZPassFunc[back]);
	 cc->cc1.bf_stencil_ref = _mesa_get_stencil_ref(ctx, back);
	 cc->cc2.bf_stencil_write_mask = ctx->Stencil.WriteMask[back];
	 cc->cc2.bf_stencil_test_mask = ctx->Stencil.ValueMask[back];
      }

      /* Not really sure about this:
       */
      if (ctx->Stencil.WriteMask[0] ||
	  (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[back]))
	 cc->cc0.stencil_write_enable = 1;
   }

   /* _NEW_COLOR */
   if (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY) {
      cc->cc2.logicop_enable = 1;
      cc->cc5.logicop_func = intel_translate_logic_op(ctx->Color.LogicOp);
   } else if (ctx->Color.BlendEnabled) {
      GLenum eqRGB = ctx->Color.Blend[0].EquationRGB;
      GLenum eqA = ctx->Color.Blend[0].EquationA;
      GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
      GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
      GLenum srcA = ctx->Color.Blend[0].SrcA;
      GLenum dstA = ctx->Color.Blend[0].DstA;

      /* If the renderbuffer is XRGB, we have to frob the blend function to
       * force the destination alpha to 1.0.  This means replacing GL_DST_ALPHA
       * with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO.
       */
      if (ctx->DrawBuffer->Visual.alphaBits == 0) {
	 srcRGB = brw_fix_xRGB_alpha(srcRGB);
	 srcA   = brw_fix_xRGB_alpha(srcA);
	 dstRGB = brw_fix_xRGB_alpha(dstRGB);
	 dstA   = brw_fix_xRGB_alpha(dstA);
      }

      if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
	 srcRGB = dstRGB = GL_ONE;
      }

      if (eqA == GL_MIN || eqA == GL_MAX) {
	 srcA = dstA = GL_ONE;
      }

      cc->cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
      cc->cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
      cc->cc6.blend_function = brw_translate_blend_equation(eqRGB);

      cc->cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
      cc->cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
      cc->cc5.ia_blend_function = brw_translate_blend_equation(eqA);

      cc->cc3.blend_enable = 1;
      cc->cc3.ia_blend_enable = (srcA != srcRGB ||
				dstA != dstRGB ||
				eqA != eqRGB);
   }

   /* _NEW_BUFFERS */
   if (ctx->Color.AlphaEnabled && ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
      cc->cc3.alpha_test = 1;
      cc->cc3.alpha_test_func =
	 intel_translate_compare_func(ctx->Color.AlphaFunc);
      cc->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;

      UNCLAMPED_FLOAT_TO_UBYTE(cc->cc7.alpha_ref.ub[0], ctx->Color.AlphaRef);
   }

   if (ctx->Color.DitherFlag) {
      cc->cc5.dither_enable = 1;
      cc->cc6.y_dither_offset = 0;
      cc->cc6.x_dither_offset = 0;
   }

   /* _NEW_DEPTH */
   if (ctx->Depth.Test) {
      cc->cc2.depth_test = 1;
      cc->cc2.depth_test_function =
	 intel_translate_compare_func(ctx->Depth.Func);
      cc->cc2.depth_write_enable = ctx->Depth.Mask;
   }

   if (brw->stats_wm || unlikely(INTEL_DEBUG & DEBUG_STATS))
      cc->cc5.statistics_enable = 1;

   /* CACHE_NEW_CC_VP */
   cc->cc4.cc_viewport_state_offset = (brw->batch.bo->offset +
				       brw->cc.vp_offset) >> 5; /* reloc */

   brw->state.dirty.cache |= CACHE_NEW_CC_UNIT;

   /* Emit CC viewport relocation */
   drm_intel_bo_emit_reloc(brw->batch.bo,
			   (brw->cc.state_offset +
			    offsetof(struct brw_cc_unit_state, cc4)),
			   brw->batch.bo, brw->cc.vp_offset,
			   I915_GEM_DOMAIN_INSTRUCTION, 0);
}
Ejemplo n.º 6
0
static void
update_depth_stencil_alpha(struct st_context *st)
{
   struct pipe_depth_stencil_alpha_state *dsa = &st->state.depth_stencil;
   struct pipe_stencil_ref sr;
   struct gl_context *ctx = st->ctx;

   memset(dsa, 0, sizeof(*dsa));
   memset(&sr, 0, sizeof(sr));

   if (ctx->DrawBuffer->Visual.depthBits > 0) {
      if (ctx->Depth.Test) {
         dsa->depth.enabled = 1;
         dsa->depth.writemask = ctx->Depth.Mask;
         dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func);
      }
      if (ctx->Depth.BoundsTest) {
         dsa->depth.bounds_test = 1;
         dsa->depth.bounds_min = ctx->Depth.BoundsMin;
         dsa->depth.bounds_max = ctx->Depth.BoundsMax;
      }
   }

   if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) {
      dsa->stencil[0].enabled = 1;
      dsa->stencil[0].func = st_compare_func_to_pipe(ctx->Stencil.Function[0]);
      dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[0]);
      dsa->stencil[0].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[0]);
      dsa->stencil[0].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[0]);
      dsa->stencil[0].valuemask = ctx->Stencil.ValueMask[0] & 0xff;
      dsa->stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
      sr.ref_value[0] = _mesa_get_stencil_ref(ctx, 0);

      if (ctx->Stencil._TestTwoSide) {
         const GLuint back = ctx->Stencil._BackFace;
         dsa->stencil[1].enabled = 1;
         dsa->stencil[1].func = st_compare_func_to_pipe(ctx->Stencil.Function[back]);
         dsa->stencil[1].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[back]);
         dsa->stencil[1].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[back]);
         dsa->stencil[1].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[back]);
         dsa->stencil[1].valuemask = ctx->Stencil.ValueMask[back] & 0xff;
         dsa->stencil[1].writemask = ctx->Stencil.WriteMask[back] & 0xff;
         sr.ref_value[1] = _mesa_get_stencil_ref(ctx, back);
      }
      else {
         /* This should be unnecessary. Drivers must not expect this to
          * contain valid data, except the enabled bit
          */
         dsa->stencil[1] = dsa->stencil[0];
         dsa->stencil[1].enabled = 0;
         sr.ref_value[1] = sr.ref_value[0];
      }
   }

   if (ctx->Color.AlphaEnabled &&
       !(ctx->DrawBuffer->_IntegerBuffers & 0x1)) {
      dsa->alpha.enabled = 1;
      dsa->alpha.func = st_compare_func_to_pipe(ctx->Color.AlphaFunc);
      dsa->alpha.ref_value = ctx->Color.AlphaRefUnclamped;
   }

   cso_set_depth_stencil_alpha(st->cso_context, dsa);
   cso_set_stencil_ref(st->cso_context, &sr);
}