Esempio n. 1
0
void
brw_populate_sampler_prog_key_data(struct gl_context *ctx,
				   const struct gl_program *prog,
                                   unsigned sampler_count,
				   struct brw_sampler_prog_key_data *key)
{
   struct brw_context *brw = brw_context(ctx);

   for (int s = 0; s < sampler_count; s++) {
      key->swizzles[s] = SWIZZLE_NOOP;

      if (!(prog->SamplersUsed & (1 << s)))
	 continue;

      int unit_id = prog->SamplerUnits[s];
      const struct gl_texture_unit *unit = &ctx->Texture.Unit[unit_id];

      if (unit->_ReallyEnabled && unit->_Current->Target != GL_TEXTURE_BUFFER) {
	 const struct gl_texture_object *t = unit->_Current;
	 const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
	 struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit_id);

         const bool alpha_depth = t->DepthMode == GL_ALPHA &&
            (img->_BaseFormat == GL_DEPTH_COMPONENT ||
             img->_BaseFormat == GL_DEPTH_STENCIL);

         /* Haswell handles texture swizzling as surface format overrides
          * (except for GL_ALPHA); all other platforms need MOVs in the shader.
          */
         if (!brw->is_haswell || alpha_depth)
            key->swizzles[s] = brw_get_texture_swizzle(ctx, t);

	 if (img->InternalFormat == GL_YCBCR_MESA) {
	    key->yuvtex_mask |= 1 << s;
	    if (img->TexFormat == MESA_FORMAT_YCBCR)
		key->yuvtex_swap_mask |= 1 << s;
	 }

	 if (sampler->MinFilter != GL_NEAREST &&
	     sampler->MagFilter != GL_NEAREST) {
	    if (sampler->WrapS == GL_CLAMP)
	       key->gl_clamp_mask[0] |= 1 << s;
	    if (sampler->WrapT == GL_CLAMP)
	       key->gl_clamp_mask[1] |= 1 << s;
	    if (sampler->WrapR == GL_CLAMP)
	       key->gl_clamp_mask[2] |= 1 << s;
	 }

         /* gather4's channel select for green from RG32F is broken;
          * requires a shader w/a on IVB; fixable with just SCS on HSW. */
         if (brw->gen >= 7 && !brw->is_haswell && prog->UsesGather) {
            if (img->InternalFormat == GL_RG32F)
               key->gather_channel_quirk_mask |= 1 << s;
         }
      }
   }
}
Esempio n. 2
0
void
brw_populate_sampler_prog_key_data(struct gl_context *ctx,
				   const struct gl_program *prog,
				   struct brw_sampler_prog_key_data *key)
{
   struct intel_context *intel = intel_context(ctx);

   for (int s = 0; s < MAX_SAMPLERS; s++) {
      key->swizzles[s] = SWIZZLE_NOOP;

      if (!(prog->SamplersUsed & (1 << s)))
	 continue;

      int unit_id = prog->SamplerUnits[s];
      const struct gl_texture_unit *unit = &ctx->Texture.Unit[unit_id];

      if (unit->_ReallyEnabled && unit->_Current->Target != GL_TEXTURE_BUFFER) {
	 const struct gl_texture_object *t = unit->_Current;
	 const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
	 struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit_id);

         const bool alpha_depth = t->DepthMode == GL_ALPHA &&
            (img->_BaseFormat == GL_DEPTH_COMPONENT ||
             img->_BaseFormat == GL_DEPTH_STENCIL);

         /* Haswell handles texture swizzling as surface format overrides
          * (except for GL_ALPHA); all other platforms need MOVs in the shader.
          */
         if (!intel->is_haswell || alpha_depth)
            key->swizzles[s] = brw_get_texture_swizzle(ctx, t);

	 if (img->InternalFormat == GL_YCBCR_MESA) {
	    key->yuvtex_mask |= 1 << s;
	    if (img->TexFormat == MESA_FORMAT_YCBCR)
		key->yuvtex_swap_mask |= 1 << s;
	 }

	 if (sampler->MinFilter != GL_NEAREST &&
	     sampler->MagFilter != GL_NEAREST) {
	    if (sampler->WrapS == GL_CLAMP)
	       key->gl_clamp_mask[0] |= 1 << s;
	    if (sampler->WrapT == GL_CLAMP)
	       key->gl_clamp_mask[1] |= 1 << s;
	    if (sampler->WrapR == GL_CLAMP)
	       key->gl_clamp_mask[2] |= 1 << s;
	 }
      }
   }
}
Esempio n. 3
0
void
brw_populate_sampler_prog_key_data(struct gl_context *ctx,
                                   const struct gl_program *prog,
                                   struct brw_sampler_prog_key_data *key)
{
   struct brw_context *brw = brw_context(ctx);
   const struct gen_device_info *devinfo = &brw->screen->devinfo;
   GLbitfield mask = prog->SamplersUsed;

   while (mask) {
      const int s = u_bit_scan(&mask);

      key->swizzles[s] = SWIZZLE_NOOP;
      key->scale_factors[s] = 0.0f;

      int unit_id = prog->SamplerUnits[s];
      const struct gl_texture_unit *unit = &ctx->Texture.Unit[unit_id];

      if (unit->_Current && unit->_Current->Target != GL_TEXTURE_BUFFER) {
         const struct gl_texture_object *t = unit->_Current;
         const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
         struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit_id);

         const bool alpha_depth = t->DepthMode == GL_ALPHA &&
            (img->_BaseFormat == GL_DEPTH_COMPONENT ||
             img->_BaseFormat == GL_DEPTH_STENCIL);

         /* Haswell handles texture swizzling as surface format overrides
          * (except for GL_ALPHA); all other platforms need MOVs in the shader.
          */
         if (alpha_depth || (devinfo->gen < 8 && !devinfo->is_haswell))
            key->swizzles[s] = brw_get_texture_swizzle(ctx, t);

         if (devinfo->gen < 8 &&
             sampler->MinFilter != GL_NEAREST &&
             sampler->MagFilter != GL_NEAREST) {
            if (sampler->WrapS == GL_CLAMP)
               key->gl_clamp_mask[0] |= 1 << s;
            if (sampler->WrapT == GL_CLAMP)
               key->gl_clamp_mask[1] |= 1 << s;
            if (sampler->WrapR == GL_CLAMP)
               key->gl_clamp_mask[2] |= 1 << s;
         }

         /* gather4 for RG32* is broken in multiple ways on Gen7. */
         if (devinfo->gen == 7 && prog->info.uses_texture_gather) {
            switch (img->InternalFormat) {
            case GL_RG32I:
            case GL_RG32UI: {
               /* We have to override the format to R32G32_FLOAT_LD.
                * This means that SCS_ALPHA and SCS_ONE will return 0x3f8
                * (1.0) rather than integer 1.  This needs shader hacks.
                *
                * On Ivybridge, we whack W (alpha) to ONE in our key's
                * swizzle.  On Haswell, we look at the original texture
                * swizzle, and use XYZW with channels overridden to ONE,
                * leaving normal texture swizzling to SCS.
                */
               unsigned src_swizzle =
                  devinfo->is_haswell ? t->_Swizzle : key->swizzles[s];
               for (int i = 0; i < 4; i++) {
                  unsigned src_comp = GET_SWZ(src_swizzle, i);
                  if (src_comp == SWIZZLE_ONE || src_comp == SWIZZLE_W) {
                     key->swizzles[i] &= ~(0x7 << (3 * i));
                     key->swizzles[i] |= SWIZZLE_ONE << (3 * i);
                  }
               }
               /* fallthrough */
            }
            case GL_RG32F:
               /* The channel select for green doesn't work - we have to
                * request blue.  Haswell can use SCS for this, but Ivybridge
                * needs a shader workaround.
                */
               if (!devinfo->is_haswell)
                  key->gather_channel_quirk_mask |= 1 << s;
               break;
            }
         }

         /* Gen6's gather4 is broken for UINT/SINT; we treat them as
          * UNORM/FLOAT instead and fix it in the shader.
          */
         if (devinfo->gen == 6 && prog->info.uses_texture_gather) {
            key->gen6_gather_wa[s] = gen6_gather_workaround(img->InternalFormat);
         }

         /* If this is a multisample sampler, and uses the CMS MSAA layout,
          * then we need to emit slightly different code to first sample the
          * MCS surface.
          */
         struct intel_texture_object *intel_tex =
            intel_texture_object((struct gl_texture_object *)t);

         /* From gen9 onwards some single sampled buffers can also be
          * compressed. These don't need ld2dms sampling along with mcs fetch.
          */
         if (intel_tex->mt->aux_usage == ISL_AUX_USAGE_MCS) {
            assert(devinfo->gen >= 7);
            assert(intel_tex->mt->surf.samples > 1);
            assert(intel_tex->mt->aux_buf);
            assert(intel_tex->mt->surf.msaa_layout == ISL_MSAA_LAYOUT_ARRAY);
            key->compressed_multisample_layout_mask |= 1 << s;

            if (intel_tex->mt->surf.samples >= 16) {
               assert(devinfo->gen >= 9);
               key->msaa_16 |= 1 << s;
            }
         }

         if (t->Target == GL_TEXTURE_EXTERNAL_OES && intel_tex->planar_format) {

            /* Setup possible scaling factor. */
            key->scale_factors[s] = intel_tex->planar_format->scaling_factor;

            switch (intel_tex->planar_format->components) {
            case __DRI_IMAGE_COMPONENTS_Y_UV:
               key->y_uv_image_mask |= 1 << s;
               break;
            case __DRI_IMAGE_COMPONENTS_Y_U_V:
               key->y_u_v_image_mask |= 1 << s;
               break;
            case __DRI_IMAGE_COMPONENTS_Y_XUXV:
               key->yx_xuxv_image_mask |= 1 << s;
               break;
            case __DRI_IMAGE_COMPONENTS_Y_UXVX:
               key->xy_uxvx_image_mask |= 1 << s;
               break;
            case __DRI_IMAGE_COMPONENTS_AYUV:
               key->ayuv_image_mask |= 1 << s;
               break;
            case __DRI_IMAGE_COMPONENTS_XYUV:
               key->xyuv_image_mask |= 1 << s;
               break;
            default:
               break;
            }
         }

      }
   }
}
Esempio n. 4
0
void
brw_populate_sampler_prog_key_data(struct gl_context *ctx,
				   const struct gl_program *prog,
                                   unsigned sampler_count,
				   struct brw_sampler_prog_key_data *key)
{
   struct brw_context *brw = brw_context(ctx);

   for (int s = 0; s < sampler_count; s++) {
      key->swizzles[s] = SWIZZLE_NOOP;

      if (!(prog->SamplersUsed & (1 << s)))
	 continue;

      int unit_id = prog->SamplerUnits[s];
      const struct gl_texture_unit *unit = &ctx->Texture.Unit[unit_id];

      if (unit->_Current && unit->_Current->Target != GL_TEXTURE_BUFFER) {
	 const struct gl_texture_object *t = unit->_Current;
	 const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
	 struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit_id);

         const bool alpha_depth = t->DepthMode == GL_ALPHA &&
            (img->_BaseFormat == GL_DEPTH_COMPONENT ||
             img->_BaseFormat == GL_DEPTH_STENCIL);

         /* Haswell handles texture swizzling as surface format overrides
          * (except for GL_ALPHA); all other platforms need MOVs in the shader.
          */
         if (alpha_depth || (brw->gen < 8 && !brw->is_haswell))
            key->swizzles[s] = brw_get_texture_swizzle(ctx, t);

	 if (brw->gen < 8 &&
             sampler->MinFilter != GL_NEAREST &&
	     sampler->MagFilter != GL_NEAREST) {
	    if (sampler->WrapS == GL_CLAMP)
	       key->gl_clamp_mask[0] |= 1 << s;
	    if (sampler->WrapT == GL_CLAMP)
	       key->gl_clamp_mask[1] |= 1 << s;
	    if (sampler->WrapR == GL_CLAMP)
	       key->gl_clamp_mask[2] |= 1 << s;
	 }

         /* gather4's channel select for green from RG32F is broken; requires
          * a shader w/a on IVB; fixable with just SCS on HSW.
          */
         if (brw->gen == 7 && !brw->is_haswell && prog->UsesGather) {
            if (img->InternalFormat == GL_RG32F)
               key->gather_channel_quirk_mask |= 1 << s;
         }

         /* Gen6's gather4 is broken for UINT/SINT; we treat them as
          * UNORM/FLOAT instead and fix it in the shader.
          */
         if (brw->gen == 6 && prog->UsesGather) {
            key->gen6_gather_wa[s] = gen6_gather_workaround(img->InternalFormat);
         }

         /* If this is a multisample sampler, and uses the CMS MSAA layout,
          * then we need to emit slightly different code to first sample the
          * MCS surface.
          */
         struct intel_texture_object *intel_tex =
            intel_texture_object((struct gl_texture_object *)t);

         if (brw->gen >= 7 &&
             intel_tex->mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
            key->compressed_multisample_layout_mask |= 1 << s;

            if (intel_tex->mt->num_samples >= 16) {
               assert(brw->gen >= 9);
               key->msaa_16 |= 1 << s;
            }
         }
      }
   }
}