r300: split unaligned 3D texsubimage uploads by layer
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

TexSubImage3D failures were caused by tiled multi-slice uploads for
unaligned XY box. Falls back to per-layer uploads when the 3D box
depth is > 1 and XY box is unaligned.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39897>
This commit is contained in:
Pavel Ondračka 2026-02-13 23:28:11 +01:00 committed by Marge Bot
parent eedbe136ea
commit 7ae9262dc3
4 changed files with 66 additions and 4 deletions

View file

@ -555,7 +555,6 @@ spec@!opengl 1.1@polygon-mode-offset@config 4: Expected white pixel on right edg
spec@!opengl 1.1@polygon-mode-offset@config 4: Expected white pixel on top edge,Fail
spec@!opengl 1.1@polygon-offset,Fail
spec@!opengl 1.1@read-front samples=6,Fail
spec@!opengl 1.1@texsubimage,Fail
spec@!opengl 1.1@texwrap formats bordercolor,Fail
spec@!opengl 1.1@texwrap formats bordercolor-swizzled,Fail
spec@!opengl 1.1@texwrap formats bordercolor-swizzled@GL_RGB12- swizzled- border color only,Fail

View file

@ -554,7 +554,6 @@ spec@!opengl 1.1@linestipple@Line strip,Fail
spec@!opengl 1.1@linestipple@Restarting lines within a single Begin-End block,Fail
spec@!opengl 1.1@read-front samples=6,Fail
spec@!opengl 1.1@texgen,Fail
spec@!opengl 1.1@texsubimage,Fail
spec@!opengl 1.1@texwrap formats bordercolor,Fail
spec@!opengl 1.1@texwrap formats bordercolor-swizzled,Fail
spec@!opengl 1.1@texwrap formats bordercolor-swizzled@GL_RGB12- swizzled- border color only,Fail

View file

@ -397,7 +397,6 @@ spec@!opengl 1.1@linestipple@Line loop,Fail
spec@!opengl 1.1@linestipple@Line strip,Fail
spec@!opengl 1.1@linestipple@Restarting lines within a single Begin-End block,Fail
spec@!opengl 1.1@read-front samples=6,Fail
spec@!opengl 1.1@texsubimage,Fail
spec@!opengl 1.2@lodclamp-between,Fail
spec@!opengl 1.2@lodclamp-between-max,Fail

View file

@ -6,9 +6,74 @@
#include "r300_context.h"
#include "r300_texture.h"
#include "r300_texture_desc.h"
#include "r300_transfer.h"
#include "r300_screen_buffer.h"
static bool
r300_3d_subdata_needs_layered_upload(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
const struct pipe_box *box)
{
struct r300_resource *tex = r300_resource(resource);
struct r300_screen *screen = r300_context(pipe)->screen;
bool is_rs690 = screen->caps.family == CHIP_RS600 ||
screen->caps.family == CHIP_RS690 ||
screen->caps.family == CHIP_RS740;
unsigned tile_width, tile_height;
if (resource->target != PIPE_TEXTURE_3D || box->depth <= 1)
return false;
if (!tex->tex.microtile && !tex->tex.macrotile[level])
return false;
tile_width = r300_get_pixel_alignment(resource->format,
resource->nr_samples,
tex->tex.microtile,
tex->tex.macrotile[level],
DIM_WIDTH, is_rs690,
resource->bind & PIPE_BIND_SCANOUT);
tile_height = r300_get_pixel_alignment(resource->format,
resource->nr_samples,
tex->tex.microtile,
tex->tex.macrotile[level],
DIM_HEIGHT, is_rs690,
resource->bind & PIPE_BIND_SCANOUT);
return box->x % tile_width || box->y % tile_height ||
box->width % tile_width || box->height % tile_height;
}
static void
r300_texture_subdata(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
const void *data,
unsigned stride,
uintptr_t layer_stride)
{
if (r300_3d_subdata_needs_layered_upload(pipe, resource, level, box)) {
struct pipe_box layer_box = *box;
layer_box.depth = 1;
for (layer_box.z = box->z; layer_box.z < box->z + box->depth;
layer_box.z++) {
u_default_texture_subdata(pipe, resource, level, usage, &layer_box,
data, stride, layer_stride);
data += layer_stride;
}
return;
}
u_default_texture_subdata(pipe, resource, level, usage, box, data, stride,
layer_stride);
}
static struct pipe_resource *
r300_resource_create(struct pipe_screen *screen,
const struct pipe_resource *templ)
@ -28,7 +93,7 @@ void r300_init_resource_functions(struct r300_context *r300)
r300->context.buffer_unmap = r300_buffer_transfer_unmap;
r300->context.texture_unmap = r300_texture_transfer_unmap;
r300->context.buffer_subdata = u_default_buffer_subdata;
r300->context.texture_subdata = u_default_texture_subdata;
r300->context.texture_subdata = r300_texture_subdata;
r300->context.create_surface = r300_create_surface;
r300->context.surface_destroy = r300_surface_destroy;
}