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 "intel_mipmap_tree.h"
19 #include "intel_buffer_objects.h"
20 #include "intel_batchbuffer.h"
21 #include "intel_tex.h"
22 #include "intel_blit.h"
23 #include "intel_fbo.h"
25 #include "brw_context.h"
27 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
29 /* Work back from the specified level of the image to the baselevel and create a
30 * miptree of that size.
32 struct intel_mipmap_tree
*
33 intel_miptree_create_for_teximage(struct brw_context
*brw
,
34 struct intel_texture_object
*intelObj
,
35 struct intel_texture_image
*intelImage
,
36 bool expect_accelerated_upload
)
39 int width
, height
, depth
;
42 intel_miptree_get_dimensions_for_image(&intelImage
->base
.Base
,
43 &width
, &height
, &depth
);
45 DBG("%s\n", __FUNCTION__
);
47 /* Figure out image dimensions at start level. */
48 for (i
= intelImage
->base
.Base
.Level
; i
> 0; i
--) {
56 /* Guess a reasonable value for lastLevel. This is probably going
57 * to be wrong fairly often and might mean that we have to look at
58 * resizable buffers, or require that buffers implement lazy
59 * pagetable arrangements.
61 if ((intelObj
->base
.Sampler
.MinFilter
== GL_NEAREST
||
62 intelObj
->base
.Sampler
.MinFilter
== GL_LINEAR
) &&
63 intelImage
->base
.Base
.Level
== 0 &&
64 !intelObj
->base
.GenerateMipmap
) {
67 lastLevel
= _mesa_get_tex_max_num_levels(intelObj
->base
.Target
,
68 width
, height
, depth
) - 1;
71 return intel_miptree_create(brw
,
72 intelObj
->base
.Target
,
73 intelImage
->base
.Base
.TexFormat
,
79 expect_accelerated_upload
,
80 intelImage
->base
.Base
.NumSamples
,
81 INTEL_MIPTREE_TILING_ANY
);
84 /* XXX: Do this for TexSubImage also:
87 try_pbo_upload(struct gl_context
*ctx
,
88 struct gl_texture_image
*image
,
89 const struct gl_pixelstore_attrib
*unpack
,
90 GLenum format
, GLenum type
, const void *pixels
)
92 struct intel_texture_image
*intelImage
= intel_texture_image(image
);
93 struct brw_context
*brw
= brw_context(ctx
);
94 struct intel_buffer_object
*pbo
= intel_buffer_object(unpack
->BufferObj
);
96 drm_intel_bo
*src_buffer
;
98 if (!_mesa_is_bufferobj(unpack
->BufferObj
))
101 DBG("trying pbo upload\n");
103 if (ctx
->_ImageTransferState
|| unpack
->SkipPixels
|| unpack
->SkipRows
) {
104 DBG("%s: image transfer\n", __FUNCTION__
);
108 ctx
->Driver
.AllocTextureImageBuffer(ctx
, image
);
110 if (!intelImage
->mt
) {
111 DBG("%s: no miptree\n", __FUNCTION__
);
115 if (!_mesa_format_matches_format_and_type(intelImage
->mt
->format
,
116 format
, type
, false)) {
117 DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n",
118 __FUNCTION__
, _mesa_get_format_name(intelImage
->mt
->format
),
123 if (image
->TexObject
->Target
== GL_TEXTURE_1D_ARRAY
||
124 image
->TexObject
->Target
== GL_TEXTURE_2D_ARRAY
) {
125 DBG("%s: no support for array textures\n", __FUNCTION__
);
130 _mesa_image_row_stride(unpack
, image
->Width
, format
, type
);
132 /* note: potential 64-bit ptr to 32-bit int cast */
133 src_offset
= (GLuint
) (unsigned long) pixels
;
134 src_buffer
= intel_bufferobj_buffer(brw
, pbo
,
135 src_offset
, src_stride
* image
->Height
);
137 struct intel_mipmap_tree
*pbo_mt
=
138 intel_miptree_create_for_bo(brw
,
140 intelImage
->mt
->format
,
142 image
->Width
, image
->Height
,
143 src_stride
, I915_TILING_NONE
);
147 if (!intel_miptree_blit(brw
,
150 intelImage
->mt
, image
->Level
, image
->Face
,
152 image
->Width
, image
->Height
, GL_COPY
)) {
153 DBG("%s: blit failed\n", __FUNCTION__
);
154 intel_miptree_release(&pbo_mt
);
158 intel_miptree_release(&pbo_mt
);
160 DBG("%s: success\n", __FUNCTION__
);
165 intelTexImage(struct gl_context
* ctx
,
167 struct gl_texture_image
*texImage
,
168 GLenum format
, GLenum type
, const void *pixels
,
169 const struct gl_pixelstore_attrib
*unpack
)
173 DBG("%s target %s level %d %dx%dx%d\n", __FUNCTION__
,
174 _mesa_lookup_enum_by_nr(texImage
->TexObject
->Target
),
175 texImage
->Level
, texImage
->Width
, texImage
->Height
, texImage
->Depth
);
177 ok
= intel_texsubimage_tiled_memcpy(ctx
, dims
, texImage
,
178 0, 0, 0, /*x,y,z offsets*/
182 format
, type
, pixels
, unpack
,
183 true /*for_glTexImage*/);
187 /* Attempt to use the blitter for PBO image uploads.
190 try_pbo_upload(ctx
, texImage
, unpack
, format
, type
, pixels
)) {
194 DBG("%s: upload image %dx%dx%d pixels %p\n",
195 __FUNCTION__
, texImage
->Width
, texImage
->Height
, texImage
->Depth
,
198 _mesa_store_teximage(ctx
, dims
, texImage
,
199 format
, type
, pixels
, unpack
);
204 * Binds a region to a texture image, like it was uploaded by glTexImage2D().
206 * Used for GLX_EXT_texture_from_pixmap and EGL image extensions,
209 intel_set_texture_image_region(struct gl_context
*ctx
,
210 struct gl_texture_image
*image
,
211 struct intel_region
*region
,
213 GLenum internalFormat
,
221 struct brw_context
*brw
= brw_context(ctx
);
222 struct intel_texture_image
*intel_image
= intel_texture_image(image
);
223 struct gl_texture_object
*texobj
= image
->TexObject
;
224 struct intel_texture_object
*intel_texobj
= intel_texture_object(texobj
);
225 uint32_t draw_x
, draw_y
;
227 _mesa_init_teximage_fields(&brw
->ctx
, image
,
229 0, internalFormat
, format
);
231 ctx
->Driver
.FreeTextureImageBuffer(ctx
, image
);
233 intel_image
->mt
= intel_miptree_create_layout(brw
, target
, image
->TexFormat
,
236 true, 0 /* num_samples */);
237 if (intel_image
->mt
== NULL
)
239 intel_region_reference(&intel_image
->mt
->region
, region
);
240 intel_image
->mt
->total_width
= width
;
241 intel_image
->mt
->total_height
= height
;
242 intel_image
->mt
->level
[0].slice
[0].x_offset
= tile_x
;
243 intel_image
->mt
->level
[0].slice
[0].y_offset
= tile_y
;
245 intel_miptree_get_tile_offsets(intel_image
->mt
, 0, 0, &draw_x
, &draw_y
);
247 /* From "OES_EGL_image" error reporting. We report GL_INVALID_OPERATION
248 * for EGL images from non-tile aligned sufaces in gen4 hw and earlier which has
249 * trouble resolving back to destination image due to alignment issues.
251 if (!brw
->has_surface_tile_offset
&&
252 (draw_x
!= 0 || draw_y
!= 0)) {
253 _mesa_error(ctx
, GL_INVALID_OPERATION
, __func__
);
254 intel_miptree_release(&intel_image
->mt
);
258 intel_texobj
->needs_validate
= true;
260 intel_image
->mt
->offset
= offset
;
261 assert(region
->pitch
% region
->cpp
== 0);
262 intel_image
->base
.RowStride
= region
->pitch
/ region
->cpp
;
264 /* Immediately validate the image to the object. */
265 intel_miptree_reference(&intel_texobj
->mt
, intel_image
->mt
);
269 intelSetTexBuffer2(__DRIcontext
*pDRICtx
, GLint target
,
270 GLint texture_format
,
271 __DRIdrawable
*dPriv
)
273 struct gl_framebuffer
*fb
= dPriv
->driverPrivate
;
274 struct brw_context
*brw
= pDRICtx
->driverPrivate
;
275 struct gl_context
*ctx
= &brw
->ctx
;
276 struct intel_texture_object
*intelObj
;
277 struct intel_renderbuffer
*rb
;
278 struct gl_texture_object
*texObj
;
279 struct gl_texture_image
*texImage
;
280 int level
= 0, internalFormat
= 0;
281 mesa_format texFormat
= MESA_FORMAT_NONE
;
283 texObj
= _mesa_get_current_tex_object(ctx
, target
);
284 intelObj
= intel_texture_object(texObj
);
289 if (dPriv
->lastStamp
!= dPriv
->dri2
.stamp
||
290 !pDRICtx
->driScreenPriv
->dri2
.useInvalidate
)
291 intel_update_renderbuffers(pDRICtx
, dPriv
);
293 rb
= intel_get_renderbuffer(fb
, BUFFER_FRONT_LEFT
);
294 /* If the region isn't set, then intel_update_renderbuffers was unable
295 * to get the buffers for the drawable.
300 if (rb
->mt
->cpp
== 4) {
301 if (texture_format
== __DRI_TEXTURE_FORMAT_RGB
) {
302 internalFormat
= GL_RGB
;
303 texFormat
= MESA_FORMAT_B8G8R8X8_UNORM
;
306 internalFormat
= GL_RGBA
;
307 texFormat
= MESA_FORMAT_B8G8R8A8_UNORM
;
309 } else if (rb
->mt
->cpp
== 2) {
310 internalFormat
= GL_RGB
;
311 texFormat
= MESA_FORMAT_B5G6R5_UNORM
;
314 _mesa_lock_texture(&brw
->ctx
, texObj
);
315 texImage
= _mesa_get_tex_image(ctx
, texObj
, target
, level
);
316 intel_miptree_make_shareable(brw
, rb
->mt
);
317 intel_set_texture_image_region(ctx
, texImage
, rb
->mt
->region
, target
,
318 internalFormat
, texFormat
, 0,
319 rb
->mt
->region
->width
,
320 rb
->mt
->region
->height
,
322 _mesa_unlock_texture(&brw
->ctx
, texObj
);
326 intelSetTexBuffer(__DRIcontext
*pDRICtx
, GLint target
, __DRIdrawable
*dPriv
)
328 /* The old interface didn't have the format argument, so copy our
329 * implementation's behavior at the time.
331 intelSetTexBuffer2(pDRICtx
, target
, __DRI_TEXTURE_FORMAT_RGBA
, dPriv
);
335 intel_image_target_texture_2d(struct gl_context
*ctx
, GLenum target
,
336 struct gl_texture_object
*texObj
,
337 struct gl_texture_image
*texImage
,
338 GLeglImageOES image_handle
)
340 struct brw_context
*brw
= brw_context(ctx
);
344 screen
= brw
->intelScreen
->driScrnPriv
;
345 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
346 screen
->loaderPrivate
);
351 * Images originating via EGL_EXT_image_dma_buf_import can be used only
352 * with GL_OES_EGL_image_external only.
354 if (image
->dma_buf_imported
&& target
!= GL_TEXTURE_EXTERNAL_OES
) {
355 _mesa_error(ctx
, GL_INVALID_OPERATION
,
356 "glEGLImageTargetTexture2DOES(dma buffers can be used with "
357 "GL_OES_EGL_image_external only");
361 if (target
== GL_TEXTURE_EXTERNAL_OES
&& !image
->dma_buf_imported
) {
362 _mesa_error(ctx
, GL_INVALID_OPERATION
,
363 "glEGLImageTargetTexture2DOES(external target is enabled only "
364 "for images created with EGL_EXT_image_dma_buf_import");
368 /* Disallow depth/stencil textures: we don't have a way to pass the
369 * separate stencil miptree of a GL_DEPTH_STENCIL texture through.
371 if (image
->has_depthstencil
) {
372 _mesa_error(ctx
, GL_INVALID_OPERATION
, __func__
);
376 intel_set_texture_image_region(ctx
, texImage
, image
->region
,
377 target
, image
->internal_format
,
378 image
->format
, image
->offset
,
379 image
->width
, image
->height
,
380 image
->tile_x
, image
->tile_y
);
384 intelInitTextureImageFuncs(struct dd_function_table
*functions
)
386 functions
->TexImage
= intelTexImage
;
387 functions
->EGLImageTargetTexture2D
= intel_image_target_texture_2d
;