1 #include "main/mtypes.h"
2 #include "main/macros.h"
3 #include "main/samplerobj.h"
5 #include "intel_context.h"
6 #include "intel_mipmap_tree.h"
7 #include "intel_blit.h"
9 #include "intel_tex_layout.h"
11 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
14 * When validating, we only care about the texture images that could
15 * be seen, so for non-mipmapped modes we want to ignore everything
19 intel_update_max_level(struct intel_texture_object
*intelObj
,
20 struct gl_sampler_object
*sampler
)
22 struct gl_texture_object
*tObj
= &intelObj
->base
;
24 if (sampler
->MinFilter
== GL_NEAREST
||
25 sampler
->MinFilter
== GL_LINEAR
) {
26 intelObj
->_MaxLevel
= tObj
->BaseLevel
;
28 intelObj
->_MaxLevel
= tObj
->_MaxLevel
;
35 intel_finalize_mipmap_tree(struct intel_context
*intel
, GLuint unit
)
37 struct gl_context
*ctx
= &intel
->ctx
;
38 struct gl_texture_object
*tObj
= intel
->ctx
.Texture
.Unit
[unit
]._Current
;
39 struct intel_texture_object
*intelObj
= intel_texture_object(tObj
);
40 struct gl_sampler_object
*sampler
= _mesa_get_samplerobj(ctx
, unit
);
43 struct intel_texture_image
*firstImage
;
44 int width
, height
, depth
;
46 /* We know/require this is true by now:
48 assert(intelObj
->base
._Complete
);
50 /* What levels must the tree include at a minimum?
52 intel_update_max_level(intelObj
, sampler
);
53 firstImage
= intel_texture_image(tObj
->Image
[0][tObj
->BaseLevel
]);
57 if (firstImage
->base
.Base
.Border
) {
58 intel_miptree_release(&intelObj
->mt
);
62 intel_miptree_get_dimensions_for_image(&firstImage
->base
.Base
,
63 &width
, &height
, &depth
);
65 /* Check tree can hold all active levels. Check tree matches
66 * target, imageFormat, etc.
68 * For pre-gen4, we have to match first_level == tObj->BaseLevel,
69 * because we don't have the control that gen4 does to make min/mag
70 * determination happen at a nonzero (hardware) baselevel. Because
71 * of that, we just always relayout on baselevel change.
74 (intelObj
->mt
->target
!= intelObj
->base
.Target
||
75 intelObj
->mt
->format
!= firstImage
->base
.Base
.TexFormat
||
76 intelObj
->mt
->first_level
!= tObj
->BaseLevel
||
77 intelObj
->mt
->last_level
< intelObj
->_MaxLevel
||
78 intelObj
->mt
->width0
!= width
||
79 intelObj
->mt
->height0
!= height
||
80 intelObj
->mt
->depth0
!= depth
)) {
81 intel_miptree_release(&intelObj
->mt
);
85 /* May need to create a new tree:
88 intelObj
->mt
= intel_miptree_create(intel
,
89 intelObj
->base
.Target
,
90 firstImage
->base
.Base
.TexFormat
,
101 /* Pull in any images not in the object's tree:
103 nr_faces
= (intelObj
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
104 for (face
= 0; face
< nr_faces
; face
++) {
105 for (i
= tObj
->BaseLevel
; i
<= intelObj
->_MaxLevel
; i
++) {
106 struct intel_texture_image
*intelImage
=
107 intel_texture_image(intelObj
->base
.Image
[face
][i
]);
108 /* skip too small size mipmap */
109 if (intelImage
== NULL
)
111 /* Need to import images in main memory or held in other trees.
112 * If it's a render target, then its data isn't needed to be in
113 * the object tree (otherwise we'd be FBO incomplete), and we need
114 * to keep track of the image's MT as needing to be pulled in still,
115 * or we'll lose the rendering that's done to it.
117 if (intelObj
->mt
!= intelImage
->mt
&&
118 !intelImage
->used_as_render_target
) {
119 intel_miptree_copy_teximage(intel
, intelImage
, intelObj
->mt
);
128 * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
131 intel_tex_map_image_for_swrast(struct intel_context
*intel
,
132 struct intel_texture_image
*intel_image
,
135 int level
= intel_image
->base
.Base
.Level
;
136 int face
= intel_image
->base
.Base
.Face
;
137 struct intel_mipmap_tree
*mt
;
140 if (!intel_image
|| !intel_image
->mt
)
143 mt
= intel_image
->mt
;
145 if (mt
->target
== GL_TEXTURE_3D
||
146 mt
->target
== GL_TEXTURE_2D_ARRAY
||
147 mt
->target
== GL_TEXTURE_1D_ARRAY
) {
150 if (mt
->target
== GL_TEXTURE_2D_ARRAY
||
151 mt
->target
== GL_TEXTURE_1D_ARRAY
) {
152 /* Mesa only allocates one entry for these, but we really do have an
155 free(intel_image
->base
.Base
.ImageOffsets
);
156 intel_image
->base
.Base
.ImageOffsets
= malloc(mt
->level
[level
].depth
*
160 /* ImageOffsets[] is only used for swrast's fetch_texel_3d, so we can't
161 * share code with the normal path.
163 for (i
= 0; i
< mt
->level
[level
].depth
; i
++) {
164 intel_miptree_get_image_offset(mt
, level
, face
, i
, &x
, &y
);
165 intel_image
->base
.Base
.ImageOffsets
[i
] = x
+ y
* mt
->region
->pitch
;
168 DBG("%s \n", __FUNCTION__
);
170 intel_image
->base
.Base
.Data
= intel_region_map(intel
, mt
->region
, mode
);
172 assert(mt
->level
[level
].depth
== 1);
173 intel_miptree_get_image_offset(mt
, level
, face
, 0, &x
, &y
);
174 intel_image
->base
.Base
.ImageOffsets
[0] = 0;
176 DBG("%s: (%d,%d) -> (%d, %d)/%d\n",
177 __FUNCTION__
, face
, level
, x
, y
, mt
->region
->pitch
* mt
->cpp
);
179 intel_image
->base
.Base
.Data
= intel_region_map(intel
, mt
->region
, mode
) +
180 (x
+ y
* mt
->region
->pitch
) * mt
->cpp
;
183 intel_image
->base
.Base
.RowStride
= mt
->region
->pitch
;
187 intel_tex_unmap_image_for_swrast(struct intel_context
*intel
,
188 struct intel_texture_image
*intel_image
)
190 if (intel_image
&& intel_image
->mt
) {
191 intel_region_unmap(intel
, intel_image
->mt
->region
);
192 intel_image
->base
.Base
.Data
= NULL
;
197 * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
200 intel_tex_map_images(struct intel_context
*intel
,
201 struct intel_texture_object
*intelObj
,
204 GLuint nr_faces
= (intelObj
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
207 DBG("%s\n", __FUNCTION__
);
209 for (i
= intelObj
->base
.BaseLevel
; i
<= intelObj
->_MaxLevel
; i
++) {
210 for (face
= 0; face
< nr_faces
; face
++) {
211 struct intel_texture_image
*intel_image
=
212 intel_texture_image(intelObj
->base
.Image
[face
][i
]);
214 intel_tex_map_image_for_swrast(intel
, intel_image
, mode
);
220 intel_tex_unmap_images(struct intel_context
*intel
,
221 struct intel_texture_object
*intelObj
)
223 GLuint nr_faces
= (intelObj
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
226 for (i
= intelObj
->base
.BaseLevel
; i
<= intelObj
->_MaxLevel
; i
++) {
227 for (face
= 0; face
< nr_faces
; face
++) {
228 struct intel_texture_image
*intel_image
=
229 intel_texture_image(intelObj
->base
.Image
[face
][i
]);
231 intel_tex_unmap_image_for_swrast(intel
, intel_image
);