1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2015 Intel Corporation. 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 "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Jason Ekstrand <jason.ekstrand (at) intel.com> 26 */ 27 28 #include "blend.h" 29 #include "bufferobj.h" 30 #include "buffers.h" 31 #include "clear.h" 32 #include "fbobject.h" 33 #include "framebuffer.h" 34 #include "glformats.h" 35 #include "glheader.h" 36 #include "image.h" 37 #include "macros.h" 38 #include "meta.h" 39 #include "pbo.h" 40 #include "readpix.h" 41 #include "shaderapi.h" 42 #include "state.h" 43 #include "teximage.h" 44 #include "texobj.h" 45 #include "texstate.h" 46 #include "uniforms.h" 47 #include "varray.h" 48 49 static bool 50 need_signed_unsigned_int_conversion(mesa_format mesaFormat, 51 GLenum format, GLenum type) 52 { 53 const GLenum mesaFormatType = _mesa_get_format_datatype(mesaFormat); 54 const bool is_format_integer = _mesa_is_enum_format_integer(format); 55 return (mesaFormatType == GL_INT && 56 is_format_integer && 57 (type == GL_UNSIGNED_INT || 58 type == GL_UNSIGNED_SHORT || 59 type == GL_UNSIGNED_BYTE)) || 60 (mesaFormatType == GL_UNSIGNED_INT && 61 is_format_integer && 62 (type == GL_INT || 63 type == GL_SHORT || 64 type == GL_BYTE)); 65 } 66 67 static struct gl_texture_image * 68 create_texture_for_pbo(struct gl_context *ctx, 69 bool create_pbo, GLenum pbo_target, 70 int dims, int width, int height, int depth, 71 GLenum format, GLenum type, const void *pixels, 72 const struct gl_pixelstore_attrib *packing, 73 struct gl_buffer_object **tmp_pbo, GLuint *tmp_tex) 74 { 75 uint32_t pbo_format; 76 GLenum internal_format; 77 unsigned row_stride; 78 struct gl_buffer_object *buffer_obj; 79 struct gl_texture_object *tex_obj; 80 struct gl_texture_image *tex_image; 81 bool read_only; 82 83 if (packing->SwapBytes || 84 packing->LsbFirst || 85 packing->Invert) 86 return NULL; 87 88 pbo_format = _mesa_format_from_format_and_type(format, type); 89 if (_mesa_format_is_mesa_array_format(pbo_format)) 90 pbo_format = _mesa_format_from_array_format(pbo_format); 91 92 if (!pbo_format || !ctx->TextureFormatSupported[pbo_format]) 93 return NULL; 94 95 /* Account for SKIP_PIXELS, SKIP_ROWS, ALIGNMENT, and SKIP_IMAGES */ 96 uint32_t first_pixel = _mesa_image_offset(dims, packing, width, height, 97 format, type, 98 0, 0, 0); 99 uint32_t last_pixel = _mesa_image_offset(dims, packing, width, height, 100 format, type, 101 depth-1, height-1, width); 102 row_stride = _mesa_image_row_stride(packing, width, format, type); 103 104 if (_mesa_is_bufferobj(packing->BufferObj)) { 105 *tmp_pbo = NULL; 106 buffer_obj = packing->BufferObj; 107 first_pixel += (intptr_t)pixels; 108 } else { 109 bool is_pixel_pack = pbo_target == GL_PIXEL_PACK_BUFFER; 110 111 assert(create_pbo); 112 113 *tmp_pbo = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF); 114 if (*tmp_pbo == NULL) 115 return NULL; 116 117 /* In case of GL_PIXEL_PACK_BUFFER, pass null pointer for the pixel 118 * data to avoid unnecessary data copying in _mesa_buffer_data. 119 */ 120 if (is_pixel_pack) 121 _mesa_buffer_data(ctx, *tmp_pbo, GL_NONE, 122 last_pixel - first_pixel, 123 NULL, 124 GL_STREAM_READ, 125 __func__); 126 else 127 _mesa_buffer_data(ctx, *tmp_pbo, GL_NONE, 128 last_pixel - first_pixel, 129 (char *)pixels + first_pixel, 130 GL_STREAM_DRAW, 131 __func__); 132 133 buffer_obj = *tmp_pbo; 134 first_pixel = 0; 135 } 136 137 _mesa_GenTextures(1, tmp_tex); 138 tex_obj = _mesa_lookup_texture(ctx, *tmp_tex); 139 _mesa_initialize_texture_object(ctx, tex_obj, *tmp_tex, GL_TEXTURE_2D); 140 /* This must be set after _mesa_initialize_texture_object, not before. */ 141 tex_obj->Immutable = GL_TRUE; 142 /* This is required for interactions with ARB_texture_view. */ 143 tex_obj->NumLayers = 1; 144 145 internal_format = _mesa_get_format_base_format(pbo_format); 146 147 /* The texture is addressed as a single very-tall image, so we 148 * need to pack the multiple image depths together taking the 149 * inter-image padding into account. 150 */ 151 int image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight; 152 int full_height = image_height * (depth - 1) + height; 153 154 tex_image = _mesa_get_tex_image(ctx, tex_obj, tex_obj->Target, 0); 155 _mesa_init_teximage_fields(ctx, tex_image, width, full_height, 1, 156 0, internal_format, pbo_format); 157 158 read_only = pbo_target == GL_PIXEL_UNPACK_BUFFER; 159 if (!ctx->Driver.SetTextureStorageForBufferObject(ctx, tex_obj, 160 buffer_obj, 161 first_pixel, 162 row_stride, 163 read_only)) { 164 _mesa_DeleteTextures(1, tmp_tex); 165 _mesa_reference_buffer_object(ctx, tmp_pbo, NULL); 166 return NULL; 167 } 168 169 return tex_image; 170 } 171 172 bool 173 _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims, 174 struct gl_texture_image *tex_image, 175 int xoffset, int yoffset, int zoffset, 176 int width, int height, int depth, 177 GLenum format, GLenum type, const void *pixels, 178 bool create_pbo, 179 const struct gl_pixelstore_attrib *packing) 180 { 181 struct gl_buffer_object *pbo = NULL; 182 GLuint pbo_tex = 0; 183 struct gl_framebuffer *readFb = NULL; 184 struct gl_framebuffer *drawFb = NULL; 185 int image_height; 186 struct gl_texture_image *pbo_tex_image; 187 GLenum status; 188 bool success = false; 189 int z; 190 191 if (!_mesa_is_bufferobj(packing->BufferObj) && 192 (!create_pbo || pixels == NULL)) 193 return false; 194 195 if (format == GL_DEPTH_COMPONENT || 196 format == GL_DEPTH_STENCIL || 197 format == GL_STENCIL_INDEX || 198 format == GL_COLOR_INDEX) 199 return false; 200 201 if (ctx->_ImageTransferState) 202 return false; 203 204 /* This function rely on BlitFramebuffer to fill in the pixel data for 205 * glTex[Sub]Image*D. But, BlitFrameBuffer doesn't support signed to 206 * unsigned or unsigned to signed integer conversions. 207 */ 208 if (need_signed_unsigned_int_conversion(tex_image->TexFormat, format, type)) 209 return false; 210 211 /* For arrays, use a tall (height * depth) 2D texture but taking into 212 * account the inter-image padding specified with the image height packing 213 * property. 214 */ 215 image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight; 216 217 _mesa_meta_begin(ctx, ~(MESA_META_PIXEL_TRANSFER | 218 MESA_META_PIXEL_STORE)); 219 220 pbo_tex_image = create_texture_for_pbo(ctx, create_pbo, 221 GL_PIXEL_UNPACK_BUFFER, 222 dims, width, height, depth, 223 format, type, pixels, packing, 224 &pbo, &pbo_tex); 225 if (!pbo_tex_image) { 226 _mesa_meta_end(ctx); 227 return false; 228 } 229 230 readFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF); 231 if (readFb == NULL) 232 goto fail; 233 234 drawFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF); 235 if (drawFb == NULL) 236 goto fail; 237 238 _mesa_bind_framebuffers(ctx, drawFb, readFb); 239 240 if (tex_image->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 241 assert(depth == 1); 242 assert(zoffset == 0); 243 depth = height; 244 height = 1; 245 image_height = 1; 246 zoffset = yoffset; 247 yoffset = 0; 248 } 249 250 _mesa_meta_framebuffer_texture_image(ctx, ctx->ReadBuffer, 251 GL_COLOR_ATTACHMENT0, 252 pbo_tex_image, 0); 253 /* If this passes on the first layer it should pass on the others */ 254 status = _mesa_check_framebuffer_status(ctx, ctx->ReadBuffer); 255 if (status != GL_FRAMEBUFFER_COMPLETE) 256 goto fail; 257 258 _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, 259 GL_COLOR_ATTACHMENT0, 260 tex_image, zoffset); 261 /* If this passes on the first layer it should pass on the others */ 262 status = _mesa_check_framebuffer_status(ctx, ctx->DrawBuffer); 263 if (status != GL_FRAMEBUFFER_COMPLETE) 264 goto fail; 265 266 /* Explicitly disable sRGB encoding */ 267 ctx->DrawBuffer->Visual.sRGBCapable = false; 268 269 _mesa_update_state(ctx); 270 271 if (_mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 272 0, 0, width, height, 273 xoffset, yoffset, 274 xoffset + width, yoffset + height, 275 GL_COLOR_BUFFER_BIT, GL_NEAREST)) 276 goto fail; 277 278 for (z = 1; z < depth; z++) { 279 _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, 280 GL_COLOR_ATTACHMENT0, 281 tex_image, zoffset + z); 282 283 _mesa_update_state(ctx); 284 285 _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 286 0, z * image_height, 287 width, z * image_height + height, 288 xoffset, yoffset, 289 xoffset + width, yoffset + height, 290 GL_COLOR_BUFFER_BIT, GL_NEAREST); 291 } 292 293 success = true; 294 295 fail: 296 _mesa_reference_framebuffer(&readFb, NULL); 297 _mesa_reference_framebuffer(&drawFb, NULL); 298 _mesa_DeleteTextures(1, &pbo_tex); 299 _mesa_reference_buffer_object(ctx, &pbo, NULL); 300 301 _mesa_meta_end(ctx); 302 303 return success; 304 } 305 306 bool 307 _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims, 308 struct gl_texture_image *tex_image, 309 int xoffset, int yoffset, int zoffset, 310 int width, int height, int depth, 311 GLenum format, GLenum type, const void *pixels, 312 const struct gl_pixelstore_attrib *packing) 313 { 314 struct gl_buffer_object *pbo = NULL; 315 GLuint pbo_tex = 0; 316 struct gl_framebuffer *readFb; 317 struct gl_framebuffer *drawFb; 318 int image_height; 319 struct gl_texture_image *pbo_tex_image; 320 struct gl_renderbuffer *rb = NULL; 321 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format); 322 GLenum status, src_base_format; 323 bool success = false, clear_channels_to_zero = false; 324 float save_clear_color[4]; 325 int z; 326 327 if (!_mesa_is_bufferobj(packing->BufferObj)) 328 return false; 329 330 if (format == GL_DEPTH_COMPONENT || 331 format == GL_DEPTH_STENCIL || 332 format == GL_STENCIL_INDEX || 333 format == GL_COLOR_INDEX) 334 return false; 335 336 /* Don't use meta path for readpixels in below conditions. */ 337 if (!tex_image) { 338 rb = ctx->ReadBuffer->_ColorReadBuffer; 339 340 /* _mesa_get_readpixels_transfer_ops() includes the cases of read 341 * color clamping along with the ctx->_ImageTransferState. 342 */ 343 if (_mesa_get_readpixels_transfer_ops(ctx, rb->Format, format, 344 type, GL_FALSE)) 345 return false; 346 347 if (_mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, 348 dstBaseFormat)) 349 return false; 350 351 /* This function rely on BlitFramebuffer to fill in the pixel data for 352 * ReadPixels. But, BlitFrameBuffer doesn't support signed to unsigned 353 * or unsigned to signed integer conversions. OpenGL spec expects an 354 * invalid operation in that case. 355 */ 356 if (need_signed_unsigned_int_conversion(rb->Format, format, type)) 357 return false; 358 } else { 359 if (need_signed_unsigned_int_conversion(tex_image->TexFormat, format, type)) 360 return false; 361 } 362 363 /* For arrays, use a tall (height * depth) 2D texture but taking into 364 * account the inter-image padding specified with the image height packing 365 * property. 366 */ 367 image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight; 368 369 _mesa_meta_begin(ctx, ~(MESA_META_PIXEL_TRANSFER | 370 MESA_META_PIXEL_STORE)); 371 372 pbo_tex_image = create_texture_for_pbo(ctx, false, GL_PIXEL_PACK_BUFFER, 373 dims, width, height, depth, 374 format, type, pixels, packing, 375 &pbo, &pbo_tex); 376 377 if (!pbo_tex_image) { 378 _mesa_meta_end(ctx); 379 return false; 380 } 381 382 /* GL_CLAMP_FRAGMENT_COLOR doesn't affect ReadPixels and GettexImage */ 383 if (ctx->Extensions.ARB_color_buffer_float) 384 _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 385 386 readFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF); 387 if (readFb == NULL) 388 goto fail; 389 390 drawFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF); 391 if (drawFb == NULL) 392 goto fail; 393 394 if (tex_image && tex_image->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 395 assert(depth == 1); 396 assert(zoffset == 0); 397 depth = height; 398 height = 1; 399 image_height = 1; 400 zoffset = yoffset; 401 yoffset = 0; 402 } 403 404 /* If we were given a texture, bind it to the read framebuffer. If not, 405 * we're doing a ReadPixels and we should just use whatever framebuffer 406 * the client has bound. 407 */ 408 _mesa_bind_framebuffers(ctx, drawFb, tex_image ? readFb : ctx->ReadBuffer); 409 if (tex_image) { 410 _mesa_meta_framebuffer_texture_image(ctx, ctx->ReadBuffer, 411 GL_COLOR_ATTACHMENT0, 412 tex_image, zoffset); 413 /* If this passes on the first layer it should pass on the others */ 414 status = _mesa_check_framebuffer_status(ctx, ctx->ReadBuffer); 415 if (status != GL_FRAMEBUFFER_COMPLETE) 416 goto fail; 417 } else { 418 assert(depth == 1); 419 } 420 421 _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, 422 GL_COLOR_ATTACHMENT0, 423 pbo_tex_image, 0); 424 /* If this passes on the first layer it should pass on the others */ 425 status = _mesa_check_framebuffer_status(ctx, ctx->DrawBuffer); 426 if (status != GL_FRAMEBUFFER_COMPLETE) 427 goto fail; 428 429 /* Explicitly disable sRGB encoding */ 430 ctx->DrawBuffer->Visual.sRGBCapable = false; 431 432 _mesa_update_state(ctx); 433 434 if (_mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 435 xoffset, yoffset, 436 xoffset + width, yoffset + height, 437 0, 0, width, height, 438 GL_COLOR_BUFFER_BIT, GL_NEAREST)) 439 goto fail; 440 441 src_base_format = tex_image ? 442 tex_image->_BaseFormat : 443 ctx->ReadBuffer->_ColorReadBuffer->_BaseFormat; 444 445 /* Depending on the base formats involved we might need to rebase some 446 * values. For example if we download from a Luminance format to RGBA 447 * format, we want G=0 and B=0. 448 */ 449 clear_channels_to_zero = 450 _mesa_need_luminance_to_rgb_conversion(src_base_format, 451 pbo_tex_image->_BaseFormat); 452 453 if (clear_channels_to_zero) { 454 memcpy(save_clear_color, ctx->Color.ClearColor.f, 4 * sizeof(float)); 455 /* Clear the Green, Blue channels. */ 456 _mesa_ColorMask(GL_FALSE, GL_TRUE, GL_TRUE, 457 src_base_format != GL_LUMINANCE_ALPHA); 458 _mesa_ClearColor(0.0, 0.0, 0.0, 1.0); 459 _mesa_Clear(GL_COLOR_BUFFER_BIT); 460 } 461 462 for (z = 1; z < depth; z++) { 463 _mesa_meta_framebuffer_texture_image(ctx, ctx->ReadBuffer, 464 GL_COLOR_ATTACHMENT0, 465 tex_image, zoffset + z); 466 467 _mesa_update_state(ctx); 468 469 _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 470 xoffset, yoffset, 471 xoffset + width, yoffset + height, 472 0, z * image_height, 473 width, z * image_height + height, 474 GL_COLOR_BUFFER_BIT, GL_NEAREST); 475 if (clear_channels_to_zero) 476 _mesa_Clear(GL_COLOR_BUFFER_BIT); 477 } 478 479 /* Unmask the color channels and restore the saved clear color values. */ 480 if (clear_channels_to_zero) { 481 _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 482 _mesa_ClearColor(save_clear_color[0], save_clear_color[1], 483 save_clear_color[2], save_clear_color[3]); 484 } 485 486 success = true; 487 488 fail: 489 _mesa_reference_framebuffer(&drawFb, NULL); 490 _mesa_reference_framebuffer(&readFb, NULL); 491 _mesa_DeleteTextures(1, &pbo_tex); 492 _mesa_reference_buffer_object(ctx, &pbo, NULL); 493 494 _mesa_meta_end(ctx); 495 496 return success; 497 } 498