summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300/r300_texture.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2011-12-29 18:18:38 +0100
committerMarek Olšák <[email protected]>2012-01-01 11:47:05 +0100
commitce9d61fec64138ebf8d0bec2511e66593297b7d5 (patch)
tree3e60c2743b8df17392415e7d22b0e10446343624 /src/gallium/drivers/r300/r300_texture.c
parentce31970af16558ebd60cfae33c000252bc3e1cbf (diff)
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.
Diffstat (limited to 'src/gallium/drivers/r300/r300_texture.c')
-rw-r--r--src/gallium/drivers/r300/r300_texture.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 6fc60fb60d6..b63afa18c2b 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -722,7 +722,10 @@ boolean r300_is_sampler_format_supported(enum pipe_format format)
void r300_texture_setup_format_state(struct r300_screen *screen,
struct r300_resource *tex,
+ enum pipe_format format,
unsigned level,
+ unsigned width0_override,
+ unsigned height0_override,
struct r300_texture_format_state *out)
{
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 txwidth, txheight, txdepth;
- width = u_minify(desc->width0, level);
- height = u_minify(desc->height0, level);
+ width = u_minify(width0_override, level);
+ height = u_minify(height0_override, level);
depth = u_minify(desc->depth0, level);
txwidth = (width - 1) & 0x7ff;
@@ -752,9 +755,11 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
R300_TX_DEPTH(txdepth);
if (desc->uses_stride_addressing) {
+ unsigned stride =
+ r300_stride_to_width(format, desc->stride_in_bytes[level]);
/* rectangles love this */
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) {
@@ -803,11 +808,13 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
{
struct r300_resource *tex = r300_resource(surf->base.texture);
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. */
if (util_format_is_depth_or_stencil(surf->base.format)) {
surf->pitch =
- tex->tex.stride_in_pixels[level] |
+ stride |
R300_DEPTHMACROTILE(tex->tex.macrotile[level]) |
R300_DEPTHMICROTILE(tex->tex.microtile);
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];
} else {
surf->pitch =
- tex->tex.stride_in_pixels[level] |
+ stride |
r300_translate_colorformat(surf->base.format) |
R300_COLOR_TILE(tex->tex.macrotile[level]) |
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,
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));
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,
@@ -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:
*/
-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,
- 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_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);
surface->base.context = ctx;
surface->base.format = surf_tmpl->format;
- surface->base.width = u_minify(texture->width0, level);
- surface->base.height = u_minify(texture->height0, level);
+ surface->base.width = u_minify(width0_override, level);
+ surface->base.height = u_minify(height0_override, level);
surface->base.usage = surf_tmpl->usage;
surface->base.u.tex.level = level;
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);
/* 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->tex.microtile,
tex->tex.macrotile[level],
@@ -1070,6 +1078,15 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
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:
*/
void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s)