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:
@@ -434,21 +434,14 @@ void r300_decompress_zmask_locked(struct r300_context *r300)
|
||||
pipe_surface_reference(&r300->locked_zbuffer, NULL);
|
||||
}
|
||||
|
||||
/* Copy a block of pixels from one surface to another using HW. */
|
||||
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)
|
||||
bool r300_is_blit_supported(enum pipe_format format)
|
||||
{
|
||||
struct r300_context* r300 = r300_context(pipe);
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(format);
|
||||
|
||||
r300_blitter_begin(r300, R300_COPY);
|
||||
util_blitter_copy_texture(r300->blitter, dst, dst_level, dstx, dsty, dstz,
|
||||
src, src_level, src_box, TRUE);
|
||||
r300_blitter_end(r300);
|
||||
return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ||
|
||||
desc->layout == UTIL_FORMAT_LAYOUT_S3TC ||
|
||||
desc->layout == UTIL_FORMAT_LAYOUT_RGTC;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
const struct pipe_box *src_box)
|
||||
{
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct r300_context *r300 = r300_context(pipe);
|
||||
struct pipe_framebuffer_state *fb =
|
||||
(struct pipe_framebuffer_state*)r300->fb_state.state;
|
||||
struct pipe_resource old_src = *src;
|
||||
struct pipe_resource old_dst = *dst;
|
||||
struct pipe_resource new_src = old_src;
|
||||
struct pipe_resource new_dst = old_dst;
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(dst->format);
|
||||
unsigned src_width0 = r300_resource(src)->tex.width0;
|
||||
unsigned src_height0 = r300_resource(src)->tex.height0;
|
||||
unsigned dst_width0 = r300_resource(dst)->tex.width0;
|
||||
unsigned dst_height0 = r300_resource(dst)->tex.height0;
|
||||
unsigned layout;
|
||||
struct pipe_box box;
|
||||
struct pipe_sampler_view src_templ, *src_view;
|
||||
struct pipe_surface dst_templ, *dst_view;
|
||||
|
||||
/* 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,
|
||||
src, src_level, src_box);
|
||||
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 (fb->zsbuf->texture == src ||
|
||||
fb->zsbuf->texture == dst) {
|
||||
@@ -485,78 +574,17 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle non-renderable plain formats. */
|
||||
if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
|
||||
(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;
|
||||
}
|
||||
dst_view = r300_create_surface_custom(pipe, dst, &dst_templ, dst_width0, dst_height0);
|
||||
src_view = r300_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0);
|
||||
|
||||
/* Handle compressed formats. */
|
||||
if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC ||
|
||||
desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
|
||||
switch (util_format_get_blocksize(old_dst.format)) {
|
||||
case 8:
|
||||
/* 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;
|
||||
}
|
||||
r300_blitter_begin(r300, R300_COPY);
|
||||
util_blitter_copy_texture_view(r300->blitter, dst_view, dstx, dsty,
|
||||
src_view, src_box,
|
||||
src_width0, src_height0);
|
||||
r300_blitter_end(r300);
|
||||
|
||||
/* Since the pixels are 4 times larger, we must decrease
|
||||
* the image size and the coordinates 4 times. */
|
||||
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);
|
||||
pipe_surface_reference(&dst_view, NULL);
|
||||
pipe_sampler_view_reference(&src_view, NULL);
|
||||
}
|
||||
|
||||
void r300_init_blit_functions(struct r300_context *r300)
|
||||
|
@@ -196,6 +196,10 @@ struct r300_texture_format_state {
|
||||
struct r300_sampler_view {
|
||||
struct pipe_sampler_view base;
|
||||
|
||||
/* For resource_copy_region. */
|
||||
unsigned width0_override;
|
||||
unsigned height0_override;
|
||||
|
||||
/* Swizzles in the UTIL_FORMAT_SWIZZLE_* representation,
|
||||
* derived from base. */
|
||||
unsigned char swizzle[4];
|
||||
@@ -339,7 +343,6 @@ struct r300_texture_desc {
|
||||
unsigned offset_in_bytes[R300_MAX_TEXTURE_LEVELS];
|
||||
|
||||
/* Strides for each mip-level. */
|
||||
unsigned stride_in_pixels[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. */
|
||||
@@ -395,10 +398,6 @@ struct r300_resource
|
||||
/* Texture description (addressing, layout, special features). */
|
||||
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.
|
||||
* It's used to prevent redundant tiling-flags changes from happening.*/
|
||||
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_locked_unsafe(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 */
|
||||
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);
|
||||
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 */
|
||||
void r300_update_derived_state(struct r300_context* r300);
|
||||
|
||||
|
@@ -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, "
|
||||
"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",
|
||||
|
||||
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.microtile ? "YES" : " NO",
|
||||
rtex->tex.stride_in_pixels[0],
|
||||
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,
|
||||
@@ -888,7 +887,7 @@ r300_set_framebuffer_state(struct pipe_context* pipe,
|
||||
r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE);
|
||||
|
||||
if (state->zsbuf) {
|
||||
switch (util_format_get_blocksize(state->zsbuf->texture->format)) {
|
||||
switch (util_format_get_blocksize(state->zsbuf->format)) {
|
||||
case 2:
|
||||
zbuffer_bpp = 16;
|
||||
break;
|
||||
@@ -1458,10 +1457,12 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
|
||||
}
|
||||
}
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
r300_create_sampler_view(struct pipe_context *pipe,
|
||||
struct pipe_sampler_view *
|
||||
r300_create_sampler_view_custom(struct pipe_context *pipe,
|
||||
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_resource *tex = r300_resource(texture);
|
||||
@@ -1477,6 +1478,8 @@ r300_create_sampler_view(struct pipe_context *pipe,
|
||||
view->base.texture = NULL;
|
||||
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[1] = templ->swizzle_g;
|
||||
view->swizzle[2] = templ->swizzle_b;
|
||||
@@ -1493,7 +1496,10 @@ r300_create_sampler_view(struct pipe_context *pipe,
|
||||
}
|
||||
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;
|
||||
if (is_r500) {
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
r300_sampler_view_destroy(struct pipe_context *pipe,
|
||||
struct pipe_sampler_view *view)
|
||||
|
@@ -785,7 +785,10 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
|
||||
offset = tex->tex.offset_in_bytes[base_level];
|
||||
|
||||
r300_texture_setup_format_state(r300->screen, tex,
|
||||
view->base.format,
|
||||
base_level,
|
||||
view->width0_override,
|
||||
view->height0_override,
|
||||
&texstate->format);
|
||||
texstate->format.tile_config |= offset & 0xffffffe0;
|
||||
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;
|
||||
|
||||
/* 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];
|
||||
|
||||
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.
|
||||
* The depth here is at the Y component. */
|
||||
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 &&
|
||||
util_format_is_compressed(tex->b.b.b.format)) {
|
||||
util_format_is_compressed(view->base.format)) {
|
||||
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. */
|
||||
if (util_format_is_float(tex->b.b.b.format)) {
|
||||
if (util_format_is_float(view->base.format)) {
|
||||
/* No MAG linear filtering. */
|
||||
if ((texstate->filter0 & R300_TX_MAG_FILTER_MASK) ==
|
||||
R300_TX_MAG_FILTER_LINEAR) {
|
||||
|
@@ -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)
|
||||
|
@@ -46,10 +46,6 @@ uint32_t r300_translate_texformat(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_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,
|
||||
struct r300_resource *tex,
|
||||
enum pipe_format format,
|
||||
unsigned level,
|
||||
unsigned width0_override,
|
||||
unsigned height0_override,
|
||||
struct r300_texture_format_state *out);
|
||||
|
||||
boolean r300_resource_get_handle(struct pipe_screen* screen,
|
||||
@@ -74,6 +73,11 @@ struct pipe_resource*
|
||||
r300_texture_create(struct pipe_screen* screen,
|
||||
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_resource* texture,
|
||||
|
@@ -206,8 +206,8 @@ static unsigned r300_texture_get_nblocksy(struct r300_resource *tex,
|
||||
}
|
||||
|
||||
/* Get a width in pixels from a stride in bytes. */
|
||||
static unsigned stride_to_width(enum pipe_format format,
|
||||
unsigned stride_in_bytes)
|
||||
unsigned r300_stride_to_width(enum pipe_format format,
|
||||
unsigned stride_in_bytes)
|
||||
{
|
||||
return (stride_in_bytes / util_format_get_blocksize(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.layer_size_in_bytes[i] = layer_size;
|
||||
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;
|
||||
|
||||
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 =
|
||||
!util_is_power_of_two(tex->b.b.b.width0) ||
|
||||
(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.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++) {
|
||||
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);
|
||||
|
||||
/* The 8x8 compression mode needs macrotiling. */
|
||||
@@ -467,7 +468,7 @@ static void r300_tex_print_info(struct r300_resource *tex,
|
||||
func,
|
||||
tex->tex.macrotile[0] ? "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.last_level, tex->tex.size_in_bytes,
|
||||
util_format_short_name(tex->b.b.b.format));
|
||||
|
@@ -50,4 +50,7 @@ void r300_texture_desc_init(struct r300_screen *rscreen,
|
||||
unsigned r300_texture_get_offset(struct r300_resource *tex,
|
||||
unsigned level, unsigned layer);
|
||||
|
||||
unsigned r300_stride_to_width(enum pipe_format format,
|
||||
unsigned stride_in_bytes);
|
||||
|
||||
#endif
|
||||
|
@@ -87,9 +87,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
|
||||
struct r300_resource *tex = r300_resource(texture);
|
||||
struct r300_transfer *trans;
|
||||
struct pipe_resource base;
|
||||
boolean referenced_cs, referenced_hw, blittable;
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(texture->format);
|
||||
boolean referenced_cs, referenced_hw;
|
||||
|
||||
referenced_cs =
|
||||
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);
|
||||
}
|
||||
|
||||
blittable = desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ||
|
||||
desc->layout == UTIL_FORMAT_LAYOUT_S3TC ||
|
||||
desc->layout == UTIL_FORMAT_LAYOUT_RGTC;
|
||||
|
||||
trans = CALLOC_STRUCT(r300_transfer);
|
||||
if (trans) {
|
||||
/* Initialize the transfer object. */
|
||||
@@ -116,7 +110,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,
|
||||
* for this transfer.
|
||||
* Also make write transfers pipelined. */
|
||||
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) {
|
||||
fprintf(stderr, "r300: ERROR: Blitter recursion in texture_get_transfer.\n");
|
||||
os_break();
|
||||
|
Reference in New Issue
Block a user