1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2009-2011 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci ********************************************************* 25bf215546Sopenharmony_ci * Authors: 26bf215546Sopenharmony_ci * Zack Rusin <zackr-at-vmware-dot-com> 27bf215546Sopenharmony_ci */ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "xa_context.h" 30bf215546Sopenharmony_ci#include "xa_priv.h" 31bf215546Sopenharmony_ci#include <math.h> 32bf215546Sopenharmony_ci#include "cso_cache/cso_context.h" 33bf215546Sopenharmony_ci#include "util/u_inlines.h" 34bf215546Sopenharmony_ci#include "util/u_sampler.h" 35bf215546Sopenharmony_ci#include "util/u_draw_quad.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#define floatsEqual(x, y) (fabsf(x - y) <= 0.00001f * MIN2(fabsf(x), fabsf(y))) 38bf215546Sopenharmony_ci#define floatIsZero(x) (floatsEqual((x) + 1.0f, 1.0f)) 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#define NUM_COMPONENTS 4 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_civoid 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_cirenderer_set_constants(struct xa_context *r, 46bf215546Sopenharmony_ci int shader_type, const float *params, int param_bytes); 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_cistatic inline boolean 49bf215546Sopenharmony_ciis_affine(const float *matrix) 50bf215546Sopenharmony_ci{ 51bf215546Sopenharmony_ci return floatIsZero(matrix[2]) && floatIsZero(matrix[5]) 52bf215546Sopenharmony_ci && floatsEqual(matrix[8], 1.0f); 53bf215546Sopenharmony_ci} 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_cistatic inline void 56bf215546Sopenharmony_cimap_point(const float *mat, float x, float y, float *out_x, float *out_y) 57bf215546Sopenharmony_ci{ 58bf215546Sopenharmony_ci if (!mat) { 59bf215546Sopenharmony_ci *out_x = x; 60bf215546Sopenharmony_ci *out_y = y; 61bf215546Sopenharmony_ci return; 62bf215546Sopenharmony_ci } 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci *out_x = mat[0] * x + mat[3] * y + mat[6]; 65bf215546Sopenharmony_ci *out_y = mat[1] * x + mat[4] * y + mat[7]; 66bf215546Sopenharmony_ci if (!is_affine(mat)) { 67bf215546Sopenharmony_ci float w = 1 / (mat[2] * x + mat[5] * y + mat[8]); 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci *out_x *= w; 70bf215546Sopenharmony_ci *out_y *= w; 71bf215546Sopenharmony_ci } 72bf215546Sopenharmony_ci} 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_cistatic inline void 75bf215546Sopenharmony_cirenderer_draw(struct xa_context *r) 76bf215546Sopenharmony_ci{ 77bf215546Sopenharmony_ci int num_verts = r->buffer_size / (r->attrs_per_vertex * NUM_COMPONENTS); 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci if (!r->buffer_size) 80bf215546Sopenharmony_ci return; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci if (!r->scissor_valid) { 83bf215546Sopenharmony_ci r->scissor.minx = 0; 84bf215546Sopenharmony_ci r->scissor.miny = 0; 85bf215546Sopenharmony_ci r->scissor.maxx = r->dst->tex->width0; 86bf215546Sopenharmony_ci r->scissor.maxy = r->dst->tex->height0; 87bf215546Sopenharmony_ci } 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci r->pipe->set_scissor_states(r->pipe, 0, 1, &r->scissor); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci struct cso_velems_state velems; 92bf215546Sopenharmony_ci velems.count = r->attrs_per_vertex; 93bf215546Sopenharmony_ci memcpy(velems.velems, r->velems, sizeof(r->velems[0]) * velems.count); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci cso_set_vertex_elements(r->cso, &velems); 96bf215546Sopenharmony_ci util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS, 97bf215546Sopenharmony_ci num_verts, /* verts */ 98bf215546Sopenharmony_ci r->attrs_per_vertex); /* attribs/vert */ 99bf215546Sopenharmony_ci r->buffer_size = 0; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci xa_scissor_reset(r); 102bf215546Sopenharmony_ci} 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_cistatic inline void 105bf215546Sopenharmony_cirenderer_draw_conditional(struct xa_context *r, int next_batch) 106bf215546Sopenharmony_ci{ 107bf215546Sopenharmony_ci if (r->buffer_size + next_batch >= XA_VB_SIZE || 108bf215546Sopenharmony_ci (next_batch == 0 && r->buffer_size)) { 109bf215546Sopenharmony_ci renderer_draw(r); 110bf215546Sopenharmony_ci } 111bf215546Sopenharmony_ci} 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_civoid 114bf215546Sopenharmony_cirenderer_init_state(struct xa_context *r) 115bf215546Sopenharmony_ci{ 116bf215546Sopenharmony_ci struct pipe_depth_stencil_alpha_state dsa; 117bf215546Sopenharmony_ci struct pipe_rasterizer_state raster; 118bf215546Sopenharmony_ci unsigned i; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci /* set common initial clip state */ 121bf215546Sopenharmony_ci memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); 122bf215546Sopenharmony_ci cso_set_depth_stencil_alpha(r->cso, &dsa); 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci /* XXX: move to renderer_init_state? */ 125bf215546Sopenharmony_ci memset(&raster, 0, sizeof(struct pipe_rasterizer_state)); 126bf215546Sopenharmony_ci raster.half_pixel_center = 1; 127bf215546Sopenharmony_ci raster.bottom_edge_rule = 1; 128bf215546Sopenharmony_ci raster.depth_clip_near = 1; 129bf215546Sopenharmony_ci raster.depth_clip_far = 1; 130bf215546Sopenharmony_ci raster.scissor = 1; 131bf215546Sopenharmony_ci cso_set_rasterizer(r->cso, &raster); 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci /* vertex elements state */ 134bf215546Sopenharmony_ci memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3); 135bf215546Sopenharmony_ci for (i = 0; i < 3; i++) { 136bf215546Sopenharmony_ci r->velems[i].src_offset = i * 4 * sizeof(float); 137bf215546Sopenharmony_ci r->velems[i].instance_divisor = 0; 138bf215546Sopenharmony_ci r->velems[i].vertex_buffer_index = 0; 139bf215546Sopenharmony_ci r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci} 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_cistatic inline void 144bf215546Sopenharmony_ciadd_vertex_none(struct xa_context *r, float x, float y) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci float *vertex = r->buffer + r->buffer_size; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci vertex[0] = x; 149bf215546Sopenharmony_ci vertex[1] = y; 150bf215546Sopenharmony_ci vertex[2] = 0.f; /*z */ 151bf215546Sopenharmony_ci vertex[3] = 1.f; /*w */ 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci r->buffer_size += 4; 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_cistatic inline void 157bf215546Sopenharmony_ciadd_vertex_1tex(struct xa_context *r, float x, float y, float s, float t) 158bf215546Sopenharmony_ci{ 159bf215546Sopenharmony_ci float *vertex = r->buffer + r->buffer_size; 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci vertex[0] = x; 162bf215546Sopenharmony_ci vertex[1] = y; 163bf215546Sopenharmony_ci vertex[2] = 0.f; /*z */ 164bf215546Sopenharmony_ci vertex[3] = 1.f; /*w */ 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci vertex[4] = s; /*s */ 167bf215546Sopenharmony_ci vertex[5] = t; /*t */ 168bf215546Sopenharmony_ci vertex[6] = 0.f; /*r */ 169bf215546Sopenharmony_ci vertex[7] = 1.f; /*q */ 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci r->buffer_size += 8; 172bf215546Sopenharmony_ci} 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_cistatic inline void 175bf215546Sopenharmony_ciadd_vertex_2tex(struct xa_context *r, 176bf215546Sopenharmony_ci float x, float y, float s0, float t0, float s1, float t1) 177bf215546Sopenharmony_ci{ 178bf215546Sopenharmony_ci float *vertex = r->buffer + r->buffer_size; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci vertex[0] = x; 181bf215546Sopenharmony_ci vertex[1] = y; 182bf215546Sopenharmony_ci vertex[2] = 0.f; /*z */ 183bf215546Sopenharmony_ci vertex[3] = 1.f; /*w */ 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci vertex[4] = s0; /*s */ 186bf215546Sopenharmony_ci vertex[5] = t0; /*t */ 187bf215546Sopenharmony_ci vertex[6] = 0.f; /*r */ 188bf215546Sopenharmony_ci vertex[7] = 1.f; /*q */ 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci vertex[8] = s1; /*s */ 191bf215546Sopenharmony_ci vertex[9] = t1; /*t */ 192bf215546Sopenharmony_ci vertex[10] = 0.f; /*r */ 193bf215546Sopenharmony_ci vertex[11] = 1.f; /*q */ 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci r->buffer_size += 12; 196bf215546Sopenharmony_ci} 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_cistatic void 199bf215546Sopenharmony_cicompute_src_coords(float sx, float sy, const struct pipe_resource *src, 200bf215546Sopenharmony_ci const float *src_matrix, 201bf215546Sopenharmony_ci float width, float height, 202bf215546Sopenharmony_ci float tc0[2], float tc1[2], float tc2[2], float tc3[2]) 203bf215546Sopenharmony_ci{ 204bf215546Sopenharmony_ci tc0[0] = sx; 205bf215546Sopenharmony_ci tc0[1] = sy; 206bf215546Sopenharmony_ci tc1[0] = sx + width; 207bf215546Sopenharmony_ci tc1[1] = sy; 208bf215546Sopenharmony_ci tc2[0] = sx + width; 209bf215546Sopenharmony_ci tc2[1] = sy + height; 210bf215546Sopenharmony_ci tc3[0] = sx; 211bf215546Sopenharmony_ci tc3[1] = sy + height; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci if (src_matrix) { 214bf215546Sopenharmony_ci map_point(src_matrix, tc0[0], tc0[1], &tc0[0], &tc0[1]); 215bf215546Sopenharmony_ci map_point(src_matrix, tc1[0], tc1[1], &tc1[0], &tc1[1]); 216bf215546Sopenharmony_ci map_point(src_matrix, tc2[0], tc2[1], &tc2[0], &tc2[1]); 217bf215546Sopenharmony_ci map_point(src_matrix, tc3[0], tc3[1], &tc3[0], &tc3[1]); 218bf215546Sopenharmony_ci } 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci tc0[0] /= src->width0; 221bf215546Sopenharmony_ci tc1[0] /= src->width0; 222bf215546Sopenharmony_ci tc2[0] /= src->width0; 223bf215546Sopenharmony_ci tc3[0] /= src->width0; 224bf215546Sopenharmony_ci tc0[1] /= src->height0; 225bf215546Sopenharmony_ci tc1[1] /= src->height0; 226bf215546Sopenharmony_ci tc2[1] /= src->height0; 227bf215546Sopenharmony_ci tc3[1] /= src->height0; 228bf215546Sopenharmony_ci} 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_cistatic void 231bf215546Sopenharmony_ciadd_vertex_data1(struct xa_context *r, 232bf215546Sopenharmony_ci float srcX, float srcY, float dstX, float dstY, 233bf215546Sopenharmony_ci float width, float height, 234bf215546Sopenharmony_ci const struct pipe_resource *src, const float *src_matrix) 235bf215546Sopenharmony_ci{ 236bf215546Sopenharmony_ci float tc0[2], tc1[2], tc2[2], tc3[2]; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci compute_src_coords(srcX, srcY, src, src_matrix, width, height, 239bf215546Sopenharmony_ci tc0, tc1, tc2, tc3); 240bf215546Sopenharmony_ci /* 1st vertex */ 241bf215546Sopenharmony_ci add_vertex_1tex(r, dstX, dstY, tc0[0], tc0[1]); 242bf215546Sopenharmony_ci /* 2nd vertex */ 243bf215546Sopenharmony_ci add_vertex_1tex(r, dstX + width, dstY, tc1[0], tc1[1]); 244bf215546Sopenharmony_ci /* 3rd vertex */ 245bf215546Sopenharmony_ci add_vertex_1tex(r, dstX + width, dstY + height, tc2[0], tc2[1]); 246bf215546Sopenharmony_ci /* 4th vertex */ 247bf215546Sopenharmony_ci add_vertex_1tex(r, dstX, dstY + height, tc3[0], tc3[1]); 248bf215546Sopenharmony_ci} 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_cistatic void 251bf215546Sopenharmony_ciadd_vertex_data2(struct xa_context *r, 252bf215546Sopenharmony_ci float srcX, float srcY, float maskX, float maskY, 253bf215546Sopenharmony_ci float dstX, float dstY, float width, float height, 254bf215546Sopenharmony_ci struct pipe_resource *src, 255bf215546Sopenharmony_ci struct pipe_resource *mask, 256bf215546Sopenharmony_ci const float *src_matrix, const float *mask_matrix) 257bf215546Sopenharmony_ci{ 258bf215546Sopenharmony_ci float spt0[2], spt1[2], spt2[2], spt3[2]; 259bf215546Sopenharmony_ci float mpt0[2], mpt1[2], mpt2[2], mpt3[2]; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci compute_src_coords(srcX, srcY, src, src_matrix, width, height, 262bf215546Sopenharmony_ci spt0, spt1, spt2, spt3); 263bf215546Sopenharmony_ci compute_src_coords(maskX, maskY, mask, mask_matrix, width, height, 264bf215546Sopenharmony_ci mpt0, mpt1, mpt2, mpt3); 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci /* 1st vertex */ 267bf215546Sopenharmony_ci add_vertex_2tex(r, dstX, dstY, 268bf215546Sopenharmony_ci spt0[0], spt0[1], mpt0[0], mpt0[1]); 269bf215546Sopenharmony_ci /* 2nd vertex */ 270bf215546Sopenharmony_ci add_vertex_2tex(r, dstX + width, dstY, 271bf215546Sopenharmony_ci spt1[0], spt1[1], mpt1[0], mpt1[1]); 272bf215546Sopenharmony_ci /* 3rd vertex */ 273bf215546Sopenharmony_ci add_vertex_2tex(r, dstX + width, dstY + height, 274bf215546Sopenharmony_ci spt2[0], spt2[1], mpt2[0], mpt2[1]); 275bf215546Sopenharmony_ci /* 4th vertex */ 276bf215546Sopenharmony_ci add_vertex_2tex(r, dstX, dstY + height, 277bf215546Sopenharmony_ci spt3[0], spt3[1], mpt3[0], mpt3[1]); 278bf215546Sopenharmony_ci} 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_cistatic void 281bf215546Sopenharmony_cisetup_vertex_data_yuv(struct xa_context *r, 282bf215546Sopenharmony_ci float srcX, 283bf215546Sopenharmony_ci float srcY, 284bf215546Sopenharmony_ci float srcW, 285bf215546Sopenharmony_ci float srcH, 286bf215546Sopenharmony_ci float dstX, 287bf215546Sopenharmony_ci float dstY, 288bf215546Sopenharmony_ci float dstW, float dstH, struct xa_surface *srf[]) 289bf215546Sopenharmony_ci{ 290bf215546Sopenharmony_ci float s0, t0, s1, t1; 291bf215546Sopenharmony_ci float spt0[2], spt1[2]; 292bf215546Sopenharmony_ci struct pipe_resource *tex; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci spt0[0] = srcX; 295bf215546Sopenharmony_ci spt0[1] = srcY; 296bf215546Sopenharmony_ci spt1[0] = srcX + srcW; 297bf215546Sopenharmony_ci spt1[1] = srcY + srcH; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci tex = srf[0]->tex; 300bf215546Sopenharmony_ci s0 = spt0[0] / tex->width0; 301bf215546Sopenharmony_ci t0 = spt0[1] / tex->height0; 302bf215546Sopenharmony_ci s1 = spt1[0] / tex->width0; 303bf215546Sopenharmony_ci t1 = spt1[1] / tex->height0; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci /* 1st vertex */ 306bf215546Sopenharmony_ci add_vertex_1tex(r, dstX, dstY, s0, t0); 307bf215546Sopenharmony_ci /* 2nd vertex */ 308bf215546Sopenharmony_ci add_vertex_1tex(r, dstX + dstW, dstY, s1, t0); 309bf215546Sopenharmony_ci /* 3rd vertex */ 310bf215546Sopenharmony_ci add_vertex_1tex(r, dstX + dstW, dstY + dstH, s1, t1); 311bf215546Sopenharmony_ci /* 4th vertex */ 312bf215546Sopenharmony_ci add_vertex_1tex(r, dstX, dstY + dstH, s0, t1); 313bf215546Sopenharmony_ci} 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci/* Set up framebuffer, viewport and vertex shader constant buffer 316bf215546Sopenharmony_ci * state for a particular destinaton surface. In all our rendering, 317bf215546Sopenharmony_ci * these concepts are linked. 318bf215546Sopenharmony_ci */ 319bf215546Sopenharmony_civoid 320bf215546Sopenharmony_cirenderer_bind_destination(struct xa_context *r, 321bf215546Sopenharmony_ci struct pipe_surface *surface) 322bf215546Sopenharmony_ci{ 323bf215546Sopenharmony_ci int width = surface->width; 324bf215546Sopenharmony_ci int height = surface->height; 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci struct pipe_framebuffer_state fb; 327bf215546Sopenharmony_ci struct pipe_viewport_state viewport; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci xa_scissor_reset(r); 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci /* Framebuffer uses actual surface width/height 332bf215546Sopenharmony_ci */ 333bf215546Sopenharmony_ci memset(&fb, 0, sizeof fb); 334bf215546Sopenharmony_ci fb.width = surface->width; 335bf215546Sopenharmony_ci fb.height = surface->height; 336bf215546Sopenharmony_ci fb.nr_cbufs = 1; 337bf215546Sopenharmony_ci fb.cbufs[0] = surface; 338bf215546Sopenharmony_ci fb.zsbuf = NULL; 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci /* Viewport just touches the bit we're interested in: 341bf215546Sopenharmony_ci */ 342bf215546Sopenharmony_ci viewport.scale[0] = width / 2.f; 343bf215546Sopenharmony_ci viewport.scale[1] = height / 2.f; 344bf215546Sopenharmony_ci viewport.scale[2] = 1.0; 345bf215546Sopenharmony_ci viewport.translate[0] = width / 2.f; 346bf215546Sopenharmony_ci viewport.translate[1] = height / 2.f; 347bf215546Sopenharmony_ci viewport.translate[2] = 0.0; 348bf215546Sopenharmony_ci viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; 349bf215546Sopenharmony_ci viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; 350bf215546Sopenharmony_ci viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; 351bf215546Sopenharmony_ci viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci /* Constant buffer set up to match viewport dimensions: 354bf215546Sopenharmony_ci */ 355bf215546Sopenharmony_ci if (r->fb_width != width || r->fb_height != height) { 356bf215546Sopenharmony_ci float vs_consts[8] = { 357bf215546Sopenharmony_ci 2.f / width, 2.f / height, 1, 1, 358bf215546Sopenharmony_ci -1, -1, 0, 0 359bf215546Sopenharmony_ci }; 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci r->fb_width = width; 362bf215546Sopenharmony_ci r->fb_height = height; 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci renderer_set_constants(r, PIPE_SHADER_VERTEX, 365bf215546Sopenharmony_ci vs_consts, sizeof vs_consts); 366bf215546Sopenharmony_ci } 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci cso_set_framebuffer(r->cso, &fb); 369bf215546Sopenharmony_ci cso_set_viewport(r->cso, &viewport); 370bf215546Sopenharmony_ci} 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_civoid 373bf215546Sopenharmony_cirenderer_set_constants(struct xa_context *r, 374bf215546Sopenharmony_ci int shader_type, const float *params, int param_bytes) 375bf215546Sopenharmony_ci{ 376bf215546Sopenharmony_ci struct pipe_resource **cbuf = 377bf215546Sopenharmony_ci (shader_type == PIPE_SHADER_VERTEX) ? &r->vs_const_buffer : 378bf215546Sopenharmony_ci &r->fs_const_buffer; 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci pipe_resource_reference(cbuf, NULL); 381bf215546Sopenharmony_ci *cbuf = pipe_buffer_create_const0(r->pipe->screen, 382bf215546Sopenharmony_ci PIPE_BIND_CONSTANT_BUFFER, 383bf215546Sopenharmony_ci PIPE_USAGE_DEFAULT, 384bf215546Sopenharmony_ci param_bytes); 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci if (*cbuf) { 387bf215546Sopenharmony_ci pipe_buffer_write(r->pipe, *cbuf, 0, param_bytes, params); 388bf215546Sopenharmony_ci } 389bf215546Sopenharmony_ci pipe_set_constant_buffer(r->pipe, shader_type, 0, *cbuf); 390bf215546Sopenharmony_ci} 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_civoid 393bf215546Sopenharmony_cirenderer_copy_prepare(struct xa_context *r, 394bf215546Sopenharmony_ci struct pipe_surface *dst_surface, 395bf215546Sopenharmony_ci struct pipe_resource *src_texture, 396bf215546Sopenharmony_ci const enum xa_formats src_xa_format, 397bf215546Sopenharmony_ci const enum xa_formats dst_xa_format) 398bf215546Sopenharmony_ci{ 399bf215546Sopenharmony_ci struct pipe_context *pipe = r->pipe; 400bf215546Sopenharmony_ci struct pipe_screen *screen = pipe->screen; 401bf215546Sopenharmony_ci struct xa_shader shader; 402bf215546Sopenharmony_ci uint32_t fs_traits = FS_COMPOSITE; 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci assert(screen->is_format_supported(screen, dst_surface->format, 405bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 406bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET)); 407bf215546Sopenharmony_ci (void)screen; 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci renderer_bind_destination(r, dst_surface); 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci /* set misc state we care about */ 412bf215546Sopenharmony_ci { 413bf215546Sopenharmony_ci struct pipe_blend_state blend; 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci memset(&blend, 0, sizeof(blend)); 416bf215546Sopenharmony_ci blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; 417bf215546Sopenharmony_ci blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; 418bf215546Sopenharmony_ci blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; 419bf215546Sopenharmony_ci blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; 420bf215546Sopenharmony_ci blend.rt[0].colormask = PIPE_MASK_RGBA; 421bf215546Sopenharmony_ci cso_set_blend(r->cso, &blend); 422bf215546Sopenharmony_ci } 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci /* sampler */ 425bf215546Sopenharmony_ci { 426bf215546Sopenharmony_ci struct pipe_sampler_state sampler; 427bf215546Sopenharmony_ci const struct pipe_sampler_state *p_sampler = &sampler; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci memset(&sampler, 0, sizeof(sampler)); 430bf215546Sopenharmony_ci sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 431bf215546Sopenharmony_ci sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 432bf215546Sopenharmony_ci sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 433bf215546Sopenharmony_ci sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 434bf215546Sopenharmony_ci sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 435bf215546Sopenharmony_ci sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 436bf215546Sopenharmony_ci sampler.normalized_coords = 1; 437bf215546Sopenharmony_ci cso_set_samplers(r->cso, PIPE_SHADER_FRAGMENT, 1, &p_sampler); 438bf215546Sopenharmony_ci r->num_bound_samplers = 1; 439bf215546Sopenharmony_ci } 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci /* texture/sampler view */ 442bf215546Sopenharmony_ci { 443bf215546Sopenharmony_ci struct pipe_sampler_view templ; 444bf215546Sopenharmony_ci struct pipe_sampler_view *src_view; 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci u_sampler_view_default_template(&templ, 447bf215546Sopenharmony_ci src_texture, src_texture->format); 448bf215546Sopenharmony_ci src_view = pipe->create_sampler_view(pipe, src_texture, &templ); 449bf215546Sopenharmony_ci pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view); 450bf215546Sopenharmony_ci pipe_sampler_view_reference(&src_view, NULL); 451bf215546Sopenharmony_ci } 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci /* shaders */ 454bf215546Sopenharmony_ci if (src_texture->format == PIPE_FORMAT_L8_UNORM || 455bf215546Sopenharmony_ci src_texture->format == PIPE_FORMAT_R8_UNORM) 456bf215546Sopenharmony_ci fs_traits |= FS_SRC_LUMINANCE; 457bf215546Sopenharmony_ci if (dst_surface->format == PIPE_FORMAT_L8_UNORM || 458bf215546Sopenharmony_ci dst_surface->format == PIPE_FORMAT_R8_UNORM) 459bf215546Sopenharmony_ci fs_traits |= FS_DST_LUMINANCE; 460bf215546Sopenharmony_ci if (xa_format_a(dst_xa_format) != 0 && 461bf215546Sopenharmony_ci xa_format_a(src_xa_format) == 0) 462bf215546Sopenharmony_ci fs_traits |= FS_SRC_SET_ALPHA; 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci shader = xa_shaders_get(r->shaders, VS_COMPOSITE, fs_traits); 465bf215546Sopenharmony_ci cso_set_vertex_shader_handle(r->cso, shader.vs); 466bf215546Sopenharmony_ci cso_set_fragment_shader_handle(r->cso, shader.fs); 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci r->buffer_size = 0; 469bf215546Sopenharmony_ci r->attrs_per_vertex = 2; 470bf215546Sopenharmony_ci} 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_civoid 473bf215546Sopenharmony_cirenderer_copy(struct xa_context *r, 474bf215546Sopenharmony_ci int dx, 475bf215546Sopenharmony_ci int dy, 476bf215546Sopenharmony_ci int sx, 477bf215546Sopenharmony_ci int sy, 478bf215546Sopenharmony_ci int width, int height, float src_width, float src_height) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci float s0, t0, s1, t1; 481bf215546Sopenharmony_ci float x0, y0, x1, y1; 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci /* XXX: could put the texcoord scaling calculation into the vertex 484bf215546Sopenharmony_ci * shader. 485bf215546Sopenharmony_ci */ 486bf215546Sopenharmony_ci s0 = sx / src_width; 487bf215546Sopenharmony_ci s1 = (sx + width) / src_width; 488bf215546Sopenharmony_ci t0 = sy / src_height; 489bf215546Sopenharmony_ci t1 = (sy + height) / src_height; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci x0 = dx; 492bf215546Sopenharmony_ci x1 = dx + width; 493bf215546Sopenharmony_ci y0 = dy; 494bf215546Sopenharmony_ci y1 = dy + height; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci /* draw quad */ 497bf215546Sopenharmony_ci renderer_draw_conditional(r, 4 * 8); 498bf215546Sopenharmony_ci add_vertex_1tex(r, x0, y0, s0, t0); 499bf215546Sopenharmony_ci add_vertex_1tex(r, x1, y0, s1, t0); 500bf215546Sopenharmony_ci add_vertex_1tex(r, x1, y1, s1, t1); 501bf215546Sopenharmony_ci add_vertex_1tex(r, x0, y1, s0, t1); 502bf215546Sopenharmony_ci} 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_civoid 505bf215546Sopenharmony_cirenderer_draw_yuv(struct xa_context *r, 506bf215546Sopenharmony_ci float src_x, 507bf215546Sopenharmony_ci float src_y, 508bf215546Sopenharmony_ci float src_w, 509bf215546Sopenharmony_ci float src_h, 510bf215546Sopenharmony_ci int dst_x, 511bf215546Sopenharmony_ci int dst_y, int dst_w, int dst_h, struct xa_surface *srf[]) 512bf215546Sopenharmony_ci{ 513bf215546Sopenharmony_ci const int num_attribs = 2; /*pos + tex coord */ 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci setup_vertex_data_yuv(r, 516bf215546Sopenharmony_ci src_x, src_y, src_w, src_h, 517bf215546Sopenharmony_ci dst_x, dst_y, dst_w, dst_h, srf); 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_ci if (!r->scissor_valid) { 520bf215546Sopenharmony_ci r->scissor.minx = 0; 521bf215546Sopenharmony_ci r->scissor.miny = 0; 522bf215546Sopenharmony_ci r->scissor.maxx = r->dst->tex->width0; 523bf215546Sopenharmony_ci r->scissor.maxy = r->dst->tex->height0; 524bf215546Sopenharmony_ci } 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci r->pipe->set_scissor_states(r->pipe, 0, 1, &r->scissor); 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_ci struct cso_velems_state velems; 529bf215546Sopenharmony_ci velems.count = num_attribs; 530bf215546Sopenharmony_ci memcpy(velems.velems, r->velems, sizeof(r->velems[0]) * velems.count); 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci cso_set_vertex_elements(r->cso, &velems); 533bf215546Sopenharmony_ci util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS, 534bf215546Sopenharmony_ci 4, /* verts */ 535bf215546Sopenharmony_ci num_attribs); /* attribs/vert */ 536bf215546Sopenharmony_ci r->buffer_size = 0; 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci xa_scissor_reset(r); 539bf215546Sopenharmony_ci} 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_civoid 542bf215546Sopenharmony_cirenderer_begin_solid(struct xa_context *r) 543bf215546Sopenharmony_ci{ 544bf215546Sopenharmony_ci r->buffer_size = 0; 545bf215546Sopenharmony_ci r->attrs_per_vertex = 1; 546bf215546Sopenharmony_ci renderer_set_constants(r, PIPE_SHADER_FRAGMENT, r->solid_color, 547bf215546Sopenharmony_ci 4 * sizeof(float)); 548bf215546Sopenharmony_ci} 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_civoid 551bf215546Sopenharmony_cirenderer_solid(struct xa_context *r, 552bf215546Sopenharmony_ci int x0, int y0, int x1, int y1) 553bf215546Sopenharmony_ci{ 554bf215546Sopenharmony_ci /* 555bf215546Sopenharmony_ci * debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n", 556bf215546Sopenharmony_ci * x0, y0, x1, y1, color[0], color[1], color[2], color[3]); */ 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci renderer_draw_conditional(r, 4 * 4); 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci /* 1st vertex */ 561bf215546Sopenharmony_ci add_vertex_none(r, x0, y0); 562bf215546Sopenharmony_ci /* 2nd vertex */ 563bf215546Sopenharmony_ci add_vertex_none(r, x1, y0); 564bf215546Sopenharmony_ci /* 3rd vertex */ 565bf215546Sopenharmony_ci add_vertex_none(r, x1, y1); 566bf215546Sopenharmony_ci /* 4th vertex */ 567bf215546Sopenharmony_ci add_vertex_none(r, x0, y1); 568bf215546Sopenharmony_ci} 569bf215546Sopenharmony_ci 570bf215546Sopenharmony_civoid 571bf215546Sopenharmony_cirenderer_draw_flush(struct xa_context *r) 572bf215546Sopenharmony_ci{ 573bf215546Sopenharmony_ci renderer_draw_conditional(r, 0); 574bf215546Sopenharmony_ci} 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_civoid 577bf215546Sopenharmony_cirenderer_begin_textures(struct xa_context *r) 578bf215546Sopenharmony_ci{ 579bf215546Sopenharmony_ci r->attrs_per_vertex = 1 + r->num_bound_samplers; 580bf215546Sopenharmony_ci r->buffer_size = 0; 581bf215546Sopenharmony_ci if (r->has_solid_src || r->has_solid_mask) 582bf215546Sopenharmony_ci renderer_set_constants(r, PIPE_SHADER_FRAGMENT, r->solid_color, 583bf215546Sopenharmony_ci 4 * sizeof(float)); 584bf215546Sopenharmony_ci} 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_civoid 587bf215546Sopenharmony_cirenderer_texture(struct xa_context *r, 588bf215546Sopenharmony_ci int *pos, 589bf215546Sopenharmony_ci int width, int height, 590bf215546Sopenharmony_ci const float *src_matrix, 591bf215546Sopenharmony_ci const float *mask_matrix) 592bf215546Sopenharmony_ci{ 593bf215546Sopenharmony_ci struct pipe_sampler_view **sampler_view = r->bound_sampler_views; 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci#if 0 596bf215546Sopenharmony_ci if (src_matrix) { 597bf215546Sopenharmony_ci debug_printf("src_matrix = \n"); 598bf215546Sopenharmony_ci debug_printf("%f, %f, %f\n", src_matrix[0], src_matrix[1], src_matrix[2]); 599bf215546Sopenharmony_ci debug_printf("%f, %f, %f\n", src_matrix[3], src_matrix[4], src_matrix[5]); 600bf215546Sopenharmony_ci debug_printf("%f, %f, %f\n", src_matrix[6], src_matrix[7], src_matrix[8]); 601bf215546Sopenharmony_ci } 602bf215546Sopenharmony_ci if (mask_matrix) { 603bf215546Sopenharmony_ci debug_printf("mask_matrix = \n"); 604bf215546Sopenharmony_ci debug_printf("%f, %f, %f\n", mask_matrix[0], mask_matrix[1], mask_matrix[2]); 605bf215546Sopenharmony_ci debug_printf("%f, %f, %f\n", mask_matrix[3], mask_matrix[4], mask_matrix[5]); 606bf215546Sopenharmony_ci debug_printf("%f, %f, %f\n", mask_matrix[6], mask_matrix[7], mask_matrix[8]); 607bf215546Sopenharmony_ci } 608bf215546Sopenharmony_ci#endif 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci switch(r->attrs_per_vertex) { 611bf215546Sopenharmony_ci case 2: 612bf215546Sopenharmony_ci renderer_draw_conditional(r, 4 * 8); 613bf215546Sopenharmony_ci if (!r->has_solid_src) { 614bf215546Sopenharmony_ci add_vertex_data1(r, 615bf215546Sopenharmony_ci pos[0], pos[1], /* src */ 616bf215546Sopenharmony_ci pos[4], pos[5], /* dst */ 617bf215546Sopenharmony_ci width, height, 618bf215546Sopenharmony_ci sampler_view[0]->texture, src_matrix); 619bf215546Sopenharmony_ci } else { 620bf215546Sopenharmony_ci add_vertex_data1(r, 621bf215546Sopenharmony_ci pos[2], pos[3], /* mask */ 622bf215546Sopenharmony_ci pos[4], pos[5], /* dst */ 623bf215546Sopenharmony_ci width, height, 624bf215546Sopenharmony_ci sampler_view[0]->texture, mask_matrix); 625bf215546Sopenharmony_ci } 626bf215546Sopenharmony_ci break; 627bf215546Sopenharmony_ci case 3: 628bf215546Sopenharmony_ci renderer_draw_conditional(r, 4 * 12); 629bf215546Sopenharmony_ci add_vertex_data2(r, 630bf215546Sopenharmony_ci pos[0], pos[1], /* src */ 631bf215546Sopenharmony_ci pos[2], pos[3], /* mask */ 632bf215546Sopenharmony_ci pos[4], pos[5], /* dst */ 633bf215546Sopenharmony_ci width, height, 634bf215546Sopenharmony_ci sampler_view[0]->texture, sampler_view[1]->texture, 635bf215546Sopenharmony_ci src_matrix, mask_matrix); 636bf215546Sopenharmony_ci break; 637bf215546Sopenharmony_ci default: 638bf215546Sopenharmony_ci break; 639bf215546Sopenharmony_ci } 640bf215546Sopenharmony_ci} 641