12
#include "simple_list.h"
13
#include "texcompress.h"
14
#include "texformat.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_ioctl.h"
24
#include "intel_blit.h"
26
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
28
/* Functions to store texture images. Where possible, mipmap_tree's
29
* will be created or further instantiated with image data, otherwise
30
* images will be stored in malloc'd memory. A validation step is
31
* required to pull those images into a mipmap tree, or otherwise
32
* decide a fallback is required.
51
/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
54
* Otherwise, if max_level >= level >= min_level, create tree with
55
* space for textures from min_level down to max_level.
57
* Otherwise, create tree with space for textures from (level
58
* 0)..(1x1). Consider pruning this tree at a validation if the
62
guess_and_alloc_mipmap_tree(struct intel_context *intel,
63
struct intel_texture_object *intelObj,
64
struct intel_texture_image *intelImage)
68
GLuint width = intelImage->base.Width;
69
GLuint height = intelImage->base.Height;
70
GLuint depth = intelImage->base.Depth;
71
GLuint l2width, l2height, l2depth;
72
GLuint i, comp_byte = 0;
74
DBG("%s\n", __FUNCTION__);
76
if (intelImage->base.Border)
79
if (intelImage->level > intelObj->base.BaseLevel &&
80
(intelImage->base.Width == 1 ||
81
(intelObj->base.Target != GL_TEXTURE_1D &&
82
intelImage->base.Height == 1) ||
83
(intelObj->base.Target == GL_TEXTURE_3D &&
84
intelImage->base.Depth == 1)))
87
/* If this image disrespects BaseLevel, allocate from level zero.
88
* Usually BaseLevel == 0, so it's unlikely to happen.
90
if (intelImage->level < intelObj->base.BaseLevel)
93
firstLevel = intelObj->base.BaseLevel;
96
/* Figure out image dimensions at start level.
98
for (i = intelImage->level; i > firstLevel; i--) {
106
/* Guess a reasonable value for lastLevel. This is probably going
107
* to be wrong fairly often and might mean that we have to look at
108
* resizable buffers, or require that buffers implement lazy
109
* pagetable arrangements.
111
if ((intelObj->base.MinFilter == GL_NEAREST ||
112
intelObj->base.MinFilter == GL_LINEAR) &&
113
intelImage->level == firstLevel) {
114
lastLevel = firstLevel;
117
l2width = logbase2(width);
118
l2height = logbase2(height);
119
l2depth = logbase2(depth);
120
lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
123
assert(!intelObj->mt);
124
if (intelImage->base.IsCompressed)
125
comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
126
intelObj->mt = intel_miptree_create(intel,
127
intelObj->base.Target,
128
intelImage->base.InternalFormat,
134
intelImage->base.TexFormat->TexelBytes,
137
DBG("%s - success\n", __FUNCTION__);
144
target_to_face(GLenum target)
147
case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
148
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
149
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
150
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
151
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
152
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
153
return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
159
/* There are actually quite a few combinations this will work for,
160
* more than what I've listed here.
163
check_pbo_format(GLint internalFormat,
164
GLenum format, GLenum type,
165
const struct gl_texture_format *mesa_format)
167
switch (internalFormat) {
170
return (format == GL_BGRA &&
171
(type == GL_UNSIGNED_BYTE ||
172
type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
173
mesa_format == &_mesa_texformat_argb8888);
176
return (format == GL_RGB &&
177
type == GL_UNSIGNED_SHORT_5_6_5 &&
178
mesa_format == &_mesa_texformat_rgb565);
180
return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
187
/* XXX: Do this for TexSubImage also:
190
try_pbo_upload(struct intel_context *intel,
191
struct intel_texture_image *intelImage,
192
const struct gl_pixelstore_attrib *unpack,
193
GLint internalFormat,
194
GLint width, GLint height,
195
GLenum format, GLenum type, const void *pixels)
197
struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
198
GLuint src_offset, src_stride;
199
GLuint dst_offset, dst_stride;
202
intel->ctx._ImageTransferState ||
203
unpack->SkipPixels || unpack->SkipRows) {
204
_mesa_printf("%s: failure 1\n", __FUNCTION__);
208
src_offset = (GLuint) pixels;
210
if (unpack->RowLength > 0)
211
src_stride = unpack->RowLength;
215
dst_offset = intel_miptree_image_offset(intelImage->mt,
219
dst_stride = intelImage->mt->pitch;
221
intelFlush(&intel->ctx);
222
LOCK_HARDWARE(intel);
224
struct _DriBufferObject *src_buffer =
225
intel_bufferobj_buffer(intel, pbo, INTEL_READ);
226
struct _DriBufferObject *dst_buffer =
227
intel_region_buffer(intel->intelScreen, intelImage->mt->region,
231
intelEmitCopyBlit(intel,
233
src_stride, src_buffer, src_offset,
234
dst_stride, dst_buffer, dst_offset,
235
0, 0, 0, 0, width, height,
238
intel_batchbuffer_flush(intel->batch);
240
UNLOCK_HARDWARE(intel);
248
try_pbo_zcopy(struct intel_context *intel,
249
struct intel_texture_image *intelImage,
250
const struct gl_pixelstore_attrib *unpack,
251
GLint internalFormat,
252
GLint width, GLint height,
253
GLenum format, GLenum type, const void *pixels)
255
struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
256
GLuint src_offset, src_stride;
257
GLuint dst_offset, dst_stride;
260
intel->ctx._ImageTransferState ||
261
unpack->SkipPixels || unpack->SkipRows) {
262
_mesa_printf("%s: failure 1\n", __FUNCTION__);
266
src_offset = (GLuint) pixels;
268
if (unpack->RowLength > 0)
269
src_stride = unpack->RowLength;
273
dst_offset = intel_miptree_image_offset(intelImage->mt,
277
dst_stride = intelImage->mt->pitch;
279
if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) {
280
_mesa_printf("%s: failure 2\n", __FUNCTION__);
284
intel_region_attach_pbo(intel->intelScreen, intelImage->mt->region, pbo);
295
intelTexImage(GLcontext * ctx,
297
GLenum target, GLint level,
298
GLint internalFormat,
299
GLint width, GLint height, GLint depth,
301
GLenum format, GLenum type, const void *pixels,
302
const struct gl_pixelstore_attrib *unpack,
303
struct gl_texture_object *texObj,
304
struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
306
struct intel_context *intel = intel_context(ctx);
307
struct intel_texture_object *intelObj = intel_texture_object(texObj);
308
struct intel_texture_image *intelImage = intel_texture_image(texImage);
309
GLint postConvWidth = width;
310
GLint postConvHeight = height;
311
GLint texelBytes, sizeInBytes;
315
DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
316
_mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
320
intelImage->face = target_to_face(target);
321
intelImage->level = level;
323
if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
324
_mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
328
/* choose the texture format */
329
texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat,
332
assert(texImage->TexFormat);
336
texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
337
texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
340
texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
341
texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
344
texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
345
texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
352
if (texImage->TexFormat->TexelBytes == 0) {
353
/* must be a compressed format */
355
texImage->IsCompressed = GL_TRUE;
356
texImage->CompressedSize =
357
ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
358
texImage->Height, texImage->Depth,
359
texImage->TexFormat->MesaFormat);
361
texelBytes = texImage->TexFormat->TexelBytes;
363
/* Minimum pitch of 32 bytes */
364
if (postConvWidth * texelBytes < 32) {
365
postConvWidth = 32 / texelBytes;
366
texImage->RowStride = postConvWidth;
369
assert(texImage->RowStride == postConvWidth);
372
/* Release the reference to a potentially orphaned buffer.
373
* Release any old malloced memory.
375
if (intelImage->mt) {
376
intel_miptree_release(intel, &intelImage->mt);
377
assert(!texImage->Data);
379
else if (texImage->Data) {
380
_mesa_align_free(texImage->Data);
383
/* If this is the only texture image in the tree, could call
384
* bmBufferData with NULL data to free the old block and avoid
385
* waiting on any outstanding fences.
388
intelObj->mt->first_level == level &&
389
intelObj->mt->last_level == level &&
390
intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
391
!intel_miptree_match_image(intelObj->mt, &intelImage->base,
392
intelImage->face, intelImage->level)) {
395
intel_miptree_release(intel, &intelObj->mt);
396
assert(!intelObj->mt);
400
guess_and_alloc_mipmap_tree(intel, intelObj, intelImage);
402
DBG("guess_and_alloc_mipmap_tree: failed\n");
407
assert(!intelImage->mt);
410
intel_miptree_match_image(intelObj->mt, &intelImage->base,
411
intelImage->face, intelImage->level)) {
413
intel_miptree_reference(&intelImage->mt, intelObj->mt);
414
assert(intelImage->mt);
418
DBG("XXX: Image did not fit into tree - storing in local memory!\n");
424
intel_buffer_object(unpack->BufferObj) &&
425
check_pbo_format(internalFormat, format,
426
type, intelImage->base.TexFormat)) {
428
DBG("trying pbo upload\n");
430
/* Attempt to texture directly from PBO data (zero copy upload).
432
* Currently disable as it can lead to worse as well as better
433
* performance (in particular when intel_region_cow() is
436
if (intelObj->mt == intelImage->mt &&
437
intelObj->mt->first_level == level &&
438
intelObj->mt->last_level == level) {
440
if (try_pbo_zcopy(intel, intelImage, unpack,
442
width, height, format, type, pixels)) {
444
DBG("pbo zcopy upload succeeded\n");
450
/* Otherwise, attempt to use the blitter for PBO image uploads.
452
if (try_pbo_upload(intel, intelImage, unpack,
454
width, height, format, type, pixels)) {
455
DBG("pbo upload succeeded\n");
459
DBG("pbo upload failed\n");
464
/* intelCopyTexImage calls this function with pixels == NULL, with
465
* the expectation that the mipmap tree will be set up but nothing
466
* more will be done. This is where those calls return:
469
pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
471
"glCompressedTexImage");
473
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
475
pixels, unpack, "glTexImage");
482
intel_region_idle(intel->intelScreen, intelImage->mt->region);
484
LOCK_HARDWARE(intel);
486
if (intelImage->mt) {
487
texImage->Data = intel_miptree_image_map(intel,
492
intelImage->base.ImageOffsets);
495
/* Allocate regular memory and store the image there temporarily. */
496
if (texImage->IsCompressed) {
497
sizeInBytes = texImage->CompressedSize;
499
_mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
503
dstRowStride = postConvWidth * texelBytes;
504
sizeInBytes = depth * dstRowStride * postConvHeight;
507
texImage->Data = malloc(sizeInBytes);
510
DBG("Upload image %dx%dx%d row_len %x "
512
width, height, depth, width * texelBytes, dstRowStride);
514
/* Copy data. Would like to know when it's ok for us to eg. use
515
* the blitter to copy. Or, use the hardware to do the format
516
* conversion and copy:
519
memcpy(texImage->Data, pixels, imageSize);
520
} else if (!texImage->TexFormat->StoreImage(ctx, dims,
521
texImage->_BaseFormat,
523
texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
525
texImage->ImageOffsets,
526
width, height, depth,
527
format, type, pixels, unpack)) {
528
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
531
_mesa_unmap_teximage_pbo(ctx, unpack);
533
if (intelImage->mt) {
534
intel_miptree_image_unmap(intel, intelImage->mt);
535
texImage->Data = NULL;
538
UNLOCK_HARDWARE(intel);
541
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
543
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
544
intel_generate_mipmap(ctx, target,
545
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
552
intelTexImage3D(GLcontext * ctx,
553
GLenum target, GLint level,
554
GLint internalFormat,
555
GLint width, GLint height, GLint depth,
557
GLenum format, GLenum type, const void *pixels,
558
const struct gl_pixelstore_attrib *unpack,
559
struct gl_texture_object *texObj,
560
struct gl_texture_image *texImage)
562
intelTexImage(ctx, 3, target, level,
563
internalFormat, width, height, depth, border,
564
format, type, pixels, unpack, texObj, texImage, 0, 0);
569
intelTexImage2D(GLcontext * ctx,
570
GLenum target, GLint level,
571
GLint internalFormat,
572
GLint width, GLint height, GLint border,
573
GLenum format, GLenum type, const void *pixels,
574
const struct gl_pixelstore_attrib *unpack,
575
struct gl_texture_object *texObj,
576
struct gl_texture_image *texImage)
578
intelTexImage(ctx, 2, target, level,
579
internalFormat, width, height, 1, border,
580
format, type, pixels, unpack, texObj, texImage, 0, 0);
584
intelTexImage1D(GLcontext * ctx,
585
GLenum target, GLint level,
586
GLint internalFormat,
587
GLint width, GLint border,
588
GLenum format, GLenum type, const void *pixels,
589
const struct gl_pixelstore_attrib *unpack,
590
struct gl_texture_object *texObj,
591
struct gl_texture_image *texImage)
593
intelTexImage(ctx, 1, target, level,
594
internalFormat, width, 1, 1, border,
595
format, type, pixels, unpack, texObj, texImage, 0, 0);
598
void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
599
GLint internalFormat,
600
GLint width, GLint height, GLint border,
601
GLsizei imageSize, const GLvoid *data,
602
struct gl_texture_object *texObj,
603
struct gl_texture_image *texImage )
605
intelTexImage(ctx, 2, target, level,
606
internalFormat, width, height, 1, border,
607
0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
611
* Need to map texture image into memory before copying image data,
615
intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
616
GLenum format, GLenum type, GLvoid * pixels,
617
struct gl_texture_object *texObj,
618
struct gl_texture_image *texImage, int compressed)
620
struct intel_context *intel = intel_context(ctx);
621
struct intel_texture_image *intelImage = intel_texture_image(texImage);
624
if (intelImage->mt) {
625
/* Image is stored in hardware format in a buffer managed by the
626
* kernel. Need to explicitly map and unmap it.
628
intelImage->base.Data =
629
intel_miptree_image_map(intel,
633
&intelImage->base.RowStride,
634
intelImage->base.ImageOffsets);
637
/* Otherwise, the image should actually be stored in
638
* intelImage->base.Data. This is pretty confusing for
639
* everybody, I'd much prefer to separate the two functions of
640
* texImage->Data - storage for texture images in main memory
641
* and access (ie mappings) of images. In other words, we'd
642
* create a new texImage->Map field and leave Data simply for
645
assert(intelImage->base.Data);
650
_mesa_get_compressed_teximage(ctx, target, level, pixels,
653
_mesa_get_teximage(ctx, target, level, format, type, pixels,
659
if (intelImage->mt) {
660
intel_miptree_image_unmap(intel, intelImage->mt);
661
intelImage->base.Data = NULL;
666
intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
667
GLenum format, GLenum type, GLvoid * pixels,
668
struct gl_texture_object *texObj,
669
struct gl_texture_image *texImage)
671
intel_get_tex_image(ctx, target, level, format, type, pixels,
672
texObj, texImage, 0);
678
intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
680
const struct gl_texture_object *texObj,
681
const struct gl_texture_image *texImage)
683
intel_get_tex_image(ctx, target, level, 0, 0, pixels,
684
texObj, texImage, 1);