287
232
u_minify(dst->width0, level),
288
233
u_minify(dst->height0, level)); /* width, height */
290
screen->tex_transfer_destroy(dst_transfer);
235
pipe->transfer_destroy(pipe, dst_transfer);
292
237
srcUB += src_image_stride;
297
/* Copy mipmap image between textures
243
* For debug only: get/print center pixel in the src resource.
246
print_center_pixel(struct pipe_context *pipe, struct pipe_resource *src)
248
struct pipe_subresource rect;
249
struct pipe_transfer *xfer;
250
struct pipe_box region;
256
region.x = src->width0 / 2;
257
region.y = src->height0 / 2;
263
xfer = pipe->get_transfer(pipe, src, rect, PIPE_TRANSFER_READ, ®ion);
264
map = pipe->transfer_map(pipe, xfer);
266
printf("center pixel: %d %d %d %d\n", map[0], map[1], map[2], map[3]);
268
pipe->transfer_unmap(pipe, xfer);
269
pipe->transfer_destroy(pipe, xfer);
274
* Copy the image at level=0 in 'src' to the 'dst' resource at 'dstLevel'.
275
* This is used to copy mipmap images from one texture buffer to another.
276
* This typically happens when our initial guess at the total texture size
277
* is incorrect (see the guess_and_alloc_texture() function).
300
280
st_texture_image_copy(struct pipe_context *pipe,
301
struct pipe_texture *dst, GLuint dstLevel,
302
struct pipe_texture *src,
281
struct pipe_resource *dst, GLuint dstLevel,
282
struct pipe_resource *src, GLuint srcLevel,
305
struct pipe_screen *screen = pipe->screen;
306
285
GLuint width = u_minify(dst->width0, dstLevel);
307
286
GLuint height = u_minify(dst->height0, dstLevel);
308
287
GLuint depth = u_minify(dst->depth0, dstLevel);
309
struct pipe_surface *src_surface;
310
struct pipe_surface *dst_surface;
288
struct pipe_subresource dstsub, srcsub;
291
assert(u_minify(src->width0, srcLevel) == width);
292
assert(u_minify(src->height0, srcLevel) == height);
293
assert(u_minify(src->depth0, srcLevel) == depth);
296
dstsub.level = dstLevel;
298
srcsub.level = srcLevel;
299
/* Loop over 3D image slices */
313
300
for (i = 0; i < depth; i++) {
316
/* find src texture level of needed size */
317
for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) {
318
if (u_minify(src->width0, srcLevel) == width &&
319
u_minify(src->height0, srcLevel) == height) {
323
assert(u_minify(src->width0, srcLevel) == width);
324
assert(u_minify(src->height0, srcLevel) == height);
328
src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
329
PIPE_BUFFER_USAGE_CPU_READ);
330
ubyte *map = screen->surface_map(screen, src_surface, PIPE_BUFFER_USAGE_CPU_READ);
331
map += src_surface->width * src_surface->height * 4 / 2;
332
printf("%s center pixel: %d %d %d %d (pt %p[%d] -> %p[%d])\n",
334
map[0], map[1], map[2], map[3],
335
src, srcLevel, dst, dstLevel);
337
screen->surface_unmap(screen, src_surface);
338
pipe_surface_reference(&src_surface, NULL);
342
dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i,
343
PIPE_BUFFER_USAGE_GPU_WRITE);
345
src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
346
PIPE_BUFFER_USAGE_GPU_READ);
348
if (pipe->surface_copy) {
349
pipe->surface_copy(pipe,
356
util_surface_copy(pipe, FALSE,
364
pipe_surface_reference(&src_surface, NULL);
365
pipe_surface_reference(&dst_surface, NULL);
371
* Bind a pipe surface to a texture object. After the call,
372
* the texture object is marked dirty and will be (re-)validated.
374
* If this is the first surface bound, the texture object is said to
375
* switch from normal to surface based. It will be cleared first in
378
* \param ps pipe surface to be unbound
379
* \param target texture target
380
* \param level image level
381
* \param format internal format of the texture
384
st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
385
enum pipe_format format)
387
GET_CURRENT_CONTEXT(ctx);
388
const GLuint unit = ctx->Texture.CurrentUnit;
389
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
390
struct gl_texture_object *texObj;
391
struct gl_texture_image *texImage;
392
struct st_texture_object *stObj;
393
struct st_texture_image *stImage;
394
GLenum internalFormat;
398
target = GL_TEXTURE_2D;
400
case ST_TEXTURE_RECT:
401
target = GL_TEXTURE_RECTANGLE_ARB;
407
/* map pipe format to base format for now */
408
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
409
internalFormat = GL_RGBA;
411
internalFormat = GL_RGB;
413
texObj = _mesa_select_tex_object(ctx, texUnit, target);
414
_mesa_lock_texture(ctx, texObj);
416
stObj = st_texture_object(texObj);
417
/* switch to surface based */
418
if (!stObj->surface_based) {
419
_mesa_clear_texture_object(ctx, texObj);
420
stObj->surface_based = GL_TRUE;
423
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
424
stImage = st_texture_image(texImage);
426
_mesa_init_teximage_fields(ctx, target, texImage,
427
ps->width, ps->height, 1, 0, internalFormat);
428
texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
429
GL_RGBA, GL_UNSIGNED_BYTE);
430
_mesa_set_fetch_functions(texImage, 2);
431
pipe_texture_reference(&stImage->pt, ps->texture);
433
_mesa_dirty_texobj(ctx, texObj, GL_TRUE);
434
_mesa_unlock_texture(ctx, texObj);
441
* Unbind a pipe surface from a texture object. After the call,
442
* the texture object is marked dirty and will be (re-)validated.
444
* \param ps pipe surface to be unbound
445
* \param target texture target
446
* \param level image level
449
st_unbind_texture_surface(struct pipe_surface *ps, int target, int level)
451
GET_CURRENT_CONTEXT(ctx);
452
const GLuint unit = ctx->Texture.CurrentUnit;
453
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
454
struct gl_texture_object *texObj;
455
struct gl_texture_image *texImage;
456
struct st_texture_object *stObj;
457
struct st_texture_image *stImage;
461
target = GL_TEXTURE_2D;
463
case ST_TEXTURE_RECT:
464
target = GL_TEXTURE_RECTANGLE_ARB;
470
texObj = _mesa_select_tex_object(ctx, texUnit, target);
472
_mesa_lock_texture(ctx, texObj);
474
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
475
stObj = st_texture_object(texObj);
476
stImage = st_texture_image(texImage);
478
/* Make sure the pipe surface is still bound. The texture object is still
479
* considered surface based even if this is the last bound surface. */
480
if (stImage->pt == ps->texture) {
481
pipe_texture_reference(&stImage->pt, NULL);
482
_mesa_clear_texture_image(ctx, texImage);
484
_mesa_dirty_texobj(ctx, texObj, GL_TRUE);
487
_mesa_unlock_texture(ctx, texObj);
493
/** Redirect rendering into stfb's surface to a texture image */
495
st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex,
496
int target, int format, int level)
498
GET_CURRENT_CONTEXT(ctx);
499
struct st_context *st = ctx->st;
500
struct pipe_context *pipe = st->pipe;
501
struct pipe_screen *screen = pipe->screen;
502
const GLuint unit = ctx->Texture.CurrentUnit;
503
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
504
struct gl_texture_object *texObj;
505
struct gl_texture_image *texImage;
506
struct st_texture_image *stImage;
507
struct st_renderbuffer *strb;
508
GLint face = 0, slice = 0;
510
assert(surfIndex <= ST_SURFACE_DEPTH);
512
strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
514
if (strb->texture_save || strb->surface_save) {
519
if (target == ST_TEXTURE_2D) {
520
texObj = texUnit->CurrentTex[TEXTURE_2D_INDEX];
521
texImage = _mesa_get_tex_image(ctx, texObj, GL_TEXTURE_2D, level);
522
stImage = st_texture_image(texImage);
525
/* unsupported target */
529
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
531
/* save the renderbuffer's surface/texture info */
532
pipe_texture_reference(&strb->texture_save, strb->texture);
533
pipe_surface_reference(&strb->surface_save, strb->surface);
535
/* plug in new surface/texture info */
536
pipe_texture_reference(&strb->texture, stImage->pt);
537
strb->surface = screen->get_tex_surface(screen, strb->texture,
539
(PIPE_BUFFER_USAGE_GPU_READ |
540
PIPE_BUFFER_USAGE_GPU_WRITE));
542
st->dirty.st |= ST_NEW_FRAMEBUFFER;
548
/** Undo surface-to-texture binding */
550
st_release_teximage(struct st_framebuffer *stfb, uint surfIndex,
551
int target, int format, int level)
553
GET_CURRENT_CONTEXT(ctx);
554
struct st_context *st = ctx->st;
555
struct st_renderbuffer *strb;
557
assert(surfIndex <= ST_SURFACE_DEPTH);
559
strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
561
if (!strb->texture_save || !strb->surface_save) {
566
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
568
/* free tex surface, restore original */
569
pipe_surface_reference(&strb->surface, strb->surface_save);
570
pipe_texture_reference(&strb->texture, strb->texture_save);
572
pipe_surface_reference(&strb->surface_save, NULL);
573
pipe_texture_reference(&strb->texture_save, NULL);
575
st->dirty.st |= ST_NEW_FRAMEBUFFER;
581
st_teximage_flush_before_map(struct st_context *st,
582
struct pipe_texture *pt,
585
enum pipe_transfer_usage usage)
587
struct pipe_context *pipe = st->pipe;
588
unsigned referenced =
589
pipe->is_texture_referenced(pipe, pt, face, level);
591
if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
592
(usage & PIPE_TRANSFER_WRITE)))
593
st->pipe->flush(st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
303
print_center_pixel(pipe, src);
306
pipe->resource_copy_region(pipe,
309
0, 0, i,/* destX, Y, Z */
312
0, 0, i,/* srcX, Y, Z */