2 #include "main/glheader.h"
3 #include "main/macros.h"
4 #include "main/mfeatures.h"
5 #include "main/mtypes.h"
6 #include "main/enums.h"
7 #include "main/bufferobj.h"
8 #include "main/context.h"
9 #include "main/formats.h"
11 #include "main/renderbuffer.h"
12 #include "main/texcompress.h"
13 #include "main/texstore.h"
14 #include "main/texgetimage.h"
15 #include "main/texobj.h"
16 #include "main/teximage.h"
18 #include "intel_context.h"
19 #include "intel_mipmap_tree.h"
20 #include "intel_buffer_objects.h"
21 #include "intel_batchbuffer.h"
22 #include "intel_tex.h"
23 #include "intel_blit.h"
24 #include "intel_fbo.h"
25 #include "intel_span.h"
27 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
29 /* Functions to store texture images. Where possible, mipmap_tree's
30 * will be created or further instantiated with image data, otherwise
31 * images will be stored in malloc'd memory. A validation step is
32 * required to pull those images into a mipmap tree, or otherwise
33 * decide a fallback is required.
38 /* Otherwise, store it in memory if (Border != 0) or (any dimension ==
41 * Otherwise, if max_level >= level >= min_level, create tree with
42 * space for textures from min_level down to max_level.
44 * Otherwise, create tree with space for textures from (level
45 * 0)..(1x1). Consider pruning this tree at a validation if the
48 struct intel_mipmap_tree
*
49 intel_miptree_create_for_teximage(struct intel_context
*intel
,
50 struct intel_texture_object
*intelObj
,
51 struct intel_texture_image
*intelImage
,
52 GLboolean expect_accelerated_upload
)
56 int width
, height
, depth
;
59 intel_miptree_get_dimensions_for_image(&intelImage
->base
.Base
,
60 &width
, &height
, &depth
);
62 DBG("%s\n", __FUNCTION__
);
64 if (intelImage
->base
.Base
.Border
)
67 if (intelImage
->base
.Base
.Level
> intelObj
->base
.BaseLevel
&&
69 (intelObj
->base
.Target
!= GL_TEXTURE_1D
&& height
== 1) ||
70 (intelObj
->base
.Target
== GL_TEXTURE_3D
&& depth
== 1))) {
71 /* For this combination, we're at some lower mipmap level and
72 * some important dimension is 1. We can't extrapolate up to a
73 * likely base level width/height/depth for a full mipmap stack
74 * from this info, so just allocate this one level.
76 firstLevel
= intelImage
->base
.Base
.Level
;
77 lastLevel
= intelImage
->base
.Base
.Level
;
79 /* If this image disrespects BaseLevel, allocate from level zero.
80 * Usually BaseLevel == 0, so it's unlikely to happen.
82 if (intelImage
->base
.Base
.Level
< intelObj
->base
.BaseLevel
)
85 firstLevel
= intelObj
->base
.BaseLevel
;
87 /* Figure out image dimensions at start level. */
88 for (i
= intelImage
->base
.Base
.Level
; i
> firstLevel
; i
--) {
96 /* Guess a reasonable value for lastLevel. This is probably going
97 * to be wrong fairly often and might mean that we have to look at
98 * resizable buffers, or require that buffers implement lazy
99 * pagetable arrangements.
101 if ((intelObj
->base
.Sampler
.MinFilter
== GL_NEAREST
||
102 intelObj
->base
.Sampler
.MinFilter
== GL_LINEAR
) &&
103 intelImage
->base
.Base
.Level
== firstLevel
&&
104 (intel
->gen
< 4 || firstLevel
== 0)) {
105 lastLevel
= firstLevel
;
107 lastLevel
= firstLevel
+ _mesa_logbase2(MAX2(MAX2(width
, height
), depth
));
111 return intel_miptree_create(intel
,
112 intelObj
->base
.Target
,
113 intelImage
->base
.Base
.TexFormat
,
119 expect_accelerated_upload
);
122 /* There are actually quite a few combinations this will work for,
123 * more than what I've listed here.
126 check_pbo_format(GLenum format
, GLenum type
,
127 gl_format mesa_format
)
129 switch (mesa_format
) {
130 case MESA_FORMAT_ARGB8888
:
131 return (format
== GL_BGRA
&& (type
== GL_UNSIGNED_BYTE
||
132 type
== GL_UNSIGNED_INT_8_8_8_8_REV
));
133 case MESA_FORMAT_RGB565
:
134 return (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
);
136 return (format
== GL_LUMINANCE
&& type
== GL_UNSIGNED_BYTE
);
137 case MESA_FORMAT_YCBCR
:
138 return (type
== GL_UNSIGNED_SHORT_8_8_MESA
|| type
== GL_UNSIGNED_BYTE
);
145 /* XXX: Do this for TexSubImage also:
148 try_pbo_upload(struct gl_context
*ctx
,
149 struct gl_texture_image
*image
,
150 const struct gl_pixelstore_attrib
*unpack
,
151 GLenum format
, GLenum type
,
152 GLint width
, GLint height
, const void *pixels
)
154 struct intel_texture_image
*intelImage
= intel_texture_image(image
);
155 struct intel_context
*intel
= intel_context(ctx
);
156 struct intel_buffer_object
*pbo
= intel_buffer_object(unpack
->BufferObj
);
157 GLuint src_offset
, src_stride
;
158 GLuint dst_x
, dst_y
, dst_stride
;
159 drm_intel_bo
*dst_buffer
, *src_buffer
;
161 if (!_mesa_is_bufferobj(unpack
->BufferObj
))
164 DBG("trying pbo upload\n");
166 if (intel
->ctx
._ImageTransferState
||
167 unpack
->SkipPixels
|| unpack
->SkipRows
) {
168 DBG("%s: image transfer\n", __FUNCTION__
);
172 if (!check_pbo_format(format
, type
, intelImage
->base
.Base
.TexFormat
)) {
173 DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n",
174 __FUNCTION__
, _mesa_get_format_name(intelImage
->base
.Base
.TexFormat
),
179 ctx
->Driver
.AllocTextureImageBuffer(ctx
, image
, image
->TexFormat
,
182 if (!intelImage
->mt
) {
183 DBG("%s: no miptree\n", __FUNCTION__
);
187 dst_buffer
= intelImage
->mt
->region
->bo
;
188 src_buffer
= intel_bufferobj_source(intel
, pbo
, 64, &src_offset
);
189 /* note: potential 64-bit ptr to 32-bit int cast */
190 src_offset
+= (GLuint
) (unsigned long) pixels
;
192 if (unpack
->RowLength
> 0)
193 src_stride
= unpack
->RowLength
;
197 intel_miptree_get_image_offset(intelImage
->mt
, intelImage
->base
.Base
.Level
,
198 intelImage
->base
.Base
.Face
, 0,
201 dst_stride
= intelImage
->mt
->region
->pitch
;
203 if (!intelEmitCopyBlit(intel
,
205 src_stride
, src_buffer
,
206 src_offset
, GL_FALSE
,
207 dst_stride
, dst_buffer
, 0,
208 intelImage
->mt
->region
->tiling
,
209 0, 0, dst_x
, dst_y
, width
, height
,
211 DBG("%s: blit failed\n", __FUNCTION__
);
215 DBG("%s: success\n", __FUNCTION__
);
220 * \param scatter Scatter if true. Gather if false.
222 * \see intel_tex_image_x8z24_scatter
223 * \see intel_tex_image_x8z24_gather
226 intel_tex_image_s8z24_scattergather(struct intel_context
*intel
,
227 struct intel_texture_image
*intel_image
,
230 struct gl_context
*ctx
= &intel
->ctx
;
231 struct gl_renderbuffer
*depth_rb
= intel_image
->depth_rb
;
232 struct gl_renderbuffer
*stencil_rb
= intel_image
->stencil_rb
;
235 intel_miptree_get_dimensions_for_image(&intel_image
->base
.Base
, &w
, &h
, &d
);
236 assert(d
== 1); /* FINISHME */
238 uint32_t depth_row
[w
];
239 uint8_t stencil_row
[w
];
241 intel_renderbuffer_map(intel
, depth_rb
);
242 intel_renderbuffer_map(intel
, stencil_rb
);
245 for (int y
= 0; y
< h
; ++y
) {
246 depth_rb
->GetRow(ctx
, depth_rb
, w
, 0, y
, depth_row
);
247 for (int x
= 0; x
< w
; ++x
) {
248 stencil_row
[x
] = depth_row
[x
] >> 24;
250 stencil_rb
->PutRow(ctx
, stencil_rb
, w
, 0, y
, stencil_row
, NULL
);
252 } else { /* gather */
253 for (int y
= 0; y
< h
; ++y
) {
254 depth_rb
->GetRow(ctx
, depth_rb
, w
, 0, y
, depth_row
);
255 stencil_rb
->GetRow(ctx
, stencil_rb
, w
, 0, y
, stencil_row
);
256 for (int x
= 0; x
< w
; ++x
) {
257 uint32_t s8_x24
= stencil_row
[x
] << 24;
258 uint32_t x8_z24
= depth_row
[x
] & 0x00ffffff;
259 depth_row
[x
] = s8_x24
| x8_z24
;
261 depth_rb
->PutRow(ctx
, depth_rb
, w
, 0, y
, depth_row
, NULL
);
265 intel_renderbuffer_unmap(intel
, depth_rb
);
266 intel_renderbuffer_unmap(intel
, stencil_rb
);
270 * Copy the x8 bits from intel_image->depth_rb to intel_image->stencil_rb.
273 intel_tex_image_s8z24_scatter(struct intel_context
*intel
,
274 struct intel_texture_image
*intel_image
)
276 intel_tex_image_s8z24_scattergather(intel
, intel_image
, true);
280 * Copy the data in intel_image->stencil_rb to the x8 bits in
281 * intel_image->depth_rb.
284 intel_tex_image_s8z24_gather(struct intel_context
*intel
,
285 struct intel_texture_image
*intel_image
)
287 intel_tex_image_s8z24_scattergather(intel
, intel_image
, false);
291 intel_tex_image_s8z24_create_renderbuffers(struct intel_context
*intel
,
292 struct intel_texture_image
*image
)
294 struct gl_context
*ctx
= &intel
->ctx
;
296 int width
, height
, depth
;
297 struct gl_renderbuffer
*drb
;
298 struct gl_renderbuffer
*srb
;
299 struct intel_renderbuffer
*idrb
;
300 struct intel_renderbuffer
*isrb
;
302 intel_miptree_get_dimensions_for_image(&image
->base
.Base
,
303 &width
, &height
, &depth
);
304 assert(depth
== 1); /* FINISHME */
306 assert(intel
->has_separate_stencil
);
307 assert(image
->base
.Base
.TexFormat
== MESA_FORMAT_S8_Z24
);
308 assert(image
->mt
!= NULL
);
310 drb
= intel_create_wrapped_renderbuffer(ctx
, width
, height
,
312 srb
= intel_create_wrapped_renderbuffer(ctx
, width
, height
,
325 idrb
= intel_renderbuffer(drb
);
326 isrb
= intel_renderbuffer(srb
);
328 intel_region_reference(&idrb
->region
, image
->mt
->region
);
329 ok
= intel_alloc_renderbuffer_storage(ctx
, srb
, GL_STENCIL_INDEX8
,
338 intel_renderbuffer_set_draw_offset(idrb
, image
, 0);
339 intel_renderbuffer_set_draw_offset(isrb
, image
, 0);
341 _mesa_reference_renderbuffer(&image
->depth_rb
, drb
);
342 _mesa_reference_renderbuffer(&image
->stencil_rb
, srb
);
348 intelTexImage(struct gl_context
* ctx
,
350 GLenum target
, GLint level
,
351 GLint internalFormat
,
352 GLint width
, GLint height
, GLint depth
,
354 GLenum format
, GLenum type
, const void *pixels
,
355 const struct gl_pixelstore_attrib
*unpack
,
356 struct gl_texture_object
*texObj
,
357 struct gl_texture_image
*texImage
, GLsizei imageSize
)
359 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__
,
360 _mesa_lookup_enum_by_nr(target
), level
, width
, height
, depth
, border
);
362 /* Attempt to use the blitter for PBO image uploads.
365 try_pbo_upload(ctx
, texImage
, unpack
, format
, type
,
366 width
, height
, pixels
)) {
370 DBG("%s: upload image %dx%dx%d pixels %p\n",
371 __FUNCTION__
, width
, height
, depth
, pixels
);
373 _mesa_store_teximage3d(ctx
, target
, level
, internalFormat
,
374 width
, height
, depth
, border
,
375 format
, type
, pixels
,
376 unpack
, texObj
, texImage
);
381 intelTexImage3D(struct gl_context
* ctx
,
382 GLenum target
, GLint level
,
383 GLint internalFormat
,
384 GLint width
, GLint height
, GLint depth
,
386 GLenum format
, GLenum type
, const void *pixels
,
387 const struct gl_pixelstore_attrib
*unpack
,
388 struct gl_texture_object
*texObj
,
389 struct gl_texture_image
*texImage
)
391 intelTexImage(ctx
, 3, target
, level
,
392 internalFormat
, width
, height
, depth
, border
,
393 format
, type
, pixels
, unpack
, texObj
, texImage
, 0);
398 intelTexImage2D(struct gl_context
* ctx
,
399 GLenum target
, GLint level
,
400 GLint internalFormat
,
401 GLint width
, GLint height
, GLint border
,
402 GLenum format
, GLenum type
, const void *pixels
,
403 const struct gl_pixelstore_attrib
*unpack
,
404 struct gl_texture_object
*texObj
,
405 struct gl_texture_image
*texImage
)
407 intelTexImage(ctx
, 2, target
, level
,
408 internalFormat
, width
, height
, 1, border
,
409 format
, type
, pixels
, unpack
, texObj
, texImage
, 0);
414 intelTexImage1D(struct gl_context
* ctx
,
415 GLenum target
, GLint level
,
416 GLint internalFormat
,
417 GLint width
, GLint border
,
418 GLenum format
, GLenum type
, const void *pixels
,
419 const struct gl_pixelstore_attrib
*unpack
,
420 struct gl_texture_object
*texObj
,
421 struct gl_texture_image
*texImage
)
423 intelTexImage(ctx
, 1, target
, level
,
424 internalFormat
, width
, 1, 1, border
,
425 format
, type
, pixels
, unpack
, texObj
, texImage
, 0);
430 * Binds a region to a texture image, like it was uploaded by glTexImage2D().
432 * Used for GLX_EXT_texture_from_pixmap and EGL image extensions,
435 intel_set_texture_image_region(struct gl_context
*ctx
,
436 struct gl_texture_image
*image
,
437 struct intel_region
*region
,
439 GLenum internalFormat
,
442 struct intel_context
*intel
= intel_context(ctx
);
443 struct intel_texture_image
*intel_image
= intel_texture_image(image
);
445 _mesa_init_teximage_fields(&intel
->ctx
, target
, image
,
446 region
->width
, region
->height
, 1,
447 0, internalFormat
, format
);
449 ctx
->Driver
.FreeTextureImageBuffer(ctx
, image
);
451 intel_image
->mt
= intel_miptree_create_for_region(intel
, target
,
454 if (intel_image
->mt
== NULL
)
457 image
->RowStride
= region
->pitch
;
461 intelSetTexBuffer2(__DRIcontext
*pDRICtx
, GLint target
,
462 GLint texture_format
,
463 __DRIdrawable
*dPriv
)
465 struct gl_framebuffer
*fb
= dPriv
->driverPrivate
;
466 struct intel_context
*intel
= pDRICtx
->driverPrivate
;
467 struct gl_context
*ctx
= &intel
->ctx
;
468 struct intel_texture_object
*intelObj
;
469 struct intel_renderbuffer
*rb
;
470 struct gl_texture_object
*texObj
;
471 struct gl_texture_image
*texImage
;
472 int level
= 0, internalFormat
;
475 texObj
= _mesa_get_current_tex_object(ctx
, target
);
476 intelObj
= intel_texture_object(texObj
);
481 if (dPriv
->lastStamp
!= dPriv
->dri2
.stamp
||
482 !pDRICtx
->driScreenPriv
->dri2
.useInvalidate
)
483 intel_update_renderbuffers(pDRICtx
, dPriv
);
485 rb
= intel_get_renderbuffer(fb
, BUFFER_FRONT_LEFT
);
486 /* If the region isn't set, then intel_update_renderbuffers was unable
487 * to get the buffers for the drawable.
489 if (rb
->region
== NULL
)
492 if (texture_format
== __DRI_TEXTURE_FORMAT_RGB
) {
493 internalFormat
= GL_RGB
;
494 texFormat
= MESA_FORMAT_XRGB8888
;
497 internalFormat
= GL_RGBA
;
498 texFormat
= MESA_FORMAT_ARGB8888
;
501 _mesa_lock_texture(&intel
->ctx
, texObj
);
502 texImage
= _mesa_get_tex_image(ctx
, texObj
, target
, level
);
503 intel_set_texture_image_region(ctx
, texImage
, rb
->region
, target
,
504 internalFormat
, texFormat
);
505 _mesa_unlock_texture(&intel
->ctx
, texObj
);
509 intelSetTexBuffer(__DRIcontext
*pDRICtx
, GLint target
, __DRIdrawable
*dPriv
)
511 /* The old interface didn't have the format argument, so copy our
512 * implementation's behavior at the time.
514 intelSetTexBuffer2(pDRICtx
, target
, __DRI_TEXTURE_FORMAT_RGBA
, dPriv
);
517 #if FEATURE_OES_EGL_image
519 intel_image_target_texture_2d(struct gl_context
*ctx
, GLenum target
,
520 struct gl_texture_object
*texObj
,
521 struct gl_texture_image
*texImage
,
522 GLeglImageOES image_handle
)
524 struct intel_context
*intel
= intel_context(ctx
);
528 screen
= intel
->intelScreen
->driScrnPriv
;
529 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
530 screen
->loaderPrivate
);
534 intel_set_texture_image_region(ctx
, texImage
, image
->region
,
535 target
, image
->internal_format
, image
->format
);
540 intelInitTextureImageFuncs(struct dd_function_table
*functions
)
542 functions
->TexImage1D
= intelTexImage1D
;
543 functions
->TexImage2D
= intelTexImage2D
;
544 functions
->TexImage3D
= intelTexImage3D
;
546 #if FEATURE_OES_EGL_image
547 functions
->EGLImageTargetTexture2D
= intel_image_target_texture_2d
;