Am 2014-05-06 00:02, schrieb Keith Packard:
+static const glamor_facet glamor_facet_copyplane = {
+ "copy_plane",
+ .version = 130,
+ .vs_vars = "attribute vec2 primitive;\n",
+ .vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy))
+ " fill_pos = (fill_offset + primitive.xy) /
fill_size;\n"),
+ .fs_exec = (" uvec4 bits = uvec4(texture2D(sampler,
fill_pos) * bitmul + vec4(0.5,0.5,0.5,0.5));\n"
I think
uvec4(round(texture2D(sampler, fill_pos) * bitmul))
is easier to read than to add 0.5. Honestly GLSL lacks rounding +
convertion functions :/
+static void
+glamor_copy_bail(DrawablePtr src,
+ DrawablePtr dst,
+ GCPtr gc,
+ BoxPtr box,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) &&
glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
+ if (bitplane) {
+ if (src->bitsPerPixel > 1)
+ fbCopyNto1(src, dst, gc, box, nbox, dx, dy,
+ reverse, upsidedown, bitplane, closure);
+ else
+ fbCopy1toN(src, dst, gc, box, nbox, dx, dy,
+ reverse, upsidedown, bitplane, closure);
+ } else {
+ fbCopyNtoN(src, dst, gc, box, nbox, dx, dy,
+ reverse, upsidedown, bitplane, closure);
+ }
This logic should be in fbCopyNtoN imo.
+static Bool
+glamor_copy_fbo_fbo_draw(DrawablePtr src,
...
+ /* Set up the vertex buffers for the points */
+
+ v = glamor_get_vbo_space(dst->pScreen, nbox * 8 * sizeof
(int16_t), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
+ 2 * sizeof (GLshort), vbo_offset);
+
+ for (n = 0; n < nbox; n++) {
+ v[0] = box->x1; v[1] = box->y1;
+ v[2] = box->x1; v[3] = box->y2;
+ v[4] = box->x2; v[5] = box->y2;
+ v[6] = box->x2; v[7] = box->y1;
+ v += 8;
+ box++;
+ }
Why didn't you use instancing this time? We'd be able to memcpy here.
+
+ glamor_put_vbo_space(screen);
+
+ glamor_get_drawable_deltas(src, src_pixmap, &src_off_x,
&src_off_y);
+
+ set_scissor = src_priv->type == GLAMOR_TEXTURE_LARGE;
+ if (set_scissor)
+ glEnable(GL_SCISSOR_TEST);
+
+ glamor_pixmap_loop(src_priv, src_box_x, src_box_y) {
+ BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x,
src_box_y);
+
+ args.dx = dx + src_off_x - src_box->x1;
+ args.dy = dy + src_off_y - src_box->y1;
+ args.src = glamor_pixmap_fbo_at(src_priv, src_box_x,
src_box_y);
+
+ if (!glamor_use_program(dst_pixmap, gc, prog, &args))
+ goto bail_ctx;
+
+ glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) {
+ glamor_set_destination_drawable(dst, dst_box_x,
dst_box_y, FALSE, FALSE,
+ prog->matrix_uniform,
&dst_off_x, &dst_off_y);
I'm a bit worried about this loop order. We don't change the programm at
all, so glamor_use_program will be almost a no-op. But we change the FBO
in the inner loop. Large textures are quite uncommon, but this sounds
like a waste of time for me.
+ if (set_scissor)
+ glScissor(dst_off_x - args.dx,
+ dst_off_y - args.dy,
+ src_box->x2 - src_box->x1,
+ src_box->y2 - src_box->y1);
So there is still no util function for this scissor box handling?
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+ glDrawArrays(GL_QUADS, 0, nbox * 4);
+ else {
+ int i;
+ for (i = 0; i < nbox; i++)
+ glDrawArrays(GL_TRIANGLE_FAN, i*4, 4);
+ }
iirc we always have an element buffer bound for quads, so we could use
glDrawElements instead of this for loop.
+/*
+ * Copy from GPU to GPU, but create
+ * a temporary pixmap in the middle to
+ * correctly handle overlapping copies
+ * in systems lacking glCopyPixels
+ */
Outdated comment, glCopyPixels isn't used any more
+static Bool
+glamor_copy_fbo_fbo_temp(DrawablePtr src,
...
+ /* Sanity check state to avoid getting halfway through and bailing
+ * at the last second. Might be nice to have checks that didn't
+ * involve setting state.
+ */
+ glamor_make_current(glamor_priv);
+
+ if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
+ goto bail_ctx;
+
+ if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
+ goto bail_ctx;
+ glDisable(GL_COLOR_LOGIC_OP);
What would be the "last second"? I guess the first copy is always fine
and the second one will fail. So we always have to stall and to readback
a texture. imo it doesn't matter that much to make a gpu based copy
first. In the end, it's likely faster for FB to copy without
overlapping.
+static Bool
+glamor_copy_needs_temp(DrawablePtr src,
...
+ glTextureBarrierNV();
I think a comment is required here why we have to call
glTextureBarrierNV at all. eg what happens when we get two copy calls in
a row, both doesn't overlap, but they overlap each other. So the second
call might want to read the result of the first copy which isn't allowed
without this barrier.
-----------------------------
I'm very happy to see this copy code without any deprecated api usage :)
Reviewed-by: Markus Wick <[email protected]>
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel