xorg_composite.c revision f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756
1#include "xorg_composite.h" 2 3#include "xorg_exa_tgsi.h" 4 5#include <cso_cache/cso_context.h> 6 7#include <pipe/p_inlines.h> 8 9struct xorg_composite_blend { 10 int op:8; 11 12 unsigned rgb_src_factor:5; /**< PIPE_BLENDFACTOR_x */ 13 unsigned rgb_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ 14 15 unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */ 16 unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ 17}; 18 19#define BLEND_OP_OVER 3 20static const struct xorg_composite_blend xorg_blends[] = { 21 { PictOpClear, 22 PIPE_BLENDFACTOR_CONST_COLOR, PIPE_BLENDFACTOR_CONST_ALPHA, 23 PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO }, 24 25 { PictOpSrc, 26 PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE, 27 PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO }, 28 29 { PictOpDst, 30 PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO, 31 PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE }, 32 33 { PictOpOver, 34 PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE, 35 PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, 36 37 { PictOpOverReverse, 38 PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE, 39 PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, 40}; 41 42struct acceleration_info { 43 int op : 16; 44 int with_mask : 1; 45 int component_alpha : 1; 46}; 47static const struct acceleration_info accelerated_ops[] = { 48 {PictOpClear, 1, 0}, 49 {PictOpSrc, 1, 0}, 50 {PictOpDst, 1, 0}, 51 {PictOpOver, 1, 0}, 52 {PictOpOverReverse, 1, 0}, 53 {PictOpIn, 1, 0}, 54 {PictOpInReverse, 1, 0}, 55 {PictOpOut, 1, 0}, 56 {PictOpOutReverse, 1, 0}, 57 {PictOpAtop, 1, 0}, 58 {PictOpAtopReverse, 1, 0}, 59 {PictOpXor, 1, 0}, 60 {PictOpAdd, 1, 0}, 61 {PictOpSaturate, 1, 0}, 62}; 63 64static struct xorg_composite_blend 65blend_for_op(int op) 66{ 67 const int num_blends = 68 sizeof(xorg_blends)/sizeof(struct xorg_composite_blend); 69 int i; 70 71 for (i = 0; i < num_blends; ++i) { 72 if (xorg_blends[i].op == op) 73 return xorg_blends[i]; 74 } 75 return xorg_blends[BLEND_OP_OVER]; 76} 77 78static void 79draw_texture(struct exa_context *exa) 80{ 81#if 0 82 if (buf) { 83 util_draw_vertex_buffer(pipe, buf, 0, 84 PIPE_PRIM_TRIANGLE_FAN, 85 4, /* verts */ 86 2); /* attribs/vert */ 87 88 pipe_buffer_reference(&buf, NULL); 89 } 90#endif 91} 92 93boolean xorg_composite_accelerated(int op, 94 PicturePtr pSrcPicture, 95 PicturePtr pMaskPicture, 96 PicturePtr pDstPicture) 97{ 98 unsigned i; 99 unsigned accel_ops_count = 100 sizeof(accelerated_ops)/sizeof(struct acceleration_info); 101 102 if (pSrcPicture) { 103 /* component alpha not supported */ 104 if (pSrcPicture->componentAlpha) 105 return FALSE; 106 /* fills not supported */ 107 if (pSrcPicture->pSourcePict) 108 return FALSE; 109 } 110 111 for (i = 0; i < accel_ops_count; ++i) { 112 if (op == accelerated_ops[i].op) { 113 if (pMaskPicture && !accelerated_ops[i].with_mask) 114 return FALSE; 115 return TRUE; 116 } 117 } 118 return FALSE; 119} 120 121static void 122bind_framebuffer_state(struct exa_context *exa, PicturePtr pDstPicture, 123 struct exa_pixmap_priv *pDst) 124{ 125 unsigned i; 126 struct pipe_framebuffer_state state; 127 struct pipe_surface *surface = exa_gpu_surface(exa, pDst); 128 memset(&state, 0, sizeof(struct pipe_framebuffer_state)); 129 130 state.width = pDstPicture->pDrawable->width; 131 state.height = pDstPicture->pDrawable->height; 132 133 state.nr_cbufs = 1; 134 state.cbufs[0] = surface; 135 for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i) 136 state.cbufs[i] = 0; 137 138 /* currently we don't use depth/stencil */ 139 state.zsbuf = 0; 140 141 cso_set_framebuffer(exa->cso, &state); 142} 143 144enum AxisOrientation { 145 Y0_BOTTOM, 146 Y0_TOP 147}; 148 149static void 150set_viewport(struct exa_context *exa, int width, int height, 151 enum AxisOrientation orientation) 152{ 153 struct pipe_viewport_state viewport; 154 float y_scale = (orientation == Y0_BOTTOM) ? -2.f : 2.f; 155 156 viewport.scale[0] = width / 2.f; 157 viewport.scale[1] = height / y_scale; 158 viewport.scale[2] = 1.0; 159 viewport.scale[3] = 1.0; 160 viewport.translate[0] = width / 2.f; 161 viewport.translate[1] = height / 2.f; 162 viewport.translate[2] = 0.0; 163 viewport.translate[3] = 0.0; 164 165 cso_set_viewport(exa->cso, &viewport); 166} 167 168static void 169bind_viewport_state(struct exa_context *exa, PicturePtr pDstPicture) 170{ 171 const int param_bytes = 8 * sizeof(float); 172 int width = pDstPicture->pDrawable->width; 173 int height = pDstPicture->pDrawable->height; 174 float vs_consts[8] = { 175 2.f/width, 2.f/height, 1, 1, 176 -1, -1, 0, 0 177 }; 178 struct pipe_constant_buffer *cbuf = &exa->vs_const_buffer; 179 180 set_viewport(exa, width, height, Y0_BOTTOM); 181 182 pipe_buffer_reference(&cbuf->buffer, NULL); 183 cbuf->buffer = pipe_buffer_create(exa->ctx->screen, 16, 184 PIPE_BUFFER_USAGE_CONSTANT, 185 param_bytes); 186 187 if (cbuf->buffer) { 188 pipe_buffer_write(exa->ctx->screen, cbuf->buffer, 189 0, param_bytes, vs_consts); 190 } 191 exa->ctx->set_constant_buffer(exa->ctx, PIPE_SHADER_VERTEX, 0, cbuf); 192} 193 194static void 195bind_blend_state(struct exa_context *exa, int op, 196 PicturePtr pSrcPicture, PicturePtr pMaskPicture) 197{ 198 boolean component_alpha = pSrcPicture->componentAlpha; 199 struct xorg_composite_blend blend_opt; 200 struct pipe_blend_state blend; 201 202 if (component_alpha) { 203 op = PictOpOver; 204 } 205 blend_opt = blend_for_op(op); 206 207 memset(&blend, 0, sizeof(struct pipe_blend_state)); 208 blend.blend_enable = 1; 209 blend.colormask |= PIPE_MASK_R; 210 blend.colormask |= PIPE_MASK_G; 211 blend.colormask |= PIPE_MASK_B; 212 blend.colormask |= PIPE_MASK_A; 213 214 blend.rgb_src_factor = blend_opt.rgb_src_factor; 215 blend.alpha_src_factor = blend_opt.alpha_src_factor; 216 blend.rgb_dst_factor = blend_opt.rgb_dst_factor; 217 blend.alpha_dst_factor = blend_opt.alpha_dst_factor; 218 219 cso_set_blend(exa->cso, &blend); 220} 221 222static void 223bind_rasterizer_state(struct exa_context *exa) 224{ 225 struct pipe_rasterizer_state raster; 226 memset(&raster, 0, sizeof(struct pipe_rasterizer_state)); 227 raster.gl_rasterization_rules = 1; 228 cso_set_rasterizer(exa->cso, &raster); 229} 230 231static void 232bind_shaders(struct exa_context *exa, int op, 233 PicturePtr pSrcPicture, PicturePtr pMaskPicture) 234{ 235 unsigned vs_traits = 0, fs_traits = 0; 236 struct xorg_shader shader; 237 238 if (pSrcPicture) { 239 vs_traits |= VS_COMPOSITE; 240 fs_traits |= FS_COMPOSITE; 241 } 242 243 if (pMaskPicture) { 244 vs_traits |= VS_MASK; 245 fs_traits |= FS_MASK; 246 } 247 248 shader = xorg_shaders_get(exa->shaders, vs_traits, fs_traits); 249 cso_set_vertex_shader_handle(exa->cso, shader.vs); 250 cso_set_fragment_shader_handle(exa->cso, shader.fs); 251} 252 253 254static void 255bind_samplers(struct exa_context *exa, int op, 256 PicturePtr pSrcPicture, PicturePtr pMaskPicture, 257 PicturePtr pDstPicture) 258{ 259 260} 261 262boolean xorg_composite_bind_state(struct exa_context *exa, 263 int op, 264 PicturePtr pSrcPicture, 265 PicturePtr pMaskPicture, 266 PicturePtr pDstPicture, 267 struct exa_pixmap_priv *pSrc, 268 struct exa_pixmap_priv *pMask, 269 struct exa_pixmap_priv *pDst) 270{ 271 bind_framebuffer_state(exa, pDstPicture, pDst); 272 bind_viewport_state(exa, pDstPicture); 273 bind_blend_state(exa, op, pSrcPicture, pMaskPicture); 274 bind_rasterizer_state(exa); 275 bind_shaders(exa, op, pSrcPicture, pMaskPicture); 276 bind_samplers(exa, op, pSrcPicture, pMaskPicture, pDstPicture); 277 278 return FALSE; 279} 280 281void xorg_composite(struct exa_context *exa, 282 struct exa_pixmap_priv *dst, 283 int srcX, int srcY, int maskX, int maskY, 284 int dstX, int dstY, int width, int height) 285{ 286} 287 288