X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fnv50%2Fnv50_surface.c;h=40b8d255335f3ea5e66a6297a81f63e827a2074b;hb=23808f1b5e88373534c7ff546cdd89030ce1e935;hp=7a9dada531b55a451bd19fe2ef7f5293ced9914a;hpb=d97f6963aee71d8fafa2a94a5fe1f3ca4b4ef16d;p=mesa.git diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 7a9dada531b..40b8d255335 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -24,12 +24,34 @@ #include #include "nouveau/nouveau_pushbuf.h" #include "nv50_context.h" +#include "nv50_resource.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "util/u_tile.h" #include "util/u_format.h" +/* return TRUE for formats that can be converted among each other by NV50_2D */ +static INLINE boolean +nv50_2d_format_faithful(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_SRGB: + case PIPE_FORMAT_B5G6R5_UNORM: + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B10G10R10A2_UNORM: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + case PIPE_FORMAT_R32G32B32_FLOAT: + return TRUE; + default: + return FALSE; + } +} + static INLINE int nv50_format(enum pipe_format format) { @@ -46,9 +68,12 @@ nv50_format(enum pipe_format format) return NV50_2D_DST_FORMAT_R5G6B5_UNORM; case PIPE_FORMAT_B5G5R5A1_UNORM: return NV50_2D_DST_FORMAT_A1R5G5B5_UNORM; + case PIPE_FORMAT_B10G10R10A2_UNORM: + return NV50_2D_DST_FORMAT_A2R10G10B10_UNORM; case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_R8_UNORM: return NV50_2D_DST_FORMAT_R8_UNORM; case PIPE_FORMAT_R32G32B32A32_FLOAT: return NV50_2D_DST_FORMAT_R32G32B32A32_FLOAT; @@ -170,25 +195,40 @@ nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, static void nv50_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, + struct pipe_resource *dest, struct pipe_subresource subdst, + unsigned destx, unsigned desty, unsigned destz, + struct pipe_resource *src, struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, unsigned width, unsigned height) { struct nv50_context *nv50 = nv50_context(pipe); struct nv50_screen *screen = nv50->screen; + struct pipe_surface *ps_dst, *ps_src; + + assert((src->format == dest->format) || + (nv50_2d_format_faithful(src->format) && + nv50_2d_format_faithful(dest->format))); - assert(src->format == dest->format); + ps_src = nv50_miptree_surface_new(pipe->screen, dest, subsrc.face, + subsrc.level, srcz, 0 /* bind flags */); + ps_dst = nv50_miptree_surface_new(pipe->screen, dest, subdst.face, + subdst.level, destz, 0 /* bindflags */); - nv50_surface_do_copy(screen, dest, destx, desty, src, srcx, - srcy, width, height); + nv50_surface_do_copy(screen, ps_dst, destx, desty, ps_src, srcx, + srcy, width, height); + + nv50_miptree_surface_del(ps_src); + nv50_miptree_surface_del(ps_dst); } static void -nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, - unsigned destx, unsigned desty, unsigned width, - unsigned height, unsigned value) +nv50_surface_fill(struct pipe_context *pipe, struct pipe_resource *dest, + struct pipe_subresource subdst, + unsigned destx, unsigned desty, unsigned destz, + unsigned width, unsigned height, unsigned value) { struct nv50_context *nv50 = nv50_context(pipe); + struct pipe_surface *ps; struct nv50_screen *screen = nv50->screen; struct nouveau_channel *chan = screen->eng2d->channel; struct nouveau_grobj *eng2d = screen->eng2d; @@ -198,9 +238,12 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, if (format < 0) return; + ps = nv50_miptree_surface_new(pipe->screen, dest, subdst.face, + subdst.level, destz, 0 /* bind flags */); + WAIT_RING (chan, 32); - ret = nv50_surface_set(screen, dest, 1); + ret = nv50_surface_set(screen, ps, 1); if (ret) return; @@ -213,13 +256,15 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, OUT_RING (chan, desty); OUT_RING (chan, width); OUT_RING (chan, height); + + nv50_miptree_surface_del(ps); } void nv50_init_surface_functions(struct nv50_context *nv50) { - nv50->pipe.surface_copy = nv50_surface_copy; - nv50->pipe.surface_fill = nv50_surface_fill; + nv50->pipe.resource_copy_region = nv50_surface_copy; + nv50->pipe.resource_fill_region = nv50_surface_fill; }