Browse Source

intel: Move the draw_x/draw_y to the renderbuffer where it belongs.

It was originally located in the region because the tracking of
depth/color buffers was on the regions, and getting back to the irb
would have been tricky.  Now, we're keying off of the renderbuffer in
more places, which means we can move these fields where they belong.

This could fix potential rendering failure with a single texture
having multiple images attached to different renderbuffers across
shareCtx (as far as I can tell, this was the only failure we could
cause, since anything else should trigger intel_render_texture in
between, for example a BindFramebuffer).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Chad Versace <chad@chad-versace.us>
tags/mesa-7.11-rc1
Eric Anholt 14 years ago
parent
commit
b17aab5753

+ 18
- 10
src/mesa/drivers/dri/i915/i830_vtbl.c View File

struct gl_context *ctx = &intel->ctx; struct gl_context *ctx = &intel->ctx;
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
struct intel_renderbuffer *irb = intel_renderbuffer(rb); struct intel_renderbuffer *irb = intel_renderbuffer(rb);
struct gl_renderbuffer *drb;
struct intel_renderbuffer *idrb = NULL;
GLuint value; GLuint value;
struct i830_hw_state *state = &i830->state; struct i830_hw_state *state = &i830->state;
uint32_t draw_x, draw_y; uint32_t draw_x, draw_y;
} }
state->Buffer[I830_DESTREG_DV1] = value; state->Buffer[I830_DESTREG_DV1] = value;


drb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
if (!drb)
drb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;

if (drb)
idrb = intel_renderbuffer(drb);

/* We set up the drawing rectangle to be offset into the color /* We set up the drawing rectangle to be offset into the color
* region's location in the miptree. If it doesn't match with * region's location in the miptree. If it doesn't match with
* depth's offsets, we can't render to it. * depth's offsets, we can't render to it.
* can't do in general due to tiling) * can't do in general due to tiling)
*/ */
FALLBACK(intel, I830_FALLBACK_DRAW_OFFSET, FALLBACK(intel, I830_FALLBACK_DRAW_OFFSET,
(depth_region && color_regions[0]) &&
(depth_region->draw_x != color_regions[0]->draw_x ||
depth_region->draw_y != color_regions[0]->draw_y));

if (color_regions[0]) {
draw_x = color_regions[0]->draw_x;
draw_y = color_regions[0]->draw_y;
} else if (depth_region) {
draw_x = depth_region->draw_x;
draw_y = depth_region->draw_y;
idrb && irb && (idrb->draw_x != irb->draw_x ||
idrb->draw_y != irb->draw_y));

if (irb) {
draw_x = irb->draw_x;
draw_y = irb->draw_y;
} else if (idrb) {
draw_x = idrb->draw_x;
draw_y = idrb->draw_y;
} else { } else {
draw_x = 0; draw_x = 0;
draw_y = 0; draw_y = 0;

+ 18
- 10
src/mesa/drivers/dri/i915/i915_vtbl.c View File

struct gl_context *ctx = &intel->ctx; struct gl_context *ctx = &intel->ctx;
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
struct intel_renderbuffer *irb = intel_renderbuffer(rb); struct intel_renderbuffer *irb = intel_renderbuffer(rb);
struct gl_renderbuffer *drb;
struct intel_renderbuffer *idrb = NULL;
GLuint value; GLuint value;
struct i915_hw_state *state = &i915->state; struct i915_hw_state *state = &i915->state;
uint32_t draw_x, draw_y, draw_offset; uint32_t draw_x, draw_y, draw_offset;
} }
state->Buffer[I915_DESTREG_DV1] = value; state->Buffer[I915_DESTREG_DV1] = value;


drb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
if (!drb)
drb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;

if (drb)
idrb = intel_renderbuffer(drb);

/* We set up the drawing rectangle to be offset into the color /* We set up the drawing rectangle to be offset into the color
* region's location in the miptree. If it doesn't match with * region's location in the miptree. If it doesn't match with
* depth's offsets, we can't render to it. * depth's offsets, we can't render to it.
* can't do in general due to tiling) * can't do in general due to tiling)
*/ */
FALLBACK(intel, I915_FALLBACK_DRAW_OFFSET, FALLBACK(intel, I915_FALLBACK_DRAW_OFFSET,
(depth_region && color_regions[0]) &&
(depth_region->draw_x != color_regions[0]->draw_x ||
depth_region->draw_y != color_regions[0]->draw_y));

if (color_regions[0]) {
draw_x = color_regions[0]->draw_x;
draw_y = color_regions[0]->draw_y;
} else if (depth_region) {
draw_x = depth_region->draw_x;
draw_y = depth_region->draw_y;
idrb && irb && (idrb->draw_x != irb->draw_x ||
idrb->draw_y != irb->draw_y));

if (irb) {
draw_x = irb->draw_x;
draw_y = irb->draw_y;
} else if (idrb) {
draw_x = idrb->draw_x;
draw_y = idrb->draw_y;
} else { } else {
draw_x = 0; draw_x = 0;
draw_y = 0; draw_y = 0;

+ 1
- 1
src/mesa/drivers/dri/i965/brw_misc_state.c View File

return; return;
} }


offset = intel_region_tile_offsets(region, &tile_x, &tile_y);
offset = intel_renderbuffer_tile_offsets(depth_irb, &tile_x, &tile_y);


assert(intel->gen < 6 || region->tiling == I915_TILING_Y); assert(intel->gen < 6 || region->tiling == I915_TILING_Y);
assert(!hiz_region || region->tiling == I915_TILING_Y); assert(!hiz_region || region->tiling == I915_TILING_Y);

+ 1
- 1
src/mesa/drivers/dri/i965/brw_wm_surface_state.c View File

format << BRW_SURFACE_FORMAT_SHIFT); format << BRW_SURFACE_FORMAT_SHIFT);


/* reloc */ /* reloc */
surf[1] = (intel_region_tile_offsets(region, &tile_x, &tile_y) +
surf[1] = (intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y) +
region->buffer->offset); region->buffer->offset);


surf[2] = ((rb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT | surf[2] = ((rb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT |

+ 1
- 1
src/mesa/drivers/dri/i965/gen7_misc_state.c View File

struct intel_region *region = drb->region; struct intel_region *region = drb->region;
uint32_t tile_x, tile_y, offset; uint32_t tile_x, tile_y, offset;


offset = intel_region_tile_offsets(region, &tile_x, &tile_y);
offset = intel_renderbuffer_tile_offsets(drb, &tile_x, &tile_y);


assert(region->tiling == I915_TILING_Y); assert(region->tiling == I915_TILING_Y);



+ 1
- 1
src/mesa/drivers/dri/i965/gen7_wm_surface_state.c View File



surf->ss0.surface_type = BRW_SURFACE_2D; surf->ss0.surface_type = BRW_SURFACE_2D;
/* reloc */ /* reloc */
surf->ss1.base_addr = intel_region_tile_offsets(region, &tile_x, &tile_y);
surf->ss1.base_addr = intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
surf->ss1.base_addr += region->buffer->offset; /* reloc */ surf->ss1.base_addr += region->buffer->offset; /* reloc */


assert(brw->has_surface_tile_offset); assert(brw->has_surface_tile_offset);

+ 4
- 4
src/mesa/drivers/dri/intel/intel_blit.c View File

write_buffer = intel_region_buffer(intel, irb->region, write_buffer = intel_region_buffer(intel, irb->region,
all ? INTEL_WRITE_FULL : all ? INTEL_WRITE_FULL :
INTEL_WRITE_PART); INTEL_WRITE_PART);
x1 = cx + irb->region->draw_x;
y1 = cy + irb->region->draw_y;
x2 = cx + cw + irb->region->draw_x;
y2 = cy + ch + irb->region->draw_y;
x1 = cx + irb->draw_x;
y1 = cy + irb->draw_y;
x2 = cx + cw + irb->draw_x;
y2 = cy + ch + irb->draw_y;


pitch = irb->region->pitch; pitch = irb->region->pitch;
cpp = irb->region->cpp; cpp = irb->region->cpp;

+ 45
- 8
src/mesa/drivers/dri/intel/intel_fbo.c View File

} }


static void static void
intel_set_draw_offset_for_image(struct intel_texture_image *intel_image,
int zoffset)
intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb,
struct intel_texture_image *intel_image,
int zoffset)
{ {
struct intel_mipmap_tree *mt = intel_image->mt; struct intel_mipmap_tree *mt = intel_image->mt;
unsigned int dst_x, dst_y; unsigned int dst_x, dst_y;
zoffset, zoffset,
&dst_x, &dst_y); &dst_x, &dst_y);


mt->region->draw_offset = (dst_y * mt->region->pitch + dst_x) * mt->cpp;
mt->region->draw_x = dst_x;
mt->region->draw_y = dst_y;
irb->draw_offset = (dst_y * mt->region->pitch + dst_x) * mt->cpp;
irb->draw_x = dst_x;
irb->draw_y = dst_y;
}

/**
* Rendering to tiled buffers requires that the base address of the
* buffer be aligned to a page boundary. We generally render to
* textures by pointing the surface at the mipmap image level, which
* may not be aligned to a tile boundary.
*
* This function returns an appropriately-aligned base offset
* according to the tiling restrictions, plus any required x/y offset
* from there.
*/
uint32_t
intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
uint32_t *tile_x,
uint32_t *tile_y)
{
int cpp = irb->region->cpp;
uint32_t pitch = irb->region->pitch * cpp;

if (irb->region->tiling == I915_TILING_NONE) {
*tile_x = 0;
*tile_y = 0;
return irb->draw_x * cpp + irb->draw_y * pitch;
} else if (irb->region->tiling == I915_TILING_X) {
*tile_x = irb->draw_x % (512 / cpp);
*tile_y = irb->draw_y % 8;
return ((irb->draw_y / 8) * (8 * pitch) +
(irb->draw_x - *tile_x) / (512 / cpp) * 4096);
} else {
assert(irb->region->tiling == I915_TILING_Y);
*tile_x = irb->draw_x % (128 / cpp);
*tile_y = irb->draw_y % 32;
return ((irb->draw_y / 32) * (32 * pitch) +
(irb->draw_x - *tile_x) / (128 / cpp) * 4096);
}
} }


/** /**
att->Texture->Name, newImage->Width, newImage->Height, att->Texture->Name, newImage->Width, newImage->Height,
irb->Base.RefCount); irb->Base.RefCount);


intel_set_draw_offset_for_image(intel_image, att->Zoffset);
intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
intel_image->used_as_render_target = GL_TRUE; intel_image->used_as_render_target = GL_TRUE;


#ifndef I915 #ifndef I915
if (!brw_context(ctx)->has_surface_tile_offset && if (!brw_context(ctx)->has_surface_tile_offset &&
(intel_image->mt->region->draw_offset & 4095) != 0) {
(irb->draw_offset & 4095) != 0) {
/* Original gen4 hardware couldn't draw to a non-tile-aligned /* Original gen4 hardware couldn't draw to a non-tile-aligned
* destination in a miptree unless you actually setup your * destination in a miptree unless you actually setup your
* renderbuffer as a miptree and used the fragile * renderbuffer as a miptree and used the fragile


intel_miptree_release(intel, &intel_image->mt); intel_miptree_release(intel, &intel_image->mt);
intel_image->mt = new_mt; intel_image->mt = new_mt;
intel_set_draw_offset_for_image(intel_image, att->Zoffset);
intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);


intel_region_release(&irb->region); intel_region_release(&irb->region);
intel_region_reference(&irb->region, intel_image->mt->region); intel_region_reference(&irb->region, intel_image->mt->region);

+ 7
- 1
src/mesa/drivers/dri/intel/intel_fbo.h View File



/** Only used by depth renderbuffers for which HiZ is enabled. */ /** Only used by depth renderbuffers for which HiZ is enabled. */
struct intel_region *hiz_region; struct intel_region *hiz_region;

GLuint draw_offset; /**< Offset of drawing address within the region */
GLuint draw_x, draw_y; /**< Offset of drawing within the region */
}; };




extern void extern void
intel_flip_renderbuffers(struct gl_framebuffer *fb); intel_flip_renderbuffers(struct gl_framebuffer *fb);


uint32_t
intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
uint32_t *tile_x,
uint32_t *tile_y);


static INLINE struct intel_region * static INLINE struct intel_region *
intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
return NULL; return NULL;
} }



#endif /* INTEL_FBO_H */ #endif /* INTEL_FBO_H */

+ 0
- 35
src/mesa/drivers/dri/intel/intel_regions.c View File



return region->buffer; return region->buffer;
} }

/**
* Rendering to tiled buffers requires that the base address of the
* buffer be aligned to a page boundary. We generally render to
* textures by pointing the surface at the mipmap image level, which
* may not be aligned to a tile boundary.
*
* This function returns an appropriately-aligned base offset
* according to the tiling restrictions, plus any required x/y offset
* from there.
*/
uint32_t
intel_region_tile_offsets(struct intel_region *region,
uint32_t *tile_x,
uint32_t *tile_y)
{
uint32_t pitch = region->pitch * region->cpp;

if (region->tiling == I915_TILING_NONE) {
*tile_x = 0;
*tile_y = 0;
return region->draw_x * region->cpp + region->draw_y * pitch;
} else if (region->tiling == I915_TILING_X) {
*tile_x = region->draw_x % (512 / region->cpp);
*tile_y = region->draw_y % 8;
return ((region->draw_y / 8) * (8 * pitch) +
(region->draw_x - *tile_x) / (512 / region->cpp) * 4096);
} else {
assert(region->tiling == I915_TILING_Y);
*tile_x = region->draw_x % (128 / region->cpp);
*tile_y = region->draw_y % 32;
return ((region->draw_y / 32) * (32 * pitch) +
(region->draw_x - *tile_x) / (128 / region->cpp) * 4096);
}
}

+ 0
- 7
src/mesa/drivers/dri/intel/intel_regions.h View File

GLubyte *map; /**< only non-NULL when region is actually mapped */ GLubyte *map; /**< only non-NULL when region is actually mapped */
GLuint map_refcount; /**< Reference count for mapping */ GLuint map_refcount; /**< Reference count for mapping */


GLuint draw_offset; /**< Offset of drawing address within the region */
GLuint draw_x, draw_y; /**< Offset of drawing within the region */

uint32_t tiling; /**< Which tiling mode the region is in */ uint32_t tiling; /**< Which tiling mode the region is in */
struct intel_buffer_object *pbo; /* zero-copy uploads */ struct intel_buffer_object *pbo; /* zero-copy uploads */


struct intel_region *region, struct intel_region *region,
GLuint flag); GLuint flag);


uint32_t intel_region_tile_offsets(struct intel_region *region,
uint32_t *tile_x,
uint32_t *tile_y);

void _mesa_copy_rect(GLubyte * dst, void _mesa_copy_rect(GLubyte * dst,
GLuint cpp, GLuint cpp,
GLuint dst_pitch, GLuint dst_pitch,

+ 1
- 1
src/mesa/drivers/dri/intel/intel_tex_copy.c View File

dst_bo, dst_bo,
0, 0,
intelImage->mt->region->tiling, intelImage->mt->region->tiling,
irb->region->draw_x + x, irb->region->draw_y + y,
irb->draw_x + x, irb->draw_y + y,
image_x + dstx, image_y + dsty, image_x + dstx, image_y + dsty,
width, height, width, height,
GL_COPY)) { GL_COPY)) {

Loading…
Cancel
Save