renderer_set_constants(struct xa_context *r,
int shader_type, const float *params, int param_bytes);
-static INLINE boolean
-is_affine(float *matrix)
+static inline boolean
+is_affine(const float *matrix)
{
return floatIsZero(matrix[2]) && floatIsZero(matrix[5])
&& floatsEqual(matrix[8], 1);
}
-static INLINE void
-map_point(float *mat, float x, float y, float *out_x, float *out_y)
+static inline void
+map_point(const float *mat, float x, float y, float *out_x, float *out_y)
{
if (!mat) {
*out_x = x;
}
}
-static INLINE struct pipe_resource *
-renderer_buffer_create(struct xa_context *r)
-{
- struct pipe_resource *buf = pipe_user_buffer_create(r->pipe->screen,
- r->buffer,
- sizeof(float) *
- r->buffer_size,
- PIPE_BIND_VERTEX_BUFFER);
-
- r->buffer_size = 0;
-
- return buf;
-}
-
-static INLINE void
+static inline void
renderer_draw(struct xa_context *r)
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_resource *buf = 0;
int num_verts = r->buffer_size / (r->attrs_per_vertex * NUM_COMPONENTS);
if (!r->buffer_size)
return;
- buf = renderer_buffer_create(r);
+ if (!r->scissor_valid) {
+ r->scissor.minx = 0;
+ r->scissor.miny = 0;
+ r->scissor.maxx = r->dst->tex->width0;
+ r->scissor.maxy = r->dst->tex->height0;
+ }
- if (buf) {
- cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+ r->pipe->set_scissor_states(r->pipe, 0, 1, &r->scissor);
- util_draw_vertex_buffer(pipe, r->cso, buf, 0, PIPE_PRIM_QUADS, num_verts, /* verts */
- r->attrs_per_vertex); /* attribs/vert */
+ cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+ util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
+ num_verts, /* verts */
+ r->attrs_per_vertex); /* attribs/vert */
+ r->buffer_size = 0;
- pipe_resource_reference(&buf, NULL);
- }
+ xa_scissor_reset(r);
}
-static INLINE void
+static inline void
renderer_draw_conditional(struct xa_context *r, int next_batch)
{
if (r->buffer_size + next_batch >= XA_VB_SIZE ||
/* XXX: move to renderer_init_state? */
memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
- raster.gl_rasterization_rules = 1;
- raster.depth_clip = 1;
+ raster.half_pixel_center = 1;
+ raster.bottom_edge_rule = 1;
+ raster.depth_clip_near = 1;
+ raster.depth_clip_far = 1;
+ raster.scissor = 1;
cso_set_rasterizer(r->cso, &raster);
/* vertex elements state */
}
}
-static INLINE void
-add_vertex_color(struct xa_context *r, float x, float y, float color[4])
+static inline void
+add_vertex_none(struct xa_context *r, float x, float y)
{
float *vertex = r->buffer + r->buffer_size;
vertex[2] = 0.f; /*z */
vertex[3] = 1.f; /*w */
- vertex[4] = color[0]; /*r */
- vertex[5] = color[1]; /*g */
- vertex[6] = color[2]; /*b */
- vertex[7] = color[3]; /*a */
-
- r->buffer_size += 8;
+ r->buffer_size += 4;
}
-static INLINE void
+static inline void
add_vertex_1tex(struct xa_context *r, float x, float y, float s, float t)
{
float *vertex = r->buffer + r->buffer_size;
r->buffer_size += 8;
}
-static INLINE void
+static inline void
add_vertex_2tex(struct xa_context *r,
float x, float y, float s0, float t0, float s1, float t1)
{
}
static void
-add_vertex_data1(struct xa_context *r,
- float srcX, float srcY, float dstX, float dstY,
- float width, float height,
- struct pipe_resource *src, const float *src_matrix)
+compute_src_coords(float sx, float sy, const struct pipe_resource *src,
+ const float *src_matrix,
+ float width, float height,
+ float tc0[2], float tc1[2], float tc2[2], float tc3[2])
{
- float s0, t0, s1, t1, s2, t2, s3, t3;
- float pt0[2], pt1[2], pt2[2], pt3[2];
-
- pt0[0] = srcX;
- pt0[1] = srcY;
- pt1[0] = (srcX + width);
- pt1[1] = srcY;
- pt2[0] = (srcX + width);
- pt2[1] = (srcY + height);
- pt3[0] = srcX;
- pt3[1] = (srcY + height);
+ tc0[0] = sx;
+ tc0[1] = sy;
+ tc1[0] = sx + width;
+ tc1[1] = sy;
+ tc2[0] = sx + width;
+ tc2[1] = sy + height;
+ tc3[0] = sx;
+ tc3[1] = sy + height;
if (src_matrix) {
- map_point((float *)src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]);
- map_point((float *)src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]);
- map_point((float *)src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]);
- map_point((float *)src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
+ map_point(src_matrix, tc0[0], tc0[1], &tc0[0], &tc0[1]);
+ map_point(src_matrix, tc1[0], tc1[1], &tc1[0], &tc1[1]);
+ map_point(src_matrix, tc2[0], tc2[1], &tc2[0], &tc2[1]);
+ map_point(src_matrix, tc3[0], tc3[1], &tc3[0], &tc3[1]);
}
- s0 = pt0[0] / src->width0;
- s1 = pt1[0] / src->width0;
- s2 = pt2[0] / src->width0;
- s3 = pt3[0] / src->width0;
- t0 = pt0[1] / src->height0;
- t1 = pt1[1] / src->height0;
- t2 = pt2[1] / src->height0;
- t3 = pt3[1] / src->height0;
+ tc0[0] /= src->width0;
+ tc1[0] /= src->width0;
+ tc2[0] /= src->width0;
+ tc3[0] /= src->width0;
+ tc0[1] /= src->height0;
+ tc1[1] /= src->height0;
+ tc2[1] /= src->height0;
+ tc3[1] /= src->height0;
+}
+
+static void
+add_vertex_data1(struct xa_context *r,
+ float srcX, float srcY, float dstX, float dstY,
+ float width, float height,
+ const struct pipe_resource *src, const float *src_matrix)
+{
+ float tc0[2], tc1[2], tc2[2], tc3[2];
+ compute_src_coords(srcX, srcY, src, src_matrix, width, height,
+ tc0, tc1, tc2, tc3);
/* 1st vertex */
- add_vertex_1tex(r, dstX, dstY, s0, t0);
+ add_vertex_1tex(r, dstX, dstY, tc0[0], tc0[1]);
/* 2nd vertex */
- add_vertex_1tex(r, dstX + width, dstY, s1, t1);
+ add_vertex_1tex(r, dstX + width, dstY, tc1[0], tc1[1]);
/* 3rd vertex */
- add_vertex_1tex(r, dstX + width, dstY + height, s2, t2);
+ add_vertex_1tex(r, dstX + width, dstY + height, tc2[0], tc2[1]);
/* 4th vertex */
- add_vertex_1tex(r, dstX, dstY + height, s3, t3);
+ add_vertex_1tex(r, dstX, dstY + height, tc3[0], tc3[1]);
}
static void
struct pipe_resource *mask,
const float *src_matrix, const float *mask_matrix)
{
- float src_s0, src_t0, src_s1, src_t1;
- float mask_s0, mask_t0, mask_s1, mask_t1;
- float spt0[2], spt1[2];
- float mpt0[2], mpt1[2];
+ float spt0[2], spt1[2], spt2[2], spt3[2];
+ float mpt0[2], mpt1[2], mpt2[2], mpt3[2];
- spt0[0] = srcX;
- spt0[1] = srcY;
- spt1[0] = srcX + width;
- spt1[1] = srcY + height;
-
- mpt0[0] = maskX;
- mpt0[1] = maskY;
- mpt1[0] = maskX + width;
- mpt1[1] = maskY + height;
-
- if (src_matrix) {
- map_point((float *)src_matrix, spt0[0], spt0[1], &spt0[0], &spt0[1]);
- map_point((float *)src_matrix, spt1[0], spt1[1], &spt1[0], &spt1[1]);
- }
-
- if (mask_matrix) {
- map_point((float *)mask_matrix, mpt0[0], mpt0[1], &mpt0[0], &mpt0[1]);
- map_point((float *)mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]);
- }
-
- src_s0 = spt0[0] / src->width0;
- src_t0 = spt0[1] / src->height0;
- src_s1 = spt1[0] / src->width0;
- src_t1 = spt1[1] / src->height0;
-
- mask_s0 = mpt0[0] / mask->width0;
- mask_t0 = mpt0[1] / mask->height0;
- mask_s1 = mpt1[0] / mask->width0;
- mask_t1 = mpt1[1] / mask->height0;
+ compute_src_coords(srcX, srcY, src, src_matrix, width, height,
+ spt0, spt1, spt2, spt3);
+ compute_src_coords(maskX, maskY, mask, mask_matrix, width, height,
+ mpt0, mpt1, mpt2, mpt3);
/* 1st vertex */
add_vertex_2tex(r, dstX, dstY,
- src_s0, src_t0, mask_s0, mask_t0);
+ spt0[0], spt0[1], mpt0[0], mpt0[1]);
/* 2nd vertex */
add_vertex_2tex(r, dstX + width, dstY,
- src_s1, src_t0, mask_s1, mask_t0);
+ spt1[0], spt1[1], mpt1[0], mpt1[1]);
/* 3rd vertex */
add_vertex_2tex(r, dstX + width, dstY + height,
- src_s1, src_t1, mask_s1, mask_t1);
+ spt2[0], spt2[1], mpt2[0], mpt2[1]);
/* 4th vertex */
add_vertex_2tex(r, dstX, dstY + height,
- src_s0, src_t1, mask_s0, mask_t1);
+ spt3[0], spt3[1], mpt3[0], mpt3[1]);
}
-static struct pipe_resource *
+static void
setup_vertex_data_yuv(struct xa_context *r,
float srcX,
float srcY,
add_vertex_1tex(r, dstX + dstW, dstY + dstH, s1, t1);
/* 4th vertex */
add_vertex_1tex(r, dstX, dstY + dstH, s0, t1);
-
- return renderer_buffer_create(r);
}
/* Set up framebuffer, viewport and vertex shader constant buffer
*/
void
renderer_bind_destination(struct xa_context *r,
- struct pipe_surface *surface, int width, int height)
+ struct pipe_surface *surface)
{
+ int width = surface->width;
+ int height = surface->height;
struct pipe_framebuffer_state fb;
struct pipe_viewport_state viewport;
+ xa_scissor_reset(r);
+
/* Framebuffer uses actual surface width/height
*/
memset(&fb, 0, sizeof fb);
viewport.scale[0] = width / 2.f;
viewport.scale[1] = height / 2.f;
viewport.scale[2] = 1.0;
- viewport.scale[3] = 1.0;
viewport.translate[0] = width / 2.f;
viewport.translate[1] = height / 2.f;
viewport.translate[2] = 0.0;
- viewport.translate[3] = 0.0;
/* Constant buffer set up to match viewport dimensions:
*/
&r->fs_const_buffer;
pipe_resource_reference(cbuf, NULL);
- *cbuf = pipe_buffer_create(r->pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC,
- param_bytes);
+ *cbuf = pipe_buffer_create_const0(r->pipe->screen,
+ PIPE_BIND_CONSTANT_BUFFER,
+ PIPE_USAGE_DEFAULT,
+ param_bytes);
if (*cbuf) {
pipe_buffer_write(r->pipe, *cbuf, 0, param_bytes, params);
uint32_t fs_traits = FS_COMPOSITE;
assert(screen->is_format_supported(screen, dst_surface->format,
- PIPE_TEXTURE_2D, 0,
+ PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_RENDER_TARGET));
(void)screen;
+ renderer_bind_destination(r, dst_surface);
+
/* set misc state we care about */
{
struct pipe_blend_state blend;
/* sampler */
{
struct pipe_sampler_state sampler;
+ const struct pipe_sampler_state *p_sampler = &sampler;
memset(&sampler, 0, sizeof(sampler));
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.normalized_coords = 1;
- cso_single_sampler(r->cso, 0, &sampler);
- cso_single_sampler_done(r->cso);
+ cso_set_samplers(r->cso, PIPE_SHADER_FRAGMENT, 1, &p_sampler);
+ r->num_bound_samplers = 1;
}
- renderer_bind_destination(r, dst_surface,
- dst_surface->width, dst_surface->height);
-
/* texture/sampler view */
{
struct pipe_sampler_view templ;
u_sampler_view_default_template(&templ,
src_texture, src_texture->format);
src_view = pipe->create_sampler_view(pipe, src_texture, &templ);
- cso_set_fragment_sampler_views(r->cso, 1, &src_view);
+ cso_set_sampler_views(r->cso, PIPE_SHADER_FRAGMENT, 1, &src_view);
pipe_sampler_view_reference(&src_view, NULL);
}
/* shaders */
- if (src_texture->format == PIPE_FORMAT_L8_UNORM)
+ if (src_texture->format == PIPE_FORMAT_L8_UNORM ||
+ src_texture->format == PIPE_FORMAT_R8_UNORM)
fs_traits |= FS_SRC_LUMINANCE;
- if (dst_surface->format == PIPE_FORMAT_L8_UNORM)
+ if (dst_surface->format == PIPE_FORMAT_L8_UNORM ||
+ dst_surface->format == PIPE_FORMAT_R8_UNORM)
fs_traits |= FS_DST_LUMINANCE;
if (xa_format_a(dst_xa_format) != 0 &&
xa_format_a(src_xa_format) == 0)
int dst_x,
int dst_y, int dst_w, int dst_h, struct xa_surface *srf[])
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_resource *buf = 0;
+ const int num_attribs = 2; /*pos + tex coord */
- buf = setup_vertex_data_yuv(r,
- src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w,
- dst_h, srf);
+ setup_vertex_data_yuv(r,
+ src_x, src_y, src_w, src_h,
+ dst_x, dst_y, dst_w, dst_h, srf);
- if (buf) {
- const int num_attribs = 2; /*pos + tex coord */
+ if (!r->scissor_valid) {
+ r->scissor.minx = 0;
+ r->scissor.miny = 0;
+ r->scissor.maxx = r->dst->tex->width0;
+ r->scissor.maxy = r->dst->tex->height0;
+ }
- cso_set_vertex_elements(r->cso, num_attribs, r->velems);
+ r->pipe->set_scissor_states(r->pipe, 0, 1, &r->scissor);
- util_draw_vertex_buffer(pipe, r->cso, buf, 0, PIPE_PRIM_QUADS, 4, /* verts */
- num_attribs); /* attribs/vert */
+ cso_set_vertex_elements(r->cso, num_attribs, r->velems);
+ util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
+ 4, /* verts */
+ num_attribs); /* attribs/vert */
+ r->buffer_size = 0;
- pipe_resource_reference(&buf, NULL);
- }
+ xa_scissor_reset(r);
}
void
renderer_begin_solid(struct xa_context *r)
{
r->buffer_size = 0;
- r->attrs_per_vertex = 2;
+ r->attrs_per_vertex = 1;
+ renderer_set_constants(r, PIPE_SHADER_FRAGMENT, r->solid_color,
+ 4 * sizeof(float));
}
void
renderer_solid(struct xa_context *r,
- int x0, int y0, int x1, int y1, float *color)
+ int x0, int y0, int x1, int y1)
{
/*
* debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
* x0, y0, x1, y1, color[0], color[1], color[2], color[3]); */
- renderer_draw_conditional(r, 4 * 8);
+ renderer_draw_conditional(r, 4 * 4);
/* 1st vertex */
- add_vertex_color(r, x0, y0, color);
+ add_vertex_none(r, x0, y0);
/* 2nd vertex */
- add_vertex_color(r, x1, y0, color);
+ add_vertex_none(r, x1, y0);
/* 3rd vertex */
- add_vertex_color(r, x1, y1, color);
+ add_vertex_none(r, x1, y1);
/* 4th vertex */
- add_vertex_color(r, x0, y1, color);
+ add_vertex_none(r, x0, y1);
}
void
{
r->attrs_per_vertex = 1 + r->num_bound_samplers;
r->buffer_size = 0;
+ if (r->has_solid_src || r->has_solid_mask)
+ renderer_set_constants(r, PIPE_SHADER_FRAGMENT, r->solid_color,
+ 4 * sizeof(float));
}
void
switch(r->attrs_per_vertex) {
case 2:
renderer_draw_conditional(r, 4 * 8);
- add_vertex_data1(r,
- pos[0], pos[1], /* src */
- pos[4], pos[5], /* dst */
- width, height,
- sampler_view[0]->texture, src_matrix);
+ if (!r->has_solid_src) {
+ add_vertex_data1(r,
+ pos[0], pos[1], /* src */
+ pos[4], pos[5], /* dst */
+ width, height,
+ sampler_view[0]->texture, src_matrix);
+ } else {
+ add_vertex_data1(r,
+ pos[2], pos[3], /* mask */
+ pos[4], pos[5], /* dst */
+ width, height,
+ sampler_view[0]->texture, mask_matrix);
+ }
break;
case 3:
renderer_draw_conditional(r, 4 * 12);