glsl2: Add and use new variable mode ir_var_temporary
[mesa/nouveau-pmpeg.git] / src / gallium / state_trackers / vega / renderer.c
blobc40ea8675e5666793b167d2a61a18f8b476df429
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
15 * of the Software.
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 "renderer.h"
29 #include "vg_context.h"
31 #include "pipe/p_context.h"
32 #include "pipe/p_state.h"
33 #include "util/u_inlines.h"
34 #include "pipe/p_screen.h"
35 #include "pipe/p_shader_tokens.h"
37 #include "util/u_draw_quad.h"
38 #include "util/u_format.h"
39 #include "util/u_simple_shaders.h"
40 #include "util/u_memory.h"
41 #include "util/u_rect.h"
42 #include "util/u_sampler.h"
43 #include "util/u_surface.h"
45 #include "cso_cache/cso_context.h"
47 struct renderer {
48 struct pipe_context *pipe;
49 struct vg_context *owner;
51 struct cso_context *cso;
53 void *fs;
55 VGfloat vertices[4][2][4];
58 static void setup_shaders(struct renderer *ctx)
60 struct pipe_context *pipe = ctx->pipe;
61 /* fragment shader */
62 ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
63 TGSI_INTERPOLATE_LINEAR);
66 static struct pipe_resource *
67 setup_vertex_data(struct renderer *ctx,
68 float x0, float y0, float x1, float y1, float z)
70 ctx->vertices[0][0][0] = x0;
71 ctx->vertices[0][0][1] = y0;
72 ctx->vertices[0][0][2] = z;
73 ctx->vertices[0][1][0] = 0.0f; /*s*/
74 ctx->vertices[0][1][1] = 0.0f; /*t*/
76 ctx->vertices[1][0][0] = x1;
77 ctx->vertices[1][0][1] = y0;
78 ctx->vertices[1][0][2] = z;
79 ctx->vertices[1][1][0] = 1.0f; /*s*/
80 ctx->vertices[1][1][1] = 0.0f; /*t*/
82 ctx->vertices[2][0][0] = x1;
83 ctx->vertices[2][0][1] = y1;
84 ctx->vertices[2][0][2] = z;
85 ctx->vertices[2][1][0] = 1.0f;
86 ctx->vertices[2][1][1] = 1.0f;
88 ctx->vertices[3][0][0] = x0;
89 ctx->vertices[3][0][1] = y1;
90 ctx->vertices[3][0][2] = z;
91 ctx->vertices[3][1][0] = 0.0f;
92 ctx->vertices[3][1][1] = 1.0f;
94 return pipe_user_buffer_create( ctx->pipe->screen,
95 ctx->vertices,
96 sizeof(ctx->vertices),
97 PIPE_BIND_VERTEX_BUFFER);
100 static struct pipe_resource *
101 setup_vertex_data_tex(struct renderer *ctx,
102 float x0, float y0, float x1, float y1,
103 float s0, float t0, float s1, float t1,
104 float z)
106 ctx->vertices[0][0][0] = x0;
107 ctx->vertices[0][0][1] = y0;
108 ctx->vertices[0][0][2] = z;
109 ctx->vertices[0][1][0] = s0; /*s*/
110 ctx->vertices[0][1][1] = t0; /*t*/
112 ctx->vertices[1][0][0] = x1;
113 ctx->vertices[1][0][1] = y0;
114 ctx->vertices[1][0][2] = z;
115 ctx->vertices[1][1][0] = s1; /*s*/
116 ctx->vertices[1][1][1] = t0; /*t*/
118 ctx->vertices[2][0][0] = x1;
119 ctx->vertices[2][0][1] = y1;
120 ctx->vertices[2][0][2] = z;
121 ctx->vertices[2][1][0] = s1;
122 ctx->vertices[2][1][1] = t1;
124 ctx->vertices[3][0][0] = x0;
125 ctx->vertices[3][0][1] = y1;
126 ctx->vertices[3][0][2] = z;
127 ctx->vertices[3][1][0] = s0;
128 ctx->vertices[3][1][1] = t1;
130 return pipe_user_buffer_create( ctx->pipe->screen,
131 ctx->vertices,
132 sizeof(ctx->vertices),
133 PIPE_BIND_VERTEX_BUFFER);
137 static struct pipe_resource *
138 setup_vertex_data_qtex(struct renderer *ctx,
139 float x0, float y0, float x1, float y1,
140 float x2, float y2, float x3, float y3,
141 float s0, float t0, float s1, float t1,
142 float z)
144 ctx->vertices[0][0][0] = x0;
145 ctx->vertices[0][0][1] = y0;
146 ctx->vertices[0][0][2] = z;
147 ctx->vertices[0][1][0] = s0; /*s*/
148 ctx->vertices[0][1][1] = t0; /*t*/
150 ctx->vertices[1][0][0] = x1;
151 ctx->vertices[1][0][1] = y1;
152 ctx->vertices[1][0][2] = z;
153 ctx->vertices[1][1][0] = s1; /*s*/
154 ctx->vertices[1][1][1] = t0; /*t*/
156 ctx->vertices[2][0][0] = x2;
157 ctx->vertices[2][0][1] = y2;
158 ctx->vertices[2][0][2] = z;
159 ctx->vertices[2][1][0] = s1;
160 ctx->vertices[2][1][1] = t1;
162 ctx->vertices[3][0][0] = x3;
163 ctx->vertices[3][0][1] = y3;
164 ctx->vertices[3][0][2] = z;
165 ctx->vertices[3][1][0] = s0;
166 ctx->vertices[3][1][1] = t1;
168 return pipe_user_buffer_create( ctx->pipe->screen,
169 ctx->vertices,
170 sizeof(ctx->vertices),
171 PIPE_BIND_VERTEX_BUFFER);
174 struct renderer * renderer_create(struct vg_context *owner)
176 VGint i;
177 struct renderer *renderer = CALLOC_STRUCT(renderer);
179 if (!renderer)
180 return NULL;
182 renderer->owner = owner;
183 renderer->pipe = owner->pipe;
184 renderer->cso = owner->cso_context;
186 setup_shaders(renderer);
188 /* init vertex data that doesn't change */
189 for (i = 0; i < 4; i++) {
190 renderer->vertices[i][0][3] = 1.0f; /* w */
191 renderer->vertices[i][1][2] = 0.0f; /* r */
192 renderer->vertices[i][1][3] = 1.0f; /* q */
195 return renderer;
198 void renderer_destroy(struct renderer *ctx)
200 #if 0
201 if (ctx->fs) {
202 cso_delete_fragment_shader(ctx->cso, ctx->fs);
203 ctx->fs = NULL;
205 #endif
206 free(ctx);
209 void renderer_draw_quad(struct renderer *r,
210 VGfloat x1, VGfloat y1,
211 VGfloat x2, VGfloat y2,
212 VGfloat depth)
214 struct pipe_resource *buf;
216 buf = setup_vertex_data(r, x1, y1, x2, y2, depth);
218 if (buf) {
219 cso_set_vertex_elements(r->cso, 2, r->owner->velems);
220 util_draw_vertex_buffer(r->pipe, buf, 0,
221 PIPE_PRIM_TRIANGLE_FAN,
222 4, /* verts */
223 2); /* attribs/vert */
225 pipe_resource_reference( &buf,
226 NULL );
230 void renderer_draw_texture(struct renderer *r,
231 struct pipe_resource *tex,
232 VGfloat x1offset, VGfloat y1offset,
233 VGfloat x2offset, VGfloat y2offset,
234 VGfloat x1, VGfloat y1,
235 VGfloat x2, VGfloat y2)
237 struct pipe_context *pipe = r->pipe;
238 struct pipe_resource *buf;
239 VGfloat s0, t0, s1, t1;
241 assert(tex->width0 != 0);
242 assert(tex->height0 != 0);
244 s0 = x1offset / tex->width0;
245 s1 = x2offset / tex->width0;
246 t0 = y1offset / tex->height0;
247 t1 = y2offset / tex->height0;
249 cso_save_vertex_shader(r->cso);
250 /* shaders */
251 cso_set_vertex_shader_handle(r->cso, vg_texture_vs(r->owner));
253 /* draw quad */
254 buf = setup_vertex_data_tex(r, x1, y1, x2, y2,
255 s0, t0, s1, t1, 0.0f);
257 if (buf) {
258 cso_set_vertex_elements(r->cso, 2, r->owner->velems);
259 util_draw_vertex_buffer(pipe, buf, 0,
260 PIPE_PRIM_TRIANGLE_FAN,
261 4, /* verts */
262 2); /* attribs/vert */
264 pipe_resource_reference( &buf,
265 NULL );
268 cso_restore_vertex_shader(r->cso);
271 void renderer_copy_texture(struct renderer *ctx,
272 struct pipe_sampler_view *src,
273 VGfloat sx1, VGfloat sy1,
274 VGfloat sx2, VGfloat sy2,
275 struct pipe_resource *dst,
276 VGfloat dx1, VGfloat dy1,
277 VGfloat dx2, VGfloat dy2)
279 struct pipe_context *pipe = ctx->pipe;
280 struct pipe_screen *screen = pipe->screen;
281 struct pipe_resource *tex = src->texture;
282 struct pipe_resource *buf;
283 struct pipe_surface *dst_surf = screen->get_tex_surface(
284 screen, dst, 0, 0, 0,
285 PIPE_BIND_RENDER_TARGET);
286 struct pipe_framebuffer_state fb;
287 float s0, t0, s1, t1;
289 assert(tex->width0 != 0);
290 assert(tex->height0 != 0);
291 assert(dst->width0 != 0);
292 assert(dst->height0 != 0);
294 #if 0
295 debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n",
296 sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
297 #endif
299 #if 1
300 s0 = sx1 / tex->width0;
301 s1 = sx2 / tex->width0;
302 t0 = sy1 / tex->height0;
303 t1 = sy2 / tex->height0;
304 #else
305 s0 = 0;
306 s1 = 1;
307 t0 = 0;
308 t1 = 1;
309 #endif
311 assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D,
312 0, PIPE_BIND_RENDER_TARGET, 0));
314 /* save state (restored below) */
315 cso_save_blend(ctx->cso);
316 cso_save_samplers(ctx->cso);
317 cso_save_fragment_sampler_views(ctx->cso);
318 cso_save_framebuffer(ctx->cso);
319 cso_save_fragment_shader(ctx->cso);
320 cso_save_vertex_shader(ctx->cso);
322 cso_save_viewport(ctx->cso);
325 /* set misc state we care about */
327 struct pipe_blend_state blend;
328 memset(&blend, 0, sizeof(blend));
329 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
330 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
331 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
332 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
333 blend.rt[0].colormask = PIPE_MASK_RGBA;
334 cso_set_blend(ctx->cso, &blend);
337 /* sampler */
339 struct pipe_sampler_state sampler;
340 memset(&sampler, 0, sizeof(sampler));
341 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
342 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
343 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
344 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
345 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
346 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
347 sampler.normalized_coords = 1;
348 cso_single_sampler(ctx->cso, 0, &sampler);
349 cso_single_sampler_done(ctx->cso);
352 vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
354 /* texture */
355 cso_set_fragment_sampler_views(ctx->cso, 1, &src);
357 /* shaders */
358 cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
359 cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
361 /* drawing dest */
362 memset(&fb, 0, sizeof(fb));
363 fb.width = dst_surf->width;
364 fb.height = dst_surf->height;
365 fb.nr_cbufs = 1;
366 fb.cbufs[0] = dst_surf;
368 VGint i;
369 for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
370 fb.cbufs[i] = 0;
372 cso_set_framebuffer(ctx->cso, &fb);
374 /* draw quad */
375 buf = setup_vertex_data_tex(ctx,
376 dx1, dy1,
377 dx2, dy2,
378 s0, t0, s1, t1,
379 0.0f);
381 if (buf) {
382 cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
383 util_draw_vertex_buffer(ctx->pipe, buf, 0,
384 PIPE_PRIM_TRIANGLE_FAN,
385 4, /* verts */
386 2); /* attribs/vert */
388 pipe_resource_reference( &buf,
389 NULL );
392 /* restore state we changed */
393 cso_restore_blend(ctx->cso);
394 cso_restore_samplers(ctx->cso);
395 cso_restore_fragment_sampler_views(ctx->cso);
396 cso_restore_framebuffer(ctx->cso);
397 cso_restore_vertex_shader(ctx->cso);
398 cso_restore_fragment_shader(ctx->cso);
399 cso_restore_viewport(ctx->cso);
401 pipe_surface_reference(&dst_surf, NULL);
404 void renderer_copy_surface(struct renderer *ctx,
405 struct pipe_surface *src,
406 int srcX0, int srcY0,
407 int srcX1, int srcY1,
408 struct pipe_surface *dst,
409 int dstX0, int dstY0,
410 int dstX1, int dstY1,
411 float z, unsigned filter)
413 struct pipe_context *pipe = ctx->pipe;
414 struct pipe_screen *screen = pipe->screen;
415 struct pipe_resource *buf;
416 struct pipe_sampler_view view_templ;
417 struct pipe_sampler_view *view;
418 struct pipe_resource texTemp, *tex;
419 struct pipe_subresource subsrc, subdst;
420 struct pipe_framebuffer_state fb;
421 struct st_framebuffer *stfb = ctx->owner->draw_buffer;
422 const int srcW = abs(srcX1 - srcX0);
423 const int srcH = abs(srcY1 - srcY0);
424 const int srcLeft = MIN2(srcX0, srcX1);
425 const int srcTop = MIN2(srcY0, srcY1);
427 assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
428 filter == PIPE_TEX_MIPFILTER_LINEAR);
430 if (srcLeft != srcX0) {
431 /* left-right flip */
432 int tmp = dstX0;
433 dstX0 = dstX1;
434 dstX1 = tmp;
437 if (srcTop != srcY0) {
438 /* up-down flip */
439 int tmp = dstY0;
440 dstY0 = dstY1;
441 dstY1 = tmp;
444 assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
445 0, PIPE_BIND_SAMPLER_VIEW, 0));
446 assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
447 0, PIPE_BIND_SAMPLER_VIEW, 0));
448 assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
449 0, PIPE_BIND_RENDER_TARGET, 0));
452 * XXX for now we're always creating a temporary texture.
453 * Strictly speaking that's not always needed.
456 /* create temp texture */
457 memset(&texTemp, 0, sizeof(texTemp));
458 texTemp.target = PIPE_TEXTURE_2D;
459 texTemp.format = src->format;
460 texTemp.last_level = 0;
461 texTemp.width0 = srcW;
462 texTemp.height0 = srcH;
463 texTemp.depth0 = 1;
464 texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
466 tex = screen->resource_create(screen, &texTemp);
467 if (!tex)
468 return;
470 u_sampler_view_default_template(&view_templ, tex, tex->format);
471 view = pipe->create_sampler_view(pipe, tex, &view_templ);
473 if (!view)
474 return;
476 subdst.face = 0;
477 subdst.level = 0;
478 subsrc.face = src->face;
479 subsrc.level = src->level;
481 pipe->resource_copy_region(pipe,
482 tex, subdst, 0, 0, 0, /* dest */
483 src->texture, subsrc, srcLeft, srcTop, src->zslice, /* src */
484 srcW, srcH); /* size */
486 /* save state (restored below) */
487 cso_save_blend(ctx->cso);
488 cso_save_samplers(ctx->cso);
489 cso_save_fragment_sampler_views(ctx->cso);
490 cso_save_framebuffer(ctx->cso);
491 cso_save_fragment_shader(ctx->cso);
492 cso_save_vertex_shader(ctx->cso);
493 cso_save_viewport(ctx->cso);
495 /* set misc state we care about */
497 struct pipe_blend_state blend;
498 memset(&blend, 0, sizeof(blend));
499 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
500 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
501 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
502 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
503 blend.rt[0].colormask = PIPE_MASK_RGBA;
504 cso_set_blend(ctx->cso, &blend);
507 vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
509 /* sampler */
511 struct pipe_sampler_state sampler;
512 memset(&sampler, 0, sizeof(sampler));
513 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
514 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
515 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
516 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
517 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
518 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
519 sampler.normalized_coords = 1;
520 cso_single_sampler(ctx->cso, 0, &sampler);
521 cso_single_sampler_done(ctx->cso);
524 /* texture */
525 cso_set_fragment_sampler_views(ctx->cso, 1, &view);
527 /* shaders */
528 cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
529 cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
531 /* drawing dest */
532 if (stfb->strb->surface != dst) {
533 memset(&fb, 0, sizeof(fb));
534 fb.width = dst->width;
535 fb.height = dst->height;
536 fb.nr_cbufs = 1;
537 fb.cbufs[0] = dst;
538 fb.zsbuf = stfb->dsrb->surface;
539 cso_set_framebuffer(ctx->cso, &fb);
542 /* draw quad */
543 buf = setup_vertex_data(ctx,
544 (float) dstX0, (float) dstY0,
545 (float) dstX1, (float) dstY1, z);
547 if (buf) {
548 cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
549 util_draw_vertex_buffer(ctx->pipe, buf, 0,
550 PIPE_PRIM_TRIANGLE_FAN,
551 4, /* verts */
552 2); /* attribs/vert */
554 pipe_resource_reference( &buf,
555 NULL );
559 /* restore state we changed */
560 cso_restore_blend(ctx->cso);
561 cso_restore_samplers(ctx->cso);
562 cso_restore_fragment_sampler_views(ctx->cso);
563 cso_restore_framebuffer(ctx->cso);
564 cso_restore_fragment_shader(ctx->cso);
565 cso_restore_vertex_shader(ctx->cso);
566 cso_restore_viewport(ctx->cso);
568 pipe_resource_reference(&tex, NULL);
569 pipe_sampler_view_reference(&view, NULL);
572 void renderer_texture_quad(struct renderer *r,
573 struct pipe_resource *tex,
574 VGfloat x1offset, VGfloat y1offset,
575 VGfloat x2offset, VGfloat y2offset,
576 VGfloat x1, VGfloat y1,
577 VGfloat x2, VGfloat y2,
578 VGfloat x3, VGfloat y3,
579 VGfloat x4, VGfloat y4)
581 struct pipe_context *pipe = r->pipe;
582 struct pipe_resource *buf;
583 VGfloat s0, t0, s1, t1;
585 assert(tex->width0 != 0);
586 assert(tex->height0 != 0);
588 s0 = x1offset / tex->width0;
589 s1 = x2offset / tex->width0;
590 t0 = y1offset / tex->height0;
591 t1 = y2offset / tex->height0;
593 cso_save_vertex_shader(r->cso);
594 /* shaders */
595 cso_set_vertex_shader_handle(r->cso, vg_texture_vs(r->owner));
597 /* draw quad */
598 buf = setup_vertex_data_qtex(r, x1, y1, x2, y2, x3, y3, x4, y4,
599 s0, t0, s1, t1, 0.0f);
601 if (buf) {
602 cso_set_vertex_elements(r->cso, 2, r->owner->velems);
603 util_draw_vertex_buffer(pipe, buf, 0,
604 PIPE_PRIM_TRIANGLE_FAN,
605 4, /* verts */
606 2); /* attribs/vert */
608 pipe_resource_reference(&buf,
609 NULL);
612 cso_restore_vertex_shader(r->cso);