i965: Add support for rendering to depthbuffer mipmap levels > 0.
Fixes GL_ARB_depth_texture/fbo-clear-formats GL_EXT_packed_depth_stencil/fbo-clear-formats
This commit is contained in:
@@ -247,6 +247,7 @@ static void emit_depthbuffer(struct brw_context *brw)
|
|||||||
} else {
|
} else {
|
||||||
struct intel_region *region = irb->region;
|
struct intel_region *region = irb->region;
|
||||||
unsigned int format;
|
unsigned int format;
|
||||||
|
uint32_t tile_x, tile_y, offset;
|
||||||
|
|
||||||
switch (region->cpp) {
|
switch (region->cpp) {
|
||||||
case 2:
|
case 2:
|
||||||
@@ -263,7 +264,8 @@ static void emit_depthbuffer(struct brw_context *brw)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(region->tiling != I915_TILING_X);
|
offset = intel_region_tile_offsets(region, &tile_x, &tile_y);
|
||||||
|
|
||||||
assert(intel->gen < 6 || region->tiling == I915_TILING_Y);
|
assert(intel->gen < 6 || region->tiling == I915_TILING_Y);
|
||||||
|
|
||||||
BEGIN_BATCH(len);
|
BEGIN_BATCH(len);
|
||||||
@@ -275,14 +277,16 @@ static void emit_depthbuffer(struct brw_context *brw)
|
|||||||
(BRW_SURFACE_2D << 29));
|
(BRW_SURFACE_2D << 29));
|
||||||
OUT_RELOC(region->buffer,
|
OUT_RELOC(region->buffer,
|
||||||
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
|
||||||
0);
|
offset);
|
||||||
OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
|
OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
|
||||||
((region->width - 1) << 6) |
|
((region->width - 1) << 6) |
|
||||||
((region->height - 1) << 19));
|
((region->height - 1) << 19));
|
||||||
OUT_BATCH(0);
|
OUT_BATCH(0);
|
||||||
|
|
||||||
if (intel->is_g4x || intel->gen >= 5)
|
if (intel->is_g4x || intel->gen >= 5)
|
||||||
OUT_BATCH(0);
|
OUT_BATCH(tile_x | (tile_y << 16));
|
||||||
|
else
|
||||||
|
assert(tile_x == 0 && tile_y == 0);
|
||||||
|
|
||||||
if (intel->gen >= 6)
|
if (intel->gen >= 6)
|
||||||
OUT_BATCH(0);
|
OUT_BATCH(0);
|
||||||
|
@@ -450,6 +450,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
|
|||||||
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
|
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
|
||||||
struct intel_region *region = irb->region;
|
struct intel_region *region = irb->region;
|
||||||
struct brw_surface_state *surf;
|
struct brw_surface_state *surf;
|
||||||
|
uint32_t tile_x, tile_y;
|
||||||
|
|
||||||
surf = brw_state_batch(brw, sizeof(*surf), 32,
|
surf = brw_state_batch(brw, sizeof(*surf), 32,
|
||||||
&brw->wm.surf_offset[unit]);
|
&brw->wm.surf_offset[unit]);
|
||||||
@@ -488,37 +489,19 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
surf->ss0.surface_type = BRW_SURFACE_2D;
|
surf->ss0.surface_type = BRW_SURFACE_2D;
|
||||||
if (region->tiling == I915_TILING_NONE) {
|
/* reloc */
|
||||||
surf->ss1.base_addr = (region->draw_x +
|
surf->ss1.base_addr = intel_region_tile_offsets(region, &tile_x, &tile_y);
|
||||||
region->draw_y * region->pitch) * region->cpp;
|
|
||||||
} else {
|
|
||||||
uint32_t tile_base, tile_x, tile_y;
|
|
||||||
uint32_t pitch = region->pitch * region->cpp;
|
|
||||||
|
|
||||||
if (region->tiling == I915_TILING_X) {
|
|
||||||
tile_x = region->draw_x % (512 / region->cpp);
|
|
||||||
tile_y = region->draw_y % 8;
|
|
||||||
tile_base = ((region->draw_y / 8) * (8 * pitch));
|
|
||||||
tile_base += (region->draw_x - tile_x) / (512 / region->cpp) * 4096;
|
|
||||||
} else {
|
|
||||||
/* Y */
|
|
||||||
tile_x = region->draw_x % (128 / region->cpp);
|
|
||||||
tile_y = region->draw_y % 32;
|
|
||||||
tile_base = ((region->draw_y / 32) * (32 * pitch));
|
|
||||||
tile_base += (region->draw_x - tile_x) / (128 / region->cpp) * 4096;
|
|
||||||
}
|
|
||||||
assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
|
|
||||||
assert(tile_x % 4 == 0);
|
|
||||||
assert(tile_y % 2 == 0);
|
|
||||||
/* Note that the low bits of these fields are missing, so
|
|
||||||
* there's the possibility of getting in trouble.
|
|
||||||
*/
|
|
||||||
surf->ss1.base_addr = tile_base;
|
|
||||||
surf->ss5.x_offset = tile_x / 4;
|
|
||||||
surf->ss5.y_offset = tile_y / 2;
|
|
||||||
}
|
|
||||||
surf->ss1.base_addr += region->buffer->offset; /* reloc */
|
surf->ss1.base_addr += region->buffer->offset; /* reloc */
|
||||||
|
|
||||||
|
assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
|
||||||
|
/* Note that the low bits of these fields are missing, so
|
||||||
|
* there's the possibility of getting in trouble.
|
||||||
|
*/
|
||||||
|
assert(tile_x % 4 == 0);
|
||||||
|
assert(tile_y % 2 == 0);
|
||||||
|
surf->ss5.x_offset = tile_x / 4;
|
||||||
|
surf->ss5.y_offset = tile_y / 2;
|
||||||
|
|
||||||
surf->ss2.width = rb->Width - 1;
|
surf->ss2.width = rb->Width - 1;
|
||||||
surf->ss2.height = rb->Height - 1;
|
surf->ss2.height = rb->Height - 1;
|
||||||
brw_set_surface_tiling(surf, region->tiling);
|
brw_set_surface_tiling(surf, region->tiling);
|
||||||
|
@@ -524,3 +524,38 @@ intel_region_buffer(struct intel_context *intel,
|
|||||||
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -142,6 +142,10 @@ drm_intel_bo *intel_region_buffer(struct intel_context *intel,
|
|||||||
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,
|
||||||
|
Reference in New Issue
Block a user