-/**************************************************************************
- *
+/*
* Copyright 2003 VMware, Inc.
* All Rights Reserved.
*
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
+ * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
+ */
-#include "main/glheader.h"
#include "main/enums.h"
#include "main/mtypes.h"
#include "main/macros.h"
pack->Invert)
return false;
- /* This renderbuffer can come from a texture. In this case, we impose
- * some of the same restrictions we have for textures and adjust for
- * miplevels.
- */
- if (rb->TexImage) {
- if (rb->TexImage->TexObject->Target != GL_TEXTURE_2D &&
- rb->TexImage->TexObject->Target != GL_TEXTURE_RECTANGLE)
- return false;
-
- int level = rb->TexImage->Level + rb->TexImage->TexObject->MinLevel;
-
- /* Adjust x and y offset based on miplevel */
- xoffset += irb->mt->level[level].level_x;
- yoffset += irb->mt->level[level].level_y;
- }
+ /* Only a simple blit, no scale, bias or other mapping. */
+ if (ctx->_ImageTransferState)
+ return false;
/* It is possible that the renderbuffer (or underlying texture) is
* multisampled. Since ReadPixels from a multisampled buffer requires a
if (rb->NumSamples > 1)
return false;
+ /* We can't handle copying from RGBX or BGRX because the tiled_memcpy
+ * function doesn't set the last channel to 1. Note this checks BaseFormat
+ * rather than TexFormat in case the RGBX format is being simulated with an
+ * RGBA format.
+ */
+ if (rb->_BaseFormat == GL_RGB)
+ return false;
+
if (!intel_get_memcpy(rb->Format, format, type, &mem_copy, &cpp))
return false;
/* Since we are going to read raw data to the miptree, we need to resolve
* any pending fast color clears before we start.
*/
- intel_miptree_resolve_color(brw, irb->mt);
+ intel_miptree_resolve_color(brw, irb->mt, 0);
bo = irb->mt->bo;
error = brw_bo_map(brw, bo, false /* write enable */, "miptree");
if (error) {
- DBG("%s: failed to map bo\n", __FUNCTION__);
+ DBG("%s: failed to map bo\n", __func__);
return false;
}
+ xoffset += irb->mt->level[irb->mt_level].slice[irb->mt_layer].x_offset;
+ yoffset += irb->mt->level[irb->mt_level].slice[irb->mt_layer].y_offset;
+
dst_pitch = _mesa_image_row_stride(pack, width, format, type);
/* For a window-system renderbuffer, the buffer is actually flipped
DBG("%s: x,y=(%d,%d) (w,h)=(%d,%d) format=0x%x type=0x%x "
"mesa_format=0x%x tiling=%d "
"pack=(alignment=%d row_length=%d skip_pixels=%d skip_rows=%d)\n",
- __FUNCTION__, xoffset, yoffset, width, height,
+ __func__, xoffset, yoffset, width, height,
format, type, rb->Format, irb->mt->tiling,
pack->Alignment, pack->RowLength, pack->SkipPixels,
pack->SkipRows);
xoffset * cpp, (xoffset + width) * cpp,
yoffset, yoffset + height,
pixels - (ptrdiff_t) yoffset * dst_pitch - (ptrdiff_t) xoffset * cpp,
- bo->virtual,
+ bo->virtual + irb->mt->offset,
dst_pitch, irb->mt->pitch,
brw->has_swizzling,
irb->mt->tiling,
struct brw_context *brw = brw_context(ctx);
bool dirty;
- DBG("%s\n", __FUNCTION__);
+ DBG("%s\n", __func__);
if (_mesa_is_bufferobj(pack->BufferObj)) {
if (_mesa_meta_pbo_GetTexSubImage(ctx, 2, NULL, x, y, 0, width, height, 1,
- format, type, pixels, pack))
+ format, type, pixels, pack)) {
+ /* _mesa_meta_pbo_GetTexSubImage() implements PBO transfers by
+ * binding the user-provided BO as a fake framebuffer and rendering
+ * to it. This breaks the invariant of the GL that nothing is able
+ * to render to a BO, causing nondeterministic corruption issues
+ * because the render cache is not coherent with a number of other
+ * caches that the BO could potentially be bound to afterwards.
+ *
+ * This could be solved in the same way that we guarantee texture
+ * coherency after a texture is attached to a framebuffer and
+ * rendered to, but that would involve checking *all* BOs bound to
+ * the pipeline for the case we need to emit a cache flush due to
+ * previous rendering to any of them -- Including vertex, index,
+ * uniform, atomic counter, shader image, transform feedback,
+ * indirect draw buffers, etc.
+ *
+ * That would increase the per-draw call overhead even though it's
+ * very unlikely that any of the BOs bound to the pipeline has been
+ * rendered to via a PBO at any point, so it seems better to just
+ * flush here unconditionally.
+ */
+ brw_emit_mi_flush(brw);
return;
+ }
- perf_debug("%s: fallback to CPU mapping in PBO case\n", __FUNCTION__);
+ perf_debug("%s: fallback to CPU mapping in PBO case\n", __func__);
}
ok = intel_readpixels_tiled_memcpy(ctx, x, y, width, height,