Esempio n. 1
0
/**
 * ctx->Driver.AllocTextureStorage() handler.
 *
 * Compare this to _mesa_alloc_texture_storage, which would call into
 * intel_alloc_texture_image_buffer() above.
 */
static GLboolean
intel_alloc_texture_storage(struct gl_context *ctx,
                            struct gl_texture_object *texobj,
                            GLsizei levels, GLsizei width,
                            GLsizei height, GLsizei depth)
{
   struct brw_context *brw = brw_context(ctx);
   struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
   struct gl_texture_image *first_image = texobj->Image[0][0];
   int num_samples = intel_quantize_num_samples(brw->intelScreen,
                                                first_image->NumSamples);
   const int numFaces = _mesa_num_tex_faces(texobj->Target);
   int face;
   int level;

   /* If the object's current miptree doesn't match what we need, make a new
    * one.
    */
   if (!intel_texobj->mt ||
       !intel_miptree_match_image(intel_texobj->mt, first_image) ||
       intel_texobj->mt->last_level != levels - 1) {
      intel_miptree_release(&intel_texobj->mt);
      intel_texobj->mt = intel_miptree_create(brw, texobj->Target,
                                              first_image->TexFormat,
                                              0, levels - 1,
                                              width, height, depth,
                                              false, /* expect_accelerated */
                                              num_samples,
                                              INTEL_MIPTREE_TILING_ANY,
                                              false);

      if (intel_texobj->mt == NULL) {
         return false;
      }
   }

   for (face = 0; face < numFaces; face++) {
      for (level = 0; level < levels; level++) {
         struct gl_texture_image *image = texobj->Image[face][level];
         struct intel_texture_image *intel_image = intel_texture_image(image);

         image->NumSamples = num_samples;

         _swrast_free_texture_image_buffer(ctx, image);
         if (!_swrast_init_texture_image(image))
            return false;

         intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
      }
   }

   /* The miptree is in a validated state, so no need to check later. */
   intel_texobj->needs_validate = false;
   intel_texobj->validated_first_level = 0;
   intel_texobj->validated_last_level = levels - 1;
   intel_texobj->_Format = intel_texobj->mt->format;

   return true;
}
/**
 * Called via glRenderbufferStorageEXT() to set the format and allocate
 * storage for a user-created renderbuffer.
 */
GLboolean
intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
                                 GLenum internalFormat,
                                 GLuint width, GLuint height)
{
   struct intel_context *intel = intel_context(ctx);
   struct intel_screen *screen = intel->intelScreen;
   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
   rb->NumSamples = intel_quantize_num_samples(screen, rb->NumSamples);

   switch (internalFormat) {
   default:
      /* Use the same format-choice logic as for textures.
       * Renderbuffers aren't any different from textures for us,
       * except they're less useful because you can't texture with
       * them.
       */
      rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, GL_TEXTURE_2D,
							 internalFormat,
							 GL_NONE, GL_NONE);
      break;
   case GL_STENCIL_INDEX:
   case GL_STENCIL_INDEX1_EXT:
   case GL_STENCIL_INDEX4_EXT:
   case GL_STENCIL_INDEX8_EXT:
   case GL_STENCIL_INDEX16_EXT:
      /* These aren't actual texture formats, so force them here. */
      if (intel->has_separate_stencil) {
	 rb->Format = MESA_FORMAT_S8;
      } else {
	 assert(!intel->must_use_separate_stencil);
	 rb->Format = MESA_FORMAT_S8_Z24;
      }
      break;
   }

   rb->Width = width;
   rb->Height = height;
   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);

   intel_miptree_release(&irb->mt);

   DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__,
       _mesa_lookup_enum_by_nr(internalFormat),
       _mesa_get_format_name(rb->Format), width, height);

   if (width == 0 || height == 0)
      return true;

   irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
						   width, height,
                                                   rb->NumSamples);
   if (!irb->mt)
      return false;

   return true;
}
Esempio n. 3
0
static GLboolean
intel_alloc_texture_image_buffer(struct gl_context *ctx,
				 struct gl_texture_image *image)
{
   struct brw_context *brw = brw_context(ctx);
   struct intel_texture_image *intel_image = intel_texture_image(image);
   struct gl_texture_object *texobj = image->TexObject;
   struct intel_texture_object *intel_texobj = intel_texture_object(texobj);

   assert(image->Border == 0);

   /* Quantize sample count */
   if (image->NumSamples) {
      image->NumSamples = intel_quantize_num_samples(brw->screen, image->NumSamples);
      if (!image->NumSamples)
         return false;
   }

   /* Because the driver uses AllocTextureImageBuffer() internally, it may end
    * up mismatched with FreeTextureImageBuffer(), but that is safe to call
    * multiple times.
    */
   ctx->Driver.FreeTextureImageBuffer(ctx, image);

   if (!_swrast_init_texture_image(image))
      return false;

   if (intel_texobj->mt &&
       intel_miptree_match_image(intel_texobj->mt, image)) {
      intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
      DBG("%s: alloc obj %p level %d %dx%dx%d using object's miptree %p\n",
          __func__, texobj, image->Level,
          image->Width, image->Height, image->Depth, intel_texobj->mt);
   } else {
      intel_image->mt = intel_miptree_create_for_teximage(brw, intel_texobj,
                                                          intel_image,
                                                          MIPTREE_CREATE_DEFAULT);
      if (!intel_image->mt)
         return false;

      /* Even if the object currently has a mipmap tree associated
       * with it, this one is a more likely candidate to represent the
       * whole object since our level didn't fit what was there
       * before, and any lower levels would fit into our miptree.
       */
      intel_miptree_reference(&intel_texobj->mt, intel_image->mt);

      DBG("%s: alloc obj %p level %d %dx%dx%d using new miptree %p\n",
          __func__, texobj, image->Level,
          image->Width, image->Height, image->Depth, intel_image->mt);
   }

   intel_texobj->needs_validate = true;

   return true;
}
Esempio n. 4
0
/**
 * This is called when we need to set up GL rendering to a new X window.
 */
static GLboolean
intelCreateBuffer(__DRIscreen * driScrnPriv,
                  __DRIdrawable * driDrawPriv,
                  const struct gl_config * mesaVis, GLboolean isPixmap)
{
   struct intel_renderbuffer *rb;
   struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
   gl_format rgbFormat;
   unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
   struct gl_framebuffer *fb;

   if (isPixmap)
      return false;

   fb = CALLOC_STRUCT(gl_framebuffer);
   if (!fb)
      return false;

   _mesa_initialize_window_framebuffer(fb, mesaVis);

   if (mesaVis->redBits == 5)
      rgbFormat = MESA_FORMAT_RGB565;
   else if (mesaVis->sRGBCapable)
      rgbFormat = MESA_FORMAT_SARGB8;
   else if (mesaVis->alphaBits == 0)
      rgbFormat = MESA_FORMAT_XRGB8888;
   else
      rgbFormat = MESA_FORMAT_ARGB8888;

   /* setup the hardware-based renderbuffers */
   rb = intel_create_renderbuffer(rgbFormat, num_samples);
   _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);

   if (mesaVis->doubleBufferMode) {
      rb = intel_create_renderbuffer(rgbFormat, num_samples);
      _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
   }

   /*
    * Assert here that the gl_config has an expected depth/stencil bit
    * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
    * which constructs the advertised configs.)
    */
   if (mesaVis->depthBits == 24) {
      assert(mesaVis->stencilBits == 8);

      if (screen->hw_has_separate_stencil) {
         rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24,
                                                num_samples);
         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
         rb = intel_create_private_renderbuffer(MESA_FORMAT_S8,
                                                num_samples);
         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
      } else {
         /*
          * Use combined depth/stencil. Note that the renderbuffer is
          * attached to two attachment points.
          */
         rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24,
                                                num_samples);
         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
      }
   }
   else if (mesaVis->depthBits == 16) {
      assert(mesaVis->stencilBits == 0);
      rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16,
                                             num_samples);
      _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
   }
   else {
      assert(mesaVis->depthBits == 0);
      assert(mesaVis->stencilBits == 0);
   }

   /* now add any/all software-based renderbuffers we may need */
   _swrast_add_soft_renderbuffers(fb,
                                  false, /* never sw color */
                                  false, /* never sw depth */
                                  false, /* never sw stencil */
                                  mesaVis->accumRedBits > 0,
                                  false, /* never sw alpha */
                                  false  /* never sw aux */ );
   driDrawPriv->driverPrivate = fb;

   return true;
}