r300g: rework resource_copy_region, not changing pipe_resource

Changing pipe_resource was wrong, because it can be used by other contexts
at the same time. This fixes the last possible race condition in r300g
that I know of.

This also fixes blitting NPOT compressed textures. Random pixels sometimes
appeared at the right-hand edge of the texture.

Finally, this removes r300_texture_desc::stride_in_pixels. It makes little
sense with sampler views and surfaces being able to override width0, height0,
and the format entirely.
This commit is contained in:
Marek Olšák
2011-12-29 18:18:38 +01:00
parent ce31970af1
commit ce9d61fec6
9 changed files with 212 additions and 137 deletions

View File

@@ -434,21 +434,14 @@ void r300_decompress_zmask_locked(struct r300_context *r300)
pipe_surface_reference(&r300->locked_zbuffer, NULL); pipe_surface_reference(&r300->locked_zbuffer, NULL);
} }
/* Copy a block of pixels from one surface to another using HW. */ bool r300_is_blit_supported(enum pipe_format format)
static void r300_hw_copy_region(struct pipe_context* pipe,
struct pipe_resource *dst,
unsigned dst_level,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_resource *src,
unsigned src_level,
const struct pipe_box *src_box)
{ {
struct r300_context* r300 = r300_context(pipe); const struct util_format_description *desc =
util_format_description(format);
r300_blitter_begin(r300, R300_COPY); return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ||
util_blitter_copy_texture(r300->blitter, dst, dst_level, dstx, dsty, dstz, desc->layout == UTIL_FORMAT_LAYOUT_S3TC ||
src, src_level, src_box, TRUE); desc->layout == UTIL_FORMAT_LAYOUT_RGTC;
r300_blitter_end(r300);
} }
/* Copy a block of pixels from one surface to another. */ /* Copy a block of pixels from one surface to another. */
@@ -460,24 +453,120 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
unsigned src_level, unsigned src_level,
const struct pipe_box *src_box) const struct pipe_box *src_box)
{ {
struct pipe_screen *screen = pipe->screen;
struct r300_context *r300 = r300_context(pipe); struct r300_context *r300 = r300_context(pipe);
struct pipe_framebuffer_state *fb = struct pipe_framebuffer_state *fb =
(struct pipe_framebuffer_state*)r300->fb_state.state; (struct pipe_framebuffer_state*)r300->fb_state.state;
struct pipe_resource old_src = *src; unsigned src_width0 = r300_resource(src)->tex.width0;
struct pipe_resource old_dst = *dst; unsigned src_height0 = r300_resource(src)->tex.height0;
struct pipe_resource new_src = old_src; unsigned dst_width0 = r300_resource(dst)->tex.width0;
struct pipe_resource new_dst = old_dst; unsigned dst_height0 = r300_resource(dst)->tex.height0;
const struct util_format_description *desc = unsigned layout;
util_format_description(dst->format);
struct pipe_box box; struct pipe_box box;
struct pipe_sampler_view src_templ, *src_view;
struct pipe_surface dst_templ, *dst_view;
/* Fallback for buffers. */ /* Fallback for buffers. */
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { if ((dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) ||
!r300_is_blit_supported(dst->format)) {
util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box); src, src_level, src_box);
return; return;
} }
/* The code below changes the texture format so that the copy can be done
* on hardware. E.g. depth-stencil surfaces are copied as RGBA
* colorbuffers. */
util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz, src_box);
util_blitter_default_src_texture(&src_templ, src, src_level);
layout = util_format_description(dst_templ.format)->layout;
/* Handle non-renderable plain formats. */
if (layout == UTIL_FORMAT_LAYOUT_PLAIN &&
(!screen->is_format_supported(screen, src_templ.format, src->target,
src->nr_samples,
PIPE_BIND_SAMPLER_VIEW) ||
!screen->is_format_supported(screen, dst_templ.format, dst->target,
dst->nr_samples,
PIPE_BIND_RENDER_TARGET))) {
switch (util_format_get_blocksize(dst_templ.format)) {
case 1:
dst_templ.format = PIPE_FORMAT_I8_UNORM;
break;
case 2:
dst_templ.format = PIPE_FORMAT_B4G4R4A4_UNORM;
break;
case 4:
dst_templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 8:
dst_templ.format = PIPE_FORMAT_R16G16B16A16_UNORM;
break;
default:
debug_printf("r300: copy_region: Unhandled format: %s. Falling back to software.\n"
"r300: copy_region: Software fallback doesn't work for tiled textures.\n",
util_format_short_name(dst_templ.format));
}
src_templ.format = dst_templ.format;
}
/* Handle compressed formats. */
if (layout == UTIL_FORMAT_LAYOUT_S3TC ||
layout == UTIL_FORMAT_LAYOUT_RGTC) {
assert(src_templ.format == dst_templ.format);
box = *src_box;
src_box = &box;
dst_width0 = align(dst_width0, 4);
dst_height0 = align(dst_height0, 4);
src_width0 = align(src_width0, 4);
src_height0 = align(src_height0, 4);
box.width = align(box.width, 4);
box.height = align(box.height, 4);
switch (util_format_get_blocksize(dst_templ.format)) {
case 8:
/* one 4x4 pixel block has 8 bytes.
* we set 1 pixel = 4 bytes ===> 1 block corrensponds to 2 pixels. */
dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
dst_width0 = dst_width0 / 2;
src_width0 = src_width0 / 2;
dstx /= 2;
box.x /= 2;
box.width /= 2;
break;
case 16:
/* one 4x4 pixel block has 16 bytes.
* we set 1 pixel = 4 bytes ===> 1 block corresponds to 4 pixels. */
dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
break;
}
src_templ.format = dst_templ.format;
dst_height0 = dst_height0 / 4;
src_height0 = src_height0 / 4;
dsty /= 4;
box.y /= 4;
box.height /= 4;
}
/* Fallback for textures. */
if (!screen->is_format_supported(screen, dst_templ.format,
dst->target, dst->nr_samples,
PIPE_BIND_RENDER_TARGET) ||
!screen->is_format_supported(screen, src_templ.format,
src->target, src->nr_samples,
PIPE_BIND_SAMPLER_VIEW)) {
assert(0 && "this shouldn't happen, update r300_is_blit_supported");
util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box);
return;
}
/* Decompress ZMASK. */
if (r300->zmask_in_use && !r300->locked_zbuffer) { if (r300->zmask_in_use && !r300->locked_zbuffer) {
if (fb->zsbuf->texture == src || if (fb->zsbuf->texture == src ||
fb->zsbuf->texture == dst) { fb->zsbuf->texture == dst) {
@@ -485,78 +574,17 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
} }
} }
/* Handle non-renderable plain formats. */ dst_view = r300_create_surface_custom(pipe, dst, &dst_templ, dst_width0, dst_height0);
if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && src_view = r300_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0);
(desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB ||
!pipe->screen->is_format_supported(pipe->screen,
src->format, src->target,
src->nr_samples,
PIPE_BIND_SAMPLER_VIEW) ||
!pipe->screen->is_format_supported(pipe->screen,
dst->format, dst->target,
dst->nr_samples,
PIPE_BIND_RENDER_TARGET))) {
switch (util_format_get_blocksize(old_dst.format)) {
case 1:
new_dst.format = PIPE_FORMAT_I8_UNORM;
break;
case 2:
new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM;
break;
case 4:
new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 8:
new_dst.format = PIPE_FORMAT_R16G16B16A16_UNORM;
break;
default:
debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
"r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
util_format_short_name(dst->format));
}
new_src.format = new_dst.format;
}
/* Handle compressed formats. */ r300_blitter_begin(r300, R300_COPY);
if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC || util_blitter_copy_texture_view(r300->blitter, dst_view, dstx, dsty,
desc->layout == UTIL_FORMAT_LAYOUT_RGTC) { src_view, src_box,
switch (util_format_get_blocksize(old_dst.format)) { src_width0, src_height0);
case 8: r300_blitter_end(r300);
/* 1 pixel = 4 bits,
* we set 1 pixel = 2 bytes ===> 4 times larger pixels. */
new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM;
break;
case 16:
/* 1 pixel = 8 bits,
* we set 1 pixel = 4 bytes ===> 4 times larger pixels. */
new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
}
/* Since the pixels are 4 times larger, we must decrease pipe_surface_reference(&dst_view, NULL);
* the image size and the coordinates 4 times. */ pipe_sampler_view_reference(&src_view, NULL);
new_src.format = new_dst.format;
new_dst.height0 = (new_dst.height0 + 3) / 4;
new_src.height0 = (new_src.height0 + 3) / 4;
dsty /= 4;
box = *src_box;
box.y /= 4;
box.height = (box.height + 3) / 4;
src_box = &box;
}
if (old_src.format != new_src.format)
r300_resource_set_properties(pipe->screen, src, &new_src);
if (old_dst.format != new_dst.format)
r300_resource_set_properties(pipe->screen, dst, &new_dst);
r300_hw_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box);
if (old_src.format != new_src.format)
r300_resource_set_properties(pipe->screen, src, &old_src);
if (old_dst.format != new_dst.format)
r300_resource_set_properties(pipe->screen, dst, &old_dst);
} }
void r300_init_blit_functions(struct r300_context *r300) void r300_init_blit_functions(struct r300_context *r300)

View File

@@ -196,6 +196,10 @@ struct r300_texture_format_state {
struct r300_sampler_view { struct r300_sampler_view {
struct pipe_sampler_view base; struct pipe_sampler_view base;
/* For resource_copy_region. */
unsigned width0_override;
unsigned height0_override;
/* Swizzles in the UTIL_FORMAT_SWIZZLE_* representation, /* Swizzles in the UTIL_FORMAT_SWIZZLE_* representation,
* derived from base. */ * derived from base. */
unsigned char swizzle[4]; unsigned char swizzle[4];
@@ -339,7 +343,6 @@ struct r300_texture_desc {
unsigned offset_in_bytes[R300_MAX_TEXTURE_LEVELS]; unsigned offset_in_bytes[R300_MAX_TEXTURE_LEVELS];
/* Strides for each mip-level. */ /* Strides for each mip-level. */
unsigned stride_in_pixels[R300_MAX_TEXTURE_LEVELS];
unsigned stride_in_bytes[R300_MAX_TEXTURE_LEVELS]; unsigned stride_in_bytes[R300_MAX_TEXTURE_LEVELS];
/* Size of one zslice or face or 2D image based on the texture target. */ /* Size of one zslice or face or 2D image based on the texture target. */
@@ -395,10 +398,6 @@ struct r300_resource
/* Texture description (addressing, layout, special features). */ /* Texture description (addressing, layout, special features). */
struct r300_texture_desc tex; struct r300_texture_desc tex;
/* Registers carrying texture format data. */
/* Only format-independent bits should be filled in. */
struct r300_texture_format_state tx_format;
/* This is the level tiling flags were last time set for. /* This is the level tiling flags were last time set for.
* It's used to prevent redundant tiling-flags changes from happening.*/ * It's used to prevent redundant tiling-flags changes from happening.*/
unsigned surface_level; unsigned surface_level;
@@ -680,6 +679,7 @@ void r300_init_resource_functions(struct r300_context* r300);
void r300_decompress_zmask(struct r300_context *r300); void r300_decompress_zmask(struct r300_context *r300);
void r300_decompress_zmask_locked_unsafe(struct r300_context *r300); void r300_decompress_zmask_locked_unsafe(struct r300_context *r300);
void r300_decompress_zmask_locked(struct r300_context *r300); void r300_decompress_zmask_locked(struct r300_context *r300);
bool r300_is_blit_supported(enum pipe_format format);
/* r300_flush.c */ /* r300_flush.c */
void r300_flush(struct pipe_context *pipe, void r300_flush(struct pipe_context *pipe,
@@ -718,6 +718,13 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
enum r300_fb_state_change change); enum r300_fb_state_change change);
void r300_mark_fs_code_dirty(struct r300_context *r300); void r300_mark_fs_code_dirty(struct r300_context *r300);
struct pipe_sampler_view *
r300_create_sampler_view_custom(struct pipe_context *pipe,
struct pipe_resource *texture,
const struct pipe_sampler_view *templ,
unsigned width0_override,
unsigned height0_override);
/* r300_state_derived.c */ /* r300_state_derived.c */
void r300_update_derived_state(struct r300_context* r300); void r300_update_derived_state(struct r300_context* r300);

View File

@@ -756,7 +756,7 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
"r300: %s[%i] Dim: %ix%i, Firstlayer: %i, " "r300: %s[%i] Dim: %ix%i, Firstlayer: %i, "
"Lastlayer: %i, Level: %i, Format: %s\n" "Lastlayer: %i, Level: %i, Format: %s\n"
"r300: TEX: Macro: %s, Micro: %s, Pitch: %i, " "r300: TEX: Macro: %s, Micro: %s, "
"Dim: %ix%ix%i, LastLevel: %i, Format: %s\n", "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n",
binding, index, surf->width, surf->height, binding, index, surf->width, surf->height,
@@ -765,9 +765,8 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
rtex->tex.macrotile[0] ? "YES" : " NO", rtex->tex.macrotile[0] ? "YES" : " NO",
rtex->tex.microtile ? "YES" : " NO", rtex->tex.microtile ? "YES" : " NO",
rtex->tex.stride_in_pixels[0],
tex->width0, tex->height0, tex->depth0, tex->width0, tex->height0, tex->depth0,
tex->last_level, util_format_short_name(tex->format)); tex->last_level, util_format_short_name(surf->format));
} }
void r300_mark_fb_state_dirty(struct r300_context *r300, void r300_mark_fb_state_dirty(struct r300_context *r300,
@@ -888,7 +887,7 @@ r300_set_framebuffer_state(struct pipe_context* pipe,
r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE); r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE);
if (state->zsbuf) { if (state->zsbuf) {
switch (util_format_get_blocksize(state->zsbuf->texture->format)) { switch (util_format_get_blocksize(state->zsbuf->format)) {
case 2: case 2:
zbuffer_bpp = 16; zbuffer_bpp = 16;
break; break;
@@ -1458,10 +1457,12 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
} }
} }
static struct pipe_sampler_view * struct pipe_sampler_view *
r300_create_sampler_view(struct pipe_context *pipe, r300_create_sampler_view_custom(struct pipe_context *pipe,
struct pipe_resource *texture, struct pipe_resource *texture,
const struct pipe_sampler_view *templ) const struct pipe_sampler_view *templ,
unsigned width0_override,
unsigned height0_override)
{ {
struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view); struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
struct r300_resource *tex = r300_resource(texture); struct r300_resource *tex = r300_resource(texture);
@@ -1477,6 +1478,8 @@ r300_create_sampler_view(struct pipe_context *pipe,
view->base.texture = NULL; view->base.texture = NULL;
pipe_resource_reference(&view->base.texture, texture); pipe_resource_reference(&view->base.texture, texture);
view->width0_override = width0_override;
view->height0_override = height0_override;
view->swizzle[0] = templ->swizzle_r; view->swizzle[0] = templ->swizzle_r;
view->swizzle[1] = templ->swizzle_g; view->swizzle[1] = templ->swizzle_g;
view->swizzle[2] = templ->swizzle_b; view->swizzle[2] = templ->swizzle_b;
@@ -1493,7 +1496,10 @@ r300_create_sampler_view(struct pipe_context *pipe,
} }
assert(hwformat != ~0); assert(hwformat != ~0);
view->format = tex->tx_format; r300_texture_setup_format_state(r300_screen(pipe->screen), tex,
templ->format, 0,
width0_override, height0_override,
&view->format);
view->format.format1 |= hwformat; view->format.format1 |= hwformat;
if (is_r500) { if (is_r500) {
view->format.format2 |= r500_tx_format_msb_bit(templ->format); view->format.format2 |= r500_tx_format_msb_bit(templ->format);
@@ -1503,6 +1509,17 @@ r300_create_sampler_view(struct pipe_context *pipe,
return (struct pipe_sampler_view*)view; return (struct pipe_sampler_view*)view;
} }
static struct pipe_sampler_view *
r300_create_sampler_view(struct pipe_context *pipe,
struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
{
return r300_create_sampler_view_custom(pipe, texture, templ,
r300_resource(texture)->tex.width0,
r300_resource(texture)->tex.height0);
}
static void static void
r300_sampler_view_destroy(struct pipe_context *pipe, r300_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view) struct pipe_sampler_view *view)

View File

@@ -785,7 +785,10 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
offset = tex->tex.offset_in_bytes[base_level]; offset = tex->tex.offset_in_bytes[base_level];
r300_texture_setup_format_state(r300->screen, tex, r300_texture_setup_format_state(r300->screen, tex,
view->base.format,
base_level, base_level,
view->width0_override,
view->height0_override,
&texstate->format); &texstate->format);
texstate->format.tile_config |= offset & 0xffffffe0; texstate->format.tile_config |= offset & 0xffffffe0;
assert((offset & 0x1f) == 0); assert((offset & 0x1f) == 0);
@@ -795,11 +798,11 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
texstate->format.format1 |= view->texcache_region; texstate->format.format1 |= view->texcache_region;
/* Depth textures are kinda special. */ /* Depth textures are kinda special. */
if (util_format_is_depth_or_stencil(tex->b.b.b.format)) { if (util_format_is_depth_or_stencil(view->base.format)) {
unsigned char depth_swizzle[4]; unsigned char depth_swizzle[4];
if (!r300->screen->caps.is_r500 && if (!r300->screen->caps.is_r500 &&
util_format_get_blocksizebits(tex->b.b.b.format) == 32) { util_format_get_blocksizebits(view->base.format) == 32) {
/* X24x8 is sampled as Y16X16 on r3xx-r4xx. /* X24x8 is sampled as Y16X16 on r3xx-r4xx.
* The depth here is at the Y component. */ * The depth here is at the Y component. */
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
@@ -824,7 +827,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
} }
if (r300->screen->caps.dxtc_swizzle && if (r300->screen->caps.dxtc_swizzle &&
util_format_is_compressed(tex->b.b.b.format)) { util_format_is_compressed(view->base.format)) {
texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE; texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE;
} }
@@ -870,7 +873,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
} }
/* Float textures only support nearest and mip-nearest filtering. */ /* Float textures only support nearest and mip-nearest filtering. */
if (util_format_is_float(tex->b.b.b.format)) { if (util_format_is_float(view->base.format)) {
/* No MAG linear filtering. */ /* No MAG linear filtering. */
if ((texstate->filter0 & R300_TX_MAG_FILTER_MASK) == if ((texstate->filter0 & R300_TX_MAG_FILTER_MASK) ==
R300_TX_MAG_FILTER_LINEAR) { R300_TX_MAG_FILTER_LINEAR) {

View File

@@ -722,7 +722,10 @@ boolean r300_is_sampler_format_supported(enum pipe_format format)
void r300_texture_setup_format_state(struct r300_screen *screen, void r300_texture_setup_format_state(struct r300_screen *screen,
struct r300_resource *tex, struct r300_resource *tex,
enum pipe_format format,
unsigned level, unsigned level,
unsigned width0_override,
unsigned height0_override,
struct r300_texture_format_state *out) struct r300_texture_format_state *out)
{ {
struct pipe_resource *pt = &tex->b.b.b; struct pipe_resource *pt = &tex->b.b.b;
@@ -731,8 +734,8 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
unsigned width, height, depth; unsigned width, height, depth;
unsigned txwidth, txheight, txdepth; unsigned txwidth, txheight, txdepth;
width = u_minify(desc->width0, level); width = u_minify(width0_override, level);
height = u_minify(desc->height0, level); height = u_minify(height0_override, level);
depth = u_minify(desc->depth0, level); depth = u_minify(desc->depth0, level);
txwidth = (width - 1) & 0x7ff; txwidth = (width - 1) & 0x7ff;
@@ -752,9 +755,11 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
R300_TX_DEPTH(txdepth); R300_TX_DEPTH(txdepth);
if (desc->uses_stride_addressing) { if (desc->uses_stride_addressing) {
unsigned stride =
r300_stride_to_width(format, desc->stride_in_bytes[level]);
/* rectangles love this */ /* rectangles love this */
out->format0 |= R300_TX_PITCH_EN; out->format0 |= R300_TX_PITCH_EN;
out->format2 = (desc->stride_in_pixels[level] - 1) & 0x1fff; out->format2 = (stride - 1) & 0x1fff;
} }
if (pt->target == PIPE_TEXTURE_CUBE) { if (pt->target == PIPE_TEXTURE_CUBE) {
@@ -803,11 +808,13 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
{ {
struct r300_resource *tex = r300_resource(surf->base.texture); struct r300_resource *tex = r300_resource(surf->base.texture);
unsigned level = surf->base.u.tex.level; unsigned level = surf->base.u.tex.level;
unsigned stride =
r300_stride_to_width(surf->base.format, tex->tex.stride_in_bytes[level]);
/* Set framebuffer state. */ /* Set framebuffer state. */
if (util_format_is_depth_or_stencil(surf->base.format)) { if (util_format_is_depth_or_stencil(surf->base.format)) {
surf->pitch = surf->pitch =
tex->tex.stride_in_pixels[level] | stride |
R300_DEPTHMACROTILE(tex->tex.macrotile[level]) | R300_DEPTHMACROTILE(tex->tex.macrotile[level]) |
R300_DEPTHMICROTILE(tex->tex.microtile); R300_DEPTHMICROTILE(tex->tex.microtile);
surf->format = r300_translate_zsformat(surf->base.format); surf->format = r300_translate_zsformat(surf->base.format);
@@ -815,7 +822,7 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level]; surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level];
} else { } else {
surf->pitch = surf->pitch =
tex->tex.stride_in_pixels[level] | stride |
r300_translate_colorformat(surf->base.format) | r300_translate_colorformat(surf->base.format) |
R300_COLOR_TILE(tex->tex.macrotile[level]) | R300_COLOR_TILE(tex->tex.macrotile[level]) |
R300_COLOR_MICROTILE(tex->tex.microtile); R300_COLOR_MICROTILE(tex->tex.microtile);
@@ -823,7 +830,7 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
} }
} }
void r300_resource_set_properties(struct pipe_screen *screen, static void r300_resource_set_properties(struct pipe_screen *screen,
struct pipe_resource *tex, struct pipe_resource *tex,
const struct pipe_resource *new_properties) const struct pipe_resource *new_properties)
{ {
@@ -836,7 +843,6 @@ void r300_resource_set_properties(struct pipe_screen *screen,
util_format_short_name(new_properties->format)); util_format_short_name(new_properties->format));
r300_texture_desc_init(rscreen, res, new_properties); r300_texture_desc_init(rscreen, res, new_properties);
r300_texture_setup_format_state(rscreen, res, 0, &res->tx_format);
} }
static void r300_texture_destroy(struct pipe_screen *screen, static void r300_texture_destroy(struct pipe_screen *screen,
@@ -995,9 +1001,11 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
/* Not required to implement u_resource_vtbl, consider moving to another file: /* Not required to implement u_resource_vtbl, consider moving to another file:
*/ */
struct pipe_surface* r300_create_surface(struct pipe_context * ctx, struct pipe_surface* r300_create_surface_custom(struct pipe_context * ctx,
struct pipe_resource* texture, struct pipe_resource* texture,
const struct pipe_surface *surf_tmpl) const struct pipe_surface *surf_tmpl,
unsigned width0_override,
unsigned height0_override)
{ {
struct r300_resource* tex = r300_resource(texture); struct r300_resource* tex = r300_resource(texture);
struct r300_surface* surface = CALLOC_STRUCT(r300_surface); struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
@@ -1012,8 +1020,8 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
pipe_resource_reference(&surface->base.texture, texture); pipe_resource_reference(&surface->base.texture, texture);
surface->base.context = ctx; surface->base.context = ctx;
surface->base.format = surf_tmpl->format; surface->base.format = surf_tmpl->format;
surface->base.width = u_minify(texture->width0, level); surface->base.width = u_minify(width0_override, level);
surface->base.height = u_minify(texture->height0, level); surface->base.height = u_minify(height0_override, level);
surface->base.usage = surf_tmpl->usage; surface->base.usage = surf_tmpl->usage;
surface->base.u.tex.level = level; surface->base.u.tex.level = level;
surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer; surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
@@ -1036,7 +1044,7 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
surface->cbzb_width = align(surface->base.width, 64); surface->cbzb_width = align(surface->base.width, 64);
/* Height must be aligned to the size of a tile. */ /* Height must be aligned to the size of a tile. */
tile_height = r300_get_pixel_alignment(tex->b.b.b.format, tile_height = r300_get_pixel_alignment(surface->base.format,
tex->b.b.b.nr_samples, tex->b.b.b.nr_samples,
tex->tex.microtile, tex->tex.microtile,
tex->tex.macrotile[level], tex->tex.macrotile[level],
@@ -1070,6 +1078,15 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
return &surface->base; return &surface->base;
} }
struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
struct pipe_resource* texture,
const struct pipe_surface *surf_tmpl)
{
return r300_create_surface_custom(ctx, texture, surf_tmpl,
texture->width0,
texture->height0);
}
/* Not required to implement u_resource_vtbl, consider moving to another file: /* Not required to implement u_resource_vtbl, consider moving to another file:
*/ */
void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s) void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s)

View File

@@ -46,10 +46,6 @@ uint32_t r300_translate_texformat(enum pipe_format format,
uint32_t r500_tx_format_msb_bit(enum pipe_format format); uint32_t r500_tx_format_msb_bit(enum pipe_format format);
void r300_resource_set_properties(struct pipe_screen *screen,
struct pipe_resource *tex,
const struct pipe_resource *new_properties);
boolean r300_is_colorbuffer_format_supported(enum pipe_format format); boolean r300_is_colorbuffer_format_supported(enum pipe_format format);
boolean r300_is_zs_format_supported(enum pipe_format format); boolean r300_is_zs_format_supported(enum pipe_format format);
@@ -58,7 +54,10 @@ boolean r300_is_sampler_format_supported(enum pipe_format format);
void r300_texture_setup_format_state(struct r300_screen *screen, void r300_texture_setup_format_state(struct r300_screen *screen,
struct r300_resource *tex, struct r300_resource *tex,
enum pipe_format format,
unsigned level, unsigned level,
unsigned width0_override,
unsigned height0_override,
struct r300_texture_format_state *out); struct r300_texture_format_state *out);
boolean r300_resource_get_handle(struct pipe_screen* screen, boolean r300_resource_get_handle(struct pipe_screen* screen,
@@ -74,6 +73,11 @@ struct pipe_resource*
r300_texture_create(struct pipe_screen* screen, r300_texture_create(struct pipe_screen* screen,
const struct pipe_resource* templ); const struct pipe_resource* templ);
struct pipe_surface* r300_create_surface_custom(struct pipe_context * ctx,
struct pipe_resource* texture,
const struct pipe_surface *surf_tmpl,
unsigned width0_override,
unsigned height0_override);
struct pipe_surface* r300_create_surface(struct pipe_context *ctx, struct pipe_surface* r300_create_surface(struct pipe_context *ctx,
struct pipe_resource* texture, struct pipe_resource* texture,

View File

@@ -206,8 +206,8 @@ static unsigned r300_texture_get_nblocksy(struct r300_resource *tex,
} }
/* Get a width in pixels from a stride in bytes. */ /* Get a width in pixels from a stride in bytes. */
static unsigned stride_to_width(enum pipe_format format, unsigned r300_stride_to_width(enum pipe_format format,
unsigned stride_in_bytes) unsigned stride_in_bytes)
{ {
return (stride_in_bytes / util_format_get_blocksize(format)) * return (stride_in_bytes / util_format_get_blocksize(format)) *
util_format_get_blockwidth(format); util_format_get_blockwidth(format);
@@ -261,7 +261,6 @@ static void r300_setup_miptree(struct r300_screen *screen,
tex->tex.size_in_bytes = tex->tex.offset_in_bytes[i] + size; tex->tex.size_in_bytes = tex->tex.offset_in_bytes[i] + size;
tex->tex.layer_size_in_bytes[i] = layer_size; tex->tex.layer_size_in_bytes[i] = layer_size;
tex->tex.stride_in_bytes[i] = stride; tex->tex.stride_in_bytes[i] = stride;
tex->tex.stride_in_pixels[i] = stride_to_width(tex->b.b.b.format, stride);
tex->tex.cbzb_allowed[i] = tex->tex.cbzb_allowed[i] && aligned_for_cbzb; tex->tex.cbzb_allowed[i] = tex->tex.cbzb_allowed[i] && aligned_for_cbzb;
SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d " SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d "
@@ -277,7 +276,7 @@ static void r300_setup_flags(struct r300_resource *tex)
tex->tex.uses_stride_addressing = tex->tex.uses_stride_addressing =
!util_is_power_of_two(tex->b.b.b.width0) || !util_is_power_of_two(tex->b.b.b.width0) ||
(tex->tex.stride_in_bytes_override && (tex->tex.stride_in_bytes_override &&
stride_to_width(tex->b.b.b.format, r300_stride_to_width(tex->b.b.b.format,
tex->tex.stride_in_bytes_override) != tex->b.b.b.width0); tex->tex.stride_in_bytes_override) != tex->b.b.b.width0);
tex->tex.is_npot = tex->tex.is_npot =
@@ -368,7 +367,9 @@ static void r300_setup_hyperz_properties(struct r300_screen *screen,
for (i = 0; i <= tex->b.b.b.last_level; i++) { for (i = 0; i <= tex->b.b.b.last_level; i++) {
unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height; unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height;
stride = align(tex->tex.stride_in_pixels[i], 16); stride = r300_stride_to_width(tex->b.b.b.format,
tex->tex.stride_in_bytes[i]);
stride = align(stride, 16);
height = u_minify(tex->b.b.b.height0, i); height = u_minify(tex->b.b.b.height0, i);
/* The 8x8 compression mode needs macrotiling. */ /* The 8x8 compression mode needs macrotiling. */
@@ -467,7 +468,7 @@ static void r300_tex_print_info(struct r300_resource *tex,
func, func,
tex->tex.macrotile[0] ? "YES" : " NO", tex->tex.macrotile[0] ? "YES" : " NO",
tex->tex.microtile ? "YES" : " NO", tex->tex.microtile ? "YES" : " NO",
tex->tex.stride_in_pixels[0], r300_stride_to_width(tex->b.b.b.format, tex->tex.stride_in_bytes[0]),
tex->b.b.b.width0, tex->b.b.b.height0, tex->b.b.b.depth0, tex->b.b.b.width0, tex->b.b.b.height0, tex->b.b.b.depth0,
tex->b.b.b.last_level, tex->tex.size_in_bytes, tex->b.b.b.last_level, tex->tex.size_in_bytes,
util_format_short_name(tex->b.b.b.format)); util_format_short_name(tex->b.b.b.format));

View File

@@ -50,4 +50,7 @@ void r300_texture_desc_init(struct r300_screen *rscreen,
unsigned r300_texture_get_offset(struct r300_resource *tex, unsigned r300_texture_get_offset(struct r300_resource *tex,
unsigned level, unsigned layer); unsigned level, unsigned layer);
unsigned r300_stride_to_width(enum pipe_format format,
unsigned stride_in_bytes);
#endif #endif

View File

@@ -87,9 +87,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
struct r300_resource *tex = r300_resource(texture); struct r300_resource *tex = r300_resource(texture);
struct r300_transfer *trans; struct r300_transfer *trans;
struct pipe_resource base; struct pipe_resource base;
boolean referenced_cs, referenced_hw, blittable; boolean referenced_cs, referenced_hw;
const struct util_format_description *desc =
util_format_description(texture->format);
referenced_cs = referenced_cs =
r300->rws->cs_is_buffer_referenced(r300->cs, tex->cs_buf); r300->rws->cs_is_buffer_referenced(r300->cs, tex->cs_buf);
@@ -100,10 +98,6 @@ r300_texture_get_transfer(struct pipe_context *ctx,
r300->rws->buffer_is_busy(tex->buf, RADEON_USAGE_READWRITE); r300->rws->buffer_is_busy(tex->buf, RADEON_USAGE_READWRITE);
} }
blittable = desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ||
desc->layout == UTIL_FORMAT_LAYOUT_S3TC ||
desc->layout == UTIL_FORMAT_LAYOUT_RGTC;
trans = CALLOC_STRUCT(r300_transfer); trans = CALLOC_STRUCT(r300_transfer);
if (trans) { if (trans) {
/* Initialize the transfer object. */ /* Initialize the transfer object. */
@@ -116,7 +110,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,
* for this transfer. * for this transfer.
* Also make write transfers pipelined. */ * Also make write transfers pipelined. */
if (tex->tex.microtile || tex->tex.macrotile[level] || if (tex->tex.microtile || tex->tex.macrotile[level] ||
(referenced_hw && blittable && !(usage & PIPE_TRANSFER_READ))) { (referenced_hw && !(usage & PIPE_TRANSFER_READ) &&
r300_is_blit_supported(texture->format))) {
if (r300->blitter->running) { if (r300->blitter->running) {
fprintf(stderr, "r300: ERROR: Blitter recursion in texture_get_transfer.\n"); fprintf(stderr, "r300: ERROR: Blitter recursion in texture_get_transfer.\n");
os_break(); os_break();