예제 #1
0
/**
 * Store user data into texture memory.
 * Called via glTex[Sub]Image1/2/3D()
 * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
 */
GLboolean
_mesa_texstore(TEXSTORE_PARAMS)
{
   if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat,
                             dstFormat,
                             dstRowStride, dstSlices,
                             srcWidth, srcHeight, srcDepth,
                             srcFormat, srcType, srcAddr, srcPacking)) {
      return GL_TRUE;
   }

   if (_mesa_is_depth_or_stencil_format(baseInternalFormat)) {
      return texstore_depth_stencil(ctx, dims, baseInternalFormat,
                                    dstFormat, dstRowStride, dstSlices,
                                    srcWidth, srcHeight, srcDepth,
                                    srcFormat, srcType, srcAddr, srcPacking);
   } else if (_mesa_is_format_compressed(dstFormat)) {
      return texstore_compressed(ctx, dims, baseInternalFormat,
                                 dstFormat, dstRowStride, dstSlices,
                                 srcWidth, srcHeight, srcDepth,
                                 srcFormat, srcType, srcAddr, srcPacking);
   } else {
      return texstore_rgba(ctx, dims, baseInternalFormat,
                           dstFormat, dstRowStride, dstSlices,
                           srcWidth, srcHeight, srcDepth,
                           srcFormat, srcType, srcAddr, srcPacking);
   }
}
예제 #2
0
unsigned
brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw,
                                     const struct intel_mipmap_tree *mt,
                                     unsigned level)
{
   if (brw->gen >= 9) {
      /* ALL_SLICES_AT_EACH_LOD isn't supported on Gen8+ but this code will
       * effectively end up with a packed qpitch anyway whenever
       * mt->first_level == mt->last_level.
       */
      assert(mt->array_layout != ALL_SLICES_AT_EACH_LOD);

      /* On Gen9 we can pick whatever qpitch we like as long as it's aligned
       * to the vertical alignment so we don't need to add any extra rows.
       */
      unsigned qpitch = mt->total_height;

      /* If the surface might be used as a stencil buffer or HiZ buffer then
       * it needs to be a multiple of 8.
       */
      const GLenum base_format = _mesa_get_format_base_format(mt->format);
      if (_mesa_is_depth_or_stencil_format(base_format))
         qpitch = ALIGN(qpitch, 8);

      /* 3D textures need to be aligned to the tile height. At this point we
       * don't know which tiling will be used so let's just align it to 32
       */
      if (mt->target == GL_TEXTURE_3D)
         qpitch = ALIGN(qpitch, 32);

      return qpitch;

   } else if (mt->target == GL_TEXTURE_3D ||
              (brw->gen == 4 && mt->target == GL_TEXTURE_CUBE_MAP) ||
              mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
      return ALIGN_NPOT(minify(mt->physical_height0, level), mt->align_h);

   } else {
      const unsigned h0 = ALIGN_NPOT(mt->physical_height0, mt->align_h);
      const unsigned h1 = ALIGN_NPOT(minify(mt->physical_height0, 1), mt->align_h);

      return h0 + h1 + (brw->gen >= 7 ? 12 : 11) * mt->align_h;
   }
}
예제 #3
0
void
brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt)
{
   bool multisampled = mt->num_samples > 1;
   bool gen6_hiz_or_stencil = false;

   if (brw->gen == 6 && mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
      const GLenum base_format = _mesa_get_format_base_format(mt->format);
      gen6_hiz_or_stencil = _mesa_is_depth_or_stencil_format(base_format);
   }

   if (gen6_hiz_or_stencil) {
      /* On gen6, we use ALL_SLICES_AT_EACH_LOD for stencil/hiz because the
       * hardware doesn't support multiple mip levels on stencil/hiz.
       *
       * PRM Vol 2, Part 1, 7.5.3 Hierarchical Depth Buffer:
       * "The hierarchical depth buffer does not support the LOD field"
       *
       * PRM Vol 2, Part 1, 7.5.4.1 Separate Stencil Buffer:
       * "The stencil depth buffer does not support the LOD field"
       */
      if (mt->format == MESA_FORMAT_S_UINT8) {
         /* Stencil uses W tiling, so we force W tiling alignment for the
          * ALL_SLICES_AT_EACH_LOD miptree layout.
          */
         mt->align_w = 64;
         mt->align_h = 64;
      } else {
         /* Depth uses Y tiling, so we force need Y tiling alignment for the
          * ALL_SLICES_AT_EACH_LOD miptree layout.
          */
         mt->align_w = 128 / mt->cpp;
         mt->align_h = 32;
      }
   } else {
      mt->align_w = intel_horizontal_texture_alignment_unit(brw, mt);
      mt->align_h =
         intel_vertical_texture_alignment_unit(brw, mt->format, multisampled);
   }

   switch (mt->target) {
   case GL_TEXTURE_CUBE_MAP:
      if (brw->gen == 4) {
         /* Gen4 stores cube maps as 3D textures. */
         assert(mt->physical_depth0 == 6);
         brw_miptree_layout_texture_3d(brw, mt);
      } else {
         /* All other hardware stores cube maps as 2D arrays. */
	 brw_miptree_layout_texture_array(brw, mt);
      }
      break;

   case GL_TEXTURE_3D:
      if (brw->gen >= 9)
         brw_miptree_layout_texture_array(brw, mt);
      else
         brw_miptree_layout_texture_3d(brw, mt);
      break;

   case GL_TEXTURE_1D_ARRAY:
   case GL_TEXTURE_2D_ARRAY:
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   case GL_TEXTURE_CUBE_MAP_ARRAY:
      brw_miptree_layout_texture_array(brw, mt);
      break;

   default:
      switch (mt->msaa_layout) {
      case INTEL_MSAA_LAYOUT_UMS:
      case INTEL_MSAA_LAYOUT_CMS:
         brw_miptree_layout_texture_array(brw, mt);
         break;
      case INTEL_MSAA_LAYOUT_NONE:
      case INTEL_MSAA_LAYOUT_IMS:
         if (use_linear_1d_layout(brw, mt))
            gen9_miptree_layout_1d(mt);
         else
            brw_miptree_layout_2d(mt);
         break;
      }
      break;
   }
   DBG("%s: %dx%dx%d\n", __FUNCTION__,
       mt->total_width, mt->total_height, mt->cpp);
}
예제 #4
0
static void
intel_miptree_set_alignment(struct brw_context *brw,
                            struct intel_mipmap_tree *mt,
                            uint32_t layout_flags)
{
   /**
    * From the "Alignment Unit Size" section of various specs, namely:
    * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
    * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
    * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
    * - BSpec (for Ivybridge and slight variations in separate stencil)
    */
   bool gen6_hiz_or_stencil = false;

   if (brw->gen == 6 && mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
      const GLenum base_format = _mesa_get_format_base_format(mt->format);
      gen6_hiz_or_stencil = _mesa_is_depth_or_stencil_format(base_format);
   }

   if (gen6_hiz_or_stencil) {
      /* On gen6, we use ALL_SLICES_AT_EACH_LOD for stencil/hiz because the
       * hardware doesn't support multiple mip levels on stencil/hiz.
       *
       * PRM Vol 2, Part 1, 7.5.3 Hierarchical Depth Buffer:
       * "The hierarchical depth buffer does not support the LOD field"
       *
       * PRM Vol 2, Part 1, 7.5.4.1 Separate Stencil Buffer:
       * "The stencil depth buffer does not support the LOD field"
       */
      if (mt->format == MESA_FORMAT_S_UINT8) {
         /* Stencil uses W tiling, so we force W tiling alignment for the
          * ALL_SLICES_AT_EACH_LOD miptree layout.
          */
         mt->align_w = 64;
         mt->align_h = 64;
         assert((layout_flags & MIPTREE_LAYOUT_FORCE_HALIGN16) == 0);
      } else {
         /* Depth uses Y tiling, so we force need Y tiling alignment for the
          * ALL_SLICES_AT_EACH_LOD miptree layout.
          */
         mt->align_w = 128 / mt->cpp;
         mt->align_h = 32;
      }
   } else if (mt->compressed) {
       /* The hardware alignment requirements for compressed textures
        * happen to match the block boundaries.
        */
      _mesa_get_format_block_size(mt->format, &mt->align_w, &mt->align_h);

      /* On Gen9+ we can pick our own alignment for compressed textures but it
       * has to be a multiple of the block size. The minimum alignment we can
       * pick is 4 so we effectively have to align to 4 times the block
       * size
       */
      if (brw->gen >= 9) {
         mt->align_w *= 4;
         mt->align_h *= 4;
      }
   } else if (mt->format == MESA_FORMAT_S_UINT8) {
      mt->align_w = 8;
      mt->align_h = brw->gen >= 7 ? 8 : 4;
   } else if (brw->gen >= 9 && mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE) {
      /* XY_FAST_COPY_BLT doesn't support horizontal alignment < 32 or
       * vertical alignment < 64. */
      mt->align_w = MAX2(tr_mode_horizontal_texture_alignment(brw, mt), 32);
      mt->align_h = MAX2(tr_mode_vertical_texture_alignment(brw, mt), 64);
   } else {
      mt->align_w =
         intel_horizontal_texture_alignment_unit(brw, mt, layout_flags);
      mt->align_h = intel_vertical_texture_alignment_unit(brw, mt);
   }
}
예제 #5
0
파일: multisample.c 프로젝트: DirectFB/mesa
/**
 * Helper for checking a requested sample count against the limit
 * for a particular (target, internalFormat) pair. The limit imposed,
 * and the error generated, both depend on which extensions are supported.
 *
 * Returns a GL error enum, or GL_NO_ERROR if the requested sample count is
 * acceptable.
 */
GLenum
_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
                         GLenum internalFormat, GLsizei samples)
{
   /* If ARB_internalformat_query is supported, then treat its highest
    * returned sample count as the absolute maximum for this format; it is
    * allowed to exceed MAX_SAMPLES.
    *
    * From the ARB_internalformat_query spec:
    *
    * "If <samples is greater than the maximum number of samples supported
    * for <internalformat> then the error INVALID_OPERATION is generated."
    */
   if (ctx->Extensions.ARB_internalformat_query) {
      GLint buffer[16];
      int count = ctx->Driver.QuerySamplesForFormat(ctx, target,
                                                    internalFormat, buffer);
      int limit = count ? buffer[0] : -1;

      return samples > limit ? GL_INVALID_OPERATION : GL_NO_ERROR;
   }

   /* If ARB_texture_multisample is supported, we have separate limits,
    * which may be lower than MAX_SAMPLES:
    *
    * From the ARB_texture_multisample spec, when describing the operation
    * of RenderbufferStorageMultisample:
    *
    * "If <internalformat> is a signed or unsigned integer format and
    * <samples> is greater than the value of MAX_INTEGER_SAMPLES, then the
    * error INVALID_OPERATION is generated"
    *
    * And when describing the operation of TexImage*Multisample:
    *
    * "The error INVALID_OPERATION may be generated if any of the following
    * are true:
    *
    * * <internalformat> is a depth/stencil-renderable format and <samples>
    *   is greater than the value of MAX_DEPTH_TEXTURE_SAMPLES
    * * <internalformat> is a color-renderable format and <samples> is
    *   grater than the value of MAX_COLOR_TEXTURE_SAMPLES
    * * <internalformat> is a signed or unsigned integer format and
    *   <samples> is greater than the value of MAX_INTEGER_SAMPLES
    */

   if (ctx->Extensions.ARB_texture_multisample) {
      if (_mesa_is_enum_format_integer(internalFormat))
         return samples > ctx->Const.MaxIntegerSamples
            ? GL_INVALID_OPERATION : GL_NO_ERROR;

      if (target == GL_TEXTURE_2D_MULTISAMPLE ||
          target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {

         if (_mesa_is_depth_or_stencil_format(internalFormat))
            return samples > ctx->Const.MaxDepthTextureSamples
               ? GL_INVALID_OPERATION : GL_NO_ERROR;
         else
            return samples > ctx->Const.MaxColorTextureSamples
               ? GL_INVALID_OPERATION : GL_NO_ERROR;
      }
   }

   /* No more specific limit is available, so just use MAX_SAMPLES:
    *
    * On p205 of the GL3.1 spec:
    *
    * "... or if samples is greater than MAX_SAMPLES, then the error
    * INVALID_VALUE is generated"
    */
   return (GLuint) samples > ctx->Const.MaxSamples
      ? GL_INVALID_VALUE : GL_NO_ERROR;
}
예제 #6
0
파일: multisample.c 프로젝트: airlied/mesa
/**
 * Helper for checking a requested sample count against the limit
 * for a particular (target, internalFormat) pair. The limit imposed,
 * and the error generated, both depend on which extensions are supported.
 *
 * Returns a GL error enum, or GL_NO_ERROR if the requested sample count is
 * acceptable.
 */
GLenum
_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
                         GLenum internalFormat, GLsizei samples)
{
   /* Section 4.4 (Framebuffer objects), page 198 of the OpenGL ES 3.0.0
    * specification says:
    *
    *     "If internalformat is a signed or unsigned integer format and samples
    *     is greater than zero, then the error INVALID_OPERATION is generated."
    *
    * This restriction is relaxed for OpenGL ES 3.1.
    */
   if ((ctx->API == API_OPENGLES2 && ctx->Version == 30) &&
       _mesa_is_enum_format_integer(internalFormat)
       && samples > 0) {
      return GL_INVALID_OPERATION;
   }

   /* If ARB_internalformat_query is supported, then treat its highest
    * returned sample count as the absolute maximum for this format; it is
    * allowed to exceed MAX_SAMPLES.
    *
    * From the ARB_internalformat_query spec:
    *
    * "If <samples is greater than the maximum number of samples supported
    * for <internalformat> then the error INVALID_OPERATION is generated."
    */
   if (ctx->Extensions.ARB_internalformat_query) {
      GLint buffer[16] = {-1};
      GLint limit;

      ctx->Driver.QueryInternalFormat(ctx, target, internalFormat,
                                      GL_SAMPLES, buffer);
      /* since the query returns samples sorted in descending order,
       * the first element is the greatest supported sample value.
       */
      limit = buffer[0];

      return samples > limit ? GL_INVALID_OPERATION : GL_NO_ERROR;
   }

   /* If ARB_texture_multisample is supported, we have separate limits,
    * which may be lower than MAX_SAMPLES:
    *
    * From the ARB_texture_multisample spec, when describing the operation
    * of RenderbufferStorageMultisample:
    *
    * "If <internalformat> is a signed or unsigned integer format and
    * <samples> is greater than the value of MAX_INTEGER_SAMPLES, then the
    * error INVALID_OPERATION is generated"
    *
    * And when describing the operation of TexImage*Multisample:
    *
    * "The error INVALID_OPERATION may be generated if any of the following
    * are true:
    *
    * * <internalformat> is a depth/stencil-renderable format and <samples>
    *   is greater than the value of MAX_DEPTH_TEXTURE_SAMPLES
    * * <internalformat> is a color-renderable format and <samples> is
    *   grater than the value of MAX_COLOR_TEXTURE_SAMPLES
    * * <internalformat> is a signed or unsigned integer format and
    *   <samples> is greater than the value of MAX_INTEGER_SAMPLES
    */

   if (ctx->Extensions.ARB_texture_multisample) {
      if (_mesa_is_enum_format_integer(internalFormat))
         return samples > ctx->Const.MaxIntegerSamples
            ? GL_INVALID_OPERATION : GL_NO_ERROR;

      if (target == GL_TEXTURE_2D_MULTISAMPLE ||
          target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {

         if (_mesa_is_depth_or_stencil_format(internalFormat))
            return samples > ctx->Const.MaxDepthTextureSamples
               ? GL_INVALID_OPERATION : GL_NO_ERROR;
         else
            return samples > ctx->Const.MaxColorTextureSamples
               ? GL_INVALID_OPERATION : GL_NO_ERROR;
      }
   }

   /* No more specific limit is available, so just use MAX_SAMPLES:
    *
    * On p205 of the GL3.1 spec:
    *
    * "... or if samples is greater than MAX_SAMPLES, then the error
    * INVALID_VALUE is generated"
    */
   return (GLuint) samples > ctx->Const.MaxSamples
      ? GL_INVALID_VALUE : GL_NO_ERROR;
}