1 /**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <stdio.h>
29 #include "main/bufferobj.h"
30 #include "main/enums.h"
31 #include "main/errors.h"
32 #include "main/fbobject.h"
33 #include "main/formats.h"
34 #include "main/format_utils.h"
35 #include "main/glformats.h"
36 #include "main/image.h"
37
38 #include "main/macros.h"
39 #include "main/mipmap.h"
40 #include "main/pack.h"
41 #include "main/pbo.h"
42 #include "main/pixeltransfer.h"
43 #include "main/texcompress.h"
44 #include "main/texcompress_astc.h"
45 #include "main/texcompress_etc.h"
46 #include "main/texgetimage.h"
47 #include "main/teximage.h"
48 #include "main/texobj.h"
49 #include "main/texstore.h"
50
51 #include "state_tracker/st_debug.h"
52 #include "state_tracker/st_context.h"
53 #include "state_tracker/st_cb_bitmap.h"
54 #include "state_tracker/st_cb_fbo.h"
55 #include "state_tracker/st_cb_flush.h"
56 #include "state_tracker/st_cb_texture.h"
57 #include "state_tracker/st_cb_bufferobjects.h"
58 #include "state_tracker/st_cb_memoryobjects.h"
59 #include "state_tracker/st_format.h"
60 #include "state_tracker/st_pbo.h"
61 #include "state_tracker/st_texture.h"
62 #include "state_tracker/st_gen_mipmap.h"
63 #include "state_tracker/st_atom.h"
64 #include "state_tracker/st_sampler_view.h"
65 #include "state_tracker/st_util.h"
66
67 #include "pipe/p_context.h"
68 #include "pipe/p_defines.h"
69 #include "util/u_inlines.h"
70 #include "util/u_upload_mgr.h"
71 #include "pipe/p_shader_tokens.h"
72 #include "util/u_tile.h"
73 #include "util/format/u_format.h"
74 #include "util/u_surface.h"
75 #include "util/u_sampler.h"
76 #include "util/u_math.h"
77 #include "util/u_box.h"
78 #include "util/u_simple_shaders.h"
79 #include "cso_cache/cso_context.h"
80 #include "tgsi/tgsi_ureg.h"
81
82 #define DBG if (0) printf
83
84
85 enum pipe_texture_target
gl_target_to_pipe(GLenum target)86 gl_target_to_pipe(GLenum target)
87 {
88 switch (target) {
89 case GL_TEXTURE_1D:
90 case GL_PROXY_TEXTURE_1D:
91 return PIPE_TEXTURE_1D;
92 case GL_TEXTURE_2D:
93 case GL_PROXY_TEXTURE_2D:
94 case GL_TEXTURE_EXTERNAL_OES:
95 case GL_TEXTURE_2D_MULTISAMPLE:
96 case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
97 return PIPE_TEXTURE_2D;
98 case GL_TEXTURE_RECTANGLE_NV:
99 case GL_PROXY_TEXTURE_RECTANGLE_NV:
100 return PIPE_TEXTURE_RECT;
101 case GL_TEXTURE_3D:
102 case GL_PROXY_TEXTURE_3D:
103 return PIPE_TEXTURE_3D;
104 case GL_TEXTURE_CUBE_MAP_ARB:
105 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
106 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
107 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
108 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
109 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
110 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
111 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
112 return PIPE_TEXTURE_CUBE;
113 case GL_TEXTURE_1D_ARRAY_EXT:
114 case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
115 return PIPE_TEXTURE_1D_ARRAY;
116 case GL_TEXTURE_2D_ARRAY_EXT:
117 case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
118 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
119 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
120 return PIPE_TEXTURE_2D_ARRAY;
121 case GL_TEXTURE_BUFFER:
122 return PIPE_BUFFER;
123 case GL_TEXTURE_CUBE_MAP_ARRAY:
124 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
125 return PIPE_TEXTURE_CUBE_ARRAY;
126 default:
127 assert(0);
128 return 0;
129 }
130 }
131
132 static enum pipe_format
get_src_format(struct pipe_screen * screen,enum pipe_format src_format,struct pipe_resource * src)133 get_src_format(struct pipe_screen *screen, enum pipe_format src_format, struct pipe_resource *src)
134 {
135 /* Convert the source format to what is expected by GetTexImage
136 * and see if it's supported.
137 *
138 * This only applies to glGetTexImage:
139 * - Luminance must be returned as (L,0,0,1).
140 * - Luminance alpha must be returned as (L,0,0,A).
141 * - Intensity must be returned as (I,0,0,1)
142 */
143 src_format = util_format_linear(src_format);
144 src_format = util_format_luminance_to_red(src_format);
145 src_format = util_format_intensity_to_red(src_format);
146
147 if (!src_format ||
148 !screen->is_format_supported(screen, src_format, src->target,
149 src->nr_samples, src->nr_storage_samples,
150 PIPE_BIND_SAMPLER_VIEW)) {
151 return PIPE_FORMAT_NONE;
152 }
153 return src_format;
154 }
155
156 static struct pipe_resource *
create_dst_texture(struct gl_context * ctx,enum pipe_format dst_format,enum pipe_texture_target pipe_target,GLsizei width,GLsizei height,GLint depth,GLenum gl_target,unsigned bind)157 create_dst_texture(struct gl_context *ctx,
158 enum pipe_format dst_format, enum pipe_texture_target pipe_target,
159 GLsizei width, GLsizei height, GLint depth,
160 GLenum gl_target, unsigned bind)
161 {
162 struct st_context *st = st_context(ctx);
163 struct pipe_screen *screen = st->screen;
164 struct pipe_resource dst_templ;
165
166 /* create the destination texture of size (width X height X depth) */
167 memset(&dst_templ, 0, sizeof(dst_templ));
168 dst_templ.target = pipe_target;
169 dst_templ.format = dst_format;
170 dst_templ.bind = bind;
171 dst_templ.usage = PIPE_USAGE_STAGING;
172
173 st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
174 &dst_templ.width0, &dst_templ.height0,
175 &dst_templ.depth0, &dst_templ.array_size);
176
177 return screen->resource_create(screen, &dst_templ);
178 }
179
180 static boolean
copy_to_staging_dest(struct gl_context * ctx,struct pipe_resource * dst,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLint depth,GLenum format,GLenum type,void * pixels,struct gl_texture_image * texImage)181 copy_to_staging_dest(struct gl_context * ctx, struct pipe_resource *dst,
182 GLint xoffset, GLint yoffset, GLint zoffset,
183 GLsizei width, GLsizei height, GLint depth,
184 GLenum format, GLenum type, void * pixels,
185 struct gl_texture_image *texImage)
186 {
187 struct st_context *st = st_context(ctx);
188 struct pipe_context *pipe = st->pipe;
189 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
190 struct pipe_resource *src = stObj->pt;
191 enum pipe_format dst_format = dst->format;
192 mesa_format mesa_format;
193 GLenum gl_target = texImage->TexObject->Target;
194 unsigned dims;
195 struct pipe_transfer *tex_xfer;
196 ubyte *map = NULL;
197 boolean done = FALSE;
198
199 pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
200
201 map = pipe_texture_map_3d(pipe, dst, 0, PIPE_MAP_READ,
202 0, 0, 0, width, height, depth, &tex_xfer);
203 if (!map) {
204 goto end;
205 }
206
207 mesa_format = st_pipe_format_to_mesa_format(dst_format);
208 dims = _mesa_get_texture_dimensions(gl_target);
209
210 /* copy/pack data into user buffer */
211 if (_mesa_format_matches_format_and_type(mesa_format, format, type,
212 ctx->Pack.SwapBytes, NULL)) {
213 /* memcpy */
214 const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
215 GLuint row, slice;
216
217 for (slice = 0; slice < depth; slice++) {
218 ubyte *slice_map = map;
219
220 for (row = 0; row < height; row++) {
221 void *dest = _mesa_image_address(dims, &ctx->Pack, pixels,
222 width, height, format, type,
223 slice, row, 0);
224
225 memcpy(dest, slice_map, bytesPerRow);
226
227 slice_map += tex_xfer->stride;
228 }
229
230 map += tex_xfer->layer_stride;
231 }
232 }
233 else {
234 /* format translation via floats */
235 GLuint slice;
236 GLfloat *rgba;
237 uint32_t dstMesaFormat;
238 int dstStride, srcStride;
239
240 assert(util_format_is_compressed(src->format));
241
242 rgba = malloc(width * height * 4 * sizeof(GLfloat));
243 if (!rgba) {
244 goto end;
245 }
246
247 if (ST_DEBUG & DEBUG_FALLBACK)
248 debug_printf("%s: fallback format translation\n", __func__);
249
250 dstMesaFormat = _mesa_format_from_format_and_type(format, type);
251 dstStride = _mesa_image_row_stride(&ctx->Pack, width, format, type);
252 srcStride = 4 * width * sizeof(GLfloat);
253 for (slice = 0; slice < depth; slice++) {
254 void *dest = _mesa_image_address(dims, &ctx->Pack, pixels,
255 width, height, format, type,
256 slice, 0, 0);
257
258 /* get float[4] rgba row from surface */
259 pipe_get_tile_rgba(tex_xfer, map, 0, 0, width, height, dst_format,
260 rgba);
261
262 _mesa_format_convert(dest, dstMesaFormat, dstStride,
263 rgba, RGBA32_FLOAT, srcStride,
264 width, height, NULL);
265
266 /* Handle byte swapping if required */
267 if (ctx->Pack.SwapBytes) {
268 _mesa_swap_bytes_2d_image(format, type, &ctx->Pack,
269 width, height, dest, dest);
270 }
271
272 map += tex_xfer->layer_stride;
273 }
274
275 free(rgba);
276 }
277 done = TRUE;
278
279 end:
280 if (map)
281 pipe_texture_unmap(pipe, tex_xfer);
282
283 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
284 return done;
285 }
286
287 static enum pipe_format
get_dst_format(struct gl_context * ctx,enum pipe_texture_target target,enum pipe_format src_format,bool is_compressed,GLenum format,GLenum type,unsigned bind)288 get_dst_format(struct gl_context *ctx, enum pipe_texture_target target,
289 enum pipe_format src_format, bool is_compressed,
290 GLenum format, GLenum type, unsigned bind)
291 {
292 struct st_context *st = st_context(ctx);
293 struct pipe_screen *screen = st->screen;
294 /* Choose the destination format by finding the best match
295 * for the format+type combo. */
296 enum pipe_format dst_format = st_choose_matching_format(st, bind, format, type,
297 ctx->Pack.SwapBytes);
298
299 if (dst_format == PIPE_FORMAT_NONE) {
300 GLenum dst_glformat;
301
302 /* Fall back to _mesa_GetTexImage_sw except for compressed formats,
303 * where decompression with a blit is always preferred. */
304 if (!is_compressed) {
305 return PIPE_FORMAT_NONE;
306 }
307
308 /* Set the appropriate format for the decompressed texture.
309 * Luminance and sRGB formats shouldn't appear here.*/
310 switch (src_format) {
311 case PIPE_FORMAT_DXT1_RGB:
312 case PIPE_FORMAT_DXT1_RGBA:
313 case PIPE_FORMAT_DXT3_RGBA:
314 case PIPE_FORMAT_DXT5_RGBA:
315 case PIPE_FORMAT_RGTC1_UNORM:
316 case PIPE_FORMAT_RGTC2_UNORM:
317 case PIPE_FORMAT_ETC1_RGB8:
318 case PIPE_FORMAT_ETC2_RGB8:
319 case PIPE_FORMAT_ETC2_RGB8A1:
320 case PIPE_FORMAT_ETC2_RGBA8:
321 case PIPE_FORMAT_ASTC_4x4:
322 case PIPE_FORMAT_ASTC_5x4:
323 case PIPE_FORMAT_ASTC_5x5:
324 case PIPE_FORMAT_ASTC_6x5:
325 case PIPE_FORMAT_ASTC_6x6:
326 case PIPE_FORMAT_ASTC_8x5:
327 case PIPE_FORMAT_ASTC_8x6:
328 case PIPE_FORMAT_ASTC_8x8:
329 case PIPE_FORMAT_ASTC_10x5:
330 case PIPE_FORMAT_ASTC_10x6:
331 case PIPE_FORMAT_ASTC_10x8:
332 case PIPE_FORMAT_ASTC_10x10:
333 case PIPE_FORMAT_ASTC_12x10:
334 case PIPE_FORMAT_ASTC_12x12:
335 case PIPE_FORMAT_BPTC_RGBA_UNORM:
336 case PIPE_FORMAT_FXT1_RGB:
337 case PIPE_FORMAT_FXT1_RGBA:
338 dst_glformat = GL_RGBA8;
339 break;
340 case PIPE_FORMAT_RGTC1_SNORM:
341 case PIPE_FORMAT_RGTC2_SNORM:
342 if (!ctx->Extensions.EXT_texture_snorm)
343 return PIPE_FORMAT_NONE;
344 dst_glformat = GL_RGBA8_SNORM;
345 break;
346 case PIPE_FORMAT_BPTC_RGB_FLOAT:
347 case PIPE_FORMAT_BPTC_RGB_UFLOAT:
348 if (!ctx->Extensions.ARB_texture_float)
349 return PIPE_FORMAT_NONE;
350 dst_glformat = GL_RGBA32F;
351 break;
352 case PIPE_FORMAT_ETC2_R11_UNORM:
353 if (bind && !screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM,
354 target, 0, 0, bind))
355 return PIPE_FORMAT_NONE;
356 dst_glformat = GL_R16;
357 break;
358 case PIPE_FORMAT_ETC2_R11_SNORM:
359 if (bind && !screen->is_format_supported(screen, PIPE_FORMAT_R16_SNORM,
360 target, 0, 0, bind))
361 return PIPE_FORMAT_NONE;
362 dst_glformat = GL_R16_SNORM;
363 break;
364 case PIPE_FORMAT_ETC2_RG11_UNORM:
365 if (bind && !screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM,
366 target, 0, 0, bind))
367 return PIPE_FORMAT_NONE;
368 dst_glformat = GL_RG16;
369 break;
370 case PIPE_FORMAT_ETC2_RG11_SNORM:
371 if (bind && !screen->is_format_supported(screen, PIPE_FORMAT_R16G16_SNORM,
372 target, 0, 0, bind))
373 return PIPE_FORMAT_NONE;
374 dst_glformat = GL_RG16_SNORM;
375 break;
376 default:
377 assert(0);
378 return PIPE_FORMAT_NONE;
379 }
380
381 dst_format = st_choose_format(st, dst_glformat, format, type,
382 target, 0, 0, bind,
383 false, false);
384 }
385 return dst_format;
386 }
387
388 /** called via ctx->Driver.NewTextureImage() */
389 static struct gl_texture_image *
st_NewTextureImage(struct gl_context * ctx)390 st_NewTextureImage(struct gl_context * ctx)
391 {
392 DBG("%s\n", __func__);
393 (void) ctx;
394 return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
395 }
396
397
398 /** called via ctx->Driver.DeleteTextureImage() */
399 static void
st_DeleteTextureImage(struct gl_context * ctx,struct gl_texture_image * img)400 st_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
401 {
402 /* nothing special (yet) for st_texture_image */
403 _mesa_delete_texture_image(ctx, img);
404 }
405
406
407 /** called via ctx->Driver.NewTextureObject() */
408 static struct gl_texture_object *
st_NewTextureObject(struct gl_context * ctx,GLuint name,GLenum target)409 st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
410 {
411 struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
412 if (!obj)
413 return NULL;
414
415 obj->level_override = -1;
416 obj->layer_override = -1;
417
418 /* Pre-allocate a sampler views container to save a branch in the
419 * fast path.
420 */
421 obj->sampler_views = calloc(1, sizeof(struct st_sampler_views)
422 + sizeof(struct st_sampler_view));
423 if (!obj->sampler_views) {
424 free(obj);
425 return NULL;
426 }
427 obj->sampler_views->max = 1;
428
429 DBG("%s\n", __func__);
430 _mesa_initialize_texture_object(ctx, &obj->base, name, target);
431
432 simple_mtx_init(&obj->validate_mutex, mtx_plain);
433 obj->needs_validation = true;
434
435 return &obj->base;
436 }
437
438
439 /** called via ctx->Driver.DeleteTextureObject() */
440 static void
st_DeleteTextureObject(struct gl_context * ctx,struct gl_texture_object * texObj)441 st_DeleteTextureObject(struct gl_context *ctx,
442 struct gl_texture_object *texObj)
443 {
444 struct st_context *st = st_context(ctx);
445 struct st_texture_object *stObj = st_texture_object(texObj);
446
447 pipe_resource_reference(&stObj->pt, NULL);
448 st_delete_texture_sampler_views(st, stObj);
449 simple_mtx_destroy(&stObj->validate_mutex);
450 _mesa_delete_texture_object(ctx, texObj);
451 }
452
453 /**
454 * Called via ctx->Driver.TextureRemovedFromShared()
455 * When texture is removed from ctx->Shared->TexObjects we lose
456 * the ability to clean up views on context destruction, which may
457 * lead to dangling pointers to destroyed contexts.
458 * Release the views to prevent this.
459 */
460 static void
st_TextureReleaseAllSamplerViews(struct gl_context * ctx,struct gl_texture_object * texObj)461 st_TextureReleaseAllSamplerViews(struct gl_context *ctx,
462 struct gl_texture_object *texObj)
463 {
464 struct st_context *st = st_context(ctx);
465 struct st_texture_object *stObj = st_texture_object(texObj);
466
467 st_texture_release_all_sampler_views(st, stObj);
468 }
469
470 /** called via ctx->Driver.FreeTextureImageBuffer() */
471 static void
st_FreeTextureImageBuffer(struct gl_context * ctx,struct gl_texture_image * texImage)472 st_FreeTextureImageBuffer(struct gl_context *ctx,
473 struct gl_texture_image *texImage)
474 {
475 struct st_context *st = st_context(ctx);
476 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
477 struct st_texture_image *stImage = st_texture_image(texImage);
478
479 DBG("%s\n", __func__);
480
481 if (stImage->pt) {
482 pipe_resource_reference(&stImage->pt, NULL);
483 }
484
485 free(stImage->transfer);
486 stImage->transfer = NULL;
487 stImage->num_transfers = 0;
488
489 if (stImage->compressed_data &&
490 pipe_reference(&stImage->compressed_data->reference, NULL)) {
491 free(stImage->compressed_data->ptr);
492 free(stImage->compressed_data);
493 stImage->compressed_data = NULL;
494 }
495
496 /* if the texture image is being deallocated, the structure of the
497 * texture is changing so we'll likely need a new sampler view.
498 */
499 st_texture_release_all_sampler_views(st, stObj);
500 }
501
502 bool
st_astc_format_fallback(const struct st_context * st,mesa_format format)503 st_astc_format_fallback(const struct st_context *st, mesa_format format)
504 {
505 if (!_mesa_is_format_astc_2d(format))
506 return false;
507
508 if (format == MESA_FORMAT_RGBA_ASTC_5x5 ||
509 format == MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5)
510 return !st->has_astc_5x5_ldr;
511
512 return !st->has_astc_2d_ldr;
513 }
514
515 bool
st_compressed_format_fallback(struct st_context * st,mesa_format format)516 st_compressed_format_fallback(struct st_context *st, mesa_format format)
517 {
518 if (format == MESA_FORMAT_ETC1_RGB8)
519 return !st->has_etc1;
520
521 if (_mesa_is_format_etc2(format))
522 return !st->has_etc2;
523
524 if (st_astc_format_fallback(st, format))
525 return true;
526
527 return false;
528 }
529
530
531 static void
compressed_tex_fallback_allocate(struct st_context * st,struct st_texture_image * stImage)532 compressed_tex_fallback_allocate(struct st_context *st,
533 struct st_texture_image *stImage)
534 {
535 struct gl_texture_image *texImage = &stImage->base;
536
537 if (!st_compressed_format_fallback(st, texImage->TexFormat))
538 return;
539
540 if (stImage->compressed_data &&
541 pipe_reference(&stImage->compressed_data->reference, NULL)) {
542 free(stImage->compressed_data->ptr);
543 free(stImage->compressed_data);
544 }
545
546 unsigned data_size = _mesa_format_image_size(texImage->TexFormat,
547 texImage->Width2,
548 texImage->Height2,
549 texImage->Depth2);
550
551 stImage->compressed_data = ST_CALLOC_STRUCT(st_compressed_data);
552 stImage->compressed_data->ptr =
553 malloc(data_size * _mesa_num_tex_faces(texImage->TexObject->Target));
554 pipe_reference_init(&stImage->compressed_data->reference, 1);
555 }
556
557
558 /** called via ctx->Driver.MapTextureImage() */
559 static void
st_MapTextureImage(struct gl_context * ctx,struct gl_texture_image * texImage,GLuint slice,GLuint x,GLuint y,GLuint w,GLuint h,GLbitfield mode,GLubyte ** mapOut,GLint * rowStrideOut)560 st_MapTextureImage(struct gl_context *ctx,
561 struct gl_texture_image *texImage,
562 GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h,
563 GLbitfield mode,
564 GLubyte **mapOut, GLint *rowStrideOut)
565 {
566 struct st_context *st = st_context(ctx);
567 struct st_texture_image *stImage = st_texture_image(texImage);
568 GLubyte *map;
569 struct pipe_transfer *transfer;
570
571 /* Check for unexpected flags */
572 assert((mode & ~(GL_MAP_READ_BIT |
573 GL_MAP_WRITE_BIT |
574 GL_MAP_INVALIDATE_RANGE_BIT)) == 0);
575
576 const enum pipe_map_flags transfer_flags =
577 st_access_flags_to_transfer_flags(mode, false);
578
579 map = st_texture_image_map(st, stImage, transfer_flags, x, y, slice, w, h, 1,
580 &transfer);
581 if (map) {
582 if (st_compressed_format_fallback(st, texImage->TexFormat)) {
583 /* Some compressed formats don't have to be supported by drivers,
584 * and st/mesa transparently handles decompression on upload (Unmap),
585 * so that drivers don't see the compressed formats.
586 *
587 * We store the compressed data (it's needed for glGetCompressedTex-
588 * Image and image copies in OES_copy_image).
589 */
590 unsigned z = transfer->box.z;
591 struct st_texture_image_transfer *itransfer = &stImage->transfer[z];
592
593 unsigned blk_w, blk_h;
594 _mesa_get_format_block_size(texImage->TexFormat, &blk_w, &blk_h);
595
596 unsigned y_blocks = DIV_ROUND_UP(texImage->Height2, blk_h);
597 unsigned stride = *rowStrideOut = itransfer->temp_stride =
598 _mesa_format_row_stride(texImage->TexFormat, texImage->Width2);
599 unsigned block_size = _mesa_get_format_bytes(texImage->TexFormat);
600
601 assert(stImage->compressed_data);
602 *mapOut = itransfer->temp_data =
603 stImage->compressed_data->ptr +
604 (z * y_blocks + (y / blk_h)) * stride +
605 (x / blk_w) * block_size;
606 itransfer->map = map;
607 }
608 else {
609 /* supported mapping */
610 *mapOut = map;
611 *rowStrideOut = transfer->stride;
612 }
613 }
614 else {
615 *mapOut = NULL;
616 *rowStrideOut = 0;
617 }
618 }
619
620
621 /** called via ctx->Driver.UnmapTextureImage() */
622 static void
st_UnmapTextureImage(struct gl_context * ctx,struct gl_texture_image * texImage,GLuint slice)623 st_UnmapTextureImage(struct gl_context *ctx,
624 struct gl_texture_image *texImage,
625 GLuint slice)
626 {
627 struct st_context *st = st_context(ctx);
628 struct st_texture_image *stImage = st_texture_image(texImage);
629
630 if (st_compressed_format_fallback(st, texImage->TexFormat)) {
631 /* Decompress the compressed image on upload if the driver doesn't
632 * support the compressed format. */
633 unsigned z = slice + stImage->base.Face;
634 struct st_texture_image_transfer *itransfer = &stImage->transfer[z];
635 struct pipe_transfer *transfer = itransfer->transfer;
636
637 assert(z == transfer->box.z);
638
639 if (transfer->usage & PIPE_MAP_WRITE) {
640 if (util_format_is_compressed(stImage->pt->format)) {
641 /* Transcode into a different compressed format. */
642 unsigned size =
643 _mesa_format_image_size(PIPE_FORMAT_R8G8B8A8_UNORM,
644 transfer->box.width,
645 transfer->box.height, 1);
646 void *tmp = malloc(size);
647
648 /* Decompress to tmp. */
649 if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
650 _mesa_etc1_unpack_rgba8888(tmp, transfer->box.width * 4,
651 itransfer->temp_data,
652 itransfer->temp_stride,
653 transfer->box.width,
654 transfer->box.height);
655 } else if (_mesa_is_format_etc2(texImage->TexFormat)) {
656 bool bgra = stImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB;
657
658 _mesa_unpack_etc2_format(tmp, transfer->box.width * 4,
659 itransfer->temp_data,
660 itransfer->temp_stride,
661 transfer->box.width,
662 transfer->box.height,
663 texImage->TexFormat,
664 bgra);
665 } else if (_mesa_is_format_astc_2d(texImage->TexFormat)) {
666 _mesa_unpack_astc_2d_ldr(tmp, transfer->box.width * 4,
667 itransfer->temp_data,
668 itransfer->temp_stride,
669 transfer->box.width,
670 transfer->box.height,
671 texImage->TexFormat);
672 } else {
673 unreachable("unexpected format for a compressed format fallback");
674 }
675
676 /* Compress it to the target format. */
677 struct gl_pixelstore_attrib pack = {0};
678 pack.Alignment = 4;
679
680 _mesa_texstore(ctx, 2, GL_RGBA, stImage->pt->format,
681 transfer->stride, &itransfer->map,
682 transfer->box.width,
683 transfer->box.height, 1, GL_RGBA,
684 GL_UNSIGNED_BYTE, tmp, &pack);
685 free(tmp);
686 } else {
687 /* Decompress into an uncompressed format. */
688 if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
689 _mesa_etc1_unpack_rgba8888(itransfer->map, transfer->stride,
690 itransfer->temp_data,
691 itransfer->temp_stride,
692 transfer->box.width,
693 transfer->box.height);
694 } else if (_mesa_is_format_etc2(texImage->TexFormat)) {
695 bool bgra = stImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB;
696
697 _mesa_unpack_etc2_format(itransfer->map, transfer->stride,
698 itransfer->temp_data,
699 itransfer->temp_stride,
700 transfer->box.width, transfer->box.height,
701 texImage->TexFormat,
702 bgra);
703 } else if (_mesa_is_format_astc_2d(texImage->TexFormat)) {
704 _mesa_unpack_astc_2d_ldr(itransfer->map, transfer->stride,
705 itransfer->temp_data,
706 itransfer->temp_stride,
707 transfer->box.width, transfer->box.height,
708 texImage->TexFormat);
709 } else {
710 unreachable("unexpected format for a compressed format fallback");
711 }
712 }
713 }
714
715 itransfer->temp_data = NULL;
716 itransfer->temp_stride = 0;
717 itransfer->map = 0;
718 }
719
720 st_texture_image_unmap(st, stImage, slice);
721 }
722
723
724 /**
725 * Return default texture resource binding bitmask for the given format.
726 */
727 static GLuint
default_bindings(struct st_context * st,enum pipe_format format)728 default_bindings(struct st_context *st, enum pipe_format format)
729 {
730 struct pipe_screen *screen = st->screen;
731 const unsigned target = PIPE_TEXTURE_2D;
732 unsigned bindings;
733
734 if (util_format_is_depth_or_stencil(format))
735 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
736 else
737 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
738
739 if (screen->is_format_supported(screen, format, target, 0, 0, bindings))
740 return bindings;
741 else {
742 /* Try non-sRGB. */
743 format = util_format_linear(format);
744
745 if (screen->is_format_supported(screen, format, target, 0, 0, bindings))
746 return bindings;
747 else
748 return PIPE_BIND_SAMPLER_VIEW;
749 }
750 }
751
752
753 /**
754 * Given the size of a mipmap image, try to compute the size of the level=0
755 * mipmap image.
756 *
757 * Note that this isn't always accurate for odd-sized, non-POW textures.
758 * For example, if level=1 and width=40 then the level=0 width may be 80 or 81.
759 *
760 * \return GL_TRUE for success, GL_FALSE for failure
761 */
762 static GLboolean
guess_base_level_size(GLenum target,GLuint width,GLuint height,GLuint depth,GLuint level,GLuint * width0,GLuint * height0,GLuint * depth0)763 guess_base_level_size(GLenum target,
764 GLuint width, GLuint height, GLuint depth, GLuint level,
765 GLuint *width0, GLuint *height0, GLuint *depth0)
766 {
767 assert(width >= 1);
768 assert(height >= 1);
769 assert(depth >= 1);
770
771 if (level > 0) {
772 /* Guess the size of the base level.
773 * Depending on the image's size, we can't always make a guess here.
774 */
775 switch (target) {
776 case GL_TEXTURE_1D:
777 case GL_TEXTURE_1D_ARRAY:
778 width <<= level;
779 break;
780
781 case GL_TEXTURE_2D:
782 case GL_TEXTURE_2D_ARRAY:
783 /* We can't make a good guess here, because the base level dimensions
784 * can be non-square.
785 */
786 if (width == 1 || height == 1) {
787 return GL_FALSE;
788 }
789 width <<= level;
790 height <<= level;
791 break;
792
793 case GL_TEXTURE_CUBE_MAP:
794 case GL_TEXTURE_CUBE_MAP_ARRAY:
795 width <<= level;
796 height <<= level;
797 break;
798
799 case GL_TEXTURE_3D:
800 /* We can't make a good guess here, because the base level dimensions
801 * can be non-cube.
802 */
803 if (width == 1 || height == 1 || depth == 1) {
804 return GL_FALSE;
805 }
806 width <<= level;
807 height <<= level;
808 depth <<= level;
809 break;
810
811 case GL_TEXTURE_RECTANGLE:
812 break;
813
814 default:
815 assert(0);
816 }
817 }
818
819 *width0 = width;
820 *height0 = height;
821 *depth0 = depth;
822
823 return GL_TRUE;
824 }
825
826
827 /**
828 * Try to determine whether we should allocate memory for a full texture
829 * mipmap. The problem is when we get a glTexImage(level=0) call, we
830 * can't immediately know if other mipmap levels are coming next. Here
831 * we try to guess whether to allocate memory for a mipmap or just the
832 * 0th level.
833 *
834 * If we guess incorrectly here we'll later reallocate the right amount of
835 * memory either in st_AllocTextureImageBuffer() or st_finalize_texture().
836 *
837 * \param stObj the texture object we're going to allocate memory for.
838 * \param stImage describes the incoming image which we need to store.
839 */
840 static boolean
allocate_full_mipmap(const struct st_texture_object * stObj,const struct st_texture_image * stImage)841 allocate_full_mipmap(const struct st_texture_object *stObj,
842 const struct st_texture_image *stImage)
843 {
844 switch (stObj->base.Target) {
845 case GL_TEXTURE_RECTANGLE_NV:
846 case GL_TEXTURE_BUFFER:
847 case GL_TEXTURE_EXTERNAL_OES:
848 case GL_TEXTURE_2D_MULTISAMPLE:
849 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
850 /* these texture types cannot be mipmapped */
851 return FALSE;
852 }
853
854 if (stImage->base.Level > 0 || stObj->base.Attrib.GenerateMipmap)
855 return TRUE;
856
857 /* If the application has explicitly called glTextureParameter to set
858 * GL_TEXTURE_MAX_LEVEL, such that (max - base) > 0, then they're trying
859 * to communicate that they will have multiple miplevels.
860 *
861 * Core Mesa will initialize MaxLevel to value much larger than
862 * MAX_TEXTURE_LEVELS, so we check that to see if it's been set at all.
863 */
864 if (stObj->base.Attrib.MaxLevel < MAX_TEXTURE_LEVELS &&
865 stObj->base.Attrib.MaxLevel - stObj->base.Attrib.BaseLevel > 0)
866 return TRUE;
867
868 if (stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
869 stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT)
870 /* depth/stencil textures are seldom mipmapped */
871 return FALSE;
872
873 if (stObj->base.Attrib.BaseLevel == 0 && stObj->base.Attrib.MaxLevel == 0)
874 return FALSE;
875
876 if (stObj->base.Sampler.Attrib.MinFilter == GL_NEAREST ||
877 stObj->base.Sampler.Attrib.MinFilter == GL_LINEAR)
878 /* not a mipmap minification filter */
879 return FALSE;
880
881 /* If the following sequence of GL calls is used:
882 * glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, ...
883 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
884 *
885 * we would needlessly allocate a mipmapped texture, because the initial
886 * MinFilter is GL_NEAREST_MIPMAP_LINEAR. Catch this case and don't
887 * allocate a mipmapped texture by default. This may cause texture
888 * reallocation later, but GL_NEAREST_MIPMAP_LINEAR is pretty rare.
889 */
890 if (stObj->base.Sampler.Attrib.MinFilter == GL_NEAREST_MIPMAP_LINEAR)
891 return FALSE;
892
893 if (stObj->base.Target == GL_TEXTURE_3D)
894 /* 3D textures are seldom mipmapped */
895 return FALSE;
896
897 return TRUE;
898 }
899
900
901 /**
902 * Try to allocate a pipe_resource object for the given st_texture_object.
903 *
904 * We use the given st_texture_image as a clue to determine the size of the
905 * mipmap image at level=0.
906 *
907 * \return GL_TRUE for success, GL_FALSE if out of memory.
908 */
909 static GLboolean
guess_and_alloc_texture(struct st_context * st,struct st_texture_object * stObj,const struct st_texture_image * stImage)910 guess_and_alloc_texture(struct st_context *st,
911 struct st_texture_object *stObj,
912 const struct st_texture_image *stImage)
913 {
914 const struct gl_texture_image *firstImage;
915 GLuint lastLevel, width, height, depth;
916 GLuint bindings;
917 unsigned ptWidth;
918 uint16_t ptHeight, ptDepth, ptLayers;
919 enum pipe_format fmt;
920 bool guessed_box = false;
921
922 DBG("%s\n", __func__);
923
924 assert(!stObj->pt);
925
926 /* If a base level image with compatible size exists, use that as our guess.
927 */
928 firstImage = _mesa_base_tex_image(&stObj->base);
929 if (firstImage &&
930 firstImage->Width2 > 0 &&
931 firstImage->Height2 > 0 &&
932 firstImage->Depth2 > 0 &&
933 guess_base_level_size(stObj->base.Target,
934 firstImage->Width2,
935 firstImage->Height2,
936 firstImage->Depth2,
937 firstImage->Level,
938 &width, &height, &depth)) {
939 if (stImage->base.Width2 == u_minify(width, stImage->base.Level) &&
940 stImage->base.Height2 == u_minify(height, stImage->base.Level) &&
941 stImage->base.Depth2 == u_minify(depth, stImage->base.Level))
942 guessed_box = true;
943 }
944
945 if (!guessed_box)
946 guessed_box = guess_base_level_size(stObj->base.Target,
947 stImage->base.Width2,
948 stImage->base.Height2,
949 stImage->base.Depth2,
950 stImage->base.Level,
951 &width, &height, &depth);
952
953 if (!guessed_box) {
954 /* we can't determine the image size at level=0 */
955 /* this is not an out of memory error */
956 return GL_TRUE;
957 }
958
959 /* At this point, (width x height x depth) is the expected size of
960 * the level=0 mipmap image.
961 */
962
963 /* Guess a reasonable value for lastLevel. With OpenGL we have no
964 * idea how many mipmap levels will be in a texture until we start
965 * to render with it. Make an educated guess here but be prepared
966 * to re-allocating a texture buffer with space for more (or fewer)
967 * mipmap levels later.
968 */
969 if (allocate_full_mipmap(stObj, stImage)) {
970 /* alloc space for a full mipmap */
971 lastLevel = _mesa_get_tex_max_num_levels(stObj->base.Target,
972 width, height, depth) - 1;
973 }
974 else {
975 /* only alloc space for a single mipmap level */
976 lastLevel = 0;
977 }
978
979 fmt = st_mesa_format_to_pipe_format(st, stImage->base.TexFormat);
980
981 bindings = default_bindings(st, fmt);
982
983 st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
984 width, height, depth,
985 &ptWidth, &ptHeight, &ptDepth, &ptLayers);
986
987 stObj->pt = st_texture_create(st,
988 gl_target_to_pipe(stObj->base.Target),
989 fmt,
990 lastLevel,
991 ptWidth,
992 ptHeight,
993 ptDepth,
994 ptLayers, 0,
995 bindings);
996
997 stObj->lastLevel = lastLevel;
998
999 DBG("%s returning %d\n", __func__, (stObj->pt != NULL));
1000
1001 return stObj->pt != NULL;
1002 }
1003
1004
1005 /**
1006 * Called via ctx->Driver.AllocTextureImageBuffer().
1007 * If the texture object/buffer already has space for the indicated image,
1008 * we're done. Otherwise, allocate memory for the new texture image.
1009 */
1010 static GLboolean
st_AllocTextureImageBuffer(struct gl_context * ctx,struct gl_texture_image * texImage)1011 st_AllocTextureImageBuffer(struct gl_context *ctx,
1012 struct gl_texture_image *texImage)
1013 {
1014 struct st_context *st = st_context(ctx);
1015 struct st_texture_image *stImage = st_texture_image(texImage);
1016 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
1017 GLuint width = texImage->Width;
1018 GLuint height = texImage->Height;
1019 GLuint depth = texImage->Depth;
1020
1021 DBG("%s\n", __func__);
1022
1023 assert(!stImage->pt); /* xxx this might be wrong */
1024
1025 stObj->needs_validation = true;
1026
1027 compressed_tex_fallback_allocate(st, stImage);
1028 const bool allowAllocateToStObj = !stObj->pt ||
1029 stObj->pt->last_level == 0 ||
1030 texImage->Level == 0;
1031
1032 if (allowAllocateToStObj) {
1033 /* Look if the parent texture object has space for this image */
1034 if (stObj->pt &&
1035 st_texture_match_image(st, stObj->pt, texImage)) {
1036 /* this image will fit in the existing texture object's memory */
1037 pipe_resource_reference(&stImage->pt, stObj->pt);
1038 assert(stImage->pt);
1039 return GL_TRUE;
1040 }
1041
1042 /* The parent texture object does not have space for this image */
1043
1044 pipe_resource_reference(&stObj->pt, NULL);
1045 st_texture_release_all_sampler_views(st, stObj);
1046
1047 if (!guess_and_alloc_texture(st, stObj, stImage)) {
1048 /* Probably out of memory.
1049 * Try flushing any pending rendering, then retry.
1050 */
1051 st_finish(st);
1052 if (!guess_and_alloc_texture(st, stObj, stImage)) {
1053 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1054 return GL_FALSE;
1055 }
1056 }
1057 }
1058
1059 if (stObj->pt &&
1060 st_texture_match_image(st, stObj->pt, texImage)) {
1061 /* The image will live in the object's mipmap memory */
1062 pipe_resource_reference(&stImage->pt, stObj->pt);
1063 assert(stImage->pt);
1064 return GL_TRUE;
1065 }
1066 else {
1067 /* Create a new, temporary texture/resource/buffer to hold this
1068 * one texture image. Note that when we later access this image
1069 * (either for mapping or copying) we'll want to always specify
1070 * mipmap level=0, even if the image represents some other mipmap
1071 * level.
1072 */
1073 enum pipe_format format =
1074 st_mesa_format_to_pipe_format(st, texImage->TexFormat);
1075 GLuint bindings = default_bindings(st, format);
1076 unsigned ptWidth;
1077 uint16_t ptHeight, ptDepth, ptLayers;
1078
1079 st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
1080 width, height, depth,
1081 &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1082
1083 stImage->pt = st_texture_create(st,
1084 gl_target_to_pipe(stObj->base.Target),
1085 format,
1086 0, /* lastLevel */
1087 ptWidth,
1088 ptHeight,
1089 ptDepth,
1090 ptLayers, 0,
1091 bindings);
1092 return stImage->pt != NULL;
1093 }
1094 }
1095
1096
1097 /**
1098 * Preparation prior to glTexImage. Basically check the 'surface_based'
1099 * field and switch to a "normal" tex image if necessary.
1100 */
1101 static void
prep_teximage(struct gl_context * ctx,struct gl_texture_image * texImage,GLenum format,GLenum type)1102 prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
1103 GLenum format, GLenum type)
1104 {
1105 struct gl_texture_object *texObj = texImage->TexObject;
1106 struct st_texture_object *stObj = st_texture_object(texObj);
1107
1108 /* switch to "normal" */
1109 if (stObj->surface_based) {
1110 const GLenum target = texObj->Target;
1111 const GLuint level = texImage->Level;
1112 mesa_format texFormat;
1113
1114 assert(!st_texture_image(texImage)->pt);
1115 _mesa_clear_texture_object(ctx, texObj, texImage);
1116 stObj->layer_override = -1;
1117 stObj->level_override = -1;
1118 pipe_resource_reference(&stObj->pt, NULL);
1119
1120 /* oops, need to init this image again */
1121 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
1122 texImage->InternalFormat, format,
1123 type);
1124
1125 _mesa_init_teximage_fields(ctx, texImage,
1126 texImage->Width, texImage->Height,
1127 texImage->Depth, texImage->Border,
1128 texImage->InternalFormat, texFormat);
1129
1130 stObj->surface_based = GL_FALSE;
1131 }
1132 }
1133
1134
1135 /**
1136 * Return a writemask for the gallium blit. The parameters can be base
1137 * formats or "format" from glDrawPixels/glTexImage/glGetTexImage.
1138 */
1139 unsigned
st_get_blit_mask(GLenum srcFormat,GLenum dstFormat)1140 st_get_blit_mask(GLenum srcFormat, GLenum dstFormat)
1141 {
1142 switch (dstFormat) {
1143 case GL_DEPTH_STENCIL:
1144 switch (srcFormat) {
1145 case GL_DEPTH_STENCIL:
1146 return PIPE_MASK_ZS;
1147 case GL_DEPTH_COMPONENT:
1148 return PIPE_MASK_Z;
1149 case GL_STENCIL_INDEX:
1150 return PIPE_MASK_S;
1151 default:
1152 assert(0);
1153 return 0;
1154 }
1155
1156 case GL_DEPTH_COMPONENT:
1157 switch (srcFormat) {
1158 case GL_DEPTH_STENCIL:
1159 case GL_DEPTH_COMPONENT:
1160 return PIPE_MASK_Z;
1161 default:
1162 assert(0);
1163 return 0;
1164 }
1165
1166 case GL_STENCIL_INDEX:
1167 switch (srcFormat) {
1168 case GL_DEPTH_STENCIL:
1169 case GL_STENCIL_INDEX:
1170 return PIPE_MASK_S;
1171 default:
1172 assert(0);
1173 return 0;
1174 }
1175
1176 default:
1177 return PIPE_MASK_RGBA;
1178 }
1179 }
1180
1181 /**
1182 * Converts format to a format with the same components, types
1183 * and sizes, but with the components in RGBA order.
1184 */
1185 static enum pipe_format
unswizzle_format(enum pipe_format format)1186 unswizzle_format(enum pipe_format format)
1187 {
1188 switch (format)
1189 {
1190 case PIPE_FORMAT_B8G8R8A8_UNORM:
1191 case PIPE_FORMAT_A8R8G8B8_UNORM:
1192 case PIPE_FORMAT_A8B8G8R8_UNORM:
1193 return PIPE_FORMAT_R8G8B8A8_UNORM;
1194
1195 case PIPE_FORMAT_B10G10R10A2_UNORM:
1196 return PIPE_FORMAT_R10G10B10A2_UNORM;
1197
1198 case PIPE_FORMAT_B10G10R10A2_SNORM:
1199 return PIPE_FORMAT_R10G10B10A2_SNORM;
1200
1201 case PIPE_FORMAT_B10G10R10A2_UINT:
1202 return PIPE_FORMAT_R10G10B10A2_UINT;
1203
1204 default:
1205 return format;
1206 }
1207 }
1208
1209
1210 /**
1211 * Converts PIPE_FORMAT_A* to PIPE_FORMAT_R*.
1212 */
1213 static enum pipe_format
alpha_to_red(enum pipe_format format)1214 alpha_to_red(enum pipe_format format)
1215 {
1216 switch (format)
1217 {
1218 case PIPE_FORMAT_A8_UNORM:
1219 return PIPE_FORMAT_R8_UNORM;
1220 case PIPE_FORMAT_A8_SNORM:
1221 return PIPE_FORMAT_R8_SNORM;
1222 case PIPE_FORMAT_A8_UINT:
1223 return PIPE_FORMAT_R8_UINT;
1224 case PIPE_FORMAT_A8_SINT:
1225 return PIPE_FORMAT_R8_SINT;
1226
1227 case PIPE_FORMAT_A16_UNORM:
1228 return PIPE_FORMAT_R16_UNORM;
1229 case PIPE_FORMAT_A16_SNORM:
1230 return PIPE_FORMAT_R16_SNORM;
1231 case PIPE_FORMAT_A16_UINT:
1232 return PIPE_FORMAT_R16_UINT;
1233 case PIPE_FORMAT_A16_SINT:
1234 return PIPE_FORMAT_R16_SINT;
1235 case PIPE_FORMAT_A16_FLOAT:
1236 return PIPE_FORMAT_R16_FLOAT;
1237
1238 case PIPE_FORMAT_A32_UINT:
1239 return PIPE_FORMAT_R32_UINT;
1240 case PIPE_FORMAT_A32_SINT:
1241 return PIPE_FORMAT_R32_SINT;
1242 case PIPE_FORMAT_A32_FLOAT:
1243 return PIPE_FORMAT_R32_FLOAT;
1244
1245 default:
1246 return format;
1247 }
1248 }
1249
1250
1251 /**
1252 * Converts PIPE_FORMAT_R*A* to PIPE_FORMAT_R*G*.
1253 */
1254 static enum pipe_format
red_alpha_to_red_green(enum pipe_format format)1255 red_alpha_to_red_green(enum pipe_format format)
1256 {
1257 switch (format)
1258 {
1259 case PIPE_FORMAT_R8A8_UNORM:
1260 return PIPE_FORMAT_R8G8_UNORM;
1261 case PIPE_FORMAT_R8A8_SNORM:
1262 return PIPE_FORMAT_R8G8_SNORM;
1263 case PIPE_FORMAT_R8A8_UINT:
1264 return PIPE_FORMAT_R8G8_UINT;
1265 case PIPE_FORMAT_R8A8_SINT:
1266 return PIPE_FORMAT_R8G8_SINT;
1267
1268 case PIPE_FORMAT_R16A16_UNORM:
1269 return PIPE_FORMAT_R16G16_UNORM;
1270 case PIPE_FORMAT_R16A16_SNORM:
1271 return PIPE_FORMAT_R16G16_SNORM;
1272 case PIPE_FORMAT_R16A16_UINT:
1273 return PIPE_FORMAT_R16G16_UINT;
1274 case PIPE_FORMAT_R16A16_SINT:
1275 return PIPE_FORMAT_R16G16_SINT;
1276 case PIPE_FORMAT_R16A16_FLOAT:
1277 return PIPE_FORMAT_R16G16_FLOAT;
1278
1279 case PIPE_FORMAT_R32A32_UINT:
1280 return PIPE_FORMAT_R32G32_UINT;
1281 case PIPE_FORMAT_R32A32_SINT:
1282 return PIPE_FORMAT_R32G32_SINT;
1283 case PIPE_FORMAT_R32A32_FLOAT:
1284 return PIPE_FORMAT_R32G32_FLOAT;
1285
1286 default:
1287 return format;
1288 }
1289 }
1290
1291
1292 /**
1293 * Converts PIPE_FORMAT_L*A* to PIPE_FORMAT_R*G*.
1294 */
1295 static enum pipe_format
luminance_alpha_to_red_green(enum pipe_format format)1296 luminance_alpha_to_red_green(enum pipe_format format)
1297 {
1298 switch (format)
1299 {
1300 case PIPE_FORMAT_L8A8_UNORM:
1301 return PIPE_FORMAT_R8G8_UNORM;
1302 case PIPE_FORMAT_L8A8_SNORM:
1303 return PIPE_FORMAT_R8G8_SNORM;
1304 case PIPE_FORMAT_L8A8_UINT:
1305 return PIPE_FORMAT_R8G8_UINT;
1306 case PIPE_FORMAT_L8A8_SINT:
1307 return PIPE_FORMAT_R8G8_SINT;
1308
1309 case PIPE_FORMAT_L16A16_UNORM:
1310 return PIPE_FORMAT_R16G16_UNORM;
1311 case PIPE_FORMAT_L16A16_SNORM:
1312 return PIPE_FORMAT_R16G16_SNORM;
1313 case PIPE_FORMAT_L16A16_UINT:
1314 return PIPE_FORMAT_R16G16_UINT;
1315 case PIPE_FORMAT_L16A16_SINT:
1316 return PIPE_FORMAT_R16G16_SINT;
1317 case PIPE_FORMAT_L16A16_FLOAT:
1318 return PIPE_FORMAT_R16G16_FLOAT;
1319
1320 case PIPE_FORMAT_L32A32_UINT:
1321 return PIPE_FORMAT_R32G32_UINT;
1322 case PIPE_FORMAT_L32A32_SINT:
1323 return PIPE_FORMAT_R32G32_SINT;
1324 case PIPE_FORMAT_L32A32_FLOAT:
1325 return PIPE_FORMAT_R32G32_FLOAT;
1326
1327 default:
1328 return format;
1329 }
1330 }
1331
1332
1333 /**
1334 * Returns true if format is a PIPE_FORMAT_A* format, and false otherwise.
1335 */
1336 static bool
format_is_alpha(enum pipe_format format)1337 format_is_alpha(enum pipe_format format)
1338 {
1339 const struct util_format_description *desc = util_format_description(format);
1340
1341 if (desc->nr_channels == 1 &&
1342 desc->swizzle[0] == PIPE_SWIZZLE_0 &&
1343 desc->swizzle[1] == PIPE_SWIZZLE_0 &&
1344 desc->swizzle[2] == PIPE_SWIZZLE_0 &&
1345 desc->swizzle[3] == PIPE_SWIZZLE_X)
1346 return true;
1347
1348 return false;
1349 }
1350
1351
1352 /**
1353 * Returns true if format is a PIPE_FORMAT_R* format, and false otherwise.
1354 */
1355 static bool
format_is_red(enum pipe_format format)1356 format_is_red(enum pipe_format format)
1357 {
1358 const struct util_format_description *desc = util_format_description(format);
1359
1360 if (desc->nr_channels == 1 &&
1361 desc->swizzle[0] == PIPE_SWIZZLE_X &&
1362 desc->swizzle[1] == PIPE_SWIZZLE_0 &&
1363 desc->swizzle[2] == PIPE_SWIZZLE_0 &&
1364 desc->swizzle[3] == PIPE_SWIZZLE_1)
1365 return true;
1366
1367 return false;
1368 }
1369
1370
1371 /**
1372 * Returns true if format is a PIPE_FORMAT_L* format, and false otherwise.
1373 */
1374 static bool
format_is_luminance(enum pipe_format format)1375 format_is_luminance(enum pipe_format format)
1376 {
1377 const struct util_format_description *desc = util_format_description(format);
1378
1379 if (desc->nr_channels == 1 &&
1380 desc->swizzle[0] == PIPE_SWIZZLE_X &&
1381 desc->swizzle[1] == PIPE_SWIZZLE_X &&
1382 desc->swizzle[2] == PIPE_SWIZZLE_X &&
1383 desc->swizzle[3] == PIPE_SWIZZLE_1)
1384 return true;
1385
1386 return false;
1387 }
1388
1389 /**
1390 * Returns true if format is a PIPE_FORMAT_R*A* format, and false otherwise.
1391 */
1392 static bool
format_is_red_alpha(enum pipe_format format)1393 format_is_red_alpha(enum pipe_format format)
1394 {
1395 const struct util_format_description *desc = util_format_description(format);
1396
1397 if (desc->nr_channels == 2 &&
1398 desc->swizzle[0] == PIPE_SWIZZLE_X &&
1399 desc->swizzle[1] == PIPE_SWIZZLE_0 &&
1400 desc->swizzle[2] == PIPE_SWIZZLE_0 &&
1401 desc->swizzle[3] == PIPE_SWIZZLE_Y)
1402 return true;
1403
1404 return false;
1405 }
1406
1407
1408 static bool
format_is_swizzled_rgba(enum pipe_format format)1409 format_is_swizzled_rgba(enum pipe_format format)
1410 {
1411 const struct util_format_description *desc = util_format_description(format);
1412
1413 if ((desc->swizzle[0] == TGSI_SWIZZLE_X || desc->swizzle[0] == PIPE_SWIZZLE_0) &&
1414 (desc->swizzle[1] == TGSI_SWIZZLE_Y || desc->swizzle[1] == PIPE_SWIZZLE_0) &&
1415 (desc->swizzle[2] == TGSI_SWIZZLE_Z || desc->swizzle[2] == PIPE_SWIZZLE_0) &&
1416 (desc->swizzle[3] == TGSI_SWIZZLE_W || desc->swizzle[3] == PIPE_SWIZZLE_1))
1417 return false;
1418
1419 return true;
1420 }
1421
1422
1423 struct format_table
1424 {
1425 unsigned char swizzle[4];
1426 enum pipe_format format;
1427 };
1428
1429 static const struct format_table table_8888_unorm[] = {
1430 { { 0, 1, 2, 3 }, PIPE_FORMAT_R8G8B8A8_UNORM },
1431 { { 2, 1, 0, 3 }, PIPE_FORMAT_B8G8R8A8_UNORM },
1432 { { 3, 0, 1, 2 }, PIPE_FORMAT_A8R8G8B8_UNORM },
1433 { { 3, 2, 1, 0 }, PIPE_FORMAT_A8B8G8R8_UNORM }
1434 };
1435
1436 static const struct format_table table_1010102_unorm[] = {
1437 { { 0, 1, 2, 3 }, PIPE_FORMAT_R10G10B10A2_UNORM },
1438 { { 2, 1, 0, 3 }, PIPE_FORMAT_B10G10R10A2_UNORM }
1439 };
1440
1441 static const struct format_table table_1010102_snorm[] = {
1442 { { 0, 1, 2, 3 }, PIPE_FORMAT_R10G10B10A2_SNORM },
1443 { { 2, 1, 0, 3 }, PIPE_FORMAT_B10G10R10A2_SNORM }
1444 };
1445
1446 static const struct format_table table_1010102_uint[] = {
1447 { { 0, 1, 2, 3 }, PIPE_FORMAT_R10G10B10A2_UINT },
1448 { { 2, 1, 0, 3 }, PIPE_FORMAT_B10G10R10A2_UINT }
1449 };
1450
1451 static enum pipe_format
swizzle_format(enum pipe_format format,const int * const swizzle)1452 swizzle_format(enum pipe_format format, const int * const swizzle)
1453 {
1454 unsigned i;
1455
1456 switch (format) {
1457 case PIPE_FORMAT_R8G8B8A8_UNORM:
1458 case PIPE_FORMAT_B8G8R8A8_UNORM:
1459 case PIPE_FORMAT_A8R8G8B8_UNORM:
1460 case PIPE_FORMAT_A8B8G8R8_UNORM:
1461 for (i = 0; i < ARRAY_SIZE(table_8888_unorm); i++) {
1462 if (swizzle[0] == table_8888_unorm[i].swizzle[0] &&
1463 swizzle[1] == table_8888_unorm[i].swizzle[1] &&
1464 swizzle[2] == table_8888_unorm[i].swizzle[2] &&
1465 swizzle[3] == table_8888_unorm[i].swizzle[3])
1466 return table_8888_unorm[i].format;
1467 }
1468 break;
1469
1470 case PIPE_FORMAT_R10G10B10A2_UNORM:
1471 case PIPE_FORMAT_B10G10R10A2_UNORM:
1472 for (i = 0; i < ARRAY_SIZE(table_1010102_unorm); i++) {
1473 if (swizzle[0] == table_1010102_unorm[i].swizzle[0] &&
1474 swizzle[1] == table_1010102_unorm[i].swizzle[1] &&
1475 swizzle[2] == table_1010102_unorm[i].swizzle[2] &&
1476 swizzle[3] == table_1010102_unorm[i].swizzle[3])
1477 return table_1010102_unorm[i].format;
1478 }
1479 break;
1480
1481 case PIPE_FORMAT_R10G10B10A2_SNORM:
1482 case PIPE_FORMAT_B10G10R10A2_SNORM:
1483 for (i = 0; i < ARRAY_SIZE(table_1010102_snorm); i++) {
1484 if (swizzle[0] == table_1010102_snorm[i].swizzle[0] &&
1485 swizzle[1] == table_1010102_snorm[i].swizzle[1] &&
1486 swizzle[2] == table_1010102_snorm[i].swizzle[2] &&
1487 swizzle[3] == table_1010102_snorm[i].swizzle[3])
1488 return table_1010102_snorm[i].format;
1489 }
1490 break;
1491
1492 case PIPE_FORMAT_R10G10B10A2_UINT:
1493 case PIPE_FORMAT_B10G10R10A2_UINT:
1494 for (i = 0; i < ARRAY_SIZE(table_1010102_uint); i++) {
1495 if (swizzle[0] == table_1010102_uint[i].swizzle[0] &&
1496 swizzle[1] == table_1010102_uint[i].swizzle[1] &&
1497 swizzle[2] == table_1010102_uint[i].swizzle[2] &&
1498 swizzle[3] == table_1010102_uint[i].swizzle[3])
1499 return table_1010102_uint[i].format;
1500 }
1501 break;
1502
1503 default:
1504 break;
1505 }
1506
1507 return PIPE_FORMAT_NONE;
1508 }
1509
1510 static bool
reinterpret_formats(enum pipe_format * src_format,enum pipe_format * dst_format)1511 reinterpret_formats(enum pipe_format *src_format, enum pipe_format *dst_format)
1512 {
1513 enum pipe_format src = *src_format;
1514 enum pipe_format dst = *dst_format;
1515
1516 /* Note: dst_format has already been transformed from luminance/intensity
1517 * to red when this function is called. The source format will never
1518 * be an intensity format, because GL_INTENSITY is not a legal value
1519 * for the format parameter in glTex(Sub)Image(). */
1520
1521 if (format_is_alpha(src)) {
1522 if (!format_is_alpha(dst))
1523 return false;
1524
1525 src = alpha_to_red(src);
1526 dst = alpha_to_red(dst);
1527 } else if (format_is_luminance(src)) {
1528 if (!format_is_red(dst) && !format_is_red_alpha(dst))
1529 return false;
1530
1531 src = util_format_luminance_to_red(src);
1532 } else if (util_format_is_luminance_alpha(src)) {
1533 src = luminance_alpha_to_red_green(src);
1534
1535 if (format_is_red_alpha(dst)) {
1536 dst = red_alpha_to_red_green(dst);
1537 } else if (!format_is_red(dst))
1538 return false;
1539 } else if (format_is_swizzled_rgba(src)) {
1540 const struct util_format_description *src_desc = util_format_description(src);
1541 const struct util_format_description *dst_desc = util_format_description(dst);
1542 int swizzle[4];
1543 unsigned i;
1544
1545 /* Make sure the format is an RGBA and not an RGBX format */
1546 if (src_desc->nr_channels != 4 || src_desc->swizzle[3] == PIPE_SWIZZLE_1)
1547 return false;
1548
1549 if (dst_desc->nr_channels != 4 || dst_desc->swizzle[3] == PIPE_SWIZZLE_1)
1550 return false;
1551
1552 for (i = 0; i < 4; i++)
1553 swizzle[i] = dst_desc->swizzle[src_desc->swizzle[i]];
1554
1555 dst = swizzle_format(dst, swizzle);
1556 if (dst == PIPE_FORMAT_NONE)
1557 return false;
1558
1559 src = unswizzle_format(src);
1560 }
1561
1562 *src_format = src;
1563 *dst_format = dst;
1564 return true;
1565 }
1566
1567 static bool
try_pbo_upload_common(struct gl_context * ctx,struct pipe_surface * surface,const struct st_pbo_addresses * addr,enum pipe_format src_format)1568 try_pbo_upload_common(struct gl_context *ctx,
1569 struct pipe_surface *surface,
1570 const struct st_pbo_addresses *addr,
1571 enum pipe_format src_format)
1572 {
1573 struct st_context *st = st_context(ctx);
1574 struct cso_context *cso = st->cso_context;
1575 struct pipe_context *pipe = st->pipe;
1576 bool success = false;
1577 void *fs;
1578
1579 fs = st_pbo_get_upload_fs(st, src_format, surface->format, addr->depth != 1);
1580 if (!fs)
1581 return false;
1582
1583 cso_save_state(cso, (CSO_BIT_VERTEX_ELEMENTS |
1584 CSO_BIT_FRAMEBUFFER |
1585 CSO_BIT_VIEWPORT |
1586 CSO_BIT_BLEND |
1587 CSO_BIT_DEPTH_STENCIL_ALPHA |
1588 CSO_BIT_RASTERIZER |
1589 CSO_BIT_STREAM_OUTPUTS |
1590 (st->active_queries ? CSO_BIT_PAUSE_QUERIES : 0) |
1591 CSO_BIT_SAMPLE_MASK |
1592 CSO_BIT_MIN_SAMPLES |
1593 CSO_BIT_RENDER_CONDITION |
1594 CSO_BITS_ALL_SHADERS));
1595
1596 cso_set_sample_mask(cso, ~0);
1597 cso_set_min_samples(cso, 1);
1598 cso_set_render_condition(cso, NULL, FALSE, 0);
1599
1600 /* Set up the sampler_view */
1601 {
1602 struct pipe_sampler_view templ;
1603 struct pipe_sampler_view *sampler_view;
1604
1605 memset(&templ, 0, sizeof(templ));
1606 templ.target = PIPE_BUFFER;
1607 templ.format = src_format;
1608 templ.u.buf.offset = addr->first_element * addr->bytes_per_pixel;
1609 templ.u.buf.size = (addr->last_element - addr->first_element + 1) *
1610 addr->bytes_per_pixel;
1611 templ.swizzle_r = PIPE_SWIZZLE_X;
1612 templ.swizzle_g = PIPE_SWIZZLE_Y;
1613 templ.swizzle_b = PIPE_SWIZZLE_Z;
1614 templ.swizzle_a = PIPE_SWIZZLE_W;
1615
1616 sampler_view = pipe->create_sampler_view(pipe, addr->buffer, &templ);
1617 if (sampler_view == NULL)
1618 goto fail;
1619
1620 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0,
1621 false, &sampler_view);
1622 st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] =
1623 MAX2(st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], 1);
1624
1625 pipe_sampler_view_reference(&sampler_view, NULL);
1626 }
1627
1628 /* Framebuffer_state */
1629 {
1630 struct pipe_framebuffer_state fb;
1631 memset(&fb, 0, sizeof(fb));
1632 fb.width = surface->width;
1633 fb.height = surface->height;
1634 fb.nr_cbufs = 1;
1635 fb.cbufs[0] = surface;
1636
1637 cso_set_framebuffer(cso, &fb);
1638 }
1639
1640 cso_set_viewport_dims(cso, surface->width, surface->height, FALSE);
1641
1642 /* Blend state */
1643 cso_set_blend(cso, &st->pbo.upload_blend);
1644
1645 /* Depth/stencil/alpha state */
1646 {
1647 struct pipe_depth_stencil_alpha_state dsa;
1648 memset(&dsa, 0, sizeof(dsa));
1649 cso_set_depth_stencil_alpha(cso, &dsa);
1650 }
1651
1652 /* Set up the fragment shader */
1653 cso_set_fragment_shader_handle(cso, fs);
1654
1655 success = st_pbo_draw(st, addr, surface->width, surface->height);
1656
1657 fail:
1658 /* Unbind all because st/mesa won't do it if the current shader doesn't
1659 * use them.
1660 */
1661 cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS);
1662 st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0;
1663
1664 st->dirty |= ST_NEW_VERTEX_ARRAYS |
1665 ST_NEW_FS_CONSTANTS |
1666 ST_NEW_FS_SAMPLER_VIEWS;
1667
1668 return success;
1669 }
1670
1671
1672 static bool
try_pbo_upload(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLenum format,GLenum type,enum pipe_format dst_format,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,const void * pixels,const struct gl_pixelstore_attrib * unpack)1673 try_pbo_upload(struct gl_context *ctx, GLuint dims,
1674 struct gl_texture_image *texImage,
1675 GLenum format, GLenum type,
1676 enum pipe_format dst_format,
1677 GLint xoffset, GLint yoffset, GLint zoffset,
1678 GLint width, GLint height, GLint depth,
1679 const void *pixels,
1680 const struct gl_pixelstore_attrib *unpack)
1681 {
1682 struct st_context *st = st_context(ctx);
1683 struct st_texture_image *stImage = st_texture_image(texImage);
1684 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
1685 struct pipe_resource *texture = stImage->pt;
1686 struct pipe_context *pipe = st->pipe;
1687 struct pipe_screen *screen = st->screen;
1688 struct pipe_surface *surface = NULL;
1689 struct st_pbo_addresses addr;
1690 enum pipe_format src_format;
1691 const struct util_format_description *desc;
1692 GLenum gl_target = texImage->TexObject->Target;
1693 bool success;
1694
1695 if (!st->pbo.upload_enabled)
1696 return false;
1697
1698 /* From now on, we need the gallium representation of dimensions. */
1699 if (gl_target == GL_TEXTURE_1D_ARRAY) {
1700 depth = height;
1701 height = 1;
1702 zoffset = yoffset;
1703 yoffset = 0;
1704 }
1705
1706 if (depth != 1 && !st->pbo.layers)
1707 return false;
1708
1709 /* Choose the source format. Initially, we do so without checking driver
1710 * support at all because of the remapping we later perform and because
1711 * at least the Radeon driver actually supports some formats for texture
1712 * buffers which it doesn't support for regular textures. */
1713 src_format = st_choose_matching_format(st, 0, format, type,
1714 unpack->SwapBytes);
1715 if (!src_format) {
1716 return false;
1717 }
1718
1719 src_format = util_format_linear(src_format);
1720 desc = util_format_description(src_format);
1721
1722 if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
1723 return false;
1724
1725 if (desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB)
1726 return false;
1727
1728 if (st->pbo.rgba_only) {
1729 enum pipe_format orig_dst_format = dst_format;
1730
1731 if (!reinterpret_formats(&src_format, &dst_format)) {
1732 return false;
1733 }
1734
1735 if (dst_format != orig_dst_format &&
1736 !screen->is_format_supported(screen, dst_format, PIPE_TEXTURE_2D, 0,
1737 0, PIPE_BIND_RENDER_TARGET)) {
1738 return false;
1739 }
1740 }
1741
1742 if (!src_format ||
1743 !screen->is_format_supported(screen, src_format, PIPE_BUFFER, 0, 0,
1744 PIPE_BIND_SAMPLER_VIEW)) {
1745 return false;
1746 }
1747
1748 /* Compute buffer addresses */
1749 addr.xoffset = xoffset;
1750 addr.yoffset = yoffset;
1751 addr.width = width;
1752 addr.height = height;
1753 addr.depth = depth;
1754 addr.bytes_per_pixel = desc->block.bits / 8;
1755
1756 if (!st_pbo_addresses_pixelstore(st, gl_target, dims == 3, unpack, pixels,
1757 &addr))
1758 return false;
1759
1760 /* Set up the surface */
1761 {
1762 unsigned level = stObj->pt != stImage->pt
1763 ? 0 : texImage->TexObject->Attrib.MinLevel + texImage->Level;
1764 unsigned max_layer = util_max_layer(texture, level);
1765
1766 zoffset += texImage->Face + texImage->TexObject->Attrib.MinLayer;
1767
1768 struct pipe_surface templ;
1769 memset(&templ, 0, sizeof(templ));
1770 templ.format = dst_format;
1771 templ.u.tex.level = level;
1772 templ.u.tex.first_layer = MIN2(zoffset, max_layer);
1773 templ.u.tex.last_layer = MIN2(zoffset + depth - 1, max_layer);
1774
1775 surface = pipe->create_surface(pipe, texture, &templ);
1776 if (!surface)
1777 return false;
1778 }
1779
1780 success = try_pbo_upload_common(ctx, surface, &addr, src_format);
1781
1782 pipe_surface_reference(&surface, NULL);
1783
1784 return success;
1785 }
1786
1787 static bool
try_pbo_download(struct st_context * st,struct gl_texture_image * texImage,enum pipe_format src_format,enum pipe_format dst_format,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,const struct gl_pixelstore_attrib * pack,void * pixels)1788 try_pbo_download(struct st_context *st,
1789 struct gl_texture_image *texImage,
1790 enum pipe_format src_format, enum pipe_format dst_format,
1791 GLint xoffset, GLint yoffset, GLint zoffset,
1792 GLint width, GLint height, GLint depth,
1793 const struct gl_pixelstore_attrib *pack, void *pixels)
1794 {
1795 struct st_texture_image *stImage = st_texture_image(texImage);
1796 struct pipe_context *pipe = st->pipe;
1797 struct pipe_screen *screen = pipe->screen;
1798 struct pipe_resource *texture = stImage->pt;
1799 struct cso_context *cso = st->cso_context;
1800 const struct util_format_description *desc;
1801 struct st_pbo_addresses addr;
1802 struct pipe_framebuffer_state fb;
1803 enum pipe_texture_target pipe_target;
1804 GLenum gl_target = texImage->TexObject->Target;
1805 GLuint dims;
1806 bool success = false;
1807
1808 if (texture->nr_samples > 1)
1809 return false;
1810
1811 /* GetTexImage only returns a single face for cubemaps. */
1812 if (gl_target == GL_TEXTURE_CUBE_MAP) {
1813 gl_target = GL_TEXTURE_2D;
1814 }
1815 if (gl_target == GL_TEXTURE_CUBE_MAP_ARRAY) {
1816 gl_target = GL_TEXTURE_2D_ARRAY;
1817 }
1818 pipe_target = gl_target_to_pipe(gl_target);
1819 dims = _mesa_get_texture_dimensions(gl_target);
1820
1821 /* From now on, we need the gallium representation of dimensions. */
1822 if (gl_target == GL_TEXTURE_1D_ARRAY) {
1823 depth = height;
1824 height = 1;
1825 zoffset = yoffset;
1826 yoffset = 0;
1827 }
1828
1829 if (depth != 1 && !st->pbo.layers)
1830 return false;
1831
1832 if (!screen->is_format_supported(screen, dst_format, PIPE_BUFFER, 0, 0,
1833 PIPE_BIND_SHADER_IMAGE) ||
1834 util_format_is_compressed(src_format) ||
1835 util_format_is_compressed(dst_format))
1836 return false;
1837
1838 desc = util_format_description(dst_format);
1839
1840 /* Compute PBO addresses */
1841 addr.bytes_per_pixel = desc->block.bits / 8;
1842 addr.xoffset = xoffset;
1843 addr.yoffset = yoffset;
1844 addr.width = width;
1845 addr.height = height;
1846 addr.depth = depth;
1847 if (!st_pbo_addresses_pixelstore(st, gl_target, dims == 3, pack, pixels, &addr))
1848 return false;
1849
1850 cso_save_state(cso, (CSO_BIT_VERTEX_ELEMENTS |
1851 CSO_BIT_FRAMEBUFFER |
1852 CSO_BIT_VIEWPORT |
1853 CSO_BIT_BLEND |
1854 CSO_BIT_DEPTH_STENCIL_ALPHA |
1855 CSO_BIT_RASTERIZER |
1856 CSO_BIT_STREAM_OUTPUTS |
1857 (st->active_queries ? CSO_BIT_PAUSE_QUERIES : 0) |
1858 CSO_BIT_SAMPLE_MASK |
1859 CSO_BIT_MIN_SAMPLES |
1860 CSO_BIT_RENDER_CONDITION |
1861 CSO_BITS_ALL_SHADERS));
1862
1863 cso_set_sample_mask(cso, ~0);
1864 cso_set_min_samples(cso, 1);
1865 cso_set_render_condition(cso, NULL, FALSE, 0);
1866
1867 /* Set up the sampler_view */
1868 {
1869 struct pipe_sampler_view templ;
1870 struct pipe_sampler_view *sampler_view;
1871 struct pipe_sampler_state sampler = {0};
1872 const struct pipe_sampler_state *samplers[1] = {&sampler};
1873 unsigned level = texImage->TexObject->Attrib.MinLevel + texImage->Level;
1874 unsigned max_layer = util_max_layer(texture, level);
1875
1876 u_sampler_view_default_template(&templ, texture, src_format);
1877
1878 templ.target = pipe_target;
1879 templ.u.tex.first_level = level;
1880 templ.u.tex.last_level = templ.u.tex.first_level;
1881
1882 zoffset += texImage->Face + texImage->TexObject->Attrib.MinLayer;
1883 templ.u.tex.first_layer = MIN2(zoffset, max_layer);
1884 templ.u.tex.last_layer = MIN2(zoffset + depth - 1, max_layer);
1885
1886 sampler_view = pipe->create_sampler_view(pipe, texture, &templ);
1887 if (sampler_view == NULL)
1888 goto fail;
1889
1890 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, true, &sampler_view);
1891 sampler_view = NULL;
1892
1893 cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, samplers);
1894 }
1895
1896 /* Set up destination image */
1897 {
1898 struct pipe_image_view image;
1899
1900 memset(&image, 0, sizeof(image));
1901 image.resource = addr.buffer;
1902 image.format = dst_format;
1903 image.access = PIPE_IMAGE_ACCESS_WRITE;
1904 image.shader_access = PIPE_IMAGE_ACCESS_WRITE;
1905 image.u.buf.offset = addr.first_element * addr.bytes_per_pixel;
1906 image.u.buf.size = (addr.last_element - addr.first_element + 1) *
1907 addr.bytes_per_pixel;
1908
1909 pipe->set_shader_images(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, &image);
1910 }
1911
1912 /* Set up no-attachment framebuffer */
1913 memset(&fb, 0, sizeof(fb));
1914 fb.width = texture->width0;
1915 fb.height = texture->height0;
1916 fb.layers = 1;
1917 fb.samples = 1;
1918 cso_set_framebuffer(cso, &fb);
1919
1920 /* Any blend state would do. Set this just to prevent drivers having
1921 * blend == NULL.
1922 */
1923 cso_set_blend(cso, &st->pbo.upload_blend);
1924
1925 cso_set_viewport_dims(cso, fb.width, fb.height, FALSE);
1926
1927 {
1928 struct pipe_depth_stencil_alpha_state dsa;
1929 memset(&dsa, 0, sizeof(dsa));
1930 cso_set_depth_stencil_alpha(cso, &dsa);
1931 }
1932
1933 /* Set up the fragment shader */
1934 {
1935 void *fs = st_pbo_get_download_fs(st, pipe_target, src_format, dst_format, addr.depth != 1);
1936 if (!fs)
1937 goto fail;
1938
1939 cso_set_fragment_shader_handle(cso, fs);
1940 }
1941
1942 success = st_pbo_draw(st, &addr, fb.width, fb.height);
1943
1944 /* Buffer written via shader images needs explicit synchronization. */
1945 pipe->memory_barrier(pipe, PIPE_BARRIER_IMAGE | PIPE_BARRIER_TEXTURE | PIPE_BARRIER_FRAMEBUFFER);
1946
1947 fail:
1948 /* Unbind all because st/mesa won't do it if the current shader doesn't
1949 * use them.
1950 */
1951 cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS | CSO_UNBIND_FS_IMAGE0);
1952 st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0;
1953
1954 st->dirty |= ST_NEW_FS_CONSTANTS |
1955 ST_NEW_FS_IMAGES |
1956 ST_NEW_FS_SAMPLER_VIEWS |
1957 ST_NEW_VERTEX_ARRAYS;
1958
1959 return success;
1960 }
1961
1962
1963 static void
st_TexSubImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,GLenum format,GLenum type,const void * pixels,const struct gl_pixelstore_attrib * unpack)1964 st_TexSubImage(struct gl_context *ctx, GLuint dims,
1965 struct gl_texture_image *texImage,
1966 GLint xoffset, GLint yoffset, GLint zoffset,
1967 GLint width, GLint height, GLint depth,
1968 GLenum format, GLenum type, const void *pixels,
1969 const struct gl_pixelstore_attrib *unpack)
1970 {
1971 struct st_context *st = st_context(ctx);
1972 struct st_texture_image *stImage = st_texture_image(texImage);
1973 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
1974 struct pipe_context *pipe = st->pipe;
1975 struct pipe_screen *screen = st->screen;
1976 struct pipe_resource *dst = stImage->pt;
1977 struct pipe_resource *src = NULL;
1978 struct pipe_resource src_templ;
1979 struct pipe_transfer *transfer;
1980 struct pipe_blit_info blit;
1981 enum pipe_format src_format, dst_format;
1982 mesa_format mesa_src_format;
1983 GLenum gl_target = texImage->TexObject->Target;
1984 unsigned bind;
1985 GLubyte *map;
1986 unsigned dstz = texImage->Face + texImage->TexObject->Attrib.MinLayer;
1987 unsigned dst_level = 0;
1988 bool throttled = false;
1989
1990 st_flush_bitmap_cache(st);
1991 st_invalidate_readpix_cache(st);
1992
1993 if (stObj->pt == stImage->pt)
1994 dst_level = texImage->TexObject->Attrib.MinLevel + texImage->Level;
1995
1996 assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
1997 !_mesa_is_format_astc_2d(texImage->TexFormat) &&
1998 texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
1999
2000 if (!dst)
2001 goto fallback;
2002
2003 /* Try texture_subdata, which should be the fastest memcpy path. */
2004 if (pixels &&
2005 !unpack->BufferObj &&
2006 _mesa_texstore_can_use_memcpy(ctx, texImage->_BaseFormat,
2007 texImage->TexFormat, format, type,
2008 unpack)) {
2009 struct pipe_box box;
2010 unsigned stride, layer_stride;
2011 void *data;
2012
2013 stride = _mesa_image_row_stride(unpack, width, format, type);
2014 layer_stride = _mesa_image_image_stride(unpack, width, height, format,
2015 type);
2016 data = _mesa_image_address(dims, unpack, pixels, width, height, format,
2017 type, 0, 0, 0);
2018
2019 /* Convert to Gallium coordinates. */
2020 if (gl_target == GL_TEXTURE_1D_ARRAY) {
2021 zoffset = yoffset;
2022 yoffset = 0;
2023 depth = height;
2024 height = 1;
2025 layer_stride = stride;
2026 }
2027
2028 util_throttle_memory_usage(pipe, &st->throttle,
2029 (uint64_t) width * height * depth *
2030 util_format_get_blocksize(dst->format));
2031
2032 u_box_3d(xoffset, yoffset, zoffset + dstz, width, height, depth, &box);
2033 pipe->texture_subdata(pipe, dst, dst_level, 0,
2034 &box, data, stride, layer_stride);
2035 return;
2036 }
2037
2038 if (!st->prefer_blit_based_texture_transfer) {
2039 goto fallback;
2040 }
2041
2042 /* XXX Fallback for depth-stencil formats due to an incomplete stencil
2043 * blit implementation in some drivers. */
2044 if (format == GL_DEPTH_STENCIL) {
2045 goto fallback;
2046 }
2047
2048 /* If the base internal format and the texture format don't match,
2049 * we can't use blit-based TexSubImage. */
2050 if (texImage->_BaseFormat !=
2051 _mesa_get_format_base_format(texImage->TexFormat)) {
2052 goto fallback;
2053 }
2054
2055
2056 /* See if the destination format is supported. */
2057 if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
2058 bind = PIPE_BIND_DEPTH_STENCIL;
2059 else
2060 bind = PIPE_BIND_RENDER_TARGET;
2061
2062 /* For luminance and intensity, only the red channel is stored
2063 * in the destination. */
2064 dst_format = util_format_linear(dst->format);
2065 dst_format = util_format_luminance_to_red(dst_format);
2066 dst_format = util_format_intensity_to_red(dst_format);
2067
2068 if (!dst_format ||
2069 !screen->is_format_supported(screen, dst_format, dst->target,
2070 dst->nr_samples, dst->nr_storage_samples,
2071 bind)) {
2072 goto fallback;
2073 }
2074
2075 if (unpack->BufferObj) {
2076 if (try_pbo_upload(ctx, dims, texImage, format, type, dst_format,
2077 xoffset, yoffset, zoffset,
2078 width, height, depth, pixels, unpack))
2079 return;
2080 }
2081
2082 /* See if the texture format already matches the format and type,
2083 * in which case the memcpy-based fast path will likely be used and
2084 * we don't have to blit. */
2085 if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
2086 type, unpack->SwapBytes, NULL)) {
2087 goto fallback;
2088 }
2089
2090 /* Choose the source format. */
2091 src_format = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
2092 format, type, unpack->SwapBytes);
2093 if (!src_format) {
2094 goto fallback;
2095 }
2096
2097 mesa_src_format = st_pipe_format_to_mesa_format(src_format);
2098
2099 /* There is no reason to do this if we cannot use memcpy for the temporary
2100 * source texture at least. This also takes transfer ops into account,
2101 * etc. */
2102 if (!_mesa_texstore_can_use_memcpy(ctx,
2103 _mesa_get_format_base_format(mesa_src_format),
2104 mesa_src_format, format, type, unpack)) {
2105 goto fallback;
2106 }
2107
2108 /* TexSubImage only sets a single cubemap face. */
2109 if (gl_target == GL_TEXTURE_CUBE_MAP) {
2110 gl_target = GL_TEXTURE_2D;
2111 }
2112 /* TexSubImage can specify subsets of cube map array faces
2113 * so we need to upload via 2D array instead */
2114 if (gl_target == GL_TEXTURE_CUBE_MAP_ARRAY) {
2115 gl_target = GL_TEXTURE_2D_ARRAY;
2116 }
2117
2118 /* Initialize the source texture description. */
2119 memset(&src_templ, 0, sizeof(src_templ));
2120 src_templ.target = gl_target_to_pipe(gl_target);
2121 src_templ.format = src_format;
2122 src_templ.bind = PIPE_BIND_SAMPLER_VIEW;
2123 src_templ.usage = PIPE_USAGE_STAGING;
2124
2125 st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
2126 &src_templ.width0, &src_templ.height0,
2127 &src_templ.depth0, &src_templ.array_size);
2128
2129 /* Check for NPOT texture support. */
2130 if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES) &&
2131 (!util_is_power_of_two_or_zero(src_templ.width0) ||
2132 !util_is_power_of_two_or_zero(src_templ.height0) ||
2133 !util_is_power_of_two_or_zero(src_templ.depth0))) {
2134 goto fallback;
2135 }
2136
2137 util_throttle_memory_usage(pipe, &st->throttle,
2138 (uint64_t) width * height * depth *
2139 util_format_get_blocksize(src_templ.format));
2140 throttled = true;
2141
2142 /* Create the source texture. */
2143 src = screen->resource_create(screen, &src_templ);
2144 if (!src) {
2145 goto fallback;
2146 }
2147
2148 /* Map source pixels. */
2149 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
2150 format, type, pixels, unpack,
2151 "glTexSubImage");
2152 if (!pixels) {
2153 /* This is a GL error. */
2154 pipe_resource_reference(&src, NULL);
2155 return;
2156 }
2157
2158 /* From now on, we need the gallium representation of dimensions. */
2159 if (gl_target == GL_TEXTURE_1D_ARRAY) {
2160 zoffset = yoffset;
2161 yoffset = 0;
2162 depth = height;
2163 height = 1;
2164 }
2165
2166 map = pipe_texture_map_3d(pipe, src, 0, PIPE_MAP_WRITE, 0, 0, 0,
2167 width, height, depth, &transfer);
2168 if (!map) {
2169 _mesa_unmap_teximage_pbo(ctx, unpack);
2170 pipe_resource_reference(&src, NULL);
2171 goto fallback;
2172 }
2173
2174 /* Upload pixels (just memcpy). */
2175 {
2176 const uint bytesPerRow = width * util_format_get_blocksize(src_format);
2177 GLuint row, slice;
2178
2179 for (slice = 0; slice < (unsigned) depth; slice++) {
2180 if (gl_target == GL_TEXTURE_1D_ARRAY) {
2181 /* 1D array textures.
2182 * We need to convert gallium coords to GL coords.
2183 */
2184 void *src = _mesa_image_address2d(unpack, pixels,
2185 width, depth, format,
2186 type, slice, 0);
2187 memcpy(map, src, bytesPerRow);
2188 }
2189 else {
2190 ubyte *slice_map = map;
2191
2192 for (row = 0; row < (unsigned) height; row++) {
2193 void *src = _mesa_image_address(dims, unpack, pixels,
2194 width, height, format,
2195 type, slice, row, 0);
2196 memcpy(slice_map, src, bytesPerRow);
2197 slice_map += transfer->stride;
2198 }
2199 }
2200 map += transfer->layer_stride;
2201 }
2202 }
2203
2204 pipe_texture_unmap(pipe, transfer);
2205 _mesa_unmap_teximage_pbo(ctx, unpack);
2206
2207 /* Blit. */
2208 memset(&blit, 0, sizeof(blit));
2209 blit.src.resource = src;
2210 blit.src.level = 0;
2211 blit.src.format = src_format;
2212 blit.dst.resource = dst;
2213 blit.dst.level = dst_level;
2214 blit.dst.format = dst_format;
2215 blit.src.box.x = blit.src.box.y = blit.src.box.z = 0;
2216 blit.dst.box.x = xoffset;
2217 blit.dst.box.y = yoffset;
2218 blit.dst.box.z = zoffset + dstz;
2219 blit.src.box.width = blit.dst.box.width = width;
2220 blit.src.box.height = blit.dst.box.height = height;
2221 blit.src.box.depth = blit.dst.box.depth = depth;
2222 blit.mask = st_get_blit_mask(format, texImage->_BaseFormat);
2223 blit.filter = PIPE_TEX_FILTER_NEAREST;
2224 blit.scissor_enable = FALSE;
2225
2226 st->pipe->blit(st->pipe, &blit);
2227
2228 pipe_resource_reference(&src, NULL);
2229 return;
2230
2231 fallback:
2232 if (!throttled) {
2233 util_throttle_memory_usage(pipe, &st->throttle,
2234 (uint64_t) width * height * depth *
2235 _mesa_get_format_bytes(texImage->TexFormat));
2236 }
2237 _mesa_store_texsubimage(ctx, dims, texImage, xoffset, yoffset, zoffset,
2238 width, height, depth, format, type, pixels,
2239 unpack);
2240 }
2241
2242
2243 static void
st_TexImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLenum format,GLenum type,const void * pixels,const struct gl_pixelstore_attrib * unpack)2244 st_TexImage(struct gl_context * ctx, GLuint dims,
2245 struct gl_texture_image *texImage,
2246 GLenum format, GLenum type, const void *pixels,
2247 const struct gl_pixelstore_attrib *unpack)
2248 {
2249 assert(dims == 1 || dims == 2 || dims == 3);
2250
2251 prep_teximage(ctx, texImage, format, type);
2252
2253 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
2254 return;
2255
2256 /* allocate storage for texture data */
2257 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
2258 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
2259 return;
2260 }
2261
2262 st_TexSubImage(ctx, dims, texImage, 0, 0, 0,
2263 texImage->Width, texImage->Height, texImage->Depth,
2264 format, type, pixels, unpack);
2265 }
2266
2267 static bool
st_try_pbo_compressed_texsubimage(struct gl_context * ctx,struct pipe_resource * buf,intptr_t buf_offset,const struct st_pbo_addresses * addr_tmpl,struct pipe_resource * texture,const struct pipe_surface * surface_templ)2268 st_try_pbo_compressed_texsubimage(struct gl_context *ctx,
2269 struct pipe_resource *buf,
2270 intptr_t buf_offset,
2271 const struct st_pbo_addresses *addr_tmpl,
2272 struct pipe_resource *texture,
2273 const struct pipe_surface *surface_templ)
2274 {
2275 struct st_context *st = st_context(ctx);
2276 struct pipe_context *pipe = st->pipe;
2277 struct st_pbo_addresses addr;
2278 struct pipe_surface *surface = NULL;
2279 bool success;
2280
2281 addr = *addr_tmpl;
2282 if (!st_pbo_addresses_setup(st, buf, buf_offset, &addr))
2283 return false;
2284
2285 surface = pipe->create_surface(pipe, texture, surface_templ);
2286 if (!surface)
2287 return false;
2288
2289 success = try_pbo_upload_common(ctx, surface, &addr, surface_templ->format);
2290
2291 pipe_surface_reference(&surface, NULL);
2292
2293 return success;
2294 }
2295
2296 static void
st_CompressedTexSubImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint x,GLint y,GLint z,GLsizei w,GLsizei h,GLsizei d,GLenum format,GLsizei imageSize,const void * data)2297 st_CompressedTexSubImage(struct gl_context *ctx, GLuint dims,
2298 struct gl_texture_image *texImage,
2299 GLint x, GLint y, GLint z,
2300 GLsizei w, GLsizei h, GLsizei d,
2301 GLenum format, GLsizei imageSize, const void *data)
2302 {
2303 struct st_context *st = st_context(ctx);
2304 struct st_texture_image *stImage = st_texture_image(texImage);
2305 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
2306 struct pipe_resource *buf;
2307 struct pipe_resource *texture = stImage->pt;
2308 struct pipe_screen *screen = st->screen;
2309 struct pipe_resource *dst = stImage->pt;
2310 struct pipe_surface templ;
2311 struct compressed_pixelstore store;
2312 struct st_pbo_addresses addr;
2313 enum pipe_format copy_format;
2314 unsigned bw, bh, level, max_layer;
2315 int layer;
2316 intptr_t buf_offset;
2317 bool success = false;
2318
2319 /* Check basic pre-conditions for PBO upload */
2320 if (!st->prefer_blit_based_texture_transfer) {
2321 goto fallback;
2322 }
2323
2324 if (!ctx->Unpack.BufferObj)
2325 goto fallback;
2326
2327 if (st_compressed_format_fallback(st, texImage->TexFormat))
2328 goto fallback;
2329
2330 if (!dst) {
2331 goto fallback;
2332 }
2333
2334 if (!st->pbo.upload_enabled ||
2335 !screen->get_param(screen, PIPE_CAP_SURFACE_REINTERPRET_BLOCKS)) {
2336 goto fallback;
2337 }
2338
2339 /* Choose the pipe format for the upload. */
2340 addr.bytes_per_pixel = util_format_get_blocksize(dst->format);
2341 bw = util_format_get_blockwidth(dst->format);
2342 bh = util_format_get_blockheight(dst->format);
2343
2344 switch (addr.bytes_per_pixel) {
2345 case 8:
2346 copy_format = PIPE_FORMAT_R16G16B16A16_UINT;
2347 break;
2348 case 16:
2349 copy_format = PIPE_FORMAT_R32G32B32A32_UINT;
2350 break;
2351 default:
2352 goto fallback;
2353 }
2354
2355 if (!screen->is_format_supported(screen, copy_format, PIPE_BUFFER, 0, 0,
2356 PIPE_BIND_SAMPLER_VIEW)) {
2357 goto fallback;
2358 }
2359
2360 if (!screen->is_format_supported(screen, copy_format, dst->target,
2361 dst->nr_samples, dst->nr_storage_samples,
2362 PIPE_BIND_RENDER_TARGET)) {
2363 goto fallback;
2364 }
2365
2366 /* Interpret the pixelstore settings. */
2367 _mesa_compute_compressed_pixelstore(dims, texImage->TexFormat, w, h, d,
2368 &ctx->Unpack, &store);
2369 assert(store.CopyBytesPerRow % addr.bytes_per_pixel == 0);
2370 assert(store.SkipBytes % addr.bytes_per_pixel == 0);
2371
2372 /* Compute the offset into the buffer */
2373 buf_offset = (intptr_t)data + store.SkipBytes;
2374
2375 if (buf_offset % addr.bytes_per_pixel) {
2376 goto fallback;
2377 }
2378
2379 buf_offset = buf_offset / addr.bytes_per_pixel;
2380
2381 buf = st_buffer_object(ctx->Unpack.BufferObj)->buffer;
2382
2383 addr.xoffset = x / bw;
2384 addr.yoffset = y / bh;
2385 addr.width = store.CopyBytesPerRow / addr.bytes_per_pixel;
2386 addr.height = store.CopyRowsPerSlice;
2387 addr.depth = d;
2388 addr.pixels_per_row = store.TotalBytesPerRow / addr.bytes_per_pixel;
2389 addr.image_height = store.TotalRowsPerSlice;
2390
2391 /* Set up the surface. */
2392 level = stObj->pt != stImage->pt
2393 ? 0 : texImage->TexObject->Attrib.MinLevel + texImage->Level;
2394 max_layer = util_max_layer(texture, level);
2395 layer = z + texImage->Face + texImage->TexObject->Attrib.MinLayer;
2396
2397 memset(&templ, 0, sizeof(templ));
2398 templ.format = copy_format;
2399 templ.u.tex.level = level;
2400 templ.u.tex.first_layer = MIN2(layer, max_layer);
2401 templ.u.tex.last_layer = MIN2(layer + d - 1, max_layer);
2402
2403 if (st_try_pbo_compressed_texsubimage(ctx, buf, buf_offset, &addr,
2404 texture, &templ))
2405 return;
2406
2407 /* Some drivers can re-interpret surfaces but only one layer at a time.
2408 * Fall back to doing a single try_pbo_upload_common per layer.
2409 */
2410 while (layer <= max_layer) {
2411 templ.u.tex.first_layer = MIN2(layer, max_layer);
2412 templ.u.tex.last_layer = templ.u.tex.first_layer;
2413 if (!st_try_pbo_compressed_texsubimage(ctx, buf, buf_offset, &addr,
2414 texture, &templ))
2415 goto fallback;
2416
2417 /* By incrementing layer here, we ensure the fallback only uploads
2418 * layers we failed to upload.
2419 */
2420 buf_offset += addr.pixels_per_row * addr.image_height;
2421 layer++;
2422 addr.depth--;
2423 }
2424
2425 if (success)
2426 return;
2427
2428 fallback:
2429 _mesa_store_compressed_texsubimage(ctx, dims, texImage,
2430 x, y, z, w, h, d,
2431 format, imageSize, data);
2432 }
2433
2434
2435 static void
st_CompressedTexImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLsizei imageSize,const void * data)2436 st_CompressedTexImage(struct gl_context *ctx, GLuint dims,
2437 struct gl_texture_image *texImage,
2438 GLsizei imageSize, const void *data)
2439 {
2440 prep_teximage(ctx, texImage, GL_NONE, GL_NONE);
2441
2442 /* only 2D and 3D compressed images are supported at this time */
2443 if (dims == 1) {
2444 _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call");
2445 return;
2446 }
2447
2448 /* This is pretty simple, because unlike the general texstore path we don't
2449 * have to worry about the usual image unpacking or image transfer
2450 * operations.
2451 */
2452 assert(texImage);
2453 assert(texImage->Width > 0);
2454 assert(texImage->Height > 0);
2455 assert(texImage->Depth > 0);
2456
2457 /* allocate storage for texture data */
2458 if (!st_AllocTextureImageBuffer(ctx, texImage)) {
2459 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims);
2460 return;
2461 }
2462
2463 st_CompressedTexSubImage(ctx, dims, texImage,
2464 0, 0, 0,
2465 texImage->Width, texImage->Height, texImage->Depth,
2466 texImage->TexFormat,
2467 imageSize, data);
2468 }
2469
2470
2471 /**
2472 * Called via ctx->Driver.GetTexSubImage()
2473 *
2474 * This uses a blit to copy the texture to a texture format which matches
2475 * the format and type combo and then a fast read-back is done using memcpy.
2476 * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is
2477 * a format which matches the swizzling.
2478 *
2479 * If such a format isn't available, it falls back to _mesa_GetTexImage_sw.
2480 *
2481 * NOTE: Drivers usually do a blit to convert between tiled and linear
2482 * texture layouts during texture uploads/downloads, so the blit
2483 * we do here should be free in such cases.
2484 */
2485 static void
st_GetTexSubImage(struct gl_context * ctx,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLint depth,GLenum format,GLenum type,void * pixels,struct gl_texture_image * texImage)2486 st_GetTexSubImage(struct gl_context * ctx,
2487 GLint xoffset, GLint yoffset, GLint zoffset,
2488 GLsizei width, GLsizei height, GLint depth,
2489 GLenum format, GLenum type, void * pixels,
2490 struct gl_texture_image *texImage)
2491 {
2492 struct st_context *st = st_context(ctx);
2493 struct pipe_screen *screen = st->screen;
2494 struct st_texture_image *stImage = st_texture_image(texImage);
2495 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
2496 struct pipe_resource *src = stObj->pt;
2497 struct pipe_resource *dst = NULL;
2498 enum pipe_format dst_format, src_format;
2499 GLenum gl_target = texImage->TexObject->Target;
2500 enum pipe_texture_target pipe_target;
2501 struct pipe_blit_info blit;
2502 unsigned bind;
2503 boolean done = FALSE;
2504
2505 assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
2506 !_mesa_is_format_astc_2d(texImage->TexFormat) &&
2507 texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
2508
2509 st_flush_bitmap_cache(st);
2510
2511 /* GetTexImage only returns a single face for cubemaps. */
2512 if (gl_target == GL_TEXTURE_CUBE_MAP) {
2513 gl_target = GL_TEXTURE_2D;
2514 }
2515 pipe_target = gl_target_to_pipe(gl_target);
2516
2517 if (!st->prefer_blit_based_texture_transfer &&
2518 !_mesa_is_format_compressed(texImage->TexFormat)) {
2519 /* Try to avoid the fallback if we're doing texture decompression here */
2520 goto fallback;
2521 }
2522
2523 /* Handle non-finalized textures. */
2524 if (!stImage->pt || stImage->pt != stObj->pt || !src) {
2525 goto fallback;
2526 }
2527
2528 /* XXX Fallback to _mesa_GetTexImage_sw for depth-stencil formats
2529 * due to an incomplete stencil blit implementation in some drivers. */
2530 if (format == GL_DEPTH_STENCIL || format == GL_STENCIL_INDEX) {
2531 goto fallback;
2532 }
2533
2534 /* If the base internal format and the texture format don't match, we have
2535 * to fall back to _mesa_GetTexImage_sw. */
2536 if (texImage->_BaseFormat !=
2537 _mesa_get_format_base_format(texImage->TexFormat)) {
2538 goto fallback;
2539 }
2540
2541 src_format = get_src_format(screen, stObj->surface_based ? stObj->surface_format : src->format, src);
2542 if (src_format == PIPE_FORMAT_NONE)
2543 goto fallback;
2544
2545 if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
2546 bind = PIPE_BIND_DEPTH_STENCIL;
2547 else
2548 bind = PIPE_BIND_RENDER_TARGET;
2549
2550 dst_format = get_dst_format(ctx, pipe_target, src_format, util_format_is_compressed(src->format),
2551 format, type, bind);
2552 if (dst_format == PIPE_FORMAT_NONE)
2553 goto fallback;
2554
2555 if (st->pbo.download_enabled && ctx->Pack.BufferObj) {
2556 if (try_pbo_download(st, texImage,
2557 src_format, dst_format,
2558 xoffset, yoffset, zoffset,
2559 width, height, depth,
2560 &ctx->Pack, pixels))
2561 return;
2562 }
2563
2564 /* See if the texture format already matches the format and type,
2565 * in which case the memcpy-based fast path will be used. */
2566 if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
2567 type, ctx->Pack.SwapBytes, NULL))
2568 goto fallback;
2569
2570 dst = create_dst_texture(ctx, dst_format, pipe_target, width, height, depth, gl_target, bind);
2571 if (!dst)
2572 goto fallback;
2573
2574 /* From now on, we need the gallium representation of dimensions. */
2575 if (gl_target == GL_TEXTURE_1D_ARRAY) {
2576 zoffset = yoffset;
2577 yoffset = 0;
2578 depth = height;
2579 height = 1;
2580 }
2581
2582 assert(texImage->Face == 0 ||
2583 texImage->TexObject->Attrib.MinLayer == 0 ||
2584 zoffset == 0);
2585
2586 memset(&blit, 0, sizeof(blit));
2587 blit.src.resource = src;
2588 blit.src.level = texImage->Level + texImage->TexObject->Attrib.MinLevel;
2589 blit.src.format = src_format;
2590 blit.dst.resource = dst;
2591 blit.dst.level = 0;
2592 blit.dst.format = dst->format;
2593 blit.src.box.x = xoffset;
2594 blit.dst.box.x = 0;
2595 blit.src.box.y = yoffset;
2596 blit.dst.box.y = 0;
2597 blit.src.box.z = texImage->Face + texImage->TexObject->Attrib.MinLayer + zoffset;
2598 blit.dst.box.z = 0;
2599 blit.src.box.width = blit.dst.box.width = width;
2600 blit.src.box.height = blit.dst.box.height = height;
2601 blit.src.box.depth = blit.dst.box.depth = depth;
2602 blit.mask = st_get_blit_mask(texImage->_BaseFormat, format);
2603 blit.filter = PIPE_TEX_FILTER_NEAREST;
2604 blit.scissor_enable = FALSE;
2605
2606 /* blit/render/decompress */
2607 st->pipe->blit(st->pipe, &blit);
2608
2609 done = copy_to_staging_dest(ctx, dst, xoffset, yoffset, zoffset, width, height,
2610 depth, format, type, pixels, texImage);
2611 pipe_resource_reference(&dst, NULL);
2612
2613 fallback:
2614 if (!done) {
2615 _mesa_GetTexSubImage_sw(ctx, xoffset, yoffset, zoffset,
2616 width, height, depth,
2617 format, type, pixels, texImage);
2618 }
2619 }
2620
2621
2622 /**
2623 * Do a CopyTexSubImage operation using a read transfer from the source,
2624 * a write transfer to the destination and get_tile()/put_tile() to access
2625 * the pixels/texels.
2626 *
2627 * Note: srcY=0=TOP of renderbuffer
2628 */
2629 static void
fallback_copy_texsubimage(struct gl_context * ctx,struct st_renderbuffer * strb,struct st_texture_image * stImage,GLenum baseFormat,GLint destX,GLint destY,GLint slice,GLint srcX,GLint srcY,GLsizei width,GLsizei height)2630 fallback_copy_texsubimage(struct gl_context *ctx,
2631 struct st_renderbuffer *strb,
2632 struct st_texture_image *stImage,
2633 GLenum baseFormat,
2634 GLint destX, GLint destY, GLint slice,
2635 GLint srcX, GLint srcY,
2636 GLsizei width, GLsizei height)
2637 {
2638 struct st_context *st = st_context(ctx);
2639 struct pipe_context *pipe = st->pipe;
2640 struct pipe_transfer *src_trans;
2641 GLubyte *texDest;
2642 enum pipe_map_flags transfer_usage;
2643 void *map;
2644 unsigned dst_width = width;
2645 unsigned dst_height = height;
2646 unsigned dst_depth = 1;
2647 struct pipe_transfer *transfer;
2648
2649 if (ST_DEBUG & DEBUG_FALLBACK)
2650 debug_printf("%s: fallback processing\n", __func__);
2651
2652 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
2653 srcY = strb->Base.Height - srcY - height;
2654 }
2655
2656 map = pipe_texture_map(pipe,
2657 strb->texture,
2658 strb->surface->u.tex.level,
2659 strb->surface->u.tex.first_layer,
2660 PIPE_MAP_READ,
2661 srcX, srcY,
2662 width, height, &src_trans);
2663 if (!map) {
2664 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
2665 return;
2666 }
2667
2668 if ((baseFormat == GL_DEPTH_COMPONENT ||
2669 baseFormat == GL_DEPTH_STENCIL) &&
2670 util_format_is_depth_and_stencil(stImage->pt->format))
2671 transfer_usage = PIPE_MAP_READ_WRITE;
2672 else
2673 transfer_usage = PIPE_MAP_WRITE;
2674
2675 texDest = st_texture_image_map(st, stImage, transfer_usage,
2676 destX, destY, slice,
2677 dst_width, dst_height, dst_depth,
2678 &transfer);
2679 if (!texDest) {
2680 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
2681 goto err;
2682 }
2683
2684 if (baseFormat == GL_DEPTH_COMPONENT ||
2685 baseFormat == GL_DEPTH_STENCIL) {
2686 const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
2687 ctx->Pixel.DepthBias != 0.0F);
2688 GLint row, yStep;
2689 uint *data;
2690
2691 /* determine bottom-to-top vs. top-to-bottom order for src buffer */
2692 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
2693 srcY = height - 1;
2694 yStep = -1;
2695 }
2696 else {
2697 srcY = 0;
2698 yStep = 1;
2699 }
2700
2701 data = malloc(width * sizeof(uint));
2702
2703 if (data) {
2704 unsigned dst_stride = (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY ?
2705 transfer->layer_stride : transfer->stride);
2706 /* To avoid a large temp memory allocation, do copy row by row */
2707 for (row = 0; row < height; row++, srcY += yStep) {
2708 util_format_unpack_z_32unorm(strb->texture->format,
2709 data, (uint8_t *)map + src_trans->stride * srcY,
2710 width);
2711 if (scaleOrBias) {
2712 _mesa_scale_and_bias_depth_uint(ctx, width, data);
2713 }
2714
2715 util_format_pack_z_32unorm(stImage->pt->format,
2716 texDest + row * dst_stride, data, width);
2717 }
2718 }
2719 else {
2720 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
2721 }
2722
2723 free(data);
2724 }
2725 else {
2726 /* RGBA format */
2727 GLfloat *tempSrc =
2728 malloc(width * height * 4 * sizeof(GLfloat));
2729
2730 if (tempSrc) {
2731 const GLint dims = 2;
2732 GLint dstRowStride;
2733 struct gl_texture_image *texImage = &stImage->base;
2734 struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
2735
2736 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
2737 unpack.Invert = GL_TRUE;
2738 }
2739
2740 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
2741 dstRowStride = transfer->layer_stride;
2742 }
2743 else {
2744 dstRowStride = transfer->stride;
2745 }
2746
2747 /* get float/RGBA image from framebuffer */
2748 /* XXX this usually involves a lot of int/float conversion.
2749 * try to avoid that someday.
2750 */
2751 pipe_get_tile_rgba(src_trans, map, 0, 0, width, height,
2752 util_format_linear(strb->texture->format),
2753 tempSrc);
2754
2755 /* Store into texture memory.
2756 * Note that this does some special things such as pixel transfer
2757 * ops and format conversion. In particular, if the dest tex format
2758 * is actually RGBA but the user created the texture as GL_RGB we
2759 * need to fill-in/override the alpha channel with 1.0.
2760 */
2761 _mesa_texstore(ctx, dims,
2762 texImage->_BaseFormat,
2763 texImage->TexFormat,
2764 dstRowStride,
2765 &texDest,
2766 width, height, 1,
2767 GL_RGBA, GL_FLOAT, tempSrc, /* src */
2768 &unpack);
2769 }
2770 else {
2771 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
2772 }
2773
2774 free(tempSrc);
2775 }
2776
2777 st_texture_image_unmap(st, stImage, slice);
2778 err:
2779 pipe->texture_unmap(pipe, src_trans);
2780 }
2781
2782
2783 static bool
st_can_copyteximage_using_blit(const struct gl_texture_image * texImage,const struct gl_renderbuffer * rb)2784 st_can_copyteximage_using_blit(const struct gl_texture_image *texImage,
2785 const struct gl_renderbuffer *rb)
2786 {
2787 GLenum tex_baseformat = _mesa_get_format_base_format(texImage->TexFormat);
2788
2789 /* We don't blit to a teximage where the GL base format doesn't match the
2790 * texture's chosen format, except in the case of a GL_RGB texture
2791 * represented with GL_RGBA (where the alpha channel is just being
2792 * dropped).
2793 */
2794 if (texImage->_BaseFormat != tex_baseformat &&
2795 ((texImage->_BaseFormat != GL_RGB || tex_baseformat != GL_RGBA))) {
2796 return false;
2797 }
2798
2799 /* We can't blit from a RB where the GL base format doesn't match the RB's
2800 * chosen format (for example, GL RGB or ALPHA with rb->Format of an RGBA
2801 * type, because the other channels will be undefined).
2802 */
2803 if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format))
2804 return false;
2805
2806 return true;
2807 }
2808
2809
2810 /**
2811 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
2812 * Note that the region to copy has already been clipped so we know we
2813 * won't read from outside the source renderbuffer's bounds.
2814 *
2815 * Note: srcY=0=Bottom of renderbuffer (GL convention)
2816 */
2817 static void
st_CopyTexSubImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint destX,GLint destY,GLint slice,struct gl_renderbuffer * rb,GLint srcX,GLint srcY,GLsizei width,GLsizei height)2818 st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
2819 struct gl_texture_image *texImage,
2820 GLint destX, GLint destY, GLint slice,
2821 struct gl_renderbuffer *rb,
2822 GLint srcX, GLint srcY, GLsizei width, GLsizei height)
2823 {
2824 struct st_texture_image *stImage = st_texture_image(texImage);
2825 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
2826 struct st_renderbuffer *strb = st_renderbuffer(rb);
2827 struct st_context *st = st_context(ctx);
2828 struct pipe_context *pipe = st->pipe;
2829 struct pipe_screen *screen = st->screen;
2830 struct pipe_blit_info blit;
2831 enum pipe_format dst_format;
2832 GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
2833 unsigned bind;
2834 GLint srcY0, srcY1;
2835
2836 st_flush_bitmap_cache(st);
2837 st_invalidate_readpix_cache(st);
2838
2839 assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
2840 !_mesa_is_format_astc_2d(texImage->TexFormat) &&
2841 texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
2842
2843 if (!strb || !strb->surface || !stImage->pt) {
2844 debug_printf("%s: null strb or stImage\n", __func__);
2845 return;
2846 }
2847
2848 if (_mesa_texstore_needs_transfer_ops(ctx, texImage->_BaseFormat,
2849 texImage->TexFormat)) {
2850 goto fallback;
2851 }
2852
2853 if (!st_can_copyteximage_using_blit(texImage, rb)) {
2854 goto fallback;
2855 }
2856
2857 /* Choose the destination format to match the TexImage behavior. */
2858 dst_format = util_format_linear(stImage->pt->format);
2859 dst_format = util_format_luminance_to_red(dst_format);
2860 dst_format = util_format_intensity_to_red(dst_format);
2861
2862 /* See if the destination format is supported. */
2863 if (texImage->_BaseFormat == GL_DEPTH_STENCIL ||
2864 texImage->_BaseFormat == GL_DEPTH_COMPONENT) {
2865 bind = PIPE_BIND_DEPTH_STENCIL;
2866 }
2867 else {
2868 bind = PIPE_BIND_RENDER_TARGET;
2869 }
2870
2871 if (!dst_format ||
2872 !screen->is_format_supported(screen, dst_format, stImage->pt->target,
2873 stImage->pt->nr_samples,
2874 stImage->pt->nr_storage_samples, bind)) {
2875 goto fallback;
2876 }
2877
2878 /* Y flipping for the main framebuffer. */
2879 if (do_flip) {
2880 srcY1 = strb->Base.Height - srcY - height;
2881 srcY0 = srcY1 + height;
2882 }
2883 else {
2884 srcY0 = srcY;
2885 srcY1 = srcY0 + height;
2886 }
2887
2888 /* Blit the texture.
2889 * This supports flipping, format conversions, and downsampling.
2890 */
2891 memset(&blit, 0, sizeof(blit));
2892 blit.src.resource = strb->texture;
2893 blit.src.format = util_format_linear(strb->surface->format);
2894 blit.src.level = strb->surface->u.tex.level;
2895 blit.src.box.x = srcX;
2896 blit.src.box.y = srcY0;
2897 blit.src.box.z = strb->surface->u.tex.first_layer;
2898 blit.src.box.width = width;
2899 blit.src.box.height = srcY1 - srcY0;
2900 blit.src.box.depth = 1;
2901 blit.dst.resource = stImage->pt;
2902 blit.dst.format = dst_format;
2903 blit.dst.level = stObj->pt != stImage->pt
2904 ? 0 : texImage->Level + texImage->TexObject->Attrib.MinLevel;
2905 blit.dst.box.x = destX;
2906 blit.dst.box.y = destY;
2907 blit.dst.box.z = stImage->base.Face + slice +
2908 texImage->TexObject->Attrib.MinLayer;
2909 blit.dst.box.width = width;
2910 blit.dst.box.height = height;
2911 blit.dst.box.depth = 1;
2912 blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);
2913 blit.filter = PIPE_TEX_FILTER_NEAREST;
2914 pipe->blit(pipe, &blit);
2915 return;
2916
2917 fallback:
2918 /* software fallback */
2919 fallback_copy_texsubimage(ctx,
2920 strb, stImage, texImage->_BaseFormat,
2921 destX, destY, slice,
2922 srcX, srcY, width, height);
2923 }
2924
2925
2926 /**
2927 * Copy image data from stImage into the texture object 'stObj' at level
2928 * 'dstLevel'.
2929 */
2930 static void
copy_image_data_to_texture(struct st_context * st,struct st_texture_object * stObj,GLuint dstLevel,struct st_texture_image * stImage)2931 copy_image_data_to_texture(struct st_context *st,
2932 struct st_texture_object *stObj,
2933 GLuint dstLevel,
2934 struct st_texture_image *stImage)
2935 {
2936 /* debug checks */
2937 {
2938 ASSERTED const struct gl_texture_image *dstImage =
2939 stObj->base.Image[stImage->base.Face][dstLevel];
2940 assert(dstImage);
2941 assert(dstImage->Width == stImage->base.Width);
2942 assert(dstImage->Height == stImage->base.Height);
2943 assert(dstImage->Depth == stImage->base.Depth);
2944 }
2945
2946 if (stImage->pt) {
2947 /* Copy potentially with the blitter:
2948 */
2949 GLuint src_level;
2950 if (stImage->pt->last_level == 0)
2951 src_level = 0;
2952 else
2953 src_level = stImage->base.Level;
2954
2955 assert(src_level <= stImage->pt->last_level);
2956 assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width);
2957 assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY ||
2958 u_minify(stImage->pt->height0, src_level) == stImage->base.Height);
2959 assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY ||
2960 stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY ||
2961 u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth);
2962
2963 st_texture_image_copy(st->pipe,
2964 stObj->pt, dstLevel, /* dest texture, level */
2965 stImage->pt, src_level, /* src texture, level */
2966 stImage->base.Face);
2967
2968 pipe_resource_reference(&stImage->pt, NULL);
2969 }
2970 pipe_resource_reference(&stImage->pt, stObj->pt);
2971 }
2972
2973
2974 /**
2975 * Called during state validation. When this function is finished,
2976 * the texture object should be ready for rendering.
2977 * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
2978 */
2979 GLboolean
st_finalize_texture(struct gl_context * ctx,struct pipe_context * pipe,struct gl_texture_object * tObj,GLuint cubeMapFace)2980 st_finalize_texture(struct gl_context *ctx,
2981 struct pipe_context *pipe,
2982 struct gl_texture_object *tObj,
2983 GLuint cubeMapFace)
2984 {
2985 struct st_context *st = st_context(ctx);
2986 struct st_texture_object *stObj = st_texture_object(tObj);
2987 const GLuint nr_faces = _mesa_num_tex_faces(stObj->base.Target);
2988 GLuint face;
2989 const struct st_texture_image *firstImage;
2990 enum pipe_format firstImageFormat;
2991 unsigned ptWidth;
2992 uint16_t ptHeight, ptDepth, ptLayers, ptNumSamples;
2993
2994 if (tObj->Immutable)
2995 return GL_TRUE;
2996
2997 if (tObj->_MipmapComplete)
2998 stObj->lastLevel = stObj->base._MaxLevel;
2999 else if (tObj->_BaseComplete)
3000 stObj->lastLevel = stObj->base.Attrib.BaseLevel;
3001
3002 /* Skip the loop over images in the common case of no images having
3003 * changed. But if the GL_BASE_LEVEL or GL_MAX_LEVEL change to something we
3004 * haven't looked at, then we do need to look at those new images.
3005 */
3006 if (!stObj->needs_validation &&
3007 stObj->base.Attrib.BaseLevel >= stObj->validated_first_level &&
3008 stObj->lastLevel <= stObj->validated_last_level) {
3009 return GL_TRUE;
3010 }
3011
3012 /* If this texture comes from a window system, there is nothing else to do. */
3013 if (stObj->surface_based) {
3014 return GL_TRUE;
3015 }
3016
3017 firstImage = st_texture_image_const(stObj->base.Image[cubeMapFace]
3018 [stObj->base.Attrib.BaseLevel]);
3019 if (!firstImage)
3020 return false;
3021
3022 /* If both firstImage and stObj point to a texture which can contain
3023 * all active images, favour firstImage. Note that because of the
3024 * completeness requirement, we know that the image dimensions
3025 * will match.
3026 */
3027 if (firstImage->pt &&
3028 firstImage->pt != stObj->pt &&
3029 (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
3030 pipe_resource_reference(&stObj->pt, firstImage->pt);
3031 st_texture_release_all_sampler_views(st, stObj);
3032 }
3033
3034 /* Find gallium format for the Mesa texture */
3035 firstImageFormat =
3036 st_mesa_format_to_pipe_format(st, firstImage->base.TexFormat);
3037
3038 /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
3039 {
3040 unsigned width;
3041 uint16_t height, depth;
3042
3043 st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
3044 firstImage->base.Width2,
3045 firstImage->base.Height2,
3046 firstImage->base.Depth2,
3047 &width, &height, &depth, &ptLayers);
3048
3049 /* If we previously allocated a pipe texture and its sizes are
3050 * compatible, use them.
3051 */
3052 if (stObj->pt &&
3053 u_minify(stObj->pt->width0, firstImage->base.Level) == width &&
3054 u_minify(stObj->pt->height0, firstImage->base.Level) == height &&
3055 u_minify(stObj->pt->depth0, firstImage->base.Level) == depth) {
3056 ptWidth = stObj->pt->width0;
3057 ptHeight = stObj->pt->height0;
3058 ptDepth = stObj->pt->depth0;
3059 } else {
3060 /* Otherwise, compute a new level=0 size that is compatible with the
3061 * base level image.
3062 */
3063 ptWidth = width > 1 ? width << firstImage->base.Level : 1;
3064 ptHeight = height > 1 ? height << firstImage->base.Level : 1;
3065 ptDepth = depth > 1 ? depth << firstImage->base.Level : 1;
3066
3067 /* If the base level image is 1x1x1, we still need to ensure that the
3068 * resulting pipe texture ends up with the required number of levels
3069 * in total.
3070 */
3071 if (ptWidth == 1 && ptHeight == 1 && ptDepth == 1) {
3072 ptWidth <<= firstImage->base.Level;
3073
3074 if (stObj->base.Target == GL_TEXTURE_CUBE_MAP ||
3075 stObj->base.Target == GL_TEXTURE_CUBE_MAP_ARRAY)
3076 ptHeight = ptWidth;
3077 }
3078
3079 /* At this point, the texture may be incomplete (mismatched cube
3080 * face sizes, for example). If that's the case, give up, but
3081 * don't return GL_FALSE as that would raise an incorrect
3082 * GL_OUT_OF_MEMORY error. See Piglit fbo-incomplete-texture-03 test.
3083 */
3084 if (!stObj->base._BaseComplete) {
3085 _mesa_test_texobj_completeness(ctx, &stObj->base);
3086 if (!stObj->base._BaseComplete) {
3087 return TRUE;
3088 }
3089 }
3090 }
3091
3092 ptNumSamples = firstImage->base.NumSamples;
3093 }
3094
3095 /* If we already have a gallium texture, check that it matches the texture
3096 * object's format, target, size, num_levels, etc.
3097 */
3098 if (stObj->pt) {
3099 if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
3100 stObj->pt->format != firstImageFormat ||
3101 stObj->pt->last_level < stObj->lastLevel ||
3102 stObj->pt->width0 != ptWidth ||
3103 stObj->pt->height0 != ptHeight ||
3104 stObj->pt->depth0 != ptDepth ||
3105 stObj->pt->nr_samples != ptNumSamples ||
3106 stObj->pt->array_size != ptLayers)
3107 {
3108 /* The gallium texture does not match the Mesa texture so delete the
3109 * gallium texture now. We'll make a new one below.
3110 */
3111 pipe_resource_reference(&stObj->pt, NULL);
3112 st_texture_release_all_sampler_views(st, stObj);
3113 st->dirty |= ST_NEW_FRAMEBUFFER;
3114 }
3115 }
3116
3117 /* May need to create a new gallium texture:
3118 */
3119 if (!stObj->pt) {
3120 GLuint bindings = default_bindings(st, firstImageFormat);
3121
3122 stObj->pt = st_texture_create(st,
3123 gl_target_to_pipe(stObj->base.Target),
3124 firstImageFormat,
3125 stObj->lastLevel,
3126 ptWidth,
3127 ptHeight,
3128 ptDepth,
3129 ptLayers, ptNumSamples,
3130 bindings);
3131
3132 if (!stObj->pt) {
3133 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
3134 return GL_FALSE;
3135 }
3136 }
3137
3138 /* Pull in any images not in the object's texture:
3139 */
3140 for (face = 0; face < nr_faces; face++) {
3141 GLuint level;
3142 for (level = stObj->base.Attrib.BaseLevel; level <= stObj->lastLevel; level++) {
3143 struct st_texture_image *stImage =
3144 st_texture_image(stObj->base.Image[face][level]);
3145
3146 /* Need to import images in main memory or held in other textures.
3147 */
3148 if (stImage && stObj->pt != stImage->pt) {
3149 GLuint height;
3150 GLuint depth;
3151
3152 if (stObj->base.Target != GL_TEXTURE_1D_ARRAY)
3153 height = u_minify(ptHeight, level);
3154 else
3155 height = ptLayers;
3156
3157 if (stObj->base.Target == GL_TEXTURE_3D)
3158 depth = u_minify(ptDepth, level);
3159 else if (stObj->base.Target == GL_TEXTURE_CUBE_MAP)
3160 depth = 1;
3161 else
3162 depth = ptLayers;
3163
3164 if (level == 0 ||
3165 (stImage->base.Width == u_minify(ptWidth, level) &&
3166 stImage->base.Height == height &&
3167 stImage->base.Depth == depth)) {
3168 /* src image fits expected dest mipmap level size */
3169 copy_image_data_to_texture(st, stObj, level, stImage);
3170 }
3171 }
3172 }
3173 }
3174
3175 stObj->validated_first_level = stObj->base.Attrib.BaseLevel;
3176 stObj->validated_last_level = stObj->lastLevel;
3177 stObj->needs_validation = false;
3178
3179 return GL_TRUE;
3180 }
3181
3182
3183 /**
3184 * Allocate a new pipe_resource object
3185 * width0, height0, depth0 are the dimensions of the level 0 image
3186 * (the highest resolution). last_level indicates how many mipmap levels
3187 * to allocate storage for. For non-mipmapped textures, this will be zero.
3188 */
3189 static struct pipe_resource *
st_texture_create_from_memory(struct st_context * st,struct st_memory_object * memObj,GLuint64 offset,enum pipe_texture_target target,enum pipe_format format,GLuint last_level,GLuint width0,GLuint height0,GLuint depth0,GLuint layers,GLuint nr_samples,GLuint bind)3190 st_texture_create_from_memory(struct st_context *st,
3191 struct st_memory_object *memObj,
3192 GLuint64 offset,
3193 enum pipe_texture_target target,
3194 enum pipe_format format,
3195 GLuint last_level,
3196 GLuint width0,
3197 GLuint height0,
3198 GLuint depth0,
3199 GLuint layers,
3200 GLuint nr_samples,
3201 GLuint bind)
3202 {
3203 struct pipe_resource pt, *newtex;
3204 struct pipe_screen *screen = st->screen;
3205
3206 assert(target < PIPE_MAX_TEXTURE_TYPES);
3207 assert(width0 > 0);
3208 assert(height0 > 0);
3209 assert(depth0 > 0);
3210 if (target == PIPE_TEXTURE_CUBE)
3211 assert(layers == 6);
3212
3213 DBG("%s target %d format %s last_level %d\n", __func__,
3214 (int) target, util_format_name(format), last_level);
3215
3216 assert(format);
3217 assert(screen->is_format_supported(screen, format, target, 0, 0,
3218 PIPE_BIND_SAMPLER_VIEW));
3219
3220 memset(&pt, 0, sizeof(pt));
3221 pt.target = target;
3222 pt.format = format;
3223 pt.last_level = last_level;
3224 pt.width0 = width0;
3225 pt.height0 = height0;
3226 pt.depth0 = depth0;
3227 pt.array_size = layers;
3228 pt.usage = PIPE_USAGE_DEFAULT;
3229 pt.bind = bind;
3230 /* only set this for OpenGL textures, not renderbuffers */
3231 pt.flags = PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY;
3232 if (memObj->TextureTiling == GL_LINEAR_TILING_EXT)
3233 pt.bind |= PIPE_BIND_LINEAR;
3234
3235 pt.nr_samples = nr_samples;
3236 pt.nr_storage_samples = nr_samples;
3237
3238 newtex = screen->resource_from_memobj(screen, &pt, memObj->memory, offset);
3239
3240 assert(!newtex || pipe_is_referenced(&newtex->reference));
3241
3242 return newtex;
3243 }
3244
3245
3246 /**
3247 * Allocate texture memory for a whole mipmap stack.
3248 * Note: for multisample textures if the requested sample count is not
3249 * supported, we search for the next higher supported sample count.
3250 */
3251 static GLboolean
st_texture_storage(struct gl_context * ctx,struct gl_texture_object * texObj,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth,struct gl_memory_object * memObj,GLuint64 offset)3252 st_texture_storage(struct gl_context *ctx,
3253 struct gl_texture_object *texObj,
3254 GLsizei levels, GLsizei width,
3255 GLsizei height, GLsizei depth,
3256 struct gl_memory_object *memObj,
3257 GLuint64 offset)
3258 {
3259 const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
3260 struct gl_texture_image *texImage = texObj->Image[0][0];
3261 struct st_context *st = st_context(ctx);
3262 struct st_texture_object *stObj = st_texture_object(texObj);
3263 struct st_memory_object *smObj = st_memory_object(memObj);
3264 struct pipe_screen *screen = st->screen;
3265 unsigned ptWidth, bindings;
3266 uint16_t ptHeight, ptDepth, ptLayers;
3267 enum pipe_format fmt;
3268 GLint level;
3269 GLuint num_samples = texImage->NumSamples;
3270
3271 assert(levels > 0);
3272
3273 stObj->lastLevel = levels - 1;
3274
3275 fmt = st_mesa_format_to_pipe_format(st, texImage->TexFormat);
3276
3277 bindings = default_bindings(st, fmt);
3278
3279 if (smObj) {
3280 smObj->TextureTiling = texObj->TextureTiling;
3281 bindings |= PIPE_BIND_SHARED;
3282 }
3283
3284 if (num_samples > 0) {
3285 /* Find msaa sample count which is actually supported. For example,
3286 * if the user requests 1x but only 4x or 8x msaa is supported, we'll
3287 * choose 4x here.
3288 */
3289 enum pipe_texture_target ptarget = gl_target_to_pipe(texObj->Target);
3290 boolean found = FALSE;
3291
3292 if (ctx->Const.MaxSamples > 1 && num_samples == 1) {
3293 /* don't try num_samples = 1 with drivers that support real msaa */
3294 num_samples = 2;
3295 }
3296
3297 for (; num_samples <= ctx->Const.MaxSamples; num_samples++) {
3298 if (screen->is_format_supported(screen, fmt, ptarget,
3299 num_samples, num_samples,
3300 PIPE_BIND_SAMPLER_VIEW)) {
3301 /* Update the sample count in gl_texture_image as well. */
3302 texImage->NumSamples = num_samples;
3303 found = TRUE;
3304 break;
3305 }
3306 }
3307
3308 if (!found) {
3309 return GL_FALSE;
3310 }
3311 }
3312
3313 st_gl_texture_dims_to_pipe_dims(texObj->Target,
3314 width, height, depth,
3315 &ptWidth, &ptHeight, &ptDepth, &ptLayers);
3316
3317 pipe_resource_reference(&stObj->pt, NULL);
3318
3319 if (smObj) {
3320 stObj->pt = st_texture_create_from_memory(st,
3321 smObj,
3322 offset,
3323 gl_target_to_pipe(texObj->Target),
3324 fmt,
3325 levels - 1,
3326 ptWidth,
3327 ptHeight,
3328 ptDepth,
3329 ptLayers, num_samples,
3330 bindings);
3331 }
3332 else {
3333 stObj->pt = st_texture_create(st,
3334 gl_target_to_pipe(texObj->Target),
3335 fmt,
3336 levels - 1,
3337 ptWidth,
3338 ptHeight,
3339 ptDepth,
3340 ptLayers, num_samples,
3341 bindings);
3342 }
3343
3344 if (!stObj->pt)
3345 return GL_FALSE;
3346
3347 /* Set image resource pointers */
3348 for (level = 0; level < levels; level++) {
3349 GLuint face;
3350 for (face = 0; face < numFaces; face++) {
3351 struct st_texture_image *stImage =
3352 st_texture_image(texObj->Image[face][level]);
3353 pipe_resource_reference(&stImage->pt, stObj->pt);
3354
3355 compressed_tex_fallback_allocate(st, stImage);
3356 }
3357 }
3358
3359 /* The texture is in a validated state, so no need to check later. */
3360 stObj->needs_validation = false;
3361 stObj->validated_first_level = 0;
3362 stObj->validated_last_level = levels - 1;
3363
3364 return GL_TRUE;
3365 }
3366
3367 /**
3368 * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory
3369 * for a whole mipmap stack.
3370 */
3371 static GLboolean
st_AllocTextureStorage(struct gl_context * ctx,struct gl_texture_object * texObj,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth)3372 st_AllocTextureStorage(struct gl_context *ctx,
3373 struct gl_texture_object *texObj,
3374 GLsizei levels, GLsizei width,
3375 GLsizei height, GLsizei depth)
3376 {
3377 return st_texture_storage(ctx, texObj, levels,
3378 width, height, depth,
3379 NULL, 0);
3380 }
3381
3382
3383 static GLboolean
st_TestProxyTexImage(struct gl_context * ctx,GLenum target,GLuint numLevels,GLint level,mesa_format format,GLuint numSamples,GLint width,GLint height,GLint depth)3384 st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
3385 GLuint numLevels, GLint level,
3386 mesa_format format, GLuint numSamples,
3387 GLint width, GLint height, GLint depth)
3388 {
3389 struct st_context *st = st_context(ctx);
3390
3391 if (width == 0 || height == 0 || depth == 0) {
3392 /* zero-sized images are legal, and always fit! */
3393 return GL_TRUE;
3394 }
3395
3396 if (st->screen->can_create_resource) {
3397 /* Ask the gallium driver if the texture is too large */
3398 struct gl_texture_object *texObj =
3399 _mesa_get_current_tex_object(ctx, target);
3400 struct pipe_resource pt;
3401
3402 /* Setup the pipe_resource object
3403 */
3404 memset(&pt, 0, sizeof(pt));
3405
3406 pt.target = gl_target_to_pipe(target);
3407 pt.format = st_mesa_format_to_pipe_format(st, format);
3408 pt.nr_samples = numSamples;
3409 pt.nr_storage_samples = numSamples;
3410
3411 st_gl_texture_dims_to_pipe_dims(target,
3412 width, height, depth,
3413 &pt.width0, &pt.height0,
3414 &pt.depth0, &pt.array_size);
3415
3416 if (numLevels > 0) {
3417 /* For immutable textures we know the final number of mip levels */
3418 pt.last_level = numLevels - 1;
3419 }
3420 else if (level == 0 && (texObj->Sampler.Attrib.MinFilter == GL_LINEAR ||
3421 texObj->Sampler.Attrib.MinFilter == GL_NEAREST)) {
3422 /* assume just one mipmap level */
3423 pt.last_level = 0;
3424 }
3425 else {
3426 /* assume a full set of mipmaps */
3427 pt.last_level = util_logbase2(MAX4(width, height, depth, 0));
3428 }
3429
3430 return st->screen->can_create_resource(st->screen, &pt);
3431 }
3432 else {
3433 /* Use core Mesa fallback */
3434 return _mesa_test_proxy_teximage(ctx, target, numLevels, level, format,
3435 numSamples, width, height, depth);
3436 }
3437 }
3438
3439 static GLboolean
st_TextureView(struct gl_context * ctx,struct gl_texture_object * texObj,struct gl_texture_object * origTexObj)3440 st_TextureView(struct gl_context *ctx,
3441 struct gl_texture_object *texObj,
3442 struct gl_texture_object *origTexObj)
3443 {
3444 struct st_context *st = st_context(ctx);
3445 struct st_texture_object *orig = st_texture_object(origTexObj);
3446 struct st_texture_object *tex = st_texture_object(texObj);
3447 struct gl_texture_image *image = texObj->Image[0][0];
3448
3449 const int numFaces = _mesa_num_tex_faces(texObj->Target);
3450 const int numLevels = texObj->Attrib.NumLevels;
3451
3452 int face;
3453 int level;
3454
3455 pipe_resource_reference(&tex->pt, orig->pt);
3456
3457 /* Set image resource pointers */
3458 for (level = 0; level < numLevels; level++) {
3459 for (face = 0; face < numFaces; face++) {
3460 struct st_texture_image *stImage =
3461 st_texture_image(texObj->Image[face][level]);
3462 struct st_texture_image *origImage =
3463 st_texture_image(origTexObj->Image[face][level]);
3464 pipe_resource_reference(&stImage->pt, tex->pt);
3465 if (origImage &&
3466 origImage->compressed_data) {
3467 pipe_reference(NULL,
3468 &origImage->compressed_data->reference);
3469 stImage->compressed_data = origImage->compressed_data;
3470 }
3471 }
3472 }
3473
3474 tex->surface_based = GL_TRUE;
3475 tex->surface_format =
3476 st_mesa_format_to_pipe_format(st_context(ctx), image->TexFormat);
3477
3478 tex->lastLevel = numLevels - 1;
3479
3480 /* free texture sampler views. They need to be recreated when we
3481 * change the texture view parameters.
3482 */
3483 st_texture_release_all_sampler_views(st, tex);
3484
3485 /* The texture is in a validated state, so no need to check later. */
3486 tex->needs_validation = false;
3487 tex->validated_first_level = 0;
3488 tex->validated_last_level = numLevels - 1;
3489
3490 return GL_TRUE;
3491 }
3492
3493
3494 /**
3495 * Find the mipmap level in 'pt' which matches the level described by
3496 * 'texImage'.
3497 */
3498 static unsigned
find_mipmap_level(const struct gl_texture_image * texImage,const struct pipe_resource * pt)3499 find_mipmap_level(const struct gl_texture_image *texImage,
3500 const struct pipe_resource *pt)
3501 {
3502 const GLenum target = texImage->TexObject->Target;
3503 GLint texWidth = texImage->Width;
3504 GLint texHeight = texImage->Height;
3505 GLint texDepth = texImage->Depth;
3506 unsigned level, w;
3507 uint16_t h, d, layers;
3508
3509 st_gl_texture_dims_to_pipe_dims(target, texWidth, texHeight, texDepth,
3510 &w, &h, &d, &layers);
3511
3512 for (level = 0; level <= pt->last_level; level++) {
3513 if (u_minify(pt->width0, level) == w &&
3514 u_minify(pt->height0, level) == h &&
3515 u_minify(pt->depth0, level) == d) {
3516 return level;
3517 }
3518 }
3519
3520 /* If we get here, there must be some sort of inconsistency between
3521 * the Mesa texture object/images and the gallium resource.
3522 */
3523 debug_printf("Inconsistent textures in find_mipmap_level()\n");
3524
3525 return texImage->Level;
3526 }
3527
3528
3529 static void
st_ClearTexSubImage(struct gl_context * ctx,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,const void * clearValue)3530 st_ClearTexSubImage(struct gl_context *ctx,
3531 struct gl_texture_image *texImage,
3532 GLint xoffset, GLint yoffset, GLint zoffset,
3533 GLsizei width, GLsizei height, GLsizei depth,
3534 const void *clearValue)
3535 {
3536 static const char zeros[16] = {0};
3537 struct gl_texture_object *texObj = texImage->TexObject;
3538 struct st_texture_image *stImage = st_texture_image(texImage);
3539 struct pipe_resource *pt = stImage->pt;
3540 struct st_context *st = st_context(ctx);
3541 struct pipe_context *pipe = st->pipe;
3542 unsigned level;
3543 struct pipe_box box;
3544
3545 if (!pt)
3546 return;
3547
3548 st_flush_bitmap_cache(st);
3549 st_invalidate_readpix_cache(st);
3550
3551 u_box_3d(xoffset, yoffset, zoffset + texImage->Face,
3552 width, height, depth, &box);
3553
3554 if (pt->target == PIPE_TEXTURE_1D_ARRAY) {
3555 box.z = box.y;
3556 box.depth = box.height;
3557 box.y = 0;
3558 box.height = 1;
3559 }
3560
3561 if (texObj->Immutable) {
3562 /* The texture object has to be consistent (no "loose", per-image
3563 * gallium resources). If this texture is a view into another
3564 * texture, we have to apply the MinLevel/Layer offsets. If this is
3565 * not a texture view, the offsets will be zero.
3566 */
3567 assert(stImage->pt == st_texture_object(texObj)->pt);
3568 level = texImage->Level + texObj->Attrib.MinLevel;
3569 box.z += texObj->Attrib.MinLayer;
3570 }
3571 else {
3572 /* Texture level sizes may be inconsistent. We my have "loose",
3573 * per-image gallium resources. The texImage->Level may not match
3574 * the gallium resource texture level.
3575 */
3576 level = find_mipmap_level(texImage, pt);
3577 }
3578
3579 assert(level <= pt->last_level);
3580
3581 pipe->clear_texture(pipe, pt, level, &box, clearValue ? clearValue : zeros);
3582 }
3583
3584
3585 /**
3586 * Called via the glTexParam*() function, but only when some texture object
3587 * state has actually changed.
3588 */
3589 static void
st_TexParameter(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname)3590 st_TexParameter(struct gl_context *ctx,
3591 struct gl_texture_object *texObj, GLenum pname)
3592 {
3593 struct st_context *st = st_context(ctx);
3594 struct st_texture_object *stObj = st_texture_object(texObj);
3595
3596 switch (pname) {
3597 case GL_ALL_ATTRIB_BITS: /* meaning is all pnames, internal */
3598 case GL_TEXTURE_BASE_LEVEL:
3599 case GL_TEXTURE_MAX_LEVEL:
3600 case GL_DEPTH_TEXTURE_MODE:
3601 case GL_DEPTH_STENCIL_TEXTURE_MODE:
3602 case GL_TEXTURE_SRGB_DECODE_EXT:
3603 case GL_TEXTURE_SWIZZLE_R:
3604 case GL_TEXTURE_SWIZZLE_G:
3605 case GL_TEXTURE_SWIZZLE_B:
3606 case GL_TEXTURE_SWIZZLE_A:
3607 case GL_TEXTURE_SWIZZLE_RGBA:
3608 case GL_TEXTURE_BUFFER_SIZE:
3609 case GL_TEXTURE_BUFFER_OFFSET:
3610 /* changing any of these texture parameters means we must create
3611 * new sampler views.
3612 */
3613 st_texture_release_all_sampler_views(st, stObj);
3614 break;
3615 default:
3616 ; /* nothing */
3617 }
3618 }
3619
3620 static GLboolean
st_SetTextureStorageForMemoryObject(struct gl_context * ctx,struct gl_texture_object * texObj,struct gl_memory_object * memObj,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth,GLuint64 offset)3621 st_SetTextureStorageForMemoryObject(struct gl_context *ctx,
3622 struct gl_texture_object *texObj,
3623 struct gl_memory_object *memObj,
3624 GLsizei levels, GLsizei width,
3625 GLsizei height, GLsizei depth,
3626 GLuint64 offset)
3627 {
3628 return st_texture_storage(ctx, texObj, levels,
3629 width, height, depth,
3630 memObj, offset);
3631 }
3632
3633 static GLuint64
st_NewTextureHandle(struct gl_context * ctx,struct gl_texture_object * texObj,struct gl_sampler_object * sampObj)3634 st_NewTextureHandle(struct gl_context *ctx, struct gl_texture_object *texObj,
3635 struct gl_sampler_object *sampObj)
3636 {
3637 struct st_context *st = st_context(ctx);
3638 struct st_texture_object *stObj = st_texture_object(texObj);
3639 struct pipe_context *pipe = st->pipe;
3640 struct pipe_sampler_view *view;
3641 struct pipe_sampler_state sampler = {0};
3642
3643 if (texObj->Target != GL_TEXTURE_BUFFER) {
3644 if (!st_finalize_texture(ctx, pipe, texObj, 0))
3645 return 0;
3646
3647 st_convert_sampler(st, texObj, sampObj, 0, &sampler, false);
3648
3649 /* TODO: Clarify the interaction of ARB_bindless_texture and EXT_texture_sRGB_decode */
3650 view = st_get_texture_sampler_view_from_stobj(st, stObj, sampObj, 0,
3651 true, false);
3652 } else {
3653 view = st_get_buffer_sampler_view_from_stobj(st, stObj, false);
3654 }
3655
3656 return pipe->create_texture_handle(pipe, view, &sampler);
3657 }
3658
3659
3660 static void
st_DeleteTextureHandle(struct gl_context * ctx,GLuint64 handle)3661 st_DeleteTextureHandle(struct gl_context *ctx, GLuint64 handle)
3662 {
3663 struct st_context *st = st_context(ctx);
3664 struct pipe_context *pipe = st->pipe;
3665
3666 pipe->delete_texture_handle(pipe, handle);
3667 }
3668
3669
3670 static void
st_MakeTextureHandleResident(struct gl_context * ctx,GLuint64 handle,bool resident)3671 st_MakeTextureHandleResident(struct gl_context *ctx, GLuint64 handle,
3672 bool resident)
3673 {
3674 struct st_context *st = st_context(ctx);
3675 struct pipe_context *pipe = st->pipe;
3676
3677 pipe->make_texture_handle_resident(pipe, handle, resident);
3678 }
3679
3680
3681 static GLuint64
st_NewImageHandle(struct gl_context * ctx,struct gl_image_unit * imgObj)3682 st_NewImageHandle(struct gl_context *ctx, struct gl_image_unit *imgObj)
3683 {
3684 struct st_context *st = st_context(ctx);
3685 struct pipe_context *pipe = st->pipe;
3686 struct pipe_image_view image;
3687
3688 st_convert_image(st, imgObj, &image, GL_READ_WRITE);
3689
3690 return pipe->create_image_handle(pipe, &image);
3691 }
3692
3693
3694 static void
st_DeleteImageHandle(struct gl_context * ctx,GLuint64 handle)3695 st_DeleteImageHandle(struct gl_context *ctx, GLuint64 handle)
3696 {
3697 struct st_context *st = st_context(ctx);
3698 struct pipe_context *pipe = st->pipe;
3699
3700 pipe->delete_image_handle(pipe, handle);
3701 }
3702
3703
3704 static void
st_MakeImageHandleResident(struct gl_context * ctx,GLuint64 handle,GLenum access,bool resident)3705 st_MakeImageHandleResident(struct gl_context *ctx, GLuint64 handle,
3706 GLenum access, bool resident)
3707 {
3708 struct st_context *st = st_context(ctx);
3709 struct pipe_context *pipe = st->pipe;
3710
3711 pipe->make_image_handle_resident(pipe, handle, access, resident);
3712 }
3713
3714
3715 void
st_init_texture_functions(struct dd_function_table * functions)3716 st_init_texture_functions(struct dd_function_table *functions)
3717 {
3718 functions->ChooseTextureFormat = st_ChooseTextureFormat;
3719 functions->QueryInternalFormat = st_QueryInternalFormat;
3720 functions->TexImage = st_TexImage;
3721 functions->TexSubImage = st_TexSubImage;
3722 functions->CompressedTexSubImage = st_CompressedTexSubImage;
3723 functions->CopyTexSubImage = st_CopyTexSubImage;
3724 functions->GenerateMipmap = st_generate_mipmap;
3725
3726 functions->GetTexSubImage = st_GetTexSubImage;
3727
3728 /* compressed texture functions */
3729 functions->CompressedTexImage = st_CompressedTexImage;
3730
3731 functions->NewTextureObject = st_NewTextureObject;
3732 functions->NewTextureImage = st_NewTextureImage;
3733 functions->DeleteTextureImage = st_DeleteTextureImage;
3734 functions->DeleteTexture = st_DeleteTextureObject;
3735 functions->TextureRemovedFromShared = st_TextureReleaseAllSamplerViews;
3736 functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer;
3737 functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer;
3738 functions->MapTextureImage = st_MapTextureImage;
3739 functions->UnmapTextureImage = st_UnmapTextureImage;
3740
3741 /* XXX Temporary until we can query pipe's texture sizes */
3742 functions->TestProxyTexImage = st_TestProxyTexImage;
3743
3744 functions->AllocTextureStorage = st_AllocTextureStorage;
3745 functions->TextureView = st_TextureView;
3746 functions->ClearTexSubImage = st_ClearTexSubImage;
3747
3748 functions->TexParameter = st_TexParameter;
3749
3750 /* bindless functions */
3751 functions->NewTextureHandle = st_NewTextureHandle;
3752 functions->DeleteTextureHandle = st_DeleteTextureHandle;
3753 functions->MakeTextureHandleResident = st_MakeTextureHandleResident;
3754 functions->NewImageHandle = st_NewImageHandle;
3755 functions->DeleteImageHandle = st_DeleteImageHandle;
3756 functions->MakeImageHandleResident = st_MakeImageHandleResident;
3757
3758 /* external object functions */
3759 functions->SetTextureStorageForMemoryObject = st_SetTextureStorageForMemoryObject;
3760 }
3761