Currently surface_fill sets alpha incorrectly to 1.0 when drawing to A8R8G8B8 instead of the correct value. xf86-video-nouveau has the following comment confirming the issue: /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the * alpha channel gets forced to 0xFF for some reason. We're using * SURFACE_FORMAT_Y32 as a workaround */ This patch fixes it by always using SURFACE_FORMAT_Y formats in surface_fill. diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c index 3193086..dfe30c0 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.c +++ b/src/gallium/drivers/nv04/nv04_surface_2d.c @@ -34,26 +34,6 @@ nv04_surface_format(enum pipe_format format) } static INLINE int -nv04_rect_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_A8L8_UNORM: - case PIPE_FORMAT_Z16_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - default: - return -1; - } -} - -static INLINE int nv04_scaled_image_format(enum pipe_format format) { switch (format) { @@ -319,13 +299,24 @@ nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst, struct nouveau_grobj *rect = ctx->rect; struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst)); unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch; + int bpp = util_format_get_blocksize(dst->format); int cs2d_format, gdirect_format; - cs2d_format = nv04_surface_format(dst->format); - assert(cs2d_format >= 0); - - gdirect_format = nv04_rect_format(dst->format); - assert(gdirect_format >= 0); + if(bpp == 1) + { + gdirect_format = NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + cs2d_format = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + } + else if(bpp == 2) + { + gdirect_format = NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + cs2d_format = NV04_CONTEXT_SURFACES_2D_FORMAT_Y16; + } + else + { + gdirect_format = NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + cs2d_format = NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + } MARK_RING (chan, 16, 4); BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);