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
_mesa_set_fetch_functions(texImage, dims);
334
if (texImage->TexFormat->TexelBytes == 0) {
335
/* must be a compressed format */
337
texImage->IsCompressed = GL_TRUE;
338
texImage->CompressedSize =
339
ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
340
texImage->Height, texImage->Depth,
341
texImage->TexFormat->MesaFormat);
343
texelBytes = texImage->TexFormat->TexelBytes;
345
/* Minimum pitch of 32 bytes */
346
if (postConvWidth * texelBytes < 32) {
347
postConvWidth = 32 / texelBytes;
348
texImage->RowStride = postConvWidth;
351
assert(texImage->RowStride == postConvWidth);
354
/* Release the reference to a potentially orphaned buffer.
355
* Release any old malloced memory.
357
if (intelImage->mt) {
358
intel_miptree_release(intel, &intelImage->mt);
359
assert(!texImage->Data);
361
else if (texImage->Data) {
362
_mesa_align_free(texImage->Data);
365
/* If this is the only texture image in the tree, could call
366
* bmBufferData with NULL data to free the old block and avoid
367
* waiting on any outstanding fences.
370
intelObj->mt->first_level == level &&
371
intelObj->mt->last_level == level &&
372
intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
373
!intel_miptree_match_image(intelObj->mt, &intelImage->base,
374
intelImage->face, intelImage->level)) {
377
intel_miptree_release(intel, &intelObj->mt);
378
assert(!intelObj->mt);
382
guess_and_alloc_mipmap_tree(intel, intelObj, intelImage);
384
DBG("guess_and_alloc_mipmap_tree: failed\n");
388
assert(!intelImage->mt);
391
intel_miptree_match_image(intelObj->mt, &intelImage->base,
392
intelImage->face, intelImage->level)) {
394
intel_miptree_reference(&intelImage->mt, intelObj->mt);
395
assert(intelImage->mt);
399
DBG("XXX: Image did not fit into tree - storing in local memory!\n");
405
intel_buffer_object(unpack->BufferObj) &&
406
check_pbo_format(internalFormat, format,
407
type, intelImage->base.TexFormat)) {
409
DBG("trying pbo upload\n");
411
/* Attempt to texture directly from PBO data (zero copy upload).
413
* Currently disable as it can lead to worse as well as better
414
* performance (in particular when intel_region_cow() is
417
if (intelObj->mt == intelImage->mt &&
418
intelObj->mt->first_level == level &&
419
intelObj->mt->last_level == level) {
421
if (try_pbo_zcopy(intel, intelImage, unpack,
423
width, height, format, type, pixels)) {
425
DBG("pbo zcopy upload succeeded\n");
431
/* Otherwise, attempt to use the blitter for PBO image uploads.
433
if (try_pbo_upload(intel, intelImage, unpack,
435
width, height, format, type, pixels)) {
436
DBG("pbo upload succeeded\n");
440
DBG("pbo upload failed\n");
445
/* intelCopyTexImage calls this function with pixels == NULL, with
446
* the expectation that the mipmap tree will be set up but nothing
447
* more will be done. This is where those calls return:
450
pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
452
"glCompressedTexImage");
454
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
456
pixels, unpack, "glTexImage");
463
intel_region_idle(intel->intelScreen, intelImage->mt->region);
465
LOCK_HARDWARE(intel);
467
if (intelImage->mt) {
468
texImage->Data = intel_miptree_image_map(intel,
473
intelImage->base.ImageOffsets);
476
/* Allocate regular memory and store the image there temporarily. */
477
if (texImage->IsCompressed) {
478
sizeInBytes = texImage->CompressedSize;
480
_mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
484
dstRowStride = postConvWidth * texelBytes;
485
sizeInBytes = depth * dstRowStride * postConvHeight;
488
texImage->Data = malloc(sizeInBytes);
491
DBG("Upload image %dx%dx%d row_len %x "
493
width, height, depth, width * texelBytes, dstRowStride);
495
/* Copy data. Would like to know when it's ok for us to eg. use
496
* the blitter to copy. Or, use the hardware to do the format
497
* conversion and copy:
500
memcpy(texImage->Data, pixels, imageSize);
501
} else if (!texImage->TexFormat->StoreImage(ctx, dims,
502
texImage->_BaseFormat,
504
texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
506
texImage->ImageOffsets,
507
width, height, depth,
508
format, type, pixels, unpack)) {
509
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
512
_mesa_unmap_teximage_pbo(ctx, unpack);
514
if (intelImage->mt) {
515
intel_miptree_image_unmap(intel, intelImage->mt);
516
texImage->Data = NULL;
519
UNLOCK_HARDWARE(intel);
522
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
524
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
525
intel_generate_mipmap(ctx, target,
526
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
533
intelTexImage3D(GLcontext * ctx,
534
GLenum target, GLint level,
535
GLint internalFormat,
536
GLint width, GLint height, GLint depth,
538
GLenum format, GLenum type, const void *pixels,
539
const struct gl_pixelstore_attrib *unpack,
540
struct gl_texture_object *texObj,
541
struct gl_texture_image *texImage)
543
intelTexImage(ctx, 3, target, level,
544
internalFormat, width, height, depth, border,
545
format, type, pixels, unpack, texObj, texImage, 0, 0);
550
intelTexImage2D(GLcontext * ctx,
551
GLenum target, GLint level,
552
GLint internalFormat,
553
GLint width, GLint height, GLint border,
554
GLenum format, GLenum type, const void *pixels,
555
const struct gl_pixelstore_attrib *unpack,
556
struct gl_texture_object *texObj,
557
struct gl_texture_image *texImage)
559
intelTexImage(ctx, 2, target, level,
560
internalFormat, width, height, 1, border,
561
format, type, pixels, unpack, texObj, texImage, 0, 0);
565
intelTexImage1D(GLcontext * ctx,
566
GLenum target, GLint level,
567
GLint internalFormat,
568
GLint width, GLint border,
569
GLenum format, GLenum type, const void *pixels,
570
const struct gl_pixelstore_attrib *unpack,
571
struct gl_texture_object *texObj,
572
struct gl_texture_image *texImage)
574
intelTexImage(ctx, 1, target, level,
575
internalFormat, width, 1, 1, border,
576
format, type, pixels, unpack, texObj, texImage, 0, 0);
579
void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
580
GLint internalFormat,
581
GLint width, GLint height, GLint border,
582
GLsizei imageSize, const GLvoid *data,
583
struct gl_texture_object *texObj,
584
struct gl_texture_image *texImage )
586
intelTexImage(ctx, 2, target, level,
587
internalFormat, width, height, 1, border,
588
0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
592
* Need to map texture image into memory before copying image data,
596
intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
597
GLenum format, GLenum type, GLvoid * pixels,
598
struct gl_texture_object *texObj,
599
struct gl_texture_image *texImage, int compressed)
601
struct intel_context *intel = intel_context(ctx);
602
struct intel_texture_image *intelImage = intel_texture_image(texImage);
605
if (intelImage->mt) {
606
/* Image is stored in hardware format in a buffer managed by the
607
* kernel. Need to explicitly map and unmap it.
609
intelImage->base.Data =
610
intel_miptree_image_map(intel,
614
&intelImage->base.RowStride,
615
intelImage->base.ImageOffsets);
616
intelImage->base.RowStride /= intelImage->mt->cpp;
619
/* Otherwise, the image should actually be stored in
620
* intelImage->base.Data. This is pretty confusing for
621
* everybody, I'd much prefer to separate the two functions of
622
* texImage->Data - storage for texture images in main memory
623
* and access (ie mappings) of images. In other words, we'd
624
* create a new texImage->Map field and leave Data simply for
627
assert(intelImage->base.Data);
632
_mesa_get_compressed_teximage(ctx, target, level, pixels,
635
_mesa_get_teximage(ctx, target, level, format, type, pixels,
641
if (intelImage->mt) {
642
intel_miptree_image_unmap(intel, intelImage->mt);
643
intelImage->base.Data = NULL;
648
intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
649
GLenum format, GLenum type, GLvoid * pixels,
650
struct gl_texture_object *texObj,
651
struct gl_texture_image *texImage)
653
intel_get_tex_image(ctx, target, level, format, type, pixels,
654
texObj, texImage, 0);
660
intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
662
const struct gl_texture_object *texObj,
663
const struct gl_texture_image *texImage)
665
intel_get_tex_image(ctx, target, level, 0, 0, pixels,
666
texObj, texImage, 1);
671
intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
672
unsigned long long offset, GLint depth, GLuint pitch)
674
struct intel_context *intel = (struct intel_context*)
675
((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
676
struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
677
struct intel_texture_object *intelObj = intel_texture_object(tObj);
683
intel_miptree_release(intel, &intelObj->mt);
685
intelObj->imageOverride = GL_TRUE;
686
intelObj->depthOverride = depth;
687
intelObj->pitchOverride = pitch;
690
intelObj->textureOffset = offset;