1 /**************************************************************************
3 * Copyright 2009 VMware, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
27 #include "vg_context.h"
31 #include "shaders_cache.h"
34 #include "st_inlines.h"
36 #include "pipe/p_context.h"
37 #include "pipe/p_inlines.h"
38 #include "pipe/p_shader_tokens.h"
40 #include "cso_cache/cso_context.h"
42 #include "util/u_simple_shaders.h"
43 #include "util/u_memory.h"
44 #include "util/u_blit.h"
46 struct vg_context
*_vg_context
= 0;
48 struct vg_context
* vg_current_context(void)
53 static void init_clear(struct vg_context
*st
)
55 struct pipe_context
*pipe
= st
->pipe
;
57 /* rasterizer state: bypass clipping */
58 memset(&st
->clear
.raster
, 0, sizeof(st
->clear
.raster
));
59 st
->clear
.raster
.gl_rasterization_rules
= 1;
61 /* fragment shader state: color pass-through program */
63 util_make_fragment_passthrough_shader(pipe
);
65 void vg_set_current_context(struct vg_context
*ctx
)
70 struct vg_context
* vg_create_context(struct pipe_context
*pipe
,
72 struct vg_context
*share
)
74 struct vg_context
*ctx
;
76 ctx
= CALLOC_STRUCT(vg_context
);
80 vg_init_state(&ctx
->state
.vg
);
81 ctx
->state
.dirty
= ALL_DIRTY
;
83 ctx
->cso_context
= cso_create_context(pipe
);
87 ctx
->default_paint
= paint_create(ctx
);
88 ctx
->state
.vg
.stroke_paint
= ctx
->default_paint
;
89 ctx
->state
.vg
.fill_paint
= ctx
->default_paint
;
92 ctx
->mask
.sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
93 ctx
->mask
.sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
94 ctx
->mask
.sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
95 ctx
->mask
.sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
96 ctx
->mask
.sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
97 ctx
->mask
.sampler
.normalized_coords
= 0;
99 ctx
->blend_sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
100 ctx
->blend_sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
101 ctx
->blend_sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
102 ctx
->blend_sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
103 ctx
->blend_sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
104 ctx
->blend_sampler
.normalized_coords
= 0;
106 vg_set_error(ctx
, VG_NO_ERROR
);
108 ctx
->owned_objects
[VG_OBJECT_PAINT
] = cso_hash_create();
109 ctx
->owned_objects
[VG_OBJECT_IMAGE
] = cso_hash_create();
110 ctx
->owned_objects
[VG_OBJECT_MASK
] = cso_hash_create();
111 ctx
->owned_objects
[VG_OBJECT_FONT
] = cso_hash_create();
112 ctx
->owned_objects
[VG_OBJECT_PATH
] = cso_hash_create();
114 ctx
->renderer
= renderer_create(ctx
);
115 ctx
->sc
= shaders_cache_create(ctx
);
116 ctx
->shader
= shader_create(ctx
);
118 ctx
->blit
= util_create_blit(ctx
->pipe
, ctx
->cso_context
);
123 void vg_destroy_context(struct vg_context
*ctx
)
125 struct pipe_constant_buffer
*cbuf
= &ctx
->mask
.cbuf
;
126 struct pipe_constant_buffer
*vsbuf
= &ctx
->vs_const_buffer
;
128 util_destroy_blit(ctx
->blit
);
129 renderer_destroy(ctx
->renderer
);
130 shaders_cache_destroy(ctx
->sc
);
131 shader_destroy(ctx
->shader
);
132 paint_destroy(ctx
->default_paint
);
134 if (cbuf
&& cbuf
->buffer
)
135 pipe_buffer_reference(&cbuf
->buffer
, NULL
);
137 if (vsbuf
&& vsbuf
->buffer
)
138 pipe_buffer_reference(&vsbuf
->buffer
, NULL
);
141 cso_delete_fragment_shader(ctx
->cso_context
, ctx
->clear
.fs
);
142 ctx
->clear
.fs
= NULL
;
146 vg_shader_destroy(ctx
, ctx
->plain_vs
);
147 ctx
->plain_vs
= NULL
;
150 vg_shader_destroy(ctx
, ctx
->clear_vs
);
151 ctx
->clear_vs
= NULL
;
153 if (ctx
->texture_vs
) {
154 vg_shader_destroy(ctx
, ctx
->texture_vs
);
155 ctx
->texture_vs
= NULL
;
158 if (ctx
->pass_through_depth_fs
)
159 vg_shader_destroy(ctx
, ctx
->pass_through_depth_fs
);
160 if (ctx
->mask
.union_fs
)
161 vg_shader_destroy(ctx
, ctx
->mask
.union_fs
);
162 if (ctx
->mask
.intersect_fs
)
163 vg_shader_destroy(ctx
, ctx
->mask
.intersect_fs
);
164 if (ctx
->mask
.subtract_fs
)
165 vg_shader_destroy(ctx
, ctx
->mask
.subtract_fs
);
166 if (ctx
->mask
.set_fs
)
167 vg_shader_destroy(ctx
, ctx
->mask
.set_fs
);
169 cso_release_all(ctx
->cso_context
);
170 cso_destroy_context(ctx
->cso_context
);
172 cso_hash_delete(ctx
->owned_objects
[VG_OBJECT_PAINT
]);
173 cso_hash_delete(ctx
->owned_objects
[VG_OBJECT_IMAGE
]);
174 cso_hash_delete(ctx
->owned_objects
[VG_OBJECT_MASK
]);
175 cso_hash_delete(ctx
->owned_objects
[VG_OBJECT_FONT
]);
176 cso_hash_delete(ctx
->owned_objects
[VG_OBJECT_PATH
]);
181 void vg_init_object(struct vg_object
*obj
, struct vg_context
*ctx
, enum vg_object_type type
)
187 VGboolean
vg_context_is_object_valid(struct vg_context
*ctx
,
188 enum vg_object_type type
,
192 struct cso_hash
*hash
= ctx
->owned_objects
[type
];
195 return cso_hash_contains(hash
, (unsigned)(long)ptr
);
200 void vg_context_add_object(struct vg_context
*ctx
,
201 enum vg_object_type type
,
205 struct cso_hash
*hash
= ctx
->owned_objects
[type
];
208 cso_hash_insert(hash
, (unsigned)(long)ptr
, ptr
);
212 void vg_context_remove_object(struct vg_context
*ctx
,
213 enum vg_object_type type
,
217 struct cso_hash
*hash
= ctx
->owned_objects
[type
];
220 cso_hash_take(hash
, (unsigned)(long)ptr
);
224 static void update_clip_state(struct vg_context
*ctx
)
226 struct pipe_depth_stencil_alpha_state
*dsa
= &ctx
->state
.g3d
.dsa
;
227 struct vg_state
*state
= &ctx
->state
.vg
;
229 memset(dsa
, 0, sizeof(struct pipe_depth_stencil_alpha_state
));
231 if (state
->scissoring
) {
232 struct pipe_blend_state
*blend
= &ctx
->state
.g3d
.blend
;
233 struct pipe_framebuffer_state
*fb
= &ctx
->state
.g3d
.fb
;
235 <<<<<<< HEAD
:src
/gallium
/state_trackers
/vega
/vg_context
.c
238 >>>>>>> mesa_7_6_branch
:src
/gallium
/state_trackers
/vega
/vg_context
.c
239 dsa
->depth
.writemask
= 1;/*glDepthMask(TRUE);*/
240 dsa
->depth
.func
= PIPE_FUNC_ALWAYS
;
241 dsa
->depth
.enabled
= 1;
243 cso_save_blend(ctx
->cso_context
);
244 cso_save_fragment_shader(ctx
->cso_context
);
245 /* set a passthrough shader */
246 if (!ctx
->pass_through_depth_fs
)
247 ctx
->pass_through_depth_fs
= shader_create_from_text(ctx
->pipe
,
248 pass_through_depth_asm
,
250 PIPE_SHADER_FRAGMENT
);
251 cso_set_fragment_shader_handle(ctx
->cso_context
,
252 ctx
->pass_through_depth_fs
->driver
);
253 cso_set_depth_stencil_alpha(ctx
->cso_context
, dsa
);
255 ctx
->pipe
->clear(ctx
->pipe
, PIPE_CLEAR_DEPTHSTENCIL
, NULL
, 1.0, 0);
257 /* disable color writes */
258 blend
->colormask
= 0; /*disable colorwrites*/
259 cso_set_blend(ctx
->cso_context
, blend
);
261 /* enable scissoring */
262 for (i
= 0; i
< state
->scissor_rects_num
; ++i
) {
263 const float x
= state
->scissor_rects
[i
* 4 + 0].f
;
264 const float y
= state
->scissor_rects
[i
* 4 + 1].f
;
265 const float width
= state
->scissor_rects
[i
* 4 + 2].f
;
266 const float height
= state
->scissor_rects
[i
* 4 + 3].f
;
267 VGfloat minx
, miny
, maxx
, maxy
;
279 if (x
+ width
< maxx
)
281 if (y
+ height
< maxy
)
284 /* check for null space */
285 if (minx
>= maxx
|| miny
>= maxy
)
286 minx
= miny
= maxx
= maxy
= 0;
288 /*glClear(GL_DEPTH_BUFFER_BIT);*/
289 renderer_draw_quad(ctx
->renderer
, minx
, miny
, maxx
, maxy
, 0.0f
);
292 blend
->colormask
= 1; /*enable colorwrites*/
293 cso_restore_blend(ctx
->cso_context
);
294 cso_restore_fragment_shader(ctx
->cso_context
);
296 dsa
->depth
.enabled
= 1; /* glEnable(GL_DEPTH_TEST); */
297 dsa
->depth
.writemask
= 0;/*glDepthMask(FALSE);*/
298 dsa
->depth
.func
= PIPE_FUNC_GEQUAL
;
302 void vg_validate_state(struct vg_context
*ctx
)
304 if ((ctx
->state
.dirty
& BLEND_DIRTY
)) {
305 struct pipe_blend_state
*blend
= &ctx
->state
.g3d
.blend
;
306 memset(blend
, 0, sizeof(struct pipe_blend_state
));
307 blend
->blend_enable
= 1;
308 blend
->colormask
|= PIPE_MASK_R
;
309 blend
->colormask
|= PIPE_MASK_G
;
310 blend
->colormask
|= PIPE_MASK_B
;
311 blend
->colormask
|= PIPE_MASK_A
;
313 switch (ctx
->state
.vg
.blend_mode
) {
315 blend
->rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
316 blend
->alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
317 blend
->rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
318 blend
->alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
320 case VG_BLEND_SRC_OVER
:
321 blend
->rgb_src_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
322 blend
->alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
323 blend
->rgb_dst_factor
= PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
324 blend
->alpha_dst_factor
= PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
326 case VG_BLEND_DST_OVER
:
327 blend
->rgb_src_factor
= PIPE_BLENDFACTOR_INV_DST_ALPHA
;
328 blend
->alpha_src_factor
= PIPE_BLENDFACTOR_INV_DST_ALPHA
;
329 blend
->rgb_dst_factor
= PIPE_BLENDFACTOR_DST_ALPHA
;
330 blend
->alpha_dst_factor
= PIPE_BLENDFACTOR_DST_ALPHA
;
332 case VG_BLEND_SRC_IN
:
333 blend
->rgb_src_factor
= PIPE_BLENDFACTOR_DST_ALPHA
;
334 blend
->alpha_src_factor
= PIPE_BLENDFACTOR_DST_ALPHA
;
335 blend
->rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
336 blend
->alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
338 case VG_BLEND_DST_IN
:
339 blend
->rgb_src_factor
= PIPE_BLENDFACTOR_ZERO
;
340 blend
->alpha_src_factor
= PIPE_BLENDFACTOR_ZERO
;
341 blend
->rgb_dst_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
342 blend
->alpha_dst_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
344 case VG_BLEND_MULTIPLY
:
345 case VG_BLEND_SCREEN
:
346 case VG_BLEND_DARKEN
:
347 case VG_BLEND_LIGHTEN
:
348 blend
->rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
349 blend
->alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
350 blend
->rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
351 blend
->alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
353 case VG_BLEND_ADDITIVE
:
354 blend
->rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
355 blend
->alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
356 blend
->rgb_dst_factor
= PIPE_BLENDFACTOR_ONE
;
357 blend
->alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
360 assert(!"not implemented blend mode");
362 cso_set_blend(ctx
->cso_context
, &ctx
->state
.g3d
.blend
);
364 if ((ctx
->state
.dirty
& RASTERIZER_DIRTY
)) {
365 struct pipe_rasterizer_state
*raster
= &ctx
->state
.g3d
.rasterizer
;
366 memset(raster
, 0, sizeof(struct pipe_rasterizer_state
));
367 raster
->gl_rasterization_rules
= 1;
368 cso_set_rasterizer(ctx
->cso_context
, &ctx
->state
.g3d
.rasterizer
);
370 if ((ctx
->state
.dirty
& VIEWPORT_DIRTY
)) {
371 struct pipe_framebuffer_state
*fb
= &ctx
->state
.g3d
.fb
;
372 const VGint param_bytes
= 8 * sizeof(VGfloat
);
373 VGfloat vs_consts
[8] = {
374 2.f
/fb
->width
, 2.f
/fb
->height
, 1, 1,
377 struct pipe_constant_buffer
*cbuf
= &ctx
->vs_const_buffer
;
379 vg_set_viewport(ctx
, VEGA_Y0_BOTTOM
);
381 pipe_buffer_reference(&cbuf
->buffer
, NULL
);
382 cbuf
->buffer
= pipe_buffer_create(ctx
->pipe
->screen
, 16,
383 PIPE_BUFFER_USAGE_CONSTANT
,
387 st_no_flush_pipe_buffer_write(ctx
, cbuf
->buffer
,
388 0, param_bytes
, vs_consts
);
390 ctx
->pipe
->set_constant_buffer(ctx
->pipe
, PIPE_SHADER_VERTEX
, 0, cbuf
);
392 if ((ctx
->state
.dirty
& VS_DIRTY
)) {
393 cso_set_vertex_shader_handle(ctx
->cso_context
,
397 /* must be last because it renders to the depth buffer*/
398 if ((ctx
->state
.dirty
& DEPTH_STENCIL_DIRTY
)) {
399 update_clip_state(ctx
);
400 cso_set_depth_stencil_alpha(ctx
->cso_context
, &ctx
->state
.g3d
.dsa
);
403 shader_set_masking(ctx
->shader
, ctx
->state
.vg
.masking
);
404 shader_set_image_mode(ctx
->shader
, ctx
->state
.vg
.image_mode
);
406 ctx
->state
.dirty
= NONE_DIRTY
;
409 VGboolean
vg_object_is_valid(void *ptr
, enum vg_object_type type
)
411 struct vg_object
*obj
= ptr
;
412 if (ptr
&& is_aligned(obj
) && obj
->type
== type
)
418 void vg_set_error(struct vg_context
*ctx
,
421 /*vgGetError returns the oldest error code provided by
422 * an API call on the current context since the previous
423 * call to vgGetError on that context (or since the creation
425 if (ctx
->_error
== VG_NO_ERROR
)
429 void vg_prepare_blend_surface(struct vg_context
*ctx
)
431 struct pipe_surface
*dest_surface
= NULL
;
432 struct pipe_context
*pipe
= ctx
->pipe
;
433 struct st_framebuffer
*stfb
= ctx
->draw_buffer
;
434 struct st_renderbuffer
*strb
= stfb
->strb
;
436 /* first finish all pending rendering */
439 dest_surface
= pipe
->screen
->get_tex_surface(pipe
->screen
,
442 PIPE_BUFFER_USAGE_GPU_WRITE
);
443 /* flip it, because we want to use it as a sampler */
444 util_blit_pixels_tex(ctx
->blit
,
450 strb
->width
, strb
->height
,
451 0.0, PIPE_TEX_MIPFILTER_NEAREST
);
454 pipe_surface_reference(&dest_surface
, NULL
);
456 /* make sure it's complete */
461 void vg_prepare_blend_surface_from_mask(struct vg_context
*ctx
)
463 struct pipe_surface
*dest_surface
= NULL
;
464 struct pipe_context
*pipe
= ctx
->pipe
;
465 struct st_framebuffer
*stfb
= ctx
->draw_buffer
;
466 struct st_renderbuffer
*strb
= stfb
->strb
;
468 vg_validate_state(ctx
);
470 /* first finish all pending rendering */
473 dest_surface
= pipe
->screen
->get_tex_surface(pipe
->screen
,
476 PIPE_BUFFER_USAGE_GPU_WRITE
);
478 /* flip it, because we want to use it as a sampler */
479 util_blit_pixels_tex(ctx
->blit
,
485 strb
->width
, strb
->height
,
486 0.0, PIPE_TEX_MIPFILTER_NEAREST
);
488 /* make sure it's complete */
492 pipe_surface_reference(&dest_surface
, NULL
);
495 void * vg_plain_vs(struct vg_context
*ctx
)
497 if (!ctx
->plain_vs
) {
498 ctx
->plain_vs
= shader_create_from_text(ctx
->pipe
,
504 return ctx
->plain_vs
->driver
;
508 void * vg_clear_vs(struct vg_context
*ctx
)
510 if (!ctx
->clear_vs
) {
511 ctx
->clear_vs
= shader_create_from_text(ctx
->pipe
,
517 return ctx
->clear_vs
->driver
;
520 void * vg_texture_vs(struct vg_context
*ctx
)
522 if (!ctx
->texture_vs
) {
523 ctx
->texture_vs
= shader_create_from_text(ctx
->pipe
,
529 return ctx
->texture_vs
->driver
;
532 void vg_set_viewport(struct vg_context
*ctx
, VegaOrientation orientation
)
534 struct pipe_viewport_state viewport
;
535 struct pipe_framebuffer_state
*fb
= &ctx
->state
.g3d
.fb
;
536 VGfloat y_scale
= (orientation
== VEGA_Y0_BOTTOM
) ? -2.f
: 2.f
;
538 viewport
.scale
[0] = fb
->width
/ 2.f
;
539 viewport
.scale
[1] = fb
->height
/ y_scale
;
540 viewport
.scale
[2] = 1.0;
541 viewport
.scale
[3] = 1.0;
542 viewport
.translate
[0] = fb
->width
/ 2.f
;
543 viewport
.translate
[1] = fb
->height
/ 2.f
;
544 viewport
.translate
[2] = 0.0;
545 viewport
.translate
[3] = 0.0;
547 cso_set_viewport(ctx
->cso_context
, &viewport
);