intel: Consolidate texture validation copy code, and reuse it correctly.
The path for ->Data was failing to be called for the FBO draw offset fallback, and also had mismatched compressed texture support code. This drops the intel_prepare_render() in the blit path. We aren't copying to/from a GL_FRONT buffer, so it doesn't matter.
This commit is contained in:
@@ -729,7 +729,6 @@ intel_render_texture(struct gl_context * ctx,
|
|||||||
* into that.
|
* into that.
|
||||||
*/
|
*/
|
||||||
struct intel_context *intel = intel_context(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
struct intel_mipmap_tree *old_mt = intel_image->mt;
|
|
||||||
struct intel_mipmap_tree *new_mt;
|
struct intel_mipmap_tree *new_mt;
|
||||||
|
|
||||||
new_mt = intel_miptree_create(intel, image->TexObject->Target,
|
new_mt = intel_miptree_create(intel, image->TexObject->Target,
|
||||||
@@ -741,17 +740,11 @@ intel_render_texture(struct gl_context * ctx,
|
|||||||
intel_image->base.Base.Depth,
|
intel_image->base.Base.Depth,
|
||||||
GL_TRUE);
|
GL_TRUE);
|
||||||
|
|
||||||
intel_miptree_image_copy(intel,
|
intel_miptree_copy_teximage(intel, intel_image, new_mt);
|
||||||
new_mt,
|
|
||||||
intel_image->base.Base.Face,
|
|
||||||
intel_image->base.Base.Level,
|
|
||||||
old_mt);
|
|
||||||
|
|
||||||
intel_miptree_release(&intel_image->mt);
|
|
||||||
intel_image->mt = new_mt;
|
|
||||||
intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
|
intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
|
||||||
|
|
||||||
intel_region_reference(&irb->region, intel_image->mt->region);
|
intel_region_reference(&irb->region, intel_image->mt->region);
|
||||||
|
intel_miptree_release(&new_mt);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* update drawing region, etc */
|
/* update drawing region, etc */
|
||||||
|
@@ -30,8 +30,10 @@
|
|||||||
#include "intel_regions.h"
|
#include "intel_regions.h"
|
||||||
#include "intel_tex_layout.h"
|
#include "intel_tex_layout.h"
|
||||||
#include "intel_tex.h"
|
#include "intel_tex.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
#include "main/enums.h"
|
#include "main/enums.h"
|
||||||
#include "main/formats.h"
|
#include "main/formats.h"
|
||||||
|
#include "main/teximage.h"
|
||||||
|
|
||||||
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
|
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
|
||||||
|
|
||||||
@@ -310,102 +312,107 @@ intel_miptree_get_image_offset(struct intel_mipmap_tree *mt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload data for a particular image.
|
* Copies the image's current data to the given miptree, and associates that
|
||||||
|
* miptree with the image.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
intel_miptree_image_data(struct intel_context *intel,
|
intel_miptree_copy_teximage(struct intel_context *intel,
|
||||||
struct intel_mipmap_tree *dst,
|
struct intel_texture_image *intelImage,
|
||||||
GLuint face,
|
struct intel_mipmap_tree *dst_mt)
|
||||||
GLuint level,
|
|
||||||
void *src,
|
|
||||||
GLuint src_row_pitch,
|
|
||||||
GLuint src_image_pitch)
|
|
||||||
{
|
{
|
||||||
const GLuint depth = dst->level[level].depth;
|
struct intel_mipmap_tree *src_mt = intelImage->mt;
|
||||||
GLuint i;
|
int level = intelImage->base.Base.Level;
|
||||||
|
int face = intelImage->base.Base.Face;
|
||||||
|
GLuint width = src_mt->level[level].width;
|
||||||
|
GLuint height = src_mt->level[level].height;
|
||||||
|
GLuint depth = src_mt->level[level].depth;
|
||||||
|
int slice;
|
||||||
|
void *src, *dst;
|
||||||
|
|
||||||
for (i = 0; i < depth; i++) {
|
if (dst_mt->compressed) {
|
||||||
GLuint dst_x, dst_y, height, width;
|
unsigned int align_w, align_h;
|
||||||
|
|
||||||
intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y);
|
intel_get_texture_alignment_unit(intelImage->base.Base.TexFormat,
|
||||||
|
&align_w, &align_h);
|
||||||
height = dst->level[level].height;
|
height = ALIGN(height, align_h) / align_h;
|
||||||
width = dst->level[level].width;
|
width = ALIGN(width, align_w);
|
||||||
if (dst->compressed) {
|
|
||||||
unsigned int align_w, align_h;
|
|
||||||
|
|
||||||
intel_get_texture_alignment_unit(dst->format, &align_w, &align_h);
|
|
||||||
height = (height + align_h - 1) / align_h;
|
|
||||||
width = ALIGN(width, align_w);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG("%s: %d/%d %p/%d -> (%d, %d)/%d (%d, %d)\n",
|
|
||||||
__FUNCTION__, face, level,
|
|
||||||
src, src_row_pitch * dst->cpp,
|
|
||||||
dst_x, dst_y, dst->region->pitch * dst->cpp,
|
|
||||||
width, height);
|
|
||||||
|
|
||||||
intel_region_data(intel,
|
|
||||||
dst->region, 0, dst_x, dst_y,
|
|
||||||
src,
|
|
||||||
src_row_pitch,
|
|
||||||
0, 0, /* source x, y */
|
|
||||||
width, height);
|
|
||||||
|
|
||||||
src = (char *)src + src_image_pitch * dst->cpp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy mipmap image between trees
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
intel_miptree_image_copy(struct intel_context *intel,
|
|
||||||
struct intel_mipmap_tree *dst,
|
|
||||||
GLuint face, GLuint level,
|
|
||||||
struct intel_mipmap_tree *src)
|
|
||||||
{
|
|
||||||
GLuint width = src->level[level].width;
|
|
||||||
GLuint height = src->level[level].height;
|
|
||||||
GLuint depth = src->level[level].depth;
|
|
||||||
GLuint src_x, src_y, dst_x, dst_y;
|
|
||||||
GLuint i;
|
|
||||||
GLboolean success;
|
|
||||||
|
|
||||||
if (dst->compressed) {
|
|
||||||
GLuint align_w, align_h;
|
|
||||||
|
|
||||||
intel_get_texture_alignment_unit(dst->format, &align_w, &align_h);
|
|
||||||
height = (height + 3) / 4;
|
|
||||||
width = ALIGN(width, align_w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
intel_prepare_render(intel);
|
for (slice = 0; slice < depth; slice++) {
|
||||||
|
unsigned int dst_x, dst_y, src_x, src_y;
|
||||||
|
|
||||||
for (i = 0; i < depth; i++) {
|
intel_miptree_get_image_offset(dst_mt, level, face, slice,
|
||||||
intel_miptree_get_image_offset(src, level, face, i, &src_x, &src_y);
|
&dst_x, &dst_y);
|
||||||
intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y);
|
|
||||||
success = intel_region_copy(intel,
|
|
||||||
dst->region, 0, dst_x, dst_y,
|
|
||||||
src->region, 0, src_x, src_y,
|
|
||||||
width, height, GL_FALSE,
|
|
||||||
GL_COPY);
|
|
||||||
if (!success) {
|
|
||||||
GLubyte *src_ptr, *dst_ptr;
|
|
||||||
|
|
||||||
src_ptr = intel_region_map(intel, src->region);
|
if (src_mt) {
|
||||||
dst_ptr = intel_region_map(intel, dst->region);
|
/* Copy potentially with the blitter:
|
||||||
|
*/
|
||||||
|
intel_miptree_get_image_offset(src_mt, level, face, slice,
|
||||||
|
&src_x, &src_y);
|
||||||
|
|
||||||
_mesa_copy_rect(dst_ptr,
|
DBG("validate blit mt %p %d,%d/%d -> mt %p %d,%d/%d (%dx%d)\n",
|
||||||
dst->cpp,
|
src_mt, src_x, src_y, src_mt->region->pitch * src_mt->region->cpp,
|
||||||
dst->region->pitch,
|
dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp,
|
||||||
dst_x, dst_y, width, height,
|
width, height);
|
||||||
src_ptr,
|
|
||||||
src->region->pitch,
|
if (!intelEmitCopyBlit(intel,
|
||||||
src_x, src_y);
|
dst_mt->region->cpp,
|
||||||
intel_region_unmap(intel, src->region);
|
src_mt->region->pitch, src_mt->region->bo,
|
||||||
intel_region_unmap(intel, dst->region);
|
0, src_mt->region->tiling,
|
||||||
|
dst_mt->region->pitch, dst_mt->region->bo,
|
||||||
|
0, dst_mt->region->tiling,
|
||||||
|
src_x, src_y,
|
||||||
|
dst_x, dst_y,
|
||||||
|
width, height,
|
||||||
|
GL_COPY)) {
|
||||||
|
|
||||||
|
fallback_debug("miptree validate blit for %s failed\n",
|
||||||
|
_mesa_get_format_name(intelImage->base.Base.TexFormat));
|
||||||
|
dst = intel_region_map(intel, dst_mt->region);
|
||||||
|
src = intel_region_map(intel, src_mt->region);
|
||||||
|
|
||||||
|
_mesa_copy_rect(dst,
|
||||||
|
dst_mt->cpp,
|
||||||
|
dst_mt->region->pitch,
|
||||||
|
dst_x, dst_y,
|
||||||
|
width, height,
|
||||||
|
src, src_mt->region->pitch,
|
||||||
|
src_x, src_y);
|
||||||
|
|
||||||
|
intel_region_unmap(intel, dst_mt->region);
|
||||||
|
intel_region_unmap(intel, src_mt->region);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dst = intel_region_map(intel, dst_mt->region);
|
||||||
|
|
||||||
|
DBG("validate upload mt %p -> mt %p %d,%d/%d (%dx%d)\n",
|
||||||
|
src,
|
||||||
|
dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
src = intelImage->base.Base.Data;
|
||||||
|
src += (intelImage->base.Base.RowStride *
|
||||||
|
intelImage->base.Base.Height *
|
||||||
|
dst_mt->region->cpp *
|
||||||
|
slice);
|
||||||
|
|
||||||
|
_mesa_copy_rect(dst,
|
||||||
|
dst_mt->region->cpp,
|
||||||
|
dst_mt->region->pitch,
|
||||||
|
dst_x, dst_y,
|
||||||
|
width, height,
|
||||||
|
src,
|
||||||
|
intelImage->base.Base.RowStride,
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
intel_region_unmap(intel, dst_mt->region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!src_mt) {
|
||||||
|
_mesa_free_texmemory(intelImage->base.Base.Data);
|
||||||
|
intelImage->base.Base.Data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
intel_miptree_reference(&intelImage->mt, dst_mt);
|
||||||
}
|
}
|
||||||
|
@@ -56,6 +56,7 @@
|
|||||||
* temporary system buffers.
|
* temporary system buffers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct intel_texture_image;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the location of each texture image within a texture region.
|
* Describes the location of each texture image within a texture region.
|
||||||
@@ -180,21 +181,10 @@ void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
|
|||||||
GLuint level,
|
GLuint level,
|
||||||
GLuint img, GLuint x, GLuint y);
|
GLuint img, GLuint x, GLuint y);
|
||||||
|
|
||||||
/* Upload an image into a tree
|
void
|
||||||
*/
|
intel_miptree_copy_teximage(struct intel_context *intel,
|
||||||
void intel_miptree_image_data(struct intel_context *intel,
|
struct intel_texture_image *intelImage,
|
||||||
struct intel_mipmap_tree *dst,
|
struct intel_mipmap_tree *dst_mt);
|
||||||
GLuint face,
|
|
||||||
GLuint level,
|
|
||||||
void *src,
|
|
||||||
GLuint src_row_pitch, GLuint src_image_pitch);
|
|
||||||
|
|
||||||
/* Copy an image between two trees
|
|
||||||
*/
|
|
||||||
void intel_miptree_image_copy(struct intel_context *intel,
|
|
||||||
struct intel_mipmap_tree *dst,
|
|
||||||
GLuint face, GLuint level,
|
|
||||||
struct intel_mipmap_tree *src);
|
|
||||||
|
|
||||||
/* i915_mipmap_tree.c:
|
/* i915_mipmap_tree.c:
|
||||||
*/
|
*/
|
||||||
|
@@ -337,37 +337,6 @@ _mesa_copy_rect(GLubyte * dst,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Upload data to a rectangular sub-region. Lots of choices how to do this:
|
|
||||||
*
|
|
||||||
* - memcpy by span to current destination
|
|
||||||
* - upload data as new buffer and blit
|
|
||||||
*
|
|
||||||
* Currently always memcpy.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
intel_region_data(struct intel_context *intel,
|
|
||||||
struct intel_region *dst,
|
|
||||||
GLuint dst_offset,
|
|
||||||
GLuint dstx, GLuint dsty,
|
|
||||||
const void *src, GLuint src_pitch,
|
|
||||||
GLuint srcx, GLuint srcy, GLuint width, GLuint height)
|
|
||||||
{
|
|
||||||
_DBG("%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
if (intel == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
intel_prepare_render(intel);
|
|
||||||
|
|
||||||
_mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
|
|
||||||
dst->cpp,
|
|
||||||
dst->pitch,
|
|
||||||
dstx, dsty, width, height, src, src_pitch, srcx, srcy);
|
|
||||||
|
|
||||||
intel_region_unmap(intel, dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy rectangular sub-regions. Need better logic about when to
|
/* Copy rectangular sub-regions. Need better logic about when to
|
||||||
* push buffers into AGP - will currently do so whenever possible.
|
* push buffers into AGP - will currently do so whenever possible.
|
||||||
*/
|
*/
|
||||||
|
@@ -101,16 +101,6 @@ GLubyte *intel_region_map(struct intel_context *intel,
|
|||||||
|
|
||||||
void intel_region_unmap(struct intel_context *intel, struct intel_region *ib);
|
void intel_region_unmap(struct intel_context *intel, struct intel_region *ib);
|
||||||
|
|
||||||
|
|
||||||
/* Upload data to a rectangular sub-region
|
|
||||||
*/
|
|
||||||
void intel_region_data(struct intel_context *intel,
|
|
||||||
struct intel_region *dest,
|
|
||||||
GLuint dest_offset,
|
|
||||||
GLuint destx, GLuint desty,
|
|
||||||
const void *src, GLuint src_stride,
|
|
||||||
GLuint srcx, GLuint srcy, GLuint width, GLuint height);
|
|
||||||
|
|
||||||
/* Copy rectangular sub-regions
|
/* Copy rectangular sub-regions
|
||||||
*/
|
*/
|
||||||
GLboolean
|
GLboolean
|
||||||
|
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
#include "intel_context.h"
|
#include "intel_context.h"
|
||||||
#include "intel_mipmap_tree.h"
|
#include "intel_mipmap_tree.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
#include "intel_tex.h"
|
#include "intel_tex.h"
|
||||||
|
#include "intel_tex_layout.h"
|
||||||
|
|
||||||
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
|
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
|
||||||
|
|
||||||
@@ -27,44 +29,6 @@ intel_update_max_level(struct intel_texture_object *intelObj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies the image's contents at its level into the object's miptree,
|
|
||||||
* and updates the image to point at the object's miptree.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
copy_image_data_to_tree(struct intel_context *intel,
|
|
||||||
struct intel_texture_object *intelObj,
|
|
||||||
struct intel_texture_image *intelImage)
|
|
||||||
{
|
|
||||||
if (intelImage->mt) {
|
|
||||||
/* Copy potentially with the blitter:
|
|
||||||
*/
|
|
||||||
intel_miptree_image_copy(intel,
|
|
||||||
intelObj->mt,
|
|
||||||
intelImage->base.Base.Face,
|
|
||||||
intelImage->base.Base.Level, intelImage->mt);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(intelImage->base.Base.Data != NULL);
|
|
||||||
|
|
||||||
/* More straightforward upload.
|
|
||||||
*/
|
|
||||||
intel_miptree_image_data(intel,
|
|
||||||
intelObj->mt,
|
|
||||||
intelImage->base.Base.Face,
|
|
||||||
intelImage->base.Base.Level,
|
|
||||||
intelImage->base.Base.Data,
|
|
||||||
intelImage->base.Base.RowStride,
|
|
||||||
intelImage->base.Base.RowStride *
|
|
||||||
intelImage->base.Base.Height);
|
|
||||||
_mesa_align_free(intelImage->base.Base.Data);
|
|
||||||
intelImage->base.Base.Data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
intel_miptree_reference(&intelImage->mt, intelObj->mt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
GLuint
|
GLuint
|
||||||
@@ -148,7 +112,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
|
|||||||
*/
|
*/
|
||||||
if (intelObj->mt != intelImage->mt &&
|
if (intelObj->mt != intelImage->mt &&
|
||||||
!intelImage->used_as_render_target) {
|
!intelImage->used_as_render_target) {
|
||||||
copy_image_data_to_tree(intel, intelObj, intelImage);
|
intel_miptree_copy_teximage(intel, intelImage, intelObj->mt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user