g3dvl: Round surfaces up to POT, use src rect when outputting surfaces.
authorYounes Manton <younes.m@gmail.com>
Fri, 4 Jul 2008 00:05:32 +0000 (20:05 -0400)
committerYounes Manton <younes.m@gmail.com>
Mon, 7 Jul 2008 02:05:07 +0000 (22:05 -0400)
src/gallium/state_trackers/g3dvl/Makefile
src/gallium/state_trackers/g3dvl/vl_context.c
src/gallium/state_trackers/g3dvl/vl_context.h
src/gallium/state_trackers/g3dvl/vl_surface.c
src/gallium/state_trackers/g3dvl/vl_types.h
src/gallium/state_trackers/g3dvl/vl_util.c [new file with mode: 0644]
src/gallium/state_trackers/g3dvl/vl_util.h [new file with mode: 0644]

index bd46d004e23bd49ec388d9978de3b2654e97892c..50e3c843b55c00b87654aba1518afbf05732901c 100644 (file)
@@ -1,5 +1,5 @@
 TARGET         = libg3dvl.a
-OBJECTS                = vl_context.o vl_data.o vl_surface.o vl_shader_build.o
+OBJECTS                = vl_context.o vl_data.o vl_surface.o vl_shader_build.o vl_util.o
 GALLIUMDIR     = ../..
 
 CFLAGS         += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary
index bd8743dc9a5dbf3fca93dfcbe2eeedad3fe2797c..58971bd7c792406755028762f7de8442075141e1 100644 (file)
@@ -11,6 +11,7 @@
 #include <tgsi/util/tgsi_build.h>
 #include "vl_shader_build.h"
 #include "vl_data.h"
+#include "vl_util.h"
 
 static int vlInitIDCT(struct VL_CONTEXT *context)
 {
@@ -1357,8 +1358,9 @@ static int vlInitMC(struct VL_CONTEXT *context)
        
        pipe = context->pipe;
        
-       context->states.mc.viewport.scale[0] = context->video_width;
-       context->states.mc.viewport.scale[1] = context->video_height;
+       /* For MC we render to textures, which are rounded up to nearest POT */
+       context->states.mc.viewport.scale[0] = vlRoundUpPOT(context->video_width);
+       context->states.mc.viewport.scale[1] = vlRoundUpPOT(context->video_height);
        context->states.mc.viewport.scale[2] = 1;
        context->states.mc.viewport.scale[3] = 1;
        context->states.mc.viewport.translate[0] = 0;
@@ -1512,6 +1514,13 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context)
                decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
        }
+       
+       /*
+        * decl c0              ; Scaling vector to scale texcoord rect to source size
+        * decl c1              ; Translation vector to move texcoord rect into position
+        */
+       decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1);
+       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
 
        /*
         * decl o0              ; Vertex pos
@@ -1522,16 +1531,18 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context)
                decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
        }
+       
+       /* mov o0, i0           ; Move pos in to pos out */
+       inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, 0);
+       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+       
+       /* mul t0, i1, c0       ; Scale unit texcoord rect to source size */
+       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 1, TGSI_FILE_CONSTANT, 0);
+       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
-       /*
-        * mov o0, i0           ; Move pos in to pos out
-        * mov o1, i1           ; Move input texcoords to output
-        */
-       for (i = 0; i < 2; i++)
-       {
-               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
-               ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-       }
+       /* add o1, t0, c1       ; Translate texcoord rect into position */
+       inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1);
+       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /* end */
        inst = vl_end();
@@ -1693,6 +1704,19 @@ static int vlCreateDataBufsCSC(struct VL_CONTEXT *context)
        context->states.csc.vertex_buf_elems[1].nr_components = 2;
        context->states.csc.vertex_buf_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
        
+       /*
+       Create our vertex shader's constant buffer
+       Const buffer contains scaling and translation vectors
+       */
+       context->states.csc.vs_const_buf.size = sizeof(struct VL_CSC_VS_CONSTS);
+       context->states.csc.vs_const_buf.buffer = pipe->winsys->buffer_create
+       (
+               pipe->winsys,
+               1,
+               PIPE_BUFFER_USAGE_CONSTANT,
+               context->states.csc.vs_const_buf.size
+       );
+       
        /*
        Create our fragment shader's constant buffer
        Const buffer contains the color conversion matrix and bias vectors
@@ -1776,6 +1800,7 @@ static int vlDestroyCSC(struct VL_CONTEXT *context)
        context->pipe->delete_fs_state(context->pipe, context->states.csc.fragment_shader);
        context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.csc.vertex_bufs[0].buffer);
        context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.csc.vertex_bufs[1].buffer);
+       context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.csc.vs_const_buf.buffer);
        context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.csc.fs_const_buf.buffer);
        
        return 0;
@@ -1986,6 +2011,7 @@ int vlEndRender(struct VL_CONTEXT *context)
        pipe->bind_fs_state(pipe, context->states.csc.fragment_shader);
        pipe->set_vertex_buffers(pipe, 2, context->states.csc.vertex_bufs);
        pipe->set_vertex_elements(pipe, 2, context->states.csc.vertex_buf_elems);
+       pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &context->states.csc.vs_const_buf);
        pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &context->states.csc.fs_const_buf);
        
        return 0;
index 8a1231807341c95481e0c58c3a8edb0520de3792..9ebda21a1cc2c9877bf3befa3a21f0720fcff9eb 100644 (file)
@@ -49,7 +49,7 @@ struct VL_CONTEXT
                        struct pipe_shader_state                *vertex_shader, *fragment_shader;
                        struct pipe_vertex_buffer               vertex_bufs[2];
                        struct pipe_vertex_element              vertex_buf_elems[2];
-                       struct pipe_constant_buffer             fs_const_buf;
+                       struct pipe_constant_buffer             vs_const_buf, fs_const_buf;
                } csc;
        } states;
 };
index 68313cc7505932f08265639c0c417e2422564499..13f7301f07bbdba39a50dcd652247d8915013974 100644 (file)
@@ -7,6 +7,7 @@
 #include <pipe/p_inlines.h>
 #include "vl_context.h"
 #include "vl_defs.h"
+#include "vl_util.h"
 
 static int vlGrabFrameCodedFullBlock(short *src, short *dst, unsigned int dst_pitch)
 {
@@ -194,9 +195,6 @@ static int vlGrabBlocks
                pipe_surface_unmap(tex_surface);
        }
        
-       /* XXX: Texture cache is not invalidated when texture contents change */
-       context->pipe->flush(context->pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL);
-       
        return 0;
 }
 
@@ -214,8 +212,8 @@ int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface)
        sfc = calloc(1, sizeof(struct VL_SURFACE));
        
        sfc->context = context;
-       sfc->width = context->video_width;
-       sfc->height = context->video_height;
+       sfc->width = vlRoundUpPOT(context->video_width);
+       sfc->height = vlRoundUpPOT(context->video_height);
        sfc->format = context->video_format;
        
        memset(&template, 0, sizeof(struct pipe_texture));
@@ -227,6 +225,7 @@ int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface)
        template.depth[0] = 1;
        template.compressed = 0;
        pf_get_block(template.format, &template.block);
+       /* XXX: Needed? */
        template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET;
        
        sfc->texture = pipe->screen->texture_create(pipe->screen, &template);
@@ -517,6 +516,7 @@ int vlPutSurface
 {
        unsigned int            create_fb = 0;
        struct pipe_context     *pipe;
+       struct VL_CSC_VS_CONSTS *vs_consts;
        
        assert(surface);
        
@@ -568,9 +568,28 @@ int vlPutSurface
        
        vlEndRender(surface->context);
        
+       vs_consts = pipe->winsys->buffer_map
+       (
+               pipe->winsys,
+               surface->context->states.csc.vs_const_buf.buffer,
+               PIPE_BUFFER_USAGE_CPU_WRITE
+       );
+       
+       vs_consts->src_scale.x = srcw / (float)surface->width;
+       vs_consts->src_scale.y = srch / (float)surface->height;
+       vs_consts->src_scale.z = 1;
+       vs_consts->src_scale.w = 1;
+       vs_consts->src_trans.x = srcx / (float)surface->width;
+       vs_consts->src_trans.y = srcy / (float)surface->height;
+       vs_consts->src_trans.z = 0;
+       vs_consts->src_trans.w = 0;
+       
+       pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.csc.vs_const_buf.buffer);
+       
        pipe->set_sampler_textures(pipe, 1, &surface->texture);
        pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
        pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+       /* XXX: Need to take destx, desty into consideration */
        pipe->winsys->flush_frontbuffer
        (
                pipe->winsys,
index 97753699db6a1217e6e54b530ea743993932c715..4d210c9e0aa9e1c7357e8426f8edebd1a1f24bfb 100644 (file)
@@ -75,6 +75,12 @@ struct VL_MC_FS_CONSTS
        struct VL_VERTEX4F      y_divider;
 };
 
+struct VL_CSC_VS_CONSTS
+{
+       struct VL_VERTEX4F      src_scale;
+       struct VL_VERTEX4F      src_trans;
+};
+
 struct VL_CSC_FS_CONSTS
 {
        struct VL_VERTEX4F      bias;
diff --git a/src/gallium/state_trackers/g3dvl/vl_util.c b/src/gallium/state_trackers/g3dvl/vl_util.c
new file mode 100644 (file)
index 0000000..2421ae2
--- /dev/null
@@ -0,0 +1,17 @@
+#include "vl_util.h"
+#include <assert.h>
+
+unsigned int vlRoundUpPOT(unsigned int x)
+{
+       unsigned int i;
+       
+       assert(x > 0);
+       
+       --x;
+       
+       for (i = 1; i < sizeof(unsigned int) * 8; i <<= 1)
+               x |= x >> i;
+       
+       return x + 1;
+}
+
diff --git a/src/gallium/state_trackers/g3dvl/vl_util.h b/src/gallium/state_trackers/g3dvl/vl_util.h
new file mode 100644 (file)
index 0000000..e4b72c4
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef vl_util_h
+#define vl_util_h
+
+unsigned int vlRoundUpPOT(unsigned int x);
+
+#endif
+