util: Use sizeof(void *) rather than 0 as the fallback cache line size
[mesa.git] / src / gallium / state_trackers / xorg / xorg_composite.c
index 69a83b152345b70730b05621e9daae5a2830e76a..7ccb3fe4734fe5699ef1f351ea0ffacb3e480450 100644 (file)
@@ -4,10 +4,9 @@
 #include "xorg_exa_tgsi.h"
 
 #include "cso_cache/cso_context.h"
-#include "util/u_draw_quad.h"
-#include "util/u_math.h"
+#include "util/u_format.h"
+#include "util/u_sampler.h"
 
-#include "pipe/p_inlines.h"
 
 /*XXX also in Xrender.h but the including it here breaks compilition */
 #define XFixedToDouble(f)    (((double) (f)) / 65536.)
@@ -54,18 +53,17 @@ static const struct xorg_composite_blend xorg_blends[] = {
 
 
 static INLINE void
-pixel_to_float4(Pixel pixel, float *color)
+pixel_to_float4(Pixel pixel, float *color, enum pipe_format format)
 {
-   CARD32          r, g, b, a;
-
-   a = (pixel >> 24) & 0xff;
-   r = (pixel >> 16) & 0xff;
-   g = (pixel >>  8) & 0xff;
-   b = (pixel >>  0) & 0xff;
-   color[0] = ((float)r) / 255.;
-   color[1] = ((float)g) / 255.;
-   color[2] = ((float)b) / 255.;
-   color[3] = ((float)a) / 255.;
+   const struct util_format_description *format_desc;
+   uint8_t packed[4];
+
+   format_desc = util_format_description(format);
+   packed[0] = pixel;
+   packed[1] = pixel >> 8;
+   packed[2] = pixel >> 16;
+   packed[3] = pixel >> 24;
+   format_desc->unpack_rgba_float(color, 0, packed, 0, 1, 1);
 }
 
 static boolean
@@ -177,7 +175,7 @@ boolean xorg_composite_accelerated(int op,
                                    PicturePtr pDstPicture)
 {
    ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
-   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    modesettingPtr ms = modesettingPTR(pScrn);
    struct xorg_composite_blend blend;
 
@@ -220,31 +218,41 @@ bind_blend_state(struct exa_context *exa, int op,
    blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture);
 
    memset(&blend, 0, sizeof(struct pipe_blend_state));
-   blend.blend_enable = 1;
-   blend.colormask |= PIPE_MASK_RGBA;
+   blend.rt[0].blend_enable = 1;
+   blend.rt[0].colormask = PIPE_MASK_RGBA;
 
-   blend.rgb_src_factor   = blend_opt.rgb_src;
-   blend.alpha_src_factor = blend_opt.rgb_src;
-   blend.rgb_dst_factor   = blend_opt.rgb_dst;
-   blend.alpha_dst_factor = blend_opt.rgb_dst;
+   blend.rt[0].rgb_src_factor   = blend_opt.rgb_src;
+   blend.rt[0].alpha_src_factor = blend_opt.rgb_src;
+   blend.rt[0].rgb_dst_factor   = blend_opt.rgb_dst;
+   blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
 
    cso_set_blend(exa->renderer->cso, &blend);
 }
 
 static unsigned
-picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask)
+picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
+                      PicturePtr pDstPicture)
 {
    boolean set_alpha = FALSE;
    boolean swizzle = FALSE;
    unsigned ret = 0;
 
-   if (pSrc->picture_format == pSrcPicture->format) {
-      if (pSrc->picture_format == PICT_a8)
-         return mask ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE;
+   if (pSrc && pSrc->picture_format == pSrcPicture->format) {
+      if (pSrc->picture_format == PICT_a8) {
+         if (mask)
+            return FS_MASK_LUMINANCE;
+         else if (pDstPicture->format != PICT_a8) {
+            /* if both dst and src are luminance then
+             * we don't want to swizzle the alpha (X) of the
+             * source into W component of the dst because
+             * it will break our destination */
+            return FS_SRC_LUMINANCE;
+         }
+      }
       return 0;
    }
 
-   if (pSrc->picture_format != PICT_a8r8g8b8) {
+   if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) {
       assert(!"can not handle formats");
       return 0;
    }
@@ -285,7 +293,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool
 
 static void
 bind_shaders(struct exa_context *exa, int op,
-             PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+             PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
              struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
 {
    unsigned vs_traits = 0, fs_traits = 0;
@@ -303,7 +311,7 @@ bind_shaders(struct exa_context *exa, int op,
             vs_traits |= VS_SOLID_FILL;
             debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
             pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
-                            exa->solid_color);
+                            exa->solid_color, PIPE_FORMAT_B8G8R8A8_UNORM);
             exa->has_solid_color = TRUE;
          } else {
             debug_assert("!gradients not supported");
@@ -313,7 +321,7 @@ bind_shaders(struct exa_context *exa, int op,
          vs_traits |= VS_COMPOSITE;
       }
 
-      fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE);
+      fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
    }
 
    if (pMaskPicture) {
@@ -331,7 +339,7 @@ bind_shaders(struct exa_context *exa, int op,
             fs_traits |= FS_CA_FULL;
       }
 
-      fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE);
+      fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
    }
 
    shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
@@ -347,19 +355,14 @@ bind_samplers(struct exa_context *exa, int op,
               struct exa_pixmap_priv *pMask,
               struct exa_pixmap_priv *pDst)
 {
-   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0};
    struct pipe_sampler_state src_sampler, mask_sampler;
+   struct pipe_sampler_view view_templ;
+   struct pipe_sampler_view *src_view;
+   struct pipe_context *pipe = exa->pipe;
 
    exa->num_bound_samplers = 0;
 
-#if 0
-   if ((pSrc && (exa->pipe->is_texture_referenced(exa->pipe, pSrc->tex, 0, 0) &
-                 PIPE_REFERENCED_FOR_WRITE)) ||
-       (pMask && (exa->pipe->is_texture_referenced(exa->pipe, pMask->tex, 0, 0) &
-        PIPE_REFERENCED_FOR_WRITE)))
-      xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
-#endif
-
    memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
    memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
 
@@ -367,7 +370,7 @@ bind_samplers(struct exa_context *exa, int op,
       if (exa->has_solid_color) {
          debug_assert(!"solid color with textures");
          samplers[0] = NULL;
-         exa->bound_textures[0] = NULL;
+         pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
       } else {
          unsigned src_wrap = render_repeat_to_gallium(
             pSrcPicture->repeatType);
@@ -382,8 +385,13 @@ bind_samplers(struct exa_context *exa, int op,
          src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
          src_sampler.normalized_coords = 1;
          samplers[0] = &src_sampler;
-         exa->bound_textures[0] = pSrc->tex;
          exa->num_bound_samplers = 1;
+         u_sampler_view_default_template(&view_templ,
+                                         pSrc->tex,
+                                         pSrc->tex->format);
+         src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
+         pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
+         exa->bound_sampler_views[0] = src_view;
       }
    }
 
@@ -401,50 +409,24 @@ bind_samplers(struct exa_context *exa, int op,
       src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
       mask_sampler.normalized_coords = 1;
       samplers[1] = &mask_sampler;
-      exa->bound_textures[1] = pMask->tex;
       exa->num_bound_samplers = 2;
+      u_sampler_view_default_template(&view_templ,
+                                      pMask->tex,
+                                      pMask->tex->format);
+      src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
+      pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
+      exa->bound_sampler_views[1] = src_view;
    }
 
-   cso_set_samplers(exa->renderer->cso, exa->num_bound_samplers,
+   cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
+                    exa->num_bound_samplers,
                     (const struct pipe_sampler_state **)samplers);
-   cso_set_sampler_textures(exa->renderer->cso, exa->num_bound_samplers,
-                            exa->bound_textures);
-}
-
-static void
-setup_vs_constant_buffer(struct exa_context *exa,
-                         int width, int height)
-{
-   const int param_bytes = 8 * sizeof(float);
-   float vs_consts[8] = {
-      2.f/width, 2.f/height, 1, 1,
-      -1, -1, 0, 0
-   };
-   renderer_set_constants(exa->renderer, PIPE_SHADER_VERTEX,
-                          vs_consts, param_bytes);
+   cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
+                         exa->num_bound_samplers,
+                         exa->bound_sampler_views);
 }
 
 
-static void
-setup_fs_constant_buffer(struct exa_context *exa)
-{
-   const int param_bytes = 4 * sizeof(float);
-   const float fs_consts[8] = {
-      0, 0, 0, 1,
-   };
-   renderer_set_constants(exa->renderer, PIPE_SHADER_FRAGMENT,
-                          fs_consts, param_bytes);
-}
-
-static void
-setup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst)
-{
-   int width = pDst->tex->width0;
-   int height = pDst->tex->height0;
-
-   setup_vs_constant_buffer(exa, width, height);
-   setup_fs_constant_buffer(exa);
-}
 
 static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
 {
@@ -493,14 +475,16 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
                                   struct exa_pixmap_priv *pMask,
                                   struct exa_pixmap_priv *pDst)
 {
-   renderer_bind_framebuffer(exa->renderer, pDst);
-   renderer_bind_viewport(exa->renderer, pDst);
+   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pDst);
+
+   renderer_bind_destination(exa->renderer, dst_surf,
+                             pDst->width,
+                             pDst->height);
+
    bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
-   renderer_bind_rasterizer(exa->renderer);
-   bind_shaders(exa, op, pSrcPicture, pMaskPicture, pSrc, pMask);
+   bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
    bind_samplers(exa, op, pSrcPicture, pMaskPicture,
                  pDstPicture, pSrc, pMask, pDst);
-   setup_constant_buffers(exa, pDst);
 
    setup_transforms(exa, pSrcPicture, pMaskPicture);
 
@@ -508,10 +492,11 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
       renderer_begin_solid(exa->renderer);
    } else {
       renderer_begin_textures(exa->renderer,
-                              exa->bound_textures,
                               exa->num_bound_samplers);
    }
 
+
+   pipe_surface_reference(&dst_surf, NULL);
    return TRUE;
 }
 
@@ -536,7 +521,7 @@ void xorg_composite(struct exa_context *exa,
 
       renderer_texture(exa->renderer,
                        pos, width, height,
-                       exa->bound_textures,
+                       exa->bound_sampler_views,
                        exa->num_bound_samplers,
                        src_matrix, mask_matrix);
    }
@@ -546,10 +531,11 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
                               struct exa_pixmap_priv *pixmap,
                               Pixel fg)
 {
+   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap);
    unsigned vs_traits, fs_traits;
    struct xorg_shader shader;
 
-   pixel_to_float4(fg, exa->solid_color);
+   pixel_to_float4(fg, exa->solid_color, pixmap->tex->format);
    exa->has_solid_color = TRUE;
 
 #if 0
@@ -563,13 +549,11 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
    vs_traits = VS_SOLID_FILL;
    fs_traits = FS_SOLID_FILL;
 
-   renderer_bind_framebuffer(exa->renderer, pixmap);
-   renderer_bind_viewport(exa->renderer, pixmap);
-   renderer_bind_rasterizer(exa->renderer);
+   renderer_bind_destination(exa->renderer, dst_surf, 
+                             pixmap->width, pixmap->height);
    bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
-   cso_set_samplers(exa->renderer->cso, 0, NULL);
-   cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
-   setup_constant_buffers(exa, pixmap);
+   cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
+   cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
 
    shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
    cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
@@ -577,6 +561,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
 
    renderer_begin_solid(exa->renderer);
 
+   pipe_surface_reference(&dst_surf, NULL);
    return TRUE;
 }
 
@@ -588,3 +573,13 @@ void xorg_solid(struct exa_context *exa,
                   x0, y0, x1, y1, exa->solid_color);
 }
 
+void
+xorg_composite_done(struct exa_context *exa)
+{
+   renderer_draw_flush(exa->renderer);
+
+   exa->transform.has_src = FALSE;
+   exa->transform.has_mask = FALSE;
+   exa->has_solid_color = FALSE;
+   exa->num_bound_samplers = 0;
+}