1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.  All Rights Reserved.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "shader.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vg_context.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "shaders_cache.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "paint.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "mask.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "image.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "renderer.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX_CONSTANTS 28
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct shader {
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *context;
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGboolean color_transform;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGboolean masking;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_paint *paint;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_image *image;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct matrix modelview;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct matrix paint_matrix;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGboolean drawing_image;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGImageMode image_mode;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float constants[MAX_CONSTANTS];
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_resource *cbuf;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_shader_state fs_state;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *fs;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct shader * shader_create(struct vg_context *ctx)
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct shader *shader = 0;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader = CALLOC_STRUCT(shader);
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->context = ctx;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shader;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_destroy(struct shader *shader)
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(shader);
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_set_color_transform(struct shader *shader, VGboolean set)
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->color_transform = set;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_set_masking(struct shader *shader, VGboolean set)
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->masking = set;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGboolean shader_is_masking(struct shader *shader)
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shader->masking;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_set_paint(struct shader *shader, struct vg_paint *paint)
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->paint = paint;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct vg_paint * shader_paint(struct shader *shader)
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shader->paint;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGint setup_constant_buffer(struct shader *shader)
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct vg_state *state = &shader->context->state.vg;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint param_bytes = paint_constant_buffer_size(shader->paint);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint i;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   param_bytes += sizeof(VGfloat) * 8;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(param_bytes <= sizeof(shader->constants));
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state->color_transform) {
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < 8; i++) {
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         VGfloat val = (i < 4) ? 127.0f : 1.0f;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader->constants[i] =
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            CLAMP(state->color_transform_values[i], -val, val);
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memset(shader->constants, 0, sizeof(VGfloat) * 8);
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   paint_fill_constant_buffer(shader->paint,
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         &shader->paint_matrix, shader->constants + 8);
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return param_bytes;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGboolean blend_use_shader(struct shader *shader)
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = shader->context;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGboolean advanced_blending;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ctx->state.vg.blend_mode) {
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VG_BLEND_DST_OVER:
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VG_BLEND_MULTIPLY:
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VG_BLEND_SCREEN:
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VG_BLEND_DARKEN:
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VG_BLEND_LIGHTEN:
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VG_BLEND_ADDITIVE:
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      advanced_blending = VG_TRUE;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VG_BLEND_SRC_OVER:
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (util_format_has_alpha(ctx->draw_buffer->strb->format)) {
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* no blending is required if the paints and the image are opaque */
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         advanced_blending = !paint_is_opaque(ctx->state.vg.fill_paint) ||
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             !paint_is_opaque(ctx->state.vg.stroke_paint);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!advanced_blending && shader->drawing_image) {
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            advanced_blending =
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               util_format_has_alpha(shader->image->sampler_view->format);
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* fall through */
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      advanced_blending = VG_FALSE;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return advanced_blending;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGint blend_bind_samplers(struct shader *shader,
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 struct pipe_sampler_state **samplers,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 struct pipe_sampler_view **sampler_views)
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (blend_use_shader(shader)) {
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct vg_context *ctx = shader->context;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      samplers[2] = &ctx->blend_sampler;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sampler_views[2] = vg_prepare_blend_surface(ctx);
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!samplers[0] || !sampler_views[0]) {
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         samplers[0] = samplers[2];
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sampler_views[0] = sampler_views[2];
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!samplers[1] || !sampler_views[1]) {
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         samplers[1] = samplers[0];
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sampler_views[1] = sampler_views[0];
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 1;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return 0;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGint setup_samplers(struct shader *shader,
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            struct pipe_sampler_state **samplers,
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            struct pipe_sampler_view **sampler_views)
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* a little wonky: we use the num as a boolean that just says
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * whether any sampler/textures have been set. the actual numbering
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * for samplers is always the same:
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * 0 - paint sampler/texture for gradient/pattern
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * 1 - mask sampler/texture
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * 2 - blend sampler/texture
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * 3 - image sampler/texture
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * */
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint num = 0;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   samplers[0] = NULL;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   samplers[1] = NULL;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   samplers[2] = NULL;
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   samplers[3] = NULL;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler_views[0] = NULL;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler_views[1] = NULL;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler_views[2] = NULL;
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler_views[3] = NULL;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num += paint_bind_samplers(shader->paint, samplers, sampler_views);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num += mask_bind_samplers(samplers, sampler_views);
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num += blend_bind_samplers(shader, samplers, sampler_views);
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shader->drawing_image && shader->image)
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num += image_bind_samplers(shader->image, samplers, sampler_views);
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (num) ? 4 : 0;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGboolean is_format_bw(struct shader *shader)
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = shader->context;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_framebuffer *stfb = ctx->draw_buffer;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shader->drawing_image && shader->image) {
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shader->image->format == VG_BW_1)
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return VG_TRUE;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return VG_FALSE;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void setup_shader_program(struct shader *shader)
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = shader->context;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint shader_id = 0;
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGBlendMode blend_mode = ctx->state.vg.blend_mode;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGboolean black_white = is_format_bw(shader);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* 1st stage: fill */
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!shader->drawing_image ||
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (shader->image_mode == VG_DRAW_IMAGE_MULTIPLY || shader->image_mode == VG_DRAW_IMAGE_STENCIL)) {
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch(paint_type(shader->paint)) {
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_PAINT_TYPE_COLOR:
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_SOLID_FILL_SHADER;
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_PAINT_TYPE_LINEAR_GRADIENT:
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_LINEAR_GRADIENT_SHADER;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_PAINT_TYPE_RADIAL_GRADIENT:
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_RADIAL_GRADIENT_SHADER;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_PAINT_TYPE_PATTERN:
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_PATTERN_SHADER;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         abort();
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (paint_is_degenerate(shader->paint))
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id = VEGA_PAINT_DEGENERATE_SHADER;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* second stage image */
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shader->drawing_image) {
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch(shader->image_mode) {
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_DRAW_IMAGE_NORMAL:
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_IMAGE_NORMAL_SHADER;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_DRAW_IMAGE_MULTIPLY:
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_IMAGE_MULTIPLY_SHADER;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_DRAW_IMAGE_STENCIL:
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_IMAGE_STENCIL_SHADER;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("Unknown image mode!");
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shader->color_transform)
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader_id |= VEGA_COLOR_TRANSFORM_SHADER;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (blend_use_shader(shader)) {
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_ALPHA_NORMAL_SHADER;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch(blend_mode) {
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_SRC:
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_SRC_SHADER;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_SRC_OVER:
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_SRC_OVER_SHADER;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_DST_OVER:
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_DST_OVER_SHADER;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_SRC_IN:
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_SRC_IN_SHADER;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_DST_IN:
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_DST_IN_SHADER;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_MULTIPLY:
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_SCREEN:
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_SCREEN_SHADER;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_DARKEN:
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_DARKEN_SHADER;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_LIGHTEN:
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case VG_BLEND_ADDITIVE:
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_BLEND_ADDITIVE_SHADER;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* update alpha of the source */
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shader->masking)
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader_id |= VEGA_MASK_SHADER;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (black_white)
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader_id |= VEGA_BW_SHADER;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->fs = shaders_cache_fill(ctx->sc, shader_id);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_bind(struct shader *shader)
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *ctx = shader->context;
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint num_samplers, param_bytes;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* first resolve the real paint type */
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   paint_resolve_type(shader->paint);
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_samplers = setup_samplers(shader, samplers, sampler_views);
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   param_bytes = setup_constant_buffer(shader);
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   setup_shader_program(shader);
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   renderer_validate_for_shader(ctx->renderer,
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (const struct pipe_sampler_state **) samplers,
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sampler_views, num_samplers,
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         &shader->modelview,
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader->fs, (const void *) shader->constants, param_bytes);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_set_image_mode(struct shader *shader, VGImageMode image_mode)
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->image_mode = image_mode;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGImageMode shader_image_mode(struct shader *shader)
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shader->image_mode;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_set_drawing_image(struct shader *shader, VGboolean drawing_image)
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->drawing_image = drawing_image;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGboolean shader_drawing_image(struct shader *shader)
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shader->drawing_image;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_set_image(struct shader *shader, struct vg_image *img)
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->image = img;
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set the transformation to map a vertex to the surface coordinates.
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_set_surface_matrix(struct shader *shader,
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               const struct matrix *mat)
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->modelview = *mat;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set the transformation to map a pixel to the paint coordinates.
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shader_set_paint_matrix(struct shader *shader, const struct matrix *mat)
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct st_framebuffer *stfb = shader->context->draw_buffer;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const VGfloat px_center_offset = 0.5f;
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(&shader->paint_matrix, mat, sizeof(*mat));
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* make it window-to-paint for the shaders */
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   matrix_translate(&shader->paint_matrix, px_center_offset,
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         stfb->height - 1.0f + px_center_offset);
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   matrix_scale(&shader->paint_matrix, 1.0f, -1.0f);
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
415