From 7ae9262dc3cf3910d77cc67813558e93a8fa4530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Fri, 13 Feb 2026 23:28:11 +0100 Subject: [PATCH] r300: split unaligned 3D texsubimage uploads by layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Part-of: --- .../drivers/r300/ci/r300-rs740-fails.txt | 1 - .../drivers/r300/ci/r300-rv410-fails.txt | 1 - .../r300/ci/r300-rv530-nohiz-fails.txt | 1 - src/gallium/drivers/r300/r300_resource.c | 67 ++++++++++++++++++- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/r300/ci/r300-rs740-fails.txt b/src/gallium/drivers/r300/ci/r300-rs740-fails.txt index cb0d6314d15..6104a44737b 100644 --- a/src/gallium/drivers/r300/ci/r300-rs740-fails.txt +++ b/src/gallium/drivers/r300/ci/r300-rs740-fails.txt @@ -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 diff --git a/src/gallium/drivers/r300/ci/r300-rv410-fails.txt b/src/gallium/drivers/r300/ci/r300-rv410-fails.txt index 562e28255e1..52e52444702 100644 --- a/src/gallium/drivers/r300/ci/r300-rv410-fails.txt +++ b/src/gallium/drivers/r300/ci/r300-rv410-fails.txt @@ -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 diff --git a/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt b/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt index c83d26db022..e3997093ceb 100644 --- a/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt +++ b/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt @@ -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 diff --git a/src/gallium/drivers/r300/r300_resource.c b/src/gallium/drivers/r300/r300_resource.c index f453ed67696..31f729604f9 100644 --- a/src/gallium/drivers/r300/r300_resource.c +++ b/src/gallium/drivers/r300/r300_resource.c @@ -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; }