1#include "swrast/swrast.h"
2#include "main/renderbuffer.h"
3#include "main/texobj.h"
4#include "main/teximage.h"
5#include "main/mipmap.h"
6#include "drivers/common/meta.h"
7#include "brw_context.h"
8#include "brw_defines.h"
9#include "intel_buffer_objects.h"
10#include "intel_mipmap_tree.h"
11#include "intel_tex.h"
12#include "intel_fbo.h"
13
14#define FILE_DEBUG_FLAG DEBUG_TEXTURE
15
16static struct gl_texture_image *
17intelNewTextureImage(struct gl_context * ctx)
18{
19   DBG("%s\n", __func__);
20   (void) ctx;
21   return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image);
22}
23
24static void
25intelDeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
26{
27   /* nothing special (yet) for intel_texture_image */
28   _mesa_delete_texture_image(ctx, img);
29}
30
31
32static struct gl_texture_object *
33intelNewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
34{
35   struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object);
36
37   (void) ctx;
38
39   DBG("%s\n", __func__);
40
41   if (obj == NULL)
42      return NULL;
43
44   _mesa_initialize_texture_object(ctx, &obj->base, name, target);
45
46   obj->needs_validate = true;
47
48   return &obj->base;
49}
50
51static void
52intelDeleteTextureObject(struct gl_context *ctx,
53			 struct gl_texture_object *texObj)
54{
55   struct intel_texture_object *intelObj = intel_texture_object(texObj);
56
57   intel_miptree_release(&intelObj->mt);
58   _mesa_delete_texture_object(ctx, texObj);
59}
60
61static GLboolean
62intel_alloc_texture_image_buffer(struct gl_context *ctx,
63				 struct gl_texture_image *image)
64{
65   struct brw_context *brw = brw_context(ctx);
66   struct intel_texture_image *intel_image = intel_texture_image(image);
67   struct gl_texture_object *texobj = image->TexObject;
68   struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
69
70   assert(image->Border == 0);
71
72   /* Quantize sample count */
73   if (image->NumSamples) {
74      image->NumSamples = intel_quantize_num_samples(brw->screen, image->NumSamples);
75      if (!image->NumSamples)
76         return false;
77   }
78
79   /* Because the driver uses AllocTextureImageBuffer() internally, it may end
80    * up mismatched with FreeTextureImageBuffer(), but that is safe to call
81    * multiple times.
82    */
83   ctx->Driver.FreeTextureImageBuffer(ctx, image);
84
85   if (!_swrast_init_texture_image(image))
86      return false;
87
88   if (intel_texobj->mt &&
89       intel_miptree_match_image(intel_texobj->mt, image)) {
90      intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
91      DBG("%s: alloc obj %p level %d %dx%dx%d using object's miptree %p\n",
92          __func__, texobj, image->Level,
93          image->Width, image->Height, image->Depth, intel_texobj->mt);
94   } else {
95      intel_image->mt = intel_miptree_create_for_teximage(brw, intel_texobj,
96                                                          intel_image,
97                                                          MIPTREE_CREATE_DEFAULT);
98      if (!intel_image->mt)
99         return false;
100
101      /* Even if the object currently has a mipmap tree associated
102       * with it, this one is a more likely candidate to represent the
103       * whole object since our level didn't fit what was there
104       * before, and any lower levels would fit into our miptree.
105       */
106      intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
107
108      DBG("%s: alloc obj %p level %d %dx%dx%d using new miptree %p\n",
109          __func__, texobj, image->Level,
110          image->Width, image->Height, image->Depth, intel_image->mt);
111   }
112
113   intel_texobj->needs_validate = true;
114
115   return true;
116}
117
118/**
119 * ctx->Driver.AllocTextureStorage() handler.
120 *
121 * Compare this to _mesa_AllocTextureStorage_sw, which would call into
122 * intel_alloc_texture_image_buffer() above.
123 */
124static GLboolean
125intel_alloc_texture_storage(struct gl_context *ctx,
126                            struct gl_texture_object *texobj,
127                            GLsizei levels, GLsizei width,
128                            GLsizei height, GLsizei depth)
129{
130   struct brw_context *brw = brw_context(ctx);
131   struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
132   struct gl_texture_image *first_image = texobj->Image[0][0];
133   int num_samples = intel_quantize_num_samples(brw->screen,
134                                                first_image->NumSamples);
135   const int numFaces = _mesa_num_tex_faces(texobj->Target);
136   int face;
137   int level;
138
139   /* If the object's current miptree doesn't match what we need, make a new
140    * one.
141    */
142   if (!intel_texobj->mt ||
143       !intel_miptree_match_image(intel_texobj->mt, first_image) ||
144       intel_texobj->mt->last_level != levels - 1) {
145      intel_miptree_release(&intel_texobj->mt);
146
147      intel_get_image_dims(first_image, &width, &height, &depth);
148      intel_texobj->mt = intel_miptree_create(brw, texobj->Target,
149                                              first_image->TexFormat,
150                                              0, levels - 1,
151                                              width, height, depth,
152                                              MAX2(num_samples, 1),
153                                              MIPTREE_CREATE_DEFAULT);
154
155      if (intel_texobj->mt == NULL) {
156         return false;
157      }
158   }
159
160   for (face = 0; face < numFaces; face++) {
161      for (level = 0; level < levels; level++) {
162         struct gl_texture_image *image = texobj->Image[face][level];
163         struct intel_texture_image *intel_image = intel_texture_image(image);
164
165         image->NumSamples = num_samples;
166
167         _swrast_free_texture_image_buffer(ctx, image);
168         if (!_swrast_init_texture_image(image))
169            return false;
170
171         intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
172      }
173   }
174
175   /* The miptree is in a validated state, so no need to check later. */
176   intel_texobj->needs_validate = false;
177   intel_texobj->validated_first_level = 0;
178   intel_texobj->validated_last_level = levels - 1;
179   intel_texobj->_Format = first_image->TexFormat;
180
181   return true;
182}
183
184
185static void
186intel_free_texture_image_buffer(struct gl_context * ctx,
187				struct gl_texture_image *texImage)
188{
189   struct intel_texture_image *intelImage = intel_texture_image(texImage);
190
191   DBG("%s\n", __func__);
192
193   intel_miptree_release(&intelImage->mt);
194
195   _swrast_free_texture_image_buffer(ctx, texImage);
196}
197
198/**
199 * Map texture memory/buffer into user space.
200 * Note: the region of interest parameters are ignored here.
201 * \param mode  bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
202 * \param mapOut  returns start of mapping of region of interest
203 * \param rowStrideOut  returns row stride in bytes
204 */
205static void
206intel_map_texture_image(struct gl_context *ctx,
207			struct gl_texture_image *tex_image,
208			GLuint slice,
209			GLuint x, GLuint y, GLuint w, GLuint h,
210			GLbitfield mode,
211			GLubyte **map,
212			GLint *out_stride)
213{
214   struct brw_context *brw = brw_context(ctx);
215   struct intel_texture_image *intel_image = intel_texture_image(tex_image);
216   struct intel_mipmap_tree *mt = intel_image->mt;
217   ptrdiff_t stride;
218
219   /* Our texture data is always stored in a miptree. */
220   assert(mt);
221
222   /* Check that our caller wasn't confused about how to map a 1D texture. */
223   assert(tex_image->TexObject->Target != GL_TEXTURE_1D_ARRAY ||
224	  h == 1);
225
226   /* intel_miptree_map operates on a unified "slice" number that references the
227    * cube face, since it's all just slices to the miptree code.
228    */
229   if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP)
230      slice = tex_image->Face;
231
232   intel_miptree_map(brw, mt,
233                     tex_image->Level + tex_image->TexObject->MinLevel,
234                     slice + tex_image->TexObject->MinLayer,
235                     x, y, w, h, mode,
236                     (void **)map, &stride);
237
238   *out_stride = stride;
239}
240
241static void
242intel_unmap_texture_image(struct gl_context *ctx,
243			  struct gl_texture_image *tex_image, GLuint slice)
244{
245   struct brw_context *brw = brw_context(ctx);
246   struct intel_texture_image *intel_image = intel_texture_image(tex_image);
247   struct intel_mipmap_tree *mt = intel_image->mt;
248
249   if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP)
250      slice = tex_image->Face;
251
252   intel_miptree_unmap(brw, mt,
253         tex_image->Level + tex_image->TexObject->MinLevel,
254         slice + tex_image->TexObject->MinLayer);
255}
256
257static GLboolean
258intel_texture_view(struct gl_context *ctx,
259                   struct gl_texture_object *texObj,
260                   struct gl_texture_object *origTexObj)
261{
262   struct brw_context *brw = brw_context(ctx);
263   struct intel_texture_object *intel_tex = intel_texture_object(texObj);
264   struct intel_texture_object *intel_orig_tex = intel_texture_object(origTexObj);
265
266   assert(intel_orig_tex->mt);
267   intel_miptree_reference(&intel_tex->mt, intel_orig_tex->mt);
268
269   /* Since we can only make views of immutable-format textures,
270    * we can assume that everything is in origTexObj's miptree.
271    *
272    * Mesa core has already made us a copy of all the teximage objects,
273    * except it hasn't copied our mt pointers, etc.
274    */
275   const int numFaces = _mesa_num_tex_faces(texObj->Target);
276   const int numLevels = texObj->NumLevels;
277
278   int face;
279   int level;
280
281   for (face = 0; face < numFaces; face++) {
282      for (level = 0; level < numLevels; level++) {
283         struct gl_texture_image *image = texObj->Image[face][level];
284         struct intel_texture_image *intel_image = intel_texture_image(image);
285
286         intel_miptree_reference(&intel_image->mt, intel_orig_tex->mt);
287      }
288   }
289
290   /* The miptree is in a validated state, so no need to check later. */
291   intel_tex->needs_validate = false;
292   intel_tex->validated_first_level = 0;
293   intel_tex->validated_last_level = numLevels - 1;
294
295   /* Set the validated texture format, with the same adjustments that
296    * would have been applied to determine the underlying texture's
297    * mt->format.
298    */
299   intel_tex->_Format = intel_depth_format_for_depthstencil_format(
300         intel_lower_compressed_format(brw, texObj->Image[0][0]->TexFormat));
301
302   return GL_TRUE;
303}
304
305static void
306intel_texture_barrier(struct gl_context *ctx)
307{
308   struct brw_context *brw = brw_context(ctx);
309   const struct gen_device_info *devinfo = &brw->screen->devinfo;
310
311   if (devinfo->gen >= 6) {
312      brw_emit_pipe_control_flush(brw,
313                                  PIPE_CONTROL_DEPTH_CACHE_FLUSH |
314                                  PIPE_CONTROL_RENDER_TARGET_FLUSH |
315                                  PIPE_CONTROL_CS_STALL);
316
317      brw_emit_pipe_control_flush(brw,
318                                  PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
319   } else {
320      brw_emit_mi_flush(brw);
321   }
322}
323
324void
325intelInitTextureFuncs(struct dd_function_table *functions)
326{
327   functions->NewTextureObject = intelNewTextureObject;
328   functions->NewTextureImage = intelNewTextureImage;
329   functions->DeleteTextureImage = intelDeleteTextureImage;
330   functions->DeleteTexture = intelDeleteTextureObject;
331   functions->AllocTextureImageBuffer = intel_alloc_texture_image_buffer;
332   functions->FreeTextureImageBuffer = intel_free_texture_image_buffer;
333   functions->AllocTextureStorage = intel_alloc_texture_storage;
334   functions->MapTextureImage = intel_map_texture_image;
335   functions->UnmapTextureImage = intel_unmap_texture_image;
336   functions->TextureView = intel_texture_view;
337   functions->TextureBarrier = intel_texture_barrier;
338}
339