mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 11:08:03 +02:00
r300g: add a way to change texture properties arbitrarily
So that we can implement resource_copy on arbitrary data.
This commit is contained in:
parent
56ba7e913f
commit
7c24a4c6a8
9 changed files with 104 additions and 76 deletions
|
|
@ -412,9 +412,12 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
|
|||
struct r300_context *r300 = r300_context(pipe);
|
||||
struct pipe_framebuffer_state *fb =
|
||||
(struct pipe_framebuffer_state*)r300->fb_state.state;
|
||||
enum pipe_format old_format = dst->format;
|
||||
enum pipe_format new_format = old_format;
|
||||
const struct util_format_description *desc = util_format_description(old_format);
|
||||
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);
|
||||
|
||||
if (r300->zmask_in_use && !r300->zmask_locked) {
|
||||
if (fb->zsbuf->texture == src ||
|
||||
|
|
@ -429,46 +432,46 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
|
|||
if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
|
||||
(desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB ||
|
||||
!pipe->screen->is_format_supported(pipe->screen,
|
||||
old_format, src->target,
|
||||
src->format, src->target,
|
||||
src->nr_samples,
|
||||
PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_SAMPLER_VIEW, 0))) {
|
||||
switch (util_format_get_blocksize(old_format)) {
|
||||
PIPE_BIND_SAMPLER_VIEW, 0) ||
|
||||
!pipe->screen->is_format_supported(pipe->screen,
|
||||
dst->format, dst->target,
|
||||
dst->nr_samples,
|
||||
PIPE_BIND_RENDER_TARGET, 0))) {
|
||||
switch (util_format_get_blocksize(old_dst.format)) {
|
||||
case 1:
|
||||
new_format = PIPE_FORMAT_I8_UNORM;
|
||||
new_dst.format = PIPE_FORMAT_I8_UNORM;
|
||||
break;
|
||||
case 2:
|
||||
new_format = PIPE_FORMAT_B4G4R4A4_UNORM;
|
||||
new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM;
|
||||
break;
|
||||
case 4:
|
||||
new_format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
break;
|
||||
case 8:
|
||||
new_format = PIPE_FORMAT_R16G16B16A16_UNORM;
|
||||
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(old_format));
|
||||
util_format_short_name(dst->format));
|
||||
}
|
||||
new_src.format = new_dst.format;
|
||||
}
|
||||
|
||||
if (old_format != new_format) {
|
||||
r300_texture_reinterpret_format(pipe->screen,
|
||||
dst, new_format);
|
||||
r300_texture_reinterpret_format(pipe->screen,
|
||||
src, new_format);
|
||||
}
|
||||
if (old_src.format != new_src.format)
|
||||
r300_resource_set_properties(pipe->screen, src, 0, &new_src);
|
||||
if (old_dst.format != new_dst.format)
|
||||
r300_resource_set_properties(pipe->screen, dst, 0, &new_dst);
|
||||
|
||||
r300_hw_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
|
||||
src, src_level, src_box);
|
||||
|
||||
if (old_format != new_format) {
|
||||
r300_texture_reinterpret_format(pipe->screen,
|
||||
dst, old_format);
|
||||
r300_texture_reinterpret_format(pipe->screen,
|
||||
src, old_format);
|
||||
}
|
||||
if (old_src.format != new_src.format)
|
||||
r300_resource_set_properties(pipe->screen, src, 0, &old_src);
|
||||
if (old_dst.format != new_dst.format)
|
||||
r300_resource_set_properties(pipe->screen, dst, 0, &old_dst);
|
||||
|
||||
if (r300->zmask_locked) {
|
||||
r300->zmask_locked = FALSE;
|
||||
|
|
|
|||
|
|
@ -392,6 +392,7 @@ struct r300_resource
|
|||
struct r300_winsys_buffer *buf;
|
||||
struct r300_winsys_cs_buffer *cs_buf;
|
||||
enum r300_buffer_domain domain;
|
||||
unsigned buf_size;
|
||||
|
||||
/* Constant buffers are in user memory. */
|
||||
uint8_t *constant_buffer;
|
||||
|
|
@ -403,6 +404,9 @@ struct r300_resource
|
|||
/* Only format-independent bits should be filled in. */
|
||||
struct r300_texture_format_state tx_format;
|
||||
|
||||
/* Where the texture starts in the buffer. */
|
||||
unsigned tex_offset;
|
||||
|
||||
/* HiZ memory allocations. */
|
||||
struct mem_block *hiz_mem[R300_MAX_TEXTURE_LEVELS];
|
||||
boolean hiz_in_use[R300_MAX_TEXTURE_LEVELS];
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
|
|||
rbuf->b.user_ptr = NULL;
|
||||
rbuf->domain = R300_DOMAIN_GTT;
|
||||
rbuf->buf = NULL;
|
||||
rbuf->buf_size = templ->width0;
|
||||
rbuf->constant_buffer = NULL;
|
||||
|
||||
/* Alloc constant buffers in RAM. */
|
||||
|
|
@ -262,6 +263,7 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
|
|||
rbuf->b.user_ptr = ptr;
|
||||
rbuf->domain = R300_DOMAIN_GTT;
|
||||
rbuf->buf = NULL;
|
||||
rbuf->buf_size = size;
|
||||
rbuf->constant_buffer = NULL;
|
||||
return &rbuf->b.b.b;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -733,13 +733,18 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
|
|||
/* Even though we do not implement mipmapping for NPOT
|
||||
* textures, we should at least honor the minimum level
|
||||
* which is allowed to be displayed. We do this by setting up
|
||||
* an i-th mipmap level as the zero level. */
|
||||
* the i-th mipmap level as the zero level. */
|
||||
unsigned offset = tex->tex_offset +
|
||||
tex->tex.offset_in_bytes[min_level];
|
||||
|
||||
r300_texture_setup_format_state(r300->screen, tex,
|
||||
min_level,
|
||||
&texstate->format);
|
||||
texstate->format.tile_config |=
|
||||
tex->tex.offset_in_bytes[min_level] & 0xffffffe0;
|
||||
assert((tex->tex.offset_in_bytes[min_level] & 0x1f) == 0);
|
||||
texstate->format.tile_config |= offset & 0xffffffe0;
|
||||
assert((offset & 0x1f) == 0);
|
||||
} else {
|
||||
texstate->format.tile_config |= tex->tex_offset & 0xffffffe0;
|
||||
assert((tex->tex_offset & 0x1f) == 0);
|
||||
}
|
||||
|
||||
/* Assign a texture cache region. */
|
||||
|
|
|
|||
|
|
@ -679,18 +679,27 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
|
|||
}
|
||||
}
|
||||
|
||||
void r300_texture_reinterpret_format(struct pipe_screen *screen,
|
||||
boolean r300_resource_set_properties(struct pipe_screen *screen,
|
||||
struct pipe_resource *tex,
|
||||
enum pipe_format new_format)
|
||||
unsigned offset,
|
||||
const struct pipe_resource *new_properties)
|
||||
{
|
||||
struct r300_screen *r300screen = r300_screen(screen);
|
||||
struct r300_screen *rscreen = r300_screen(screen);
|
||||
struct r300_resource *res = r300_resource(tex);
|
||||
|
||||
SCREEN_DBG(r300screen, DBG_TEX,
|
||||
"r300: texture_reinterpret_format: %s -> %s\n",
|
||||
SCREEN_DBG(rscreen, DBG_TEX,
|
||||
"r300: texture_set_properties: %s -> %s\n",
|
||||
util_format_short_name(tex->format),
|
||||
util_format_short_name(new_format));
|
||||
util_format_short_name(new_properties->format));
|
||||
|
||||
tex->format = new_format;
|
||||
if (!r300_texture_desc_init(rscreen, res, new_properties)) {
|
||||
fprintf(stderr, "r300: ERROR: Cannot set texture properties.\n");
|
||||
return FALSE;
|
||||
}
|
||||
res->tex_offset = offset;
|
||||
r300_texture_setup_format_state(rscreen, res, 0, &res->tx_format);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void r300_texture_destroy(struct pipe_screen *screen,
|
||||
|
|
@ -755,28 +764,30 @@ r300_texture_create_object(struct r300_screen *rscreen,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the descriptor. */
|
||||
if (!r300_texture_desc_init(rscreen, tex, base,
|
||||
microtile, macrotile,
|
||||
stride_in_bytes_override,
|
||||
max_buffer_size)) {
|
||||
pipe_reference_init(&tex->b.b.b.reference, 1);
|
||||
tex->b.b.b.screen = &rscreen->screen;
|
||||
tex->b.b.b.usage = base->usage;
|
||||
tex->b.b.b.bind = base->bind;
|
||||
tex->b.b.b.flags = base->flags;
|
||||
tex->b.b.vtbl = &r300_texture_vtbl;
|
||||
tex->tex.microtile = microtile;
|
||||
tex->tex.macrotile[0] = macrotile;
|
||||
tex->tex.stride_in_bytes_override = stride_in_bytes_override;
|
||||
tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
|
||||
R300_DOMAIN_GTT :
|
||||
R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
|
||||
tex->buf_size = max_buffer_size;
|
||||
|
||||
if (!r300_resource_set_properties(&rscreen->screen, &tex->b.b.b, 0, base)) {
|
||||
if (buffer)
|
||||
rws->buffer_reference(rws, &buffer, NULL);
|
||||
FREE(tex);
|
||||
return NULL;
|
||||
}
|
||||
/* Initialize the hardware state. */
|
||||
r300_texture_setup_format_state(rscreen, tex, 0, &tex->tx_format);
|
||||
|
||||
tex->b.b.vtbl = &r300_texture_vtbl;
|
||||
pipe_reference_init(&tex->b.b.b.reference, 1);
|
||||
tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
|
||||
R300_DOMAIN_GTT :
|
||||
R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
|
||||
tex->buf = buffer;
|
||||
|
||||
/* Create the backing buffer if needed. */
|
||||
if (!tex->buf) {
|
||||
if (!buffer) {
|
||||
tex->buf_size = tex->tex.size_in_bytes;
|
||||
tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048,
|
||||
base->bind, base->usage, tex->domain);
|
||||
|
||||
|
|
@ -784,6 +795,8 @@ r300_texture_create_object(struct r300_screen *rscreen,
|
|||
FREE(tex);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
tex->buf = buffer;
|
||||
}
|
||||
|
||||
tex->cs_buf = rws->buffer_get_cs_handle(rws, tex->buf);
|
||||
|
|
|
|||
|
|
@ -46,9 +46,10 @@ uint32_t r300_translate_texformat(enum pipe_format format,
|
|||
|
||||
uint32_t r500_tx_format_msb_bit(enum pipe_format format);
|
||||
|
||||
void r300_texture_reinterpret_format(struct pipe_screen *screen,
|
||||
boolean r300_resource_set_properties(struct pipe_screen *screen,
|
||||
struct pipe_resource *tex,
|
||||
enum pipe_format new_format);
|
||||
unsigned offset,
|
||||
const struct pipe_resource *new_properties);
|
||||
|
||||
boolean r300_is_colorbuffer_format_supported(enum pipe_format format);
|
||||
|
||||
|
|
|
|||
|
|
@ -401,6 +401,9 @@ static void r300_setup_tiling(struct r300_screen *screen,
|
|||
boolean is_zb = util_format_is_depth_or_stencil(format);
|
||||
boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING);
|
||||
|
||||
tex->tex.microtile = R300_BUFFER_LINEAR;
|
||||
tex->tex.macrotile[0] = R300_BUFFER_LINEAR;
|
||||
|
||||
if (!util_format_is_plain(format)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -453,15 +456,16 @@ static void r300_tex_print_info(struct r300_resource *tex,
|
|||
|
||||
boolean r300_texture_desc_init(struct r300_screen *rscreen,
|
||||
struct r300_resource *tex,
|
||||
const struct pipe_resource *base,
|
||||
enum r300_buffer_tiling microtile,
|
||||
enum r300_buffer_tiling macrotile,
|
||||
unsigned stride_in_bytes_override,
|
||||
unsigned max_buffer_size)
|
||||
const struct pipe_resource *base)
|
||||
{
|
||||
tex->b.b.b = *base;
|
||||
tex->b.b.b.screen = &rscreen->screen;
|
||||
tex->tex.stride_in_bytes_override = stride_in_bytes_override;
|
||||
tex->b.b.b.target = base->target;
|
||||
tex->b.b.b.format = base->format;
|
||||
tex->b.b.b.width0 = base->width0;
|
||||
tex->b.b.b.height0 = base->height0;
|
||||
tex->b.b.b.depth0 = base->depth0;
|
||||
tex->b.b.b.array_size = base->array_size;
|
||||
tex->b.b.b.last_level = base->last_level;
|
||||
tex->b.b.b.nr_samples = base->nr_samples;
|
||||
tex->tex.width0 = base->width0;
|
||||
tex->tex.height0 = base->height0;
|
||||
tex->tex.depth0 = base->depth0;
|
||||
|
|
@ -476,13 +480,8 @@ boolean r300_texture_desc_init(struct r300_screen *rscreen,
|
|||
}
|
||||
|
||||
/* Setup tiling. */
|
||||
if (microtile == R300_BUFFER_SELECT_LAYOUT ||
|
||||
macrotile == R300_BUFFER_SELECT_LAYOUT) {
|
||||
if (tex->tex.microtile == R300_BUFFER_SELECT_LAYOUT) {
|
||||
r300_setup_tiling(rscreen, tex);
|
||||
} else {
|
||||
tex->tex.microtile = microtile;
|
||||
tex->tex.macrotile[0] = macrotile;
|
||||
assert(tex->b.b.b.last_level == 0);
|
||||
}
|
||||
|
||||
r300_setup_cbzb_flags(rscreen, tex);
|
||||
|
|
@ -491,24 +490,24 @@ boolean r300_texture_desc_init(struct r300_screen *rscreen,
|
|||
r300_setup_miptree(rscreen, tex, TRUE);
|
||||
/* If the required buffer size is larger the given max size,
|
||||
* try again without the alignment for the CBZB clear. */
|
||||
if (max_buffer_size && tex->tex.size_in_bytes > max_buffer_size) {
|
||||
if (tex->buf_size && tex->tex.size_in_bytes > tex->buf_size) {
|
||||
r300_setup_miptree(rscreen, tex, FALSE);
|
||||
}
|
||||
|
||||
r300_texture_3d_fix_mipmapping(rscreen, tex);
|
||||
r300_setup_zmask_flags(rscreen, tex);
|
||||
|
||||
if (max_buffer_size) {
|
||||
if (tex->buf_size) {
|
||||
/* Make sure the buffer we got is large enough. */
|
||||
if (tex->tex.size_in_bytes > max_buffer_size) {
|
||||
if (tex->tex.size_in_bytes > tex->buf_size) {
|
||||
fprintf(stderr, "r300: texture_desc_init: The buffer is not "
|
||||
"large enough. Got: %i, Need: %i, Info:\n",
|
||||
max_buffer_size, tex->tex.size_in_bytes);
|
||||
tex->buf_size, tex->tex.size_in_bytes);
|
||||
r300_tex_print_info(tex, "texture_desc_init");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tex->tex.buffer_size_in_bytes = max_buffer_size;
|
||||
tex->tex.buffer_size_in_bytes = tex->buf_size;
|
||||
} else {
|
||||
tex->tex.buffer_size_in_bytes = tex->tex.size_in_bytes;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,11 +45,7 @@ unsigned r300_get_pixel_alignment(enum pipe_format format,
|
|||
|
||||
boolean r300_texture_desc_init(struct r300_screen *rscreen,
|
||||
struct r300_resource *tex,
|
||||
const struct pipe_resource *base,
|
||||
enum r300_buffer_tiling microtile,
|
||||
enum r300_buffer_tiling macrotile,
|
||||
unsigned stride_in_bytes_override,
|
||||
unsigned max_buffer_size);
|
||||
const struct pipe_resource *base);
|
||||
|
||||
unsigned r300_texture_get_offset(struct r300_resource *tex,
|
||||
unsigned level, unsigned layer);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,11 @@ r300_texture_get_transfer(struct pipe_context *ctx,
|
|||
* Also make write transfers pipelined. */
|
||||
if (tex->tex.microtile || tex->tex.macrotile[level] ||
|
||||
((referenced_hw & !(usage & PIPE_TRANSFER_READ)) && blittable)) {
|
||||
if (r300->blitter->running) {
|
||||
fprintf(stderr, "r300: ERROR: Blitter recursion in texture_get_transfer.\n");
|
||||
os_break();
|
||||
}
|
||||
|
||||
base.target = PIPE_TEXTURE_2D;
|
||||
base.format = texture->format;
|
||||
base.width0 = box->width;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue