2 #include "main/glheader.h"
3 #include "main/macros.h"
4 #include "main/mtypes.h"
5 #include "main/enums.h"
6 #include "main/bufferobj.h"
7 #include "main/context.h"
8 #include "main/formats.h"
9 #include "main/image.h"
11 #include "main/renderbuffer.h"
12 #include "main/texcompress.h"
13 #include "main/texgetimage.h"
14 #include "main/texobj.h"
15 #include "main/teximage.h"
16 #include "main/texstore.h"
18 #include "drivers/common/meta.h"
20 #include "intel_mipmap_tree.h"
21 #include "intel_buffer_objects.h"
22 #include "intel_batchbuffer.h"
23 #include "intel_tex.h"
24 #include "intel_blit.h"
25 #include "intel_fbo.h"
26 #include "intel_image.h"
28 #include "brw_context.h"
30 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
32 /* Work back from the specified level of the image to the baselevel and create a
33 * miptree of that size.
35 struct intel_mipmap_tree
*
36 intel_miptree_create_for_teximage(struct brw_context
*brw
,
37 struct intel_texture_object
*intelObj
,
38 struct intel_texture_image
*intelImage
,
39 bool expect_accelerated_upload
)
42 int width
, height
, depth
;
45 intel_miptree_get_dimensions_for_image(&intelImage
->base
.Base
,
46 &width
, &height
, &depth
);
48 DBG("%s\n", __FUNCTION__
);
50 /* Figure out image dimensions at start level. */
51 for (i
= intelImage
->base
.Base
.Level
; i
> 0; i
--) {
59 /* Guess a reasonable value for lastLevel. This is probably going
60 * to be wrong fairly often and might mean that we have to look at
61 * resizable buffers, or require that buffers implement lazy
62 * pagetable arrangements.
64 if ((intelObj
->base
.Sampler
.MinFilter
== GL_NEAREST
||
65 intelObj
->base
.Sampler
.MinFilter
== GL_LINEAR
) &&
66 intelImage
->base
.Base
.Level
== 0 &&
67 !intelObj
->base
.GenerateMipmap
) {
70 lastLevel
= _mesa_get_tex_max_num_levels(intelObj
->base
.Target
,
71 width
, height
, depth
) - 1;
74 return intel_miptree_create(brw
,
75 intelObj
->base
.Target
,
76 intelImage
->base
.Base
.TexFormat
,
82 expect_accelerated_upload
,
83 intelImage
->base
.Base
.NumSamples
,
84 INTEL_MIPTREE_TILING_ANY
,
88 /* XXX: Do this for TexSubImage also:
91 try_pbo_upload(struct gl_context
*ctx
,
92 struct gl_texture_image
*image
,
93 const struct gl_pixelstore_attrib
*unpack
,
94 GLenum format
, GLenum type
, const void *pixels
)
96 struct intel_texture_image
*intelImage
= intel_texture_image(image
);
97 struct brw_context
*brw
= brw_context(ctx
);
98 struct intel_buffer_object
*pbo
= intel_buffer_object(unpack
->BufferObj
);
100 drm_intel_bo
*src_buffer
;
102 if (!_mesa_is_bufferobj(unpack
->BufferObj
))
105 DBG("trying pbo upload\n");
107 if (ctx
->_ImageTransferState
|| unpack
->SkipPixels
|| unpack
->SkipRows
) {
108 DBG("%s: image transfer\n", __FUNCTION__
);
112 ctx
->Driver
.AllocTextureImageBuffer(ctx
, image
);
114 if (!intelImage
->mt
) {
115 DBG("%s: no miptree\n", __FUNCTION__
);
119 if (!_mesa_format_matches_format_and_type(intelImage
->mt
->format
,
120 format
, type
, false)) {
121 DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n",
122 __FUNCTION__
, _mesa_get_format_name(intelImage
->mt
->format
),
127 if (image
->TexObject
->Target
== GL_TEXTURE_1D_ARRAY
||
128 image
->TexObject
->Target
== GL_TEXTURE_2D_ARRAY
) {
129 DBG("%s: no support for array textures\n", __FUNCTION__
);
134 _mesa_image_row_stride(unpack
, image
->Width
, format
, type
);
136 /* note: potential 64-bit ptr to 32-bit int cast */
137 src_offset
= (GLuint
) (unsigned long) pixels
;
138 src_buffer
= intel_bufferobj_buffer(brw
, pbo
,
139 src_offset
, src_stride
* image
->Height
);
141 struct intel_mipmap_tree
*pbo_mt
=
142 intel_miptree_create_for_bo(brw
,
144 intelImage
->mt
->format
,
146 image
->Width
, image
->Height
,
151 if (!intel_miptree_blit(brw
,
154 intelImage
->mt
, image
->Level
, image
->Face
,
156 image
->Width
, image
->Height
, GL_COPY
)) {
157 DBG("%s: blit failed\n", __FUNCTION__
);
158 intel_miptree_release(&pbo_mt
);
162 intel_miptree_release(&pbo_mt
);
164 DBG("%s: success\n", __FUNCTION__
);
169 intelTexImage(struct gl_context
* ctx
,
171 struct gl_texture_image
*texImage
,
172 GLenum format
, GLenum type
, const void *pixels
,
173 const struct gl_pixelstore_attrib
*unpack
)
177 DBG("%s mesa_format %s target %s format %s type %s level %d %dx%dx%d\n",
178 __FUNCTION__
, _mesa_get_format_name(texImage
->TexFormat
),
179 _mesa_lookup_enum_by_nr(texImage
->TexObject
->Target
),
180 _mesa_lookup_enum_by_nr(format
), _mesa_lookup_enum_by_nr(type
),
181 texImage
->Level
, texImage
->Width
, texImage
->Height
, texImage
->Depth
);
183 ok
= intel_texsubimage_tiled_memcpy(ctx
, dims
, texImage
,
184 0, 0, 0, /*x,y,z offsets*/
188 format
, type
, pixels
, unpack
,
189 true /*for_glTexImage*/);
193 /* Attempt to use the blitter for PBO image uploads.
196 try_pbo_upload(ctx
, texImage
, unpack
, format
, type
, pixels
)) {
200 DBG("%s: upload image %dx%dx%d pixels %p\n",
201 __FUNCTION__
, texImage
->Width
, texImage
->Height
, texImage
->Depth
,
204 _mesa_store_teximage(ctx
, dims
, texImage
,
205 format
, type
, pixels
, unpack
);
210 * Binds a BO to a texture image, as if it was uploaded by glTexImage2D().
212 * Used for GLX_EXT_texture_from_pixmap and EGL image extensions,
215 intel_set_texture_image_bo(struct gl_context
*ctx
,
216 struct gl_texture_image
*image
,
219 GLenum internalFormat
,
222 GLuint width
, GLuint height
,
224 GLuint tile_x
, GLuint tile_y
)
226 struct brw_context
*brw
= brw_context(ctx
);
227 struct intel_texture_image
*intel_image
= intel_texture_image(image
);
228 struct gl_texture_object
*texobj
= image
->TexObject
;
229 struct intel_texture_object
*intel_texobj
= intel_texture_object(texobj
);
230 uint32_t draw_x
, draw_y
;
232 _mesa_init_teximage_fields(&brw
->ctx
, image
,
234 0, internalFormat
, format
);
236 ctx
->Driver
.FreeTextureImageBuffer(ctx
, image
);
238 intel_image
->mt
= intel_miptree_create_for_bo(brw
, bo
, image
->TexFormat
,
239 0, width
, height
, pitch
);
240 if (intel_image
->mt
== NULL
)
242 intel_image
->mt
->target
= target
;
243 intel_image
->mt
->total_width
= width
;
244 intel_image
->mt
->total_height
= height
;
245 intel_image
->mt
->level
[0].slice
[0].x_offset
= tile_x
;
246 intel_image
->mt
->level
[0].slice
[0].y_offset
= tile_y
;
248 intel_miptree_get_tile_offsets(intel_image
->mt
, 0, 0, &draw_x
, &draw_y
);
250 /* From "OES_EGL_image" error reporting. We report GL_INVALID_OPERATION
251 * for EGL images from non-tile aligned sufaces in gen4 hw and earlier which has
252 * trouble resolving back to destination image due to alignment issues.
254 if (!brw
->has_surface_tile_offset
&&
255 (draw_x
!= 0 || draw_y
!= 0)) {
256 _mesa_error(ctx
, GL_INVALID_OPERATION
, __func__
);
257 intel_miptree_release(&intel_image
->mt
);
261 intel_texobj
->needs_validate
= true;
263 intel_image
->mt
->offset
= offset
;
264 assert(pitch
% intel_image
->mt
->cpp
== 0);
265 intel_image
->base
.RowStride
= pitch
/ intel_image
->mt
->cpp
;
267 /* Immediately validate the image to the object. */
268 intel_miptree_reference(&intel_texobj
->mt
, intel_image
->mt
);
272 intelSetTexBuffer2(__DRIcontext
*pDRICtx
, GLint target
,
273 GLint texture_format
,
274 __DRIdrawable
*dPriv
)
276 struct gl_framebuffer
*fb
= dPriv
->driverPrivate
;
277 struct brw_context
*brw
= pDRICtx
->driverPrivate
;
278 struct gl_context
*ctx
= &brw
->ctx
;
279 struct intel_renderbuffer
*rb
;
280 struct gl_texture_object
*texObj
;
281 struct gl_texture_image
*texImage
;
282 int level
= 0, internalFormat
= 0;
283 mesa_format texFormat
= MESA_FORMAT_NONE
;
285 texObj
= _mesa_get_current_tex_object(ctx
, target
);
290 if (dPriv
->lastStamp
!= dPriv
->dri2
.stamp
||
291 !pDRICtx
->driScreenPriv
->dri2
.useInvalidate
)
292 intel_update_renderbuffers(pDRICtx
, dPriv
);
294 rb
= intel_get_renderbuffer(fb
, BUFFER_FRONT_LEFT
);
295 /* If the miptree isn't set, then intel_update_renderbuffers was unable
296 * to get the BO for the drawable from the window system.
301 if (rb
->mt
->cpp
== 4) {
302 if (texture_format
== __DRI_TEXTURE_FORMAT_RGB
) {
303 internalFormat
= GL_RGB
;
304 texFormat
= MESA_FORMAT_B8G8R8X8_UNORM
;
307 internalFormat
= GL_RGBA
;
308 texFormat
= MESA_FORMAT_B8G8R8A8_UNORM
;
310 } else if (rb
->mt
->cpp
== 2) {
311 internalFormat
= GL_RGB
;
312 texFormat
= MESA_FORMAT_B5G6R5_UNORM
;
315 _mesa_lock_texture(&brw
->ctx
, texObj
);
316 texImage
= _mesa_get_tex_image(ctx
, texObj
, target
, level
);
317 intel_miptree_make_shareable(brw
, rb
->mt
);
318 intel_set_texture_image_bo(ctx
, texImage
, rb
->mt
->bo
, target
,
319 internalFormat
, texFormat
, 0,
321 rb
->Base
.Base
.Height
,
324 _mesa_unlock_texture(&brw
->ctx
, texObj
);
328 intel_bind_renderbuffer_tex_image(struct gl_context
*ctx
,
329 struct gl_renderbuffer
*rb
,
330 struct gl_texture_image
*image
)
332 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
333 struct intel_texture_image
*intel_image
= intel_texture_image(image
);
334 struct gl_texture_object
*texobj
= image
->TexObject
;
335 struct intel_texture_object
*intel_texobj
= intel_texture_object(texobj
);
337 /* We can only handle RB allocated with AllocRenderbufferStorage, or
338 * window-system renderbuffers.
340 assert(!rb
->TexImage
);
345 _mesa_lock_texture(ctx
, texobj
);
346 _mesa_init_teximage_fields(ctx
, image
,
347 rb
->Width
, rb
->Height
, 1,
348 0, rb
->InternalFormat
, rb
->Format
);
349 image
->NumSamples
= rb
->NumSamples
;
351 intel_miptree_reference(&intel_image
->mt
, irb
->mt
);
353 /* Immediately validate the image to the object. */
354 intel_miptree_reference(&intel_texobj
->mt
, intel_image
->mt
);
356 intel_texobj
->needs_validate
= true;
357 _mesa_unlock_texture(ctx
, texobj
);
363 intelSetTexBuffer(__DRIcontext
*pDRICtx
, GLint target
, __DRIdrawable
*dPriv
)
365 /* The old interface didn't have the format argument, so copy our
366 * implementation's behavior at the time.
368 intelSetTexBuffer2(pDRICtx
, target
, __DRI_TEXTURE_FORMAT_RGBA
, dPriv
);
372 intel_image_target_texture_2d(struct gl_context
*ctx
, GLenum target
,
373 struct gl_texture_object
*texObj
,
374 struct gl_texture_image
*texImage
,
375 GLeglImageOES image_handle
)
377 struct brw_context
*brw
= brw_context(ctx
);
381 screen
= brw
->intelScreen
->driScrnPriv
;
382 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
383 screen
->loaderPrivate
);
388 * Images originating via EGL_EXT_image_dma_buf_import can be used only
389 * with GL_OES_EGL_image_external only.
391 if (image
->dma_buf_imported
&& target
!= GL_TEXTURE_EXTERNAL_OES
) {
392 _mesa_error(ctx
, GL_INVALID_OPERATION
,
393 "glEGLImageTargetTexture2DOES(dma buffers can be used with "
394 "GL_OES_EGL_image_external only");
398 if (target
== GL_TEXTURE_EXTERNAL_OES
&& !image
->dma_buf_imported
) {
399 _mesa_error(ctx
, GL_INVALID_OPERATION
,
400 "glEGLImageTargetTexture2DOES(external target is enabled only "
401 "for images created with EGL_EXT_image_dma_buf_import");
405 /* Disallow depth/stencil textures: we don't have a way to pass the
406 * separate stencil miptree of a GL_DEPTH_STENCIL texture through.
408 if (image
->has_depthstencil
) {
409 _mesa_error(ctx
, GL_INVALID_OPERATION
, __func__
);
413 intel_set_texture_image_bo(ctx
, texImage
, image
->bo
,
414 target
, image
->internal_format
,
415 image
->format
, image
->offset
,
416 image
->width
, image
->height
,
418 image
->tile_x
, image
->tile_y
);
422 blit_texture_to_pbo(struct gl_context
*ctx
,
423 GLenum format
, GLenum type
,
424 GLvoid
* pixels
, struct gl_texture_image
*texImage
)
426 struct intel_texture_image
*intelImage
= intel_texture_image(texImage
);
427 struct brw_context
*brw
= brw_context(ctx
);
428 const struct gl_pixelstore_attrib
*pack
= &ctx
->Pack
;
429 struct intel_buffer_object
*dst
= intel_buffer_object(pack
->BufferObj
);
431 drm_intel_bo
*dst_buffer
;
432 GLenum target
= texImage
->TexObject
->Target
;
434 /* Check if we can use GPU blit to copy from the hardware texture
435 * format to the user's format/type.
436 * Note that GL's pixel transfer ops don't apply to glGetTexImage()
439 if (!_mesa_format_matches_format_and_type(intelImage
->mt
->format
, format
,
442 perf_debug("%s: unsupported format, fallback to CPU mapping for PBO\n",
448 if (ctx
->_ImageTransferState
) {
449 perf_debug("%s: bad transfer state, fallback to CPU mapping for PBO\n",
454 if (pack
->SwapBytes
|| pack
->LsbFirst
) {
455 perf_debug("%s: unsupported pack swap params\n",
460 if (target
== GL_TEXTURE_1D_ARRAY
||
461 target
== GL_TEXTURE_2D_ARRAY
||
462 target
== GL_TEXTURE_CUBE_MAP_ARRAY
||
463 target
== GL_TEXTURE_3D
) {
464 perf_debug("%s: no support for multiple slices, fallback to CPU mapping "
465 "for PBO\n", __FUNCTION__
);
469 int dst_stride
= _mesa_image_row_stride(pack
, texImage
->Width
, format
, type
);
470 bool dst_flip
= false;
471 /* Mesa flips the dst_stride for ctx->Pack.Invert, our mt must have a
474 struct gl_pixelstore_attrib uninverted_pack
= *pack
;
475 if (ctx
->Pack
.Invert
) {
476 dst_stride
= -dst_stride
;
478 uninverted_pack
.Invert
= false;
480 dst_offset
= (GLintptr
) pixels
;
481 dst_offset
+= _mesa_image_offset(2, &uninverted_pack
, texImage
->Width
,
482 texImage
->Height
, format
, type
, 0, 0, 0);
483 dst_buffer
= intel_bufferobj_buffer(brw
, dst
, dst_offset
,
484 texImage
->Height
* dst_stride
);
486 struct intel_mipmap_tree
*pbo_mt
=
487 intel_miptree_create_for_bo(brw
,
489 intelImage
->mt
->format
,
491 texImage
->Width
, texImage
->Height
,
497 if (!intel_miptree_blit(brw
,
498 intelImage
->mt
, texImage
->Level
, texImage
->Face
,
502 texImage
->Width
, texImage
->Height
, GL_COPY
))
505 intel_miptree_release(&pbo_mt
);
511 intel_get_tex_image(struct gl_context
*ctx
,
512 GLenum format
, GLenum type
, GLvoid
*pixels
,
513 struct gl_texture_image
*texImage
) {
514 DBG("%s\n", __FUNCTION__
);
516 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
517 /* Using PBOs, so try the BLT based path. */
518 if (blit_texture_to_pbo(ctx
, format
, type
, pixels
, texImage
))
523 _mesa_meta_GetTexImage(ctx
, format
, type
, pixels
, texImage
);
525 DBG("%s - DONE\n", __FUNCTION__
);
529 intelInitTextureImageFuncs(struct dd_function_table
*functions
)
531 functions
->TexImage
= intelTexImage
;
532 functions
->EGLImageTargetTexture2D
= intel_image_target_texture_2d
;
533 functions
->BindRenderbufferTexImage
= intel_bind_renderbuffer_tex_image
;
534 functions
->GetTexImage
= intel_get_tex_image
;