mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
r300g: adapt to interface changes
might need further cleanup. Using surfaces internally for the u_blitter code seems nonoptimal.
This commit is contained in:
parent
b59b23a51d
commit
39b4bf71b5
5 changed files with 89 additions and 61 deletions
|
|
@ -117,25 +117,36 @@ static void r300_hw_copy(struct pipe_context* pipe,
|
|||
|
||||
/* Copy a block of pixels from one surface to another. */
|
||||
void r300_surface_copy(struct pipe_context* pipe,
|
||||
struct pipe_surface* dst,
|
||||
unsigned dstx, unsigned dsty,
|
||||
struct pipe_surface* src,
|
||||
unsigned srcx, unsigned srcy,
|
||||
struct pipe_resource* dst,
|
||||
struct pipe_subresource subdst,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
struct pipe_resource* src,
|
||||
struct pipe_subresource subsrc,
|
||||
unsigned srcx, unsigned srcy, unsigned srcz,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
enum pipe_format old_format = dst->texture->format;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
enum pipe_format old_format = dst->format;
|
||||
enum pipe_format new_format = old_format;
|
||||
struct pipe_surface *srcsurf, *dstsurf;
|
||||
unsigned bind;
|
||||
|
||||
if (dst->texture->format != src->texture->format) {
|
||||
if (util_format_is_depth_or_stencil(dst->format))
|
||||
bind = PIPE_BIND_DEPTH_STENCIL;
|
||||
else
|
||||
bind = PIPE_BIND_RENDER_TARGET;
|
||||
|
||||
if (dst->format != src->format) {
|
||||
debug_printf("r300: Implementation error: Format mismatch in %s\n"
|
||||
" : src: %s dst: %s\n", __FUNCTION__,
|
||||
util_format_short_name(src->texture->format),
|
||||
util_format_short_name(dst->texture->format));
|
||||
util_format_short_name(src->format),
|
||||
util_format_short_name(dst->format));
|
||||
debug_assert(0);
|
||||
}
|
||||
|
||||
if (!pipe->screen->is_format_supported(pipe->screen,
|
||||
old_format, src->texture->target,
|
||||
old_format, src->target,
|
||||
src->nr_samples,
|
||||
PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_SAMPLER_VIEW, 0) &&
|
||||
util_format_is_plain(old_format)) {
|
||||
|
|
@ -164,36 +175,64 @@ void r300_surface_copy(struct pipe_context* pipe,
|
|||
src->format = new_format;
|
||||
|
||||
r300_texture_reinterpret_format(pipe->screen,
|
||||
dst->texture, new_format);
|
||||
dst, new_format);
|
||||
r300_texture_reinterpret_format(pipe->screen,
|
||||
src->texture, new_format);
|
||||
src, new_format);
|
||||
}
|
||||
|
||||
r300_hw_copy(pipe, dst, dstx, dsty, src, srcx, srcy, width, height);
|
||||
srcsurf = screen->get_tex_surface(screen, src,
|
||||
subsrc.face, subsrc.level, srcz,
|
||||
PIPE_BIND_SAMPLER_VIEW);
|
||||
|
||||
dstsurf = screen->get_tex_surface(screen, dst,
|
||||
subdst.face, subdst.level, dstz,
|
||||
bind);
|
||||
|
||||
r300_hw_copy(pipe, dstsurf, dstx, dsty, srcsurf, srcx, srcy, width, height);
|
||||
|
||||
pipe_surface_reference(&srcsurf, NULL);
|
||||
pipe_surface_reference(&dstsurf, NULL);
|
||||
|
||||
if (old_format != new_format) {
|
||||
dst->format = old_format;
|
||||
src->format = old_format;
|
||||
|
||||
r300_texture_reinterpret_format(pipe->screen,
|
||||
dst->texture, old_format);
|
||||
dst, old_format);
|
||||
r300_texture_reinterpret_format(pipe->screen,
|
||||
src->texture, old_format);
|
||||
src, old_format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill a region of a surface with a constant value. */
|
||||
void r300_surface_fill(struct pipe_context* pipe,
|
||||
struct pipe_surface* dst,
|
||||
unsigned dstx, unsigned dsty,
|
||||
struct pipe_resource* dst,
|
||||
struct pipe_subresource subdst,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
unsigned width, unsigned height,
|
||||
unsigned value)
|
||||
{
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct r300_context* r300 = r300_context(pipe);
|
||||
struct pipe_surface *dstsurf;
|
||||
unsigned bind;
|
||||
|
||||
if (util_format_is_depth_or_stencil(dst->format))
|
||||
bind = PIPE_BIND_DEPTH_STENCIL;
|
||||
else
|
||||
bind = PIPE_BIND_RENDER_TARGET;
|
||||
|
||||
dstsurf = screen->get_tex_surface(screen, dst,
|
||||
subdst.face,
|
||||
subdst.level,
|
||||
dstz,
|
||||
bind);
|
||||
|
||||
r300_blitter_save_states(r300);
|
||||
util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
|
||||
|
||||
util_blitter_fill(r300->blitter,
|
||||
dst, dstx, dsty, width, height, value);
|
||||
dstsurf, dstx, dsty, width, height, value);
|
||||
|
||||
pipe_surface_reference(&dstsurf, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@
|
|||
#define R300_BLIT_H
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_surface;
|
||||
struct pipe_resource;
|
||||
struct pipe_subresource;
|
||||
|
||||
void r300_clear(struct pipe_context* pipe,
|
||||
unsigned buffers,
|
||||
|
|
@ -33,15 +34,18 @@ void r300_clear(struct pipe_context* pipe,
|
|||
unsigned stencil);
|
||||
|
||||
void r300_surface_copy(struct pipe_context* pipe,
|
||||
struct pipe_surface* dst,
|
||||
unsigned dstx, unsigned dsty,
|
||||
struct pipe_surface* src,
|
||||
unsigned srcx, unsigned srcy,
|
||||
struct pipe_resource* dst,
|
||||
struct pipe_subresource subdst,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
struct pipe_resource* src,
|
||||
struct pipe_subresource subsrc,
|
||||
unsigned srcx, unsigned srcy, unsigned srcz,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
void r300_surface_fill(struct pipe_context* pipe,
|
||||
struct pipe_surface* dst,
|
||||
unsigned dstx, unsigned dsty,
|
||||
struct pipe_resource* dst,
|
||||
struct pipe_subresource subdst,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
unsigned width, unsigned height,
|
||||
unsigned value);
|
||||
|
||||
|
|
|
|||
|
|
@ -173,8 +173,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
|||
r300->context.destroy = r300_destroy_context;
|
||||
|
||||
r300->context.clear = r300_clear;
|
||||
r300->context.surface_copy = r300_surface_copy;
|
||||
r300->context.surface_fill = r300_surface_fill;
|
||||
r300->context.resource_copy_region = r300_surface_copy;
|
||||
r300->context.resource_fill_region = r300_surface_fill;
|
||||
|
||||
if (r300screen->caps.has_tcl) {
|
||||
r300->context.draw_arrays = r300_draw_arrays;
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param)
|
|||
static boolean r300_is_format_supported(struct pipe_screen* screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
unsigned sample_count,
|
||||
unsigned usage,
|
||||
unsigned geom_flags)
|
||||
{
|
||||
|
|
@ -221,6 +222,9 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (sample_count > 1)
|
||||
return FALSE;
|
||||
|
||||
/* Check sampler format support. */
|
||||
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
|
||||
/* Z24 cannot be sampled from on non-r5xx. */
|
||||
|
|
|
|||
|
|
@ -56,63 +56,44 @@ r300_transfer(struct pipe_transfer* transfer)
|
|||
static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
|
||||
struct r300_transfer *r300transfer)
|
||||
{
|
||||
struct pipe_screen *screen = ctx->screen;
|
||||
struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
|
||||
struct pipe_resource *tex = transfer->resource;
|
||||
struct pipe_surface *src, *dst;
|
||||
struct pipe_subresource subdst;
|
||||
|
||||
src = screen->get_tex_surface(screen, tex,
|
||||
transfer->sr.face,
|
||||
transfer->sr.level,
|
||||
transfer->box.z,
|
||||
PIPE_BIND_BLIT_SOURCE);
|
||||
subdst.face = 0;
|
||||
subdst.level = 0;
|
||||
|
||||
dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b,
|
||||
0, 0, 0,
|
||||
PIPE_BIND_BLIT_DESTINATION);
|
||||
|
||||
ctx->surface_copy(ctx, dst, 0, 0, src,
|
||||
transfer->box.x, transfer->box.y,
|
||||
transfer->box.width, transfer->box.height);
|
||||
|
||||
pipe_surface_reference(&src, NULL);
|
||||
pipe_surface_reference(&dst, NULL);
|
||||
ctx->resource_copy_region(ctx, &r300transfer->detiled_texture->b.b, subdst,
|
||||
0, 0, 0,
|
||||
tex, transfer->sr,
|
||||
transfer->box.x, transfer->box.y, transfer->box.z,
|
||||
transfer->box.width, transfer->box.height);
|
||||
}
|
||||
|
||||
/* Copy a detiled texture to a tiled one. */
|
||||
static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
|
||||
struct r300_transfer *r300transfer)
|
||||
{
|
||||
struct pipe_screen *screen = ctx->screen;
|
||||
struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
|
||||
struct pipe_resource *tex = transfer->resource;
|
||||
struct pipe_surface *src, *dst;
|
||||
struct pipe_subresource subsrc;
|
||||
|
||||
src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b,
|
||||
0, 0, 0,
|
||||
PIPE_BIND_BLIT_SOURCE);
|
||||
|
||||
dst = screen->get_tex_surface(screen, tex,
|
||||
transfer->sr.face,
|
||||
transfer->sr.level,
|
||||
transfer->box.z,
|
||||
PIPE_BIND_BLIT_DESTINATION);
|
||||
subsrc.face = 0;
|
||||
subsrc.level = 0;
|
||||
|
||||
/* XXX this flush prevents the following DRM error from occuring:
|
||||
* [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation !
|
||||
* Reproducible with perf/copytex. */
|
||||
ctx->flush(ctx, 0, NULL);
|
||||
|
||||
ctx->surface_copy(ctx, dst,
|
||||
transfer->box.x, transfer->box.y,
|
||||
src, 0, 0,
|
||||
transfer->box.width, transfer->box.height);
|
||||
ctx->resource_copy_region(ctx, tex, transfer->sr,
|
||||
transfer->box.x, transfer->box.y, transfer->box.z,
|
||||
&r300transfer->detiled_texture->b.b, subsrc,
|
||||
0, 0, 0,
|
||||
transfer->box.width, transfer->box.height);
|
||||
|
||||
/* XXX this flush fixes a few piglit tests (e.g. glean/pixelFormats). */
|
||||
ctx->flush(ctx, 0, NULL);
|
||||
|
||||
pipe_surface_reference(&src, NULL);
|
||||
pipe_surface_reference(&dst, NULL);
|
||||
}
|
||||
|
||||
struct pipe_transfer*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue