summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/vega/renderer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/vega/renderer.c')
-rw-r--r--src/gallium/state_trackers/vega/renderer.c1558
1 files changed, 0 insertions, 1558 deletions
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
deleted file mode 100644
index d369c323bcc..00000000000
--- a/src/gallium/state_trackers/vega/renderer.c
+++ /dev/null
@@ -1,1558 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, Inc. All Rights Reserved.
- * Copyright 2010 LunarG, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "renderer.h"
-
-#include "vg_context.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-#include "pipe/p_screen.h"
-#include "pipe/p_shader_tokens.h"
-
-#include "util/u_draw_quad.h"
-#include "util/u_simple_shaders.h"
-#include "util/u_memory.h"
-#include "util/u_sampler.h"
-#include "util/u_surface.h"
-#include "util/u_math.h"
-#include "util/u_format.h"
-
-#include "cso_cache/cso_context.h"
-#include "tgsi/tgsi_ureg.h"
-
-typedef enum {
- RENDERER_STATE_INIT,
- RENDERER_STATE_COPY,
- RENDERER_STATE_DRAWTEX,
- RENDERER_STATE_SCISSOR,
- RENDERER_STATE_CLEAR,
- RENDERER_STATE_FILTER,
- RENDERER_STATE_POLYGON_STENCIL,
- RENDERER_STATE_POLYGON_FILL,
- NUM_RENDERER_STATES
-} RendererState;
-
-typedef enum {
- RENDERER_VS_PLAIN,
- RENDERER_VS_COLOR,
- RENDERER_VS_TEXTURE,
- NUM_RENDERER_VS
-} RendererVs;
-
-typedef enum {
- RENDERER_FS_COLOR,
- RENDERER_FS_TEXTURE,
- RENDERER_FS_SCISSOR,
- RENDERER_FS_WHITE,
- NUM_RENDERER_FS
-} RendererFs;
-
-struct renderer {
- struct pipe_context *pipe;
- struct cso_context *cso;
-
- VGbitfield dirty;
- struct {
- struct pipe_rasterizer_state rasterizer;
- struct pipe_depth_stencil_alpha_state dsa;
- struct pipe_framebuffer_state fb;
- } g3d;
- struct matrix projection;
-
- struct matrix mvp;
- struct pipe_resource *vs_cbuf;
-
- struct pipe_resource *fs_cbuf;
- VGfloat fs_cbuf_data[32];
- VGint fs_cbuf_len;
-
- struct pipe_vertex_element velems[2];
- VGfloat vertices[4][2][4];
-
- void *cached_vs[NUM_RENDERER_VS];
- void *cached_fs[NUM_RENDERER_FS];
-
- RendererState state;
-
- /* state data */
- union {
- struct {
- VGint tex_width;
- VGint tex_height;
- } copy;
-
- struct {
- VGint tex_width;
- VGint tex_height;
- } drawtex;
-
- struct {
- VGboolean restore_dsa;
- } scissor;
-
- struct {
- VGboolean use_sampler;
- VGint tex_width, tex_height;
- } filter;
-
- struct {
- struct pipe_depth_stencil_alpha_state dsa;
- VGboolean manual_two_sides;
- VGboolean restore_dsa;
- } polygon_stencil;
- } u;
-};
-
-/**
- * Return VG_TRUE if the renderer can use the resource as the asked bindings.
- */
-static VGboolean renderer_can_support(struct renderer *renderer,
- struct pipe_resource *res,
- unsigned bindings)
-{
- struct pipe_screen *screen = renderer->pipe->screen;
-
- return screen->is_format_supported(screen,
- res->format, res->target, 0, bindings);
-}
-
-/**
- * Set the model-view-projection matrix used by vertex shaders.
- */
-static void renderer_set_mvp(struct renderer *renderer,
- const struct matrix *mvp)
-{
- struct matrix *cur = &renderer->mvp;
- struct pipe_resource *cbuf;
- VGfloat consts[3][4];
- VGint i;
-
- /* projection only */
- if (!mvp)
- mvp = &renderer->projection;
-
- /* re-upload only if necessary */
- if (memcmp(cur, mvp, sizeof(*mvp)) == 0)
- return;
-
- /* 3x3 matrix to 3 constant vectors (no Z) */
- for (i = 0; i < 3; i++) {
- consts[i][0] = mvp->m[i + 0];
- consts[i][1] = mvp->m[i + 3];
- consts[i][2] = 0.0f;
- consts[i][3] = mvp->m[i + 6];
- }
-
- cbuf = renderer->vs_cbuf;
- pipe_resource_reference(&cbuf, NULL);
- cbuf = pipe_buffer_create(renderer->pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER,
- PIPE_USAGE_DEFAULT,
- sizeof(consts));
- if (cbuf) {
- pipe_buffer_write(renderer->pipe, cbuf,
- 0, sizeof(consts), consts);
- }
- pipe_set_constant_buffer(renderer->pipe,
- PIPE_SHADER_VERTEX, 0, cbuf);
-
- memcpy(cur, mvp, sizeof(*mvp));
- renderer->vs_cbuf = cbuf;
-}
-
-/**
- * Create a simple vertex shader that passes through position and the given
- * attribute.
- */
-static void *create_passthrough_vs(struct pipe_context *pipe, int semantic_name)
-{
- struct ureg_program *ureg;
- struct ureg_src src[2], constants[3];
- struct ureg_dst dst[2], tmp;
- int i;
-
- ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
- if (!ureg)
- return NULL;
-
- /* position is in user coordinates */
- src[0] = ureg_DECL_vs_input(ureg, 0);
- dst[0] = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
- tmp = ureg_DECL_temporary(ureg);
- for (i = 0; i < Elements(constants); i++)
- constants[i] = ureg_DECL_constant(ureg, i);
-
- /* transform to clipped coordinates */
- ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), src[0], constants[0]);
- ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Y), src[0], constants[1]);
- ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Z), src[0]);
- ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), src[0], constants[2]);
- ureg_MOV(ureg, dst[0], ureg_src(tmp));
-
- if (semantic_name >= 0) {
- src[1] = ureg_DECL_vs_input(ureg, 1);
- dst[1] = ureg_DECL_output(ureg, semantic_name, 0);
- ureg_MOV(ureg, dst[1], src[1]);
- }
-
- ureg_END(ureg);
-
- return ureg_create_shader_and_destroy(ureg, pipe);
-}
-
-/**
- * Set renderer vertex shader.
- *
- * This function modifies vertex_shader state.
- */
-static void renderer_set_vs(struct renderer *r, RendererVs id)
-{
- /* create as needed */
- if (!r->cached_vs[id]) {
- int semantic_name = -1;
-
- switch (id) {
- case RENDERER_VS_PLAIN:
- break;
- case RENDERER_VS_COLOR:
- semantic_name = TGSI_SEMANTIC_COLOR;
- break;
- case RENDERER_VS_TEXTURE:
- semantic_name = TGSI_SEMANTIC_GENERIC;
- break;
- default:
- assert(!"Unknown renderer vs id");
- break;
- }
-
- r->cached_vs[id] = create_passthrough_vs(r->pipe, semantic_name);
- }
-
- cso_set_vertex_shader_handle(r->cso, r->cached_vs[id]);
-}
-
-/**
- * Create a simple fragment shader that sets the depth to 0.0f.
- */
-static void *create_scissor_fs(struct pipe_context *pipe)
-{
- struct ureg_program *ureg;
- struct ureg_dst out;
- struct ureg_src imm;
-
- ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
- out = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
- imm = ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 0.0f);
-
- ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_Z), imm);
- ureg_END(ureg);
-
- return ureg_create_shader_and_destroy(ureg, pipe);
-}
-
-/**
- * Create a simple fragment shader that sets the color to white.
- */
-static void *create_white_fs(struct pipe_context *pipe)
-{
- struct ureg_program *ureg;
- struct ureg_dst out;
- struct ureg_src imm;
-
- ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
- out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
- imm = ureg_imm4f(ureg, 1.0f, 1.0f, 1.0f, 1.0f);
-
- ureg_MOV(ureg, out, imm);
- ureg_END(ureg);
-
- return ureg_create_shader_and_destroy(ureg, pipe);
-}
-
-/**
- * Set renderer fragment shader.
- *
- * This function modifies fragment_shader state.
- */
-static void renderer_set_fs(struct renderer *r, RendererFs id)
-{
- /* create as needed */
- if (!r->cached_fs[id]) {
- void *fs = NULL;
-
- switch (id) {
- case RENDERER_FS_COLOR:
- fs = util_make_fragment_passthrough_shader(r->pipe,
- TGSI_SEMANTIC_COLOR, TGSI_INTERPOLATE_PERSPECTIVE,
- TRUE);
- break;
- case RENDERER_FS_TEXTURE:
- fs = util_make_fragment_tex_shader(r->pipe,
- TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
- break;
- case RENDERER_FS_SCISSOR:
- fs = create_scissor_fs(r->pipe);
- break;
- case RENDERER_FS_WHITE:
- fs = create_white_fs(r->pipe);
- break;
- default:
- assert(!"Unknown renderer fs id");
- break;
- }
-
- r->cached_fs[id] = fs;
- }
-
- cso_set_fragment_shader_handle(r->cso, r->cached_fs[id]);
-}
-
-typedef enum {
- VEGA_Y0_TOP,
- VEGA_Y0_BOTTOM
-} VegaOrientation;
-
-static void vg_set_viewport(struct renderer *r,
- VegaOrientation orientation)
-{
- const struct pipe_framebuffer_state *fb = &r->g3d.fb;
- struct pipe_viewport_state viewport;
- VGfloat y_scale = (orientation == VEGA_Y0_BOTTOM) ? -2.f : 2.f;
-
- viewport.scale[0] = fb->width / 2.f;
- viewport.scale[1] = fb->height / y_scale;
- viewport.scale[2] = 1.0;
- viewport.translate[0] = fb->width / 2.f;
- viewport.translate[1] = fb->height / 2.f;
- viewport.translate[2] = 0.0;
-
- cso_set_viewport(r->cso, &viewport);
-}
-
-/**
- * Set renderer target.
- *
- * This function modifies framebuffer and viewport states.
- */
-static void renderer_set_target(struct renderer *r,
- struct pipe_surface *cbuf,
- struct pipe_surface *zsbuf,
- VGboolean y0_top)
-{
- struct pipe_framebuffer_state fb;
-
- memset(&fb, 0, sizeof(fb));
- fb.width = cbuf->width;
- fb.height = cbuf->height;
- fb.cbufs[0] = cbuf;
- fb.nr_cbufs = 1;
- fb.zsbuf = zsbuf;
- cso_set_framebuffer(r->cso, &fb);
-
- vg_set_viewport(r, (y0_top) ? VEGA_Y0_TOP : VEGA_Y0_BOTTOM);
-}
-
-/**
- * Set renderer blend state. Blending is disabled.
- *
- * This function modifies blend state.
- */
-static void renderer_set_blend(struct renderer *r,
- VGbitfield channel_mask)
-{
- struct pipe_blend_state blend;
-
- memset(&blend, 0, sizeof(blend));
-
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-
- if (channel_mask & VG_RED)
- blend.rt[0].colormask |= PIPE_MASK_R;
- if (channel_mask & VG_GREEN)
- blend.rt[0].colormask |= PIPE_MASK_G;
- if (channel_mask & VG_BLUE)
- blend.rt[0].colormask |= PIPE_MASK_B;
- if (channel_mask & VG_ALPHA)
- blend.rt[0].colormask |= PIPE_MASK_A;
-
- cso_set_blend(r->cso, &blend);
-}
-
-/**
- * Set renderer sampler and view states.
- *
- * This function modifies samplers and fragment_sampler_views states.
- */
-static void renderer_set_samplers(struct renderer *r,
- uint num_views,
- struct pipe_sampler_view **views)
-{
- struct pipe_sampler_state sampler;
- unsigned tex_filter = PIPE_TEX_FILTER_NEAREST;
- unsigned tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- uint i;
-
- memset(&sampler, 0, sizeof(sampler));
-
- sampler.min_img_filter = tex_filter;
- sampler.mag_img_filter = tex_filter;
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
-
- sampler.wrap_s = tex_wrap;
- sampler.wrap_t = tex_wrap;
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-
- sampler.normalized_coords = 1;
-
- /* set samplers */
- for (i = 0; i < num_views; i++)
- cso_single_sampler(r->cso, PIPE_SHADER_FRAGMENT, i, &sampler);
- cso_single_sampler_done(r->cso, PIPE_SHADER_FRAGMENT);
-
- /* set views */
- cso_set_sampler_views(r->cso, PIPE_SHADER_FRAGMENT, num_views, views);
-}
-
-/**
- * Set custom renderer fragment shader, and optionally set samplers and views
- * and upload the fragment constant buffer.
- *
- * This function modifies fragment_shader, samplers and fragment_sampler_views
- * states.
- */
-static void renderer_set_custom_fs(struct renderer *renderer,
- void *fs,
- const struct pipe_sampler_state **samplers,
- struct pipe_sampler_view **views,
- VGint num_samplers,
- const void *const_buffer,
- VGint const_buffer_len)
-{
- cso_set_fragment_shader_handle(renderer->cso, fs);
-
- /* set samplers and views */
- if (num_samplers) {
- cso_set_samplers(renderer->cso, PIPE_SHADER_FRAGMENT, num_samplers, samplers);
- cso_set_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT, num_samplers, views);
- }
-
- /* upload fs constant buffer */
- if (const_buffer_len) {
- struct pipe_resource *cbuf = renderer->fs_cbuf;
-
- if (!cbuf || renderer->fs_cbuf_len != const_buffer_len ||
- memcmp(renderer->fs_cbuf_data, const_buffer, const_buffer_len)) {
- pipe_resource_reference(&cbuf, NULL);
-
- cbuf = pipe_buffer_create(renderer->pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_DEFAULT,
- const_buffer_len);
- pipe_buffer_write(renderer->pipe, cbuf, 0,
- const_buffer_len, const_buffer);
- pipe_set_constant_buffer(renderer->pipe,
- PIPE_SHADER_FRAGMENT, 0, cbuf);
-
- renderer->fs_cbuf = cbuf;
- if (const_buffer_len <= sizeof(renderer->fs_cbuf_data)) {
- memcpy(renderer->fs_cbuf_data, const_buffer, const_buffer_len);
- renderer->fs_cbuf_len = const_buffer_len;
- }
- else {
- renderer->fs_cbuf_len = 0;
- }
- }
- }
-}
-
-/**
- * Setup renderer quad position.
- */
-static void renderer_quad_pos(struct renderer *r,
- VGfloat x0, VGfloat y0,
- VGfloat x1, VGfloat y1,
- VGboolean scissor)
-{
- VGfloat z;
-
- /* the depth test is used for scissoring */
- z = (scissor) ? 0.0f : 1.0f;
-
- /* positions */
- r->vertices[0][0][0] = x0;
- r->vertices[0][0][1] = y0;
- r->vertices[0][0][2] = z;
-
- r->vertices[1][0][0] = x1;
- r->vertices[1][0][1] = y0;
- r->vertices[1][0][2] = z;
-
- r->vertices[2][0][0] = x1;
- r->vertices[2][0][1] = y1;
- r->vertices[2][0][2] = z;
-
- r->vertices[3][0][0] = x0;
- r->vertices[3][0][1] = y1;
- r->vertices[3][0][2] = z;
-}
-
-/**
- * Setup renderer quad texture coordinates.
- */
-static void renderer_quad_texcoord(struct renderer *r,
- VGfloat x0, VGfloat y0,
- VGfloat x1, VGfloat y1,
- VGint tex_width, VGint tex_height)
-{
- VGfloat s0, t0, s1, t1, r0, q0;
- VGint i;
-
- s0 = x0 / tex_width;
- s1 = x1 / tex_width;
- t0 = y0 / tex_height;
- t1 = y1 / tex_height;
- r0 = 0.0f;
- q0 = 1.0f;
-
- /* texcoords */
- r->vertices[0][1][0] = s0;
- r->vertices[0][1][1] = t0;
-
- r->vertices[1][1][0] = s1;
- r->vertices[1][1][1] = t0;
-
- r->vertices[2][1][0] = s1;
- r->vertices[2][1][1] = t1;
-
- r->vertices[3][1][0] = s0;
- r->vertices[3][1][1] = t1;
-
- for (i = 0; i < 4; i++) {
- r->vertices[i][1][2] = r0;
- r->vertices[i][1][3] = q0;
- }
-}
-
-/**
- * Draw renderer quad.
- */
-static void renderer_quad_draw(struct renderer *r)
-{
- util_draw_user_vertex_buffer(r->cso, r->vertices, PIPE_PRIM_TRIANGLE_FAN,
- Elements(r->vertices), /* verts */
- Elements(r->vertices[0])); /* attribs/vert */
-}
-
-/**
- * Prepare the renderer for copying.
- */
-VGboolean renderer_copy_begin(struct renderer *renderer,
- struct pipe_surface *dst,
- VGboolean y0_top,
- struct pipe_sampler_view *src)
-{
- assert(renderer->state == RENDERER_STATE_INIT);
-
- /* sanity check */
- if (!renderer_can_support(renderer,
- dst->texture, PIPE_BIND_RENDER_TARGET) ||
- !renderer_can_support(renderer,
- src->texture, PIPE_BIND_SAMPLER_VIEW))
- return VG_FALSE;
-
- cso_save_framebuffer(renderer->cso);
- cso_save_viewport(renderer->cso);
- cso_save_blend(renderer->cso);
- cso_save_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_save_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_save_fragment_shader(renderer->cso);
- cso_save_vertex_shader(renderer->cso);
-
- renderer_set_target(renderer, dst, NULL, y0_top);
-
- renderer_set_blend(renderer, ~0);
- renderer_set_samplers(renderer, 1, &src);
-
- renderer_set_fs(renderer, RENDERER_FS_TEXTURE);
- renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
-
- renderer_set_mvp(renderer, NULL);
-
- /* remember the texture size */
- renderer->u.copy.tex_width = src->texture->width0;
- renderer->u.copy.tex_height = src->texture->height0;
- renderer->state = RENDERER_STATE_COPY;
-
- return VG_TRUE;
-}
-
-/**
- * Draw into the destination rectangle given by (x, y, w, h). The texture is
- * sampled from within the rectangle given by (sx, sy, sw, sh).
- *
- * The coordinates are in surface coordinates.
- */
-void renderer_copy(struct renderer *renderer,
- VGint x, VGint y, VGint w, VGint h,
- VGint sx, VGint sy, VGint sw, VGint sh)
-{
- assert(renderer->state == RENDERER_STATE_COPY);
-
- /* there is no depth buffer for scissoring anyway */
- renderer_quad_pos(renderer, x, y, x + w, y + h, VG_FALSE);
- renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
- renderer->u.copy.tex_width,
- renderer->u.copy.tex_height);
-
- renderer_quad_draw(renderer);
-}
-
-/**
- * End copying and restore the states.
- */
-void renderer_copy_end(struct renderer *renderer)
-{
- assert(renderer->state == RENDERER_STATE_COPY);
-
- cso_restore_framebuffer(renderer->cso);
- cso_restore_viewport(renderer->cso);
- cso_restore_blend(renderer->cso);
- cso_restore_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_restore_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_restore_fragment_shader(renderer->cso);
- cso_restore_vertex_shader(renderer->cso);
-
- renderer->state = RENDERER_STATE_INIT;
-}
-
-/**
- * Prepare the renderer for textured drawing.
- */
-VGboolean renderer_drawtex_begin(struct renderer *renderer,
- struct pipe_sampler_view *src)
-{
- assert(renderer->state == RENDERER_STATE_INIT);
-
- if (!renderer_can_support(renderer, src->texture, PIPE_BIND_SAMPLER_VIEW))
- return VG_FALSE;
-
- cso_save_blend(renderer->cso);
- cso_save_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_save_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_save_fragment_shader(renderer->cso);
- cso_save_vertex_shader(renderer->cso);
-
- renderer_set_blend(renderer, ~0);
-
- renderer_set_samplers(renderer, 1, &src);
-
- renderer_set_fs(renderer, RENDERER_FS_TEXTURE);
- renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
-
- renderer_set_mvp(renderer, NULL);
-
- /* remember the texture size */
- renderer->u.drawtex.tex_width = src->texture->width0;
- renderer->u.drawtex.tex_height = src->texture->height0;
- renderer->state = RENDERER_STATE_DRAWTEX;
-
- return VG_TRUE;
-}
-
-/**
- * Draw into the destination rectangle given by (x, y, w, h). The texture is
- * sampled from within the rectangle given by (sx, sy, sw, sh).
- *
- * The coordinates are in surface coordinates.
- */
-void renderer_drawtex(struct renderer *renderer,
- VGint x, VGint y, VGint w, VGint h,
- VGint sx, VGint sy, VGint sw, VGint sh)
-{
- assert(renderer->state == RENDERER_STATE_DRAWTEX);
-
- /* with scissoring */
- renderer_quad_pos(renderer, x, y, x + w, y + h, VG_TRUE);
- renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
- renderer->u.drawtex.tex_width,
- renderer->u.drawtex.tex_height);
-
- renderer_quad_draw(renderer);
-}
-
-/**
- * End textured drawing and restore the states.
- */
-void renderer_drawtex_end(struct renderer *renderer)
-{
- assert(renderer->state == RENDERER_STATE_DRAWTEX);
-
- cso_restore_blend(renderer->cso);
- cso_restore_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_restore_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_restore_fragment_shader(renderer->cso);
- cso_restore_vertex_shader(renderer->cso);
-
- renderer->state = RENDERER_STATE_INIT;
-}
-
-/**
- * Prepare the renderer for scissor update. This will reset the depth buffer
- * to 1.0f.
- */
-VGboolean renderer_scissor_begin(struct renderer *renderer,
- VGboolean restore_dsa)
-{
- struct pipe_depth_stencil_alpha_state dsa;
-
- assert(renderer->state == RENDERER_STATE_INIT);
-
- if (restore_dsa)
- cso_save_depth_stencil_alpha(renderer->cso);
- cso_save_blend(renderer->cso);
- cso_save_fragment_shader(renderer->cso);
-
- /* enable depth writes */
- memset(&dsa, 0, sizeof(dsa));
- dsa.depth.enabled = 1;
- dsa.depth.writemask = 1;
- dsa.depth.func = PIPE_FUNC_ALWAYS;
- cso_set_depth_stencil_alpha(renderer->cso, &dsa);
-
- /* disable color writes */
- renderer_set_blend(renderer, 0);
- renderer_set_fs(renderer, RENDERER_FS_SCISSOR);
-
- renderer_set_mvp(renderer, NULL);
-
- renderer->u.scissor.restore_dsa = restore_dsa;
- renderer->state = RENDERER_STATE_SCISSOR;
-
- /* clear the depth buffer to 1.0f */
- renderer->pipe->clear(renderer->pipe,
- PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0f, 0);
-
- return VG_TRUE;
-}
-
-/**
- * Add a scissor rectangle. Depth values inside the rectangle will be set to
- * 0.0f.
- */
-void renderer_scissor(struct renderer *renderer,
- VGint x, VGint y, VGint width, VGint height)
-{
- assert(renderer->state == RENDERER_STATE_SCISSOR);
-
- renderer_quad_pos(renderer, x, y, x + width, y + height, VG_FALSE);
- renderer_quad_draw(renderer);
-}
-
-/**
- * End scissor update and restore the states.
- */
-void renderer_scissor_end(struct renderer *renderer)
-{
- assert(renderer->state == RENDERER_STATE_SCISSOR);
-
- if (renderer->u.scissor.restore_dsa)
- cso_restore_depth_stencil_alpha(renderer->cso);
- cso_restore_blend(renderer->cso);
- cso_restore_fragment_shader(renderer->cso);
-
- renderer->state = RENDERER_STATE_INIT;
-}
-
-/**
- * Prepare the renderer for clearing.
- */
-VGboolean renderer_clear_begin(struct renderer *renderer)
-{
- assert(renderer->state == RENDERER_STATE_INIT);
-
- cso_save_blend(renderer->cso);
- cso_save_fragment_shader(renderer->cso);
- cso_save_vertex_shader(renderer->cso);
-
- renderer_set_blend(renderer, ~0);
- renderer_set_fs(renderer, RENDERER_FS_COLOR);
- renderer_set_vs(renderer, RENDERER_VS_COLOR);
-
- renderer_set_mvp(renderer, NULL);
-
- renderer->state = RENDERER_STATE_CLEAR;
-
- return VG_TRUE;
-}
-
-/**
- * Clear the framebuffer with the specified region and color.
- *
- * The coordinates are in surface coordinates.
- */
-void renderer_clear(struct renderer *renderer,
- VGint x, VGint y, VGint width, VGint height,
- const VGfloat color[4])
-{
- VGuint i;
-
- assert(renderer->state == RENDERER_STATE_CLEAR);
-
- renderer_quad_pos(renderer, x, y, x + width, y + height, VG_TRUE);
- for (i = 0; i < 4; i++)
- memcpy(renderer->vertices[i][1], color, sizeof(VGfloat) * 4);
-
- renderer_quad_draw(renderer);
-}
-
-/**
- * End clearing and retore the states.
- */
-void renderer_clear_end(struct renderer *renderer)
-{
- assert(renderer->state == RENDERER_STATE_CLEAR);
-
- cso_restore_blend(renderer->cso);
- cso_restore_fragment_shader(renderer->cso);
- cso_restore_vertex_shader(renderer->cso);
-
- renderer->state = RENDERER_STATE_INIT;
-}
-
-/**
- * Prepare the renderer for image filtering.
- */
-VGboolean renderer_filter_begin(struct renderer *renderer,
- struct pipe_resource *dst,
- VGboolean y0_top,
- VGbitfield channel_mask,
- const struct pipe_sampler_state **samplers,
- struct pipe_sampler_view **views,
- VGint num_samplers,
- void *fs,
- const void *const_buffer,
- VGint const_buffer_len)
-{
- struct pipe_surface *surf, surf_tmpl;
-
- assert(renderer->state == RENDERER_STATE_INIT);
-
- if (!fs)
- return VG_FALSE;
- if (!renderer_can_support(renderer, dst, PIPE_BIND_RENDER_TARGET))
- return VG_FALSE;
-
- u_surface_default_template(&surf_tmpl, dst);
- surf = renderer->pipe->create_surface(renderer->pipe, dst, &surf_tmpl);
- if (!surf)
- return VG_FALSE;
-
- cso_save_framebuffer(renderer->cso);
- cso_save_viewport(renderer->cso);
- cso_save_blend(renderer->cso);
-
- /* set the image as the target */
- renderer_set_target(renderer, surf, NULL, y0_top);
- pipe_surface_reference(&surf, NULL);
-
- renderer_set_blend(renderer, channel_mask);
-
- if (num_samplers) {
- struct pipe_resource *tex;
-
- cso_save_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_save_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_save_fragment_shader(renderer->cso);
- cso_save_vertex_shader(renderer->cso);
-
- renderer_set_custom_fs(renderer, fs,
- samplers, views, num_samplers,
- const_buffer, const_buffer_len);
- renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
-
- tex = views[0]->texture;
- renderer->u.filter.tex_width = tex->width0;
- renderer->u.filter.tex_height = tex->height0;
- renderer->u.filter.use_sampler = VG_TRUE;
- }
- else {
- cso_save_fragment_shader(renderer->cso);
-
- renderer_set_custom_fs(renderer, fs, NULL, NULL, 0,
- const_buffer, const_buffer_len);
-
- renderer->u.filter.use_sampler = VG_FALSE;
- }
-
- renderer_set_mvp(renderer, NULL);
-
- renderer->state = RENDERER_STATE_FILTER;
-
- return VG_TRUE;
-}
-
-/**
- * Draw into a rectangle of the destination with the specified region of the
- * texture(s).
- *
- * The coordinates are in surface coordinates.
- */
-void renderer_filter(struct renderer *renderer,
- VGint x, VGint y, VGint w, VGint h,
- VGint sx, VGint sy, VGint sw, VGint sh)
-{
- assert(renderer->state == RENDERER_STATE_FILTER);
-
- renderer_quad_pos(renderer, x, y, x + w, y + h, VG_FALSE);
- if (renderer->u.filter.use_sampler) {
- renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
- renderer->u.filter.tex_width,
- renderer->u.filter.tex_height);
- }
-
- renderer_quad_draw(renderer);
-}
-
-/**
- * End image filtering and restore the states.
- */
-void renderer_filter_end(struct renderer *renderer)
-{
- assert(renderer->state == RENDERER_STATE_FILTER);
-
- if (renderer->u.filter.use_sampler) {
- cso_restore_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_restore_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
- cso_restore_vertex_shader(renderer->cso);
- }
-
- cso_restore_framebuffer(renderer->cso);
- cso_restore_viewport(renderer->cso);
- cso_restore_blend(renderer->cso);
- cso_restore_fragment_shader(renderer->cso);
-
- renderer->state = RENDERER_STATE_INIT;
-}
-
-/**
- * Prepare the renderer for polygon silhouette rendering.
- */
-VGboolean renderer_polygon_stencil_begin(struct renderer *renderer,
- struct pipe_vertex_element *velem,
- VGFillRule rule,
- VGboolean restore_dsa)
-{
- struct pipe_depth_stencil_alpha_state *dsa;
- VGboolean manual_two_sides;
-
- assert(renderer->state == RENDERER_STATE_INIT);
-
- cso_save_vertex_elements(renderer->cso);
- cso_save_blend(renderer->cso);
- cso_save_depth_stencil_alpha(renderer->cso);
-
- cso_set_vertex_elements(renderer->cso, 1, velem);
-
- /* disable color writes */
- renderer_set_blend(renderer, 0);
-
- manual_two_sides = VG_FALSE;
- dsa = &renderer->u.polygon_stencil.dsa;
- memset(dsa, 0, sizeof(*dsa));
- if (rule == VG_EVEN_ODD) {
- dsa->stencil[0].enabled = 1;
- dsa->stencil[0].writemask = 1;
- dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
- dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
- dsa->stencil[0].valuemask = ~0;
- }
- else {
- assert(rule == VG_NON_ZERO);
-
- /* front face */
- dsa->stencil[0].enabled = 1;
- dsa->stencil[0].writemask = ~0;
- dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
- dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
- dsa->stencil[0].valuemask = ~0;
-
- if (renderer->pipe->screen->get_param(renderer->pipe->screen,
- PIPE_CAP_TWO_SIDED_STENCIL)) {
- /* back face */
- dsa->stencil[1] = dsa->stencil[0];
- dsa->stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
- }
- else {
- manual_two_sides = VG_TRUE;
- }
- }
- cso_set_depth_stencil_alpha(renderer->cso, dsa);
-
- if (manual_two_sides)
- cso_save_rasterizer(renderer->cso);
-
- renderer->u.polygon_stencil.manual_two_sides = manual_two_sides;
- renderer->u.polygon_stencil.restore_dsa = restore_dsa;
- renderer->state = RENDERER_STATE_POLYGON_STENCIL;
-
- return VG_TRUE;
-}
-
-/**
- * Render a polygon silhouette to stencil buffer.
- */
-void renderer_polygon_stencil(struct renderer *renderer,
- struct pipe_vertex_buffer *vbuf,
- VGuint mode, VGuint start, VGuint count)
-{
- assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
-
- cso_set_vertex_buffers(renderer->cso, 0, 1, vbuf);
-
- if (!renderer->u.polygon_stencil.manual_two_sides) {
- cso_draw_arrays(renderer->cso, mode, start, count);
- }
- else {
- struct pipe_rasterizer_state raster;
- struct pipe_depth_stencil_alpha_state dsa;
-
- raster = renderer->g3d.rasterizer;
- dsa = renderer->u.polygon_stencil.dsa;
-
- /* front */
- raster.cull_face = PIPE_FACE_BACK;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
-
- cso_set_rasterizer(renderer->cso, &raster);
- cso_set_depth_stencil_alpha(renderer->cso, &dsa);
- cso_draw_arrays(renderer->cso, mode, start, count);
-
- /* back */
- raster.cull_face = PIPE_FACE_FRONT;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
-
- cso_set_rasterizer(renderer->cso, &raster);
- cso_set_depth_stencil_alpha(renderer->cso, &dsa);
- cso_draw_arrays(renderer->cso, mode, start, count);
- }
-}
-
-/**
- * End polygon silhouette rendering.
- */
-void renderer_polygon_stencil_end(struct renderer *renderer)
-{
- assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
-
- if (renderer->u.polygon_stencil.manual_two_sides)
- cso_restore_rasterizer(renderer->cso);
-
- cso_restore_vertex_elements(renderer->cso);
-
- /* restore color writes */
- cso_restore_blend(renderer->cso);
-
- if (renderer->u.polygon_stencil.restore_dsa)
- cso_restore_depth_stencil_alpha(renderer->cso);
-
- renderer->state = RENDERER_STATE_INIT;
-}
-
-/**
- * Prepare the renderer for polygon filling.
- */
-VGboolean renderer_polygon_fill_begin(struct renderer *renderer,
- VGboolean save_dsa)
-{
- struct pipe_depth_stencil_alpha_state dsa;
-
- assert(renderer->state == RENDERER_STATE_INIT);
-
- if (save_dsa)
- cso_save_depth_stencil_alpha(renderer->cso);
-
- /* setup stencil ops */
- memset(&dsa, 0, sizeof(dsa));
- dsa.stencil[0].enabled = 1;
- dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].valuemask = ~0;
- dsa.stencil[0].writemask = ~0;
- dsa.depth = renderer->g3d.dsa.depth;
- cso_set_depth_stencil_alpha(renderer->cso, &dsa);
-
- renderer->state = RENDERER_STATE_POLYGON_FILL;
-
- return VG_TRUE;
-}
-
-/**
- * Fill a polygon.
- */
-void renderer_polygon_fill(struct renderer *renderer,
- VGfloat min_x, VGfloat min_y,
- VGfloat max_x, VGfloat max_y)
-{
- assert(renderer->state == RENDERER_STATE_POLYGON_FILL);
-
- renderer_quad_pos(renderer, min_x, min_y, max_x, max_y, VG_TRUE);
- renderer_quad_draw(renderer);
-}
-
-/**
- * End polygon filling.
- */
-void renderer_polygon_fill_end(struct renderer *renderer)
-{
- assert(renderer->state == RENDERER_STATE_POLYGON_FILL);
-
- cso_restore_depth_stencil_alpha(renderer->cso);
-
- renderer->state = RENDERER_STATE_INIT;
-}
-
-struct renderer * renderer_create(struct vg_context *owner)
-{
- struct renderer *renderer;
- struct pipe_rasterizer_state *raster;
- struct pipe_stencil_ref sr;
- VGint i;
-
- renderer = CALLOC_STRUCT(renderer);
- if (!renderer)
- return NULL;
-
- renderer->pipe = owner->pipe;
- renderer->cso = owner->cso_context;
-
- /* init vertex data that doesn't change */
- for (i = 0; i < 4; i++)
- renderer->vertices[i][0][3] = 1.0f; /* w */
-
- for (i = 0; i < 2; i++) {
- renderer->velems[i].src_offset = i * 4 * sizeof(float);
- renderer->velems[i].instance_divisor = 0;
- renderer->velems[i].vertex_buffer_index = 0;
- renderer->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- }
- cso_set_vertex_elements(renderer->cso, 2, renderer->velems);
-
- /* GL rasterization rules */
- raster = &renderer->g3d.rasterizer;
- memset(raster, 0, sizeof(*raster));
- raster->half_pixel_center = 1;
- raster->bottom_edge_rule = 1;
- raster->depth_clip = 1;
- cso_set_rasterizer(renderer->cso, raster);
-
- /* fixed at 0 */
- memset(&sr, 0, sizeof(sr));
- cso_set_stencil_ref(renderer->cso, &sr);
-
- renderer_set_vs(renderer, RENDERER_VS_PLAIN);
-
- renderer->state = RENDERER_STATE_INIT;
-
- return renderer;
-}
-
-void renderer_destroy(struct renderer *ctx)
-{
- int i;
-
- for (i = 0; i < NUM_RENDERER_VS; i++) {
- if (ctx->cached_vs[i])
- cso_delete_vertex_shader(ctx->cso, ctx->cached_vs[i]);
- }
- for (i = 0; i < NUM_RENDERER_FS; i++) {
- if (ctx->cached_fs[i])
- cso_delete_fragment_shader(ctx->cso, ctx->cached_fs[i]);
- }
-
- pipe_resource_reference(&ctx->vs_cbuf, NULL);
- pipe_resource_reference(&ctx->fs_cbuf, NULL);
-
- FREE(ctx);
-}
-
-static void update_clip_state(struct renderer *renderer,
- const struct vg_state *state)
-{
- struct pipe_depth_stencil_alpha_state *dsa = &renderer->g3d.dsa;
-
- memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
-
- if (state->scissoring) {
- struct pipe_framebuffer_state *fb = &renderer->g3d.fb;
- int i;
-
- renderer_scissor_begin(renderer, VG_FALSE);
-
- for (i = 0; i < state->scissor_rects_num; ++i) {
- const float x = state->scissor_rects[i * 4 + 0].f;
- const float y = state->scissor_rects[i * 4 + 1].f;
- const float width = state->scissor_rects[i * 4 + 2].f;
- const float height = state->scissor_rects[i * 4 + 3].f;
- VGint x0, y0, x1, y1, iw, ih;
-
- x0 = (VGint) x;
- y0 = (VGint) y;
- if (x0 < 0)
- x0 = 0;
- if (y0 < 0)
- y0 = 0;
-
- /* note that x1 and y1 are exclusive */
- x1 = (VGint) ceilf(x + width);
- y1 = (VGint) ceilf(y + height);
- if (x1 > fb->width)
- x1 = fb->width;
- if (y1 > fb->height)
- y1 = fb->height;
-
- iw = x1 - x0;
- ih = y1 - y0;
- if (iw > 0 && ih> 0 )
- renderer_scissor(renderer, x0, y0, iw, ih);
- }
-
- renderer_scissor_end(renderer);
-
- dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */
- dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/
- dsa->depth.func = PIPE_FUNC_GEQUAL;
- }
-}
-
-static void renderer_validate_blend(struct renderer *renderer,
- const struct vg_state *state,
- enum pipe_format fb_format)
-{
- struct pipe_blend_state blend;
-
- memset(&blend, 0, sizeof(blend));
- blend.rt[0].colormask = PIPE_MASK_RGBA;
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-
- /* TODO alpha masking happens after blending? */
-
- switch (state->blend_mode) {
- case VG_BLEND_SRC:
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- break;
- case VG_BLEND_SRC_OVER:
- /* use the blend state only when there is no alpha channel */
- if (!util_format_has_alpha(fb_format)) {
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- blend.rt[0].blend_enable = 1;
- }
- break;
- case VG_BLEND_SRC_IN:
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].blend_enable = 1;
- break;
- case VG_BLEND_DST_IN:
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- blend.rt[0].blend_enable = 1;
- break;
- case VG_BLEND_DST_OVER:
- case VG_BLEND_MULTIPLY:
- case VG_BLEND_SCREEN:
- case VG_BLEND_DARKEN:
- case VG_BLEND_LIGHTEN:
- case VG_BLEND_ADDITIVE:
- /* need a shader */
- break;
- default:
- assert(!"not implemented blend mode");
- break;
- }
-
- cso_set_blend(renderer->cso, &blend);
-}
-
-/**
- * Propogate OpenVG state changes to the renderer. Only framebuffer, blending
- * and scissoring states are relevant here.
- */
-void renderer_validate(struct renderer *renderer,
- VGbitfield dirty,
- const struct st_framebuffer *stfb,
- const struct vg_state *state)
-{
- assert(renderer->state == RENDERER_STATE_INIT);
-
- dirty |= renderer->dirty;
- renderer->dirty = 0;
-
- if (dirty & FRAMEBUFFER_DIRTY) {
- struct pipe_framebuffer_state *fb = &renderer->g3d.fb;
- struct matrix *proj = &renderer->projection;
-
- memset(fb, 0, sizeof(struct pipe_framebuffer_state));
- fb->width = stfb->width;
- fb->height = stfb->height;
- fb->nr_cbufs = 1;
- fb->cbufs[0] = stfb->strb->surface;
- fb->zsbuf = stfb->dsrb->surface;
-
- cso_set_framebuffer(renderer->cso, fb);
- vg_set_viewport(renderer, VEGA_Y0_BOTTOM);
-
- matrix_load_identity(proj);
- matrix_translate(proj, -1.0f, -1.0f);
- matrix_scale(proj, 2.0f / fb->width, 2.0f / fb->height);
-
- /* we also got a new depth buffer */
- if (dirty & DEPTH_STENCIL_DIRTY) {
- renderer->pipe->clear(renderer->pipe,
- PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0);
- }
- }
-
- /* must be last because it renders to the depth buffer*/
- if (dirty & DEPTH_STENCIL_DIRTY) {
- update_clip_state(renderer, state);
- cso_set_depth_stencil_alpha(renderer->cso, &renderer->g3d.dsa);
- }
-
- if (dirty & BLEND_DIRTY)
- renderer_validate_blend(renderer, state, stfb->strb->format);
-}
-
-/**
- * Prepare the renderer for OpenVG pipeline.
- */
-void renderer_validate_for_shader(struct renderer *renderer,
- const struct pipe_sampler_state **samplers,
- struct pipe_sampler_view **views,
- VGint num_samplers,
- const struct matrix *modelview,
- void *fs,
- const void *const_buffer,
- VGint const_buffer_len)
-{
- struct matrix mvp = renderer->projection;
-
- /* will be used in POLYGON_STENCIL and POLYGON_FILL */
- matrix_mult(&mvp, modelview);
- renderer_set_mvp(renderer, &mvp);
-
- renderer_set_custom_fs(renderer, fs,
- samplers, views, num_samplers,
- const_buffer, const_buffer_len);
-}
-
-void renderer_validate_for_mask_rendering(struct renderer *renderer,
- struct pipe_surface *dst,
- const struct matrix *modelview)
-{
- struct matrix mvp = renderer->projection;
-
- /* will be used in POLYGON_STENCIL and POLYGON_FILL */
- matrix_mult(&mvp, modelview);
- renderer_set_mvp(renderer, &mvp);
-
- renderer_set_target(renderer, dst, renderer->g3d.fb.zsbuf, VG_FALSE);
- renderer_set_blend(renderer, ~0);
- renderer_set_fs(renderer, RENDERER_FS_WHITE);
-
- /* set internal dirty flags (hacky!) */
- renderer->dirty = FRAMEBUFFER_DIRTY | BLEND_DIRTY;
-}
-
-void renderer_copy_surface(struct renderer *ctx,
- struct pipe_surface *src,
- int srcX0, int srcY0,
- int srcX1, int srcY1,
- struct pipe_surface *dst,
- int dstX0, int dstY0,
- int dstX1, int dstY1,
- float z, unsigned filter)
-{
- struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
- struct pipe_sampler_view view_templ;
- struct pipe_sampler_view *view;
- struct pipe_box src_box;
- struct pipe_resource texTemp, *tex;
- const struct pipe_framebuffer_state *fb = &ctx->g3d.fb;
- const int srcW = abs(srcX1 - srcX0);
- const int srcH = abs(srcY1 - srcY0);
- const int srcLeft = MIN2(srcX0, srcX1);
- const int srcTop = MIN2(srcY0, srcY1);
-
- assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
- filter == PIPE_TEX_MIPFILTER_LINEAR);
-
- if (srcLeft != srcX0) {
- /* left-right flip */
- int tmp = dstX0;
- dstX0 = dstX1;
- dstX1 = tmp;
- }
-
- if (srcTop != srcY0) {
- /* up-down flip */
- int tmp = dstY0;
- dstY0 = dstY1;
- dstY1 = tmp;
- }
-
- assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_SAMPLER_VIEW));
- assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_SAMPLER_VIEW));
- assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_RENDER_TARGET));
-
- /*
- * XXX for now we're always creating a temporary texture.
- * Strictly speaking that's not always needed.
- */
-
- /* create temp texture */
- memset(&texTemp, 0, sizeof(texTemp));
- texTemp.target = PIPE_TEXTURE_2D;
- texTemp.format = src->format;
- texTemp.last_level = 0;
- texTemp.width0 = srcW;
- texTemp.height0 = srcH;
- texTemp.depth0 = 1;
- texTemp.array_size = 1;
- texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
-
- tex = screen->resource_create(screen, &texTemp);
- if (!tex)
- return;
-
- u_sampler_view_default_template(&view_templ, tex, tex->format);
- view = pipe->create_sampler_view(pipe, tex, &view_templ);
-
- if (!view)
- return;
-
- u_box_2d_zslice(srcLeft, srcTop, src->u.tex.first_layer, srcW, srcH, &src_box);
-
- pipe->resource_copy_region(pipe,
- tex, 0, 0, 0, 0, /* dest */
- src->texture, 0, &src_box);
-
- assert(floatsEqual(z, 0.0f));
-
- /* draw */
- if (fb->cbufs[0] == dst) {
- /* transform back to surface coordinates */
- dstY0 = dst->height - dstY0;
- dstY1 = dst->height - dstY1;
-
- if (renderer_drawtex_begin(ctx, view)) {
- renderer_drawtex(ctx,
- dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0,
- 0, 0, view->texture->width0, view->texture->height0);
- renderer_drawtex_end(ctx);
- }
- }
- else {
- if (renderer_copy_begin(ctx, dst, VG_TRUE, view)) {
- renderer_copy(ctx,
- dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0,
- 0, 0, view->texture->width0, view->texture->height0);
- renderer_copy_end(ctx);
- }
- }
-}
-
-void renderer_texture_quad(struct renderer *r,
- struct pipe_resource *tex,
- VGfloat x1offset, VGfloat y1offset,
- VGfloat x2offset, VGfloat y2offset,
- VGfloat x1, VGfloat y1,
- VGfloat x2, VGfloat y2,
- VGfloat x3, VGfloat y3,
- VGfloat x4, VGfloat y4)
-{
- const VGfloat z = 0.0f;
-
- assert(r->state == RENDERER_STATE_INIT);
- assert(tex->width0 != 0);
- assert(tex->height0 != 0);
-
- cso_save_vertex_shader(r->cso);
-
- renderer_set_vs(r, RENDERER_VS_TEXTURE);
-
- /* manually set up positions */
- r->vertices[0][0][0] = x1;
- r->vertices[0][0][1] = y1;
- r->vertices[0][0][2] = z;
-
- r->vertices[1][0][0] = x2;
- r->vertices[1][0][1] = y2;
- r->vertices[1][0][2] = z;
-
- r->vertices[2][0][0] = x3;
- r->vertices[2][0][1] = y3;
- r->vertices[2][0][2] = z;
-
- r->vertices[3][0][0] = x4;
- r->vertices[3][0][1] = y4;
- r->vertices[3][0][2] = z;
-
- /* texcoords */
- renderer_quad_texcoord(r, x1offset, y1offset,
- x2offset, y2offset, tex->width0, tex->height0);
-
- renderer_quad_draw(r);
-
- cso_restore_vertex_shader(r->cso);
-}