DRI2: report swap events correctly in direct rendered case
[mesa.git] / src / gallium / auxiliary / vl / vl_compositor.c
index 6431da66110096c7001b1e202d48481af277d462..ba23435f698240257bf29fe798937e66dab6dbed 100644 (file)
@@ -1,10 +1,38 @@
+/**************************************************************************
+ * 
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 "vl_compositor.h"
 #include <assert.h>
 #include <pipe/p_context.h>
-#include <pipe/p_inlines.h>
+#include <util/u_inlines.h>
 #include <tgsi/tgsi_parse.h>
 #include <tgsi/tgsi_build.h>
 #include <util/u_memory.h>
+#include "vl_csc.h"
 #include "vl_shader_build.h"
 
 struct vertex2f
@@ -27,7 +55,6 @@ struct vertex_shader_consts
 
 struct fragment_shader_consts
 {
-   struct vertex4f bias;
    float matrix[16];
 };
 
@@ -49,94 +76,6 @@ static const struct vertex2f surface_verts[4] =
  */
 static const struct vertex2f *surface_texcoords = surface_verts;
 
-/*
- * Identity color conversion constants, for debugging
- */
-static const struct fragment_shader_consts identity =
-{
-   {
-      0.0f, 0.0f, 0.0f, 0.0f
-   },
-   {
-      1.0f, 0.0f, 0.0f, 0.0f,
-      0.0f, 1.0f, 0.0f, 0.0f,
-      0.0f, 0.0f, 1.0f, 0.0f,
-      0.0f, 0.0f, 0.0f, 1.0f
-   }
-};
-
-/*
- * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
- * Y is in [16,235], Cb and Cr are in [16,240]
- * R, G, and B are in [16,235]
- */
-static const struct fragment_shader_consts bt_601 =
-{
-   {
-      0.0f, 0.501960784f, 0.501960784f,        0.0f
-   },
-   {
-      1.0f, 0.0f,   1.371f,   0.0f,
-      1.0f, -0.336f, -0.698f, 0.0f,
-      1.0f, 1.732f, 0.0f,     0.0f,
-      0.0f, 0.0f,   0.0f,     1.0f
-   }
-};
-
-/*
- * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
- * Y is in [16,235], Cb and Cr are in [16,240]
- * R, G, and B are in [0,255]
- */
-static const struct fragment_shader_consts bt_601_full =
-{
-   {
-      0.062745098f, 0.501960784f, 0.501960784f,        0.0f
-   },
-   {
-      1.164f, 0.0f,    1.596f,  0.0f,
-      1.164f, -0.391f, -0.813f, 0.0f,
-      1.164f, 2.018f,  0.0f,    0.0f,
-      0.0f,   0.0f,    0.0f,    1.0f
-   }
-};
-
-/*
- * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
- * Y is in [16,235], Cb and Cr are in [16,240]
- * R, G, and B are in [16,235]
- */
-static const struct fragment_shader_consts bt_709 =
-{
-   {
-      0.0f, 0.501960784f, 0.501960784f,        0.0f
-   },
-   {
-      1.0f, 0.0f,    1.540f,  0.0f,
-      1.0f, -0.183f, -0.459f, 0.0f,
-      1.0f, 1.816f,  0.0f,    0.0f,
-      0.0f, 0.0f,    0.0f,    1.0f
-   }
-};
-
-/*
- * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
- * Y is in [16,235], Cb and Cr are in [16,240]
- * R, G, and B are in [0,255]
- */
-const struct fragment_shader_consts bt_709_full =
-{
-   {
-      0.062745098f, 0.501960784f, 0.501960784f,        0.0f
-   },
-   {
-      1.164f, 0.0f,    1.793f,  0.0f,
-      1.164f, -0.213f, -0.534f,        0.0f,
-      1.164f, 2.115f,  0.0f,    0.0f,
-      0.0f,   0.0f,    0.0f,    1.0f
-   }
-};
-
 static void
 create_vert_shader(struct vl_compositor *c)
 {
@@ -156,12 +95,11 @@ create_vert_shader(struct vl_compositor *c)
    assert(c);
 
    tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header*)&tokens[1];
+   header = (struct tgsi_header*)&tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
+   *(struct tgsi_processor*)&tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
 
-   ti = 3;
+   ti = 2;
 
    /*
     * decl i0             ; Vertex pos
@@ -233,22 +171,20 @@ create_frag_shader(struct vl_compositor *c)
    assert(c);
 
    tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header*)&tokens[1];
+   header = (struct tgsi_header*)&tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
+   *(struct tgsi_processor*)&tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
 
-   ti = 3;
+   ti = 2;
 
    /* decl i0             ; Texcoords for s0 */
    decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR);
    ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
 
    /*
-    * decl c0             ; Bias vector for CSC
-    * decl c1-c4          ; CSC matrix c1-c4
+    * decl c0-c3          ; CSC matrix c0-c3
     */
-   decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4);
+   decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3);
    ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
 
    /* decl o0             ; Fragment color */
@@ -267,18 +203,15 @@ create_frag_shader(struct vl_compositor *c)
    inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0);
    ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
-   /* sub t0, t0, c0      ; Subtract bias vector from pixel */
-   inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0);
-   ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
    /*
-    * dp4 o0.x, t0, c1    ; Multiply pixel by the color conversion matrix
-    * dp4 o0.y, t0, c2
-    * dp4 o0.z, t0, c3
+    * dp4 o0.x, t0, c0    ; Multiply pixel by the color conversion matrix
+    * dp4 o0.y, t0, c1
+    * dp4 o0.z, t0, c2
+    * dp4 o0.w, t0, c3
     */
-   for (i = 0; i < 3; ++i) {
-      inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1);
-      inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
+   for (i = 0; i < 4; ++i) {
+      inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i);
+      inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X << i;
       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
    }
 
@@ -312,7 +245,6 @@ init_pipe_state(struct vl_compositor *c)
    sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
    sampler.compare_func = PIPE_FUNC_ALWAYS;
    sampler.normalized_coords = 1;
-   /*sampler.prefilter = ;*/
    /*sampler.lod_bias = ;*/
    /*sampler.min_lod = ;*/
    /*sampler.max_lod = ;*/
@@ -352,6 +284,8 @@ static void cleanup_shaders(struct vl_compositor *c)
 static bool
 init_buffers(struct vl_compositor *c)
 {
+   struct fragment_shader_consts fsc;
+
    assert(c);
        
    /*
@@ -381,6 +315,7 @@ init_buffers(struct vl_compositor *c)
    pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[0].buffer);
 
    c->vertex_elems[0].src_offset = 0;
+   c->vertex_elems[0].instance_divisor = 0;
    c->vertex_elems[0].vertex_buffer_index = 0;
    c->vertex_elems[0].nr_components = 2;
    c->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
@@ -410,6 +345,7 @@ init_buffers(struct vl_compositor *c)
    pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[1].buffer);
 
    c->vertex_elems[1].src_offset = 0;
+   c->vertex_elems[1].instance_divisor = 0;
    c->vertex_elems[1].vertex_buffer_index = 1;
    c->vertex_elems[1].nr_components = 2;
    c->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
@@ -418,7 +354,7 @@ init_buffers(struct vl_compositor *c)
     * Create our vertex shader's constant buffer
     * Const buffer contains scaling and translation vectors
     */
-   c->vs_const_buf.buffer = pipe_buffer_create
+   c->vs_const_buf = pipe_buffer_create
    (
       c->pipe->screen,
       1,
@@ -430,7 +366,7 @@ init_buffers(struct vl_compositor *c)
     * Create our fragment shader's constant buffer
     * Const buffer contains the color conversion matrix and bias vectors
     */
-   c->fs_const_buf.buffer = pipe_buffer_create
+   c->fs_const_buf = pipe_buffer_create
    (
       c->pipe->screen,
       1,
@@ -438,18 +374,9 @@ init_buffers(struct vl_compositor *c)
       sizeof(struct fragment_shader_consts)
    );
 
-   /*
-    * TODO: Refactor this into a seperate function,
-    * allow changing the CSC matrix at runtime to switch between regular & full versions
-    */
-   memcpy
-   (
-      pipe_buffer_map(c->pipe->screen, c->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
-      &bt_601_full,
-      sizeof(struct fragment_shader_consts)
-   );
+   vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, fsc.matrix);
 
-   pipe_buffer_unmap(c->pipe->screen, c->fs_const_buf.buffer);
+   vl_compositor_set_csc_matrix(c, fsc.matrix);
 
    return true;
 }
@@ -464,8 +391,8 @@ cleanup_buffers(struct vl_compositor *c)
    for (i = 0; i < 2; ++i)
       pipe_buffer_reference(&c->vertex_bufs[i].buffer, NULL);
 
-   pipe_buffer_reference(&c->vs_const_buf.buffer, NULL);
-   pipe_buffer_reference(&c->fs_const_buf.buffer, NULL);
+   pipe_buffer_reference(&c->vs_const_buf, NULL);
+   pipe_buffer_reference(&c->fs_const_buf, NULL);
 }
 
 bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe)
@@ -527,8 +454,8 @@ void vl_compositor_render(struct vl_compositor          *compositor,
    assert(dst_area);
    assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME);
 
-   compositor->fb_state.width = dst_surface->width[0];
-   compositor->fb_state.height = dst_surface->height[0];
+   compositor->fb_state.width = dst_surface->width0;
+   compositor->fb_state.height = dst_surface->height0;
    compositor->fb_state.cbufs[0] = compositor->pipe->screen->get_tex_surface
    (
       compositor->pipe->screen,
@@ -545,21 +472,25 @@ void vl_compositor_render(struct vl_compositor          *compositor,
    compositor->viewport.translate[2] = 0;
    compositor->viewport.translate[3] = 0;
 
+   compositor->scissor.maxx = compositor->fb_state.width;
+   compositor->scissor.maxy = compositor->fb_state.height;
+
    compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state);
    compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport);
-   compositor->pipe->bind_sampler_states(compositor->pipe, 1, &compositor->sampler);
-   compositor->pipe->set_sampler_textures(compositor->pipe, 1, &src_surface);
+   compositor->pipe->set_scissor_state(compositor->pipe, &compositor->scissor);
+   compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler);
+   compositor->pipe->set_fragment_sampler_textures(compositor->pipe, 1, &src_surface);
    compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
    compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader);
    compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs);
    compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems);
-   compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, &compositor->vs_const_buf);
-   compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, &compositor->fs_const_buf);
+   compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, compositor->vs_const_buf);
+   compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf);
 
    vs_consts = pipe_buffer_map
    (
       compositor->pipe->screen,
-      compositor->vs_const_buf.buffer,
+      compositor->vs_const_buf,
       PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
    );
 
@@ -572,19 +503,33 @@ void vl_compositor_render(struct vl_compositor          *compositor,
    vs_consts->dst_trans.z = 0;
    vs_consts->dst_trans.w = 0;
 
-   vs_consts->src_scale.x = src_area->w / (float)src_surface->width[0];
-   vs_consts->src_scale.y = src_area->h / (float)src_surface->height[0];
+   vs_consts->src_scale.x = src_area->w / (float)src_surface->width0;
+   vs_consts->src_scale.y = src_area->h / (float)src_surface->height0;
    vs_consts->src_scale.z = 1;
    vs_consts->src_scale.w = 1;
-   vs_consts->src_trans.x = src_area->x / (float)src_surface->width[0];
-   vs_consts->src_trans.y = src_area->y / (float)src_surface->height[0];
+   vs_consts->src_trans.x = src_area->x / (float)src_surface->width0;
+   vs_consts->src_trans.y = src_area->y / (float)src_surface->height0;
    vs_consts->src_trans.z = 0;
    vs_consts->src_trans.w = 0;
 
-   pipe_buffer_unmap(compositor->pipe->screen, compositor->vs_const_buf.buffer);
+   pipe_buffer_unmap(compositor->pipe->screen, compositor->vs_const_buf);
 
    compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
    compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence);
 
    pipe_surface_reference(&compositor->fb_state.cbufs[0], NULL);
 }
+
+void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat)
+{
+   assert(compositor);
+
+   memcpy
+   (
+      pipe_buffer_map(compositor->pipe->screen, compositor->fs_const_buf, PIPE_BUFFER_USAGE_CPU_WRITE),
+      mat,
+      sizeof(struct fragment_shader_consts)
+   );
+
+   pipe_buffer_unmap(compositor->pipe->screen, compositor->fs_const_buf);
+}