draw: add viewport to varient state
authorKeith Whitwell <keith@tungstengraphics.com>
Wed, 21 May 2008 19:28:56 +0000 (20:28 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 23 May 2008 08:16:56 +0000 (09:16 +0100)
src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
src/gallium/auxiliary/draw/draw_vs.h
src/gallium/auxiliary/draw/draw_vs_aos.c
src/gallium/auxiliary/draw/draw_vs_aos.h
src/gallium/auxiliary/draw/draw_vs_sse.c
src/gallium/auxiliary/draw/draw_vs_varient.c

index 74945dcfe96df90d6922f8d764cb02bc0a49d0a6..984fbb676717fd7609ac864d7e02c64e2b25b87d 100644 (file)
@@ -95,10 +95,14 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
    
 
 
+   fse->key.output_stride = vinfo->size * 4;
    fse->key.nr_elements = MAX2(num_vs_outputs,     /* outputs - translate to hw format */
                                num_vs_inputs);     /* inputs - fetch from api format */
 
-   fse->key.output_stride = vinfo->size * 4;
+   fse->key.viewport = 1;
+   fse->key.clip = 0;
+   fse->key.pad = 0;
+
    memset(fse->key.element, 0, 
           fse->key.nr_elements * sizeof(fse->key.element[0]));
 
@@ -211,6 +215,9 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
    fse->active->set_constants( fse->active,
                                (const float (*)[4])draw->pt.user.constants );
 
+   fse->active->set_viewport( fse->active,
+                              &draw->viewport );
+
    //return TRUE;
 }
 
index 5a8d0da06d69c012c55c802c085893ae090b71d7..ff3e19b2a880266310283e572dca92ae45a141ba 100644 (file)
@@ -58,7 +58,10 @@ struct draw_vs_element {
 
 struct draw_vs_varient_key {
    unsigned output_stride;
-   unsigned nr_elements;
+   unsigned nr_elements:16;
+   unsigned viewport:1;
+   unsigned clip:1;
+   unsigned pad:14;
    struct draw_vs_element element[PIPE_MAX_ATTRIBS];
 };
 
@@ -88,6 +91,9 @@ struct draw_vs_varient {
    void (*set_constants)( struct draw_vs_varient *,
                           const float (*constants)[4] );
 
+   void (*set_viewport)( struct draw_vs_varient *,
+                         const struct pipe_viewport_state * );
+
    void (PIPE_CDECL *run_linear)( struct draw_vs_varient *shader,
                                   unsigned start,
                                   unsigned count,
index 620f5e3592f3365064f97d3da5f3601a77c5d067..b8e66e8b78ca9f49a3223df96ba373df2b173132 100644 (file)
@@ -1401,6 +1401,37 @@ emit_instruction( struct aos_compilation *cp,
    }
 }
 
+
+static boolean emit_viewport( struct aos_compilation *cp )
+{
+   struct x86_reg pos = aos_get_shader_reg(cp, 
+                                           TGSI_FILE_OUTPUT, 
+                                           0);
+
+   struct x86_reg scale = x86_make_disp(cp->machine_EDX, 
+                                        Offset(struct aos_machine, scale));
+
+   struct x86_reg translate = x86_make_disp(cp->machine_EDX, 
+                                        Offset(struct aos_machine, translate));
+
+   if (pos.file != file_XMM) {
+      struct x86_reg dst = aos_get_xmm_reg(cp);
+      sse_movups(cp->func, dst, pos);
+      pos = dst;
+   }
+
+   sse_mulps(cp->func, pos, scale);
+   sse_addps(cp->func, pos, translate);
+
+   aos_adopt_xmm_reg( cp,
+                      pos,
+                      TGSI_FILE_OUTPUT,
+                      0,
+                      TRUE );
+   return TRUE;
+}
+
+
 static boolean note_immediate( struct aos_compilation *cp,
                                struct tgsi_full_immediate *imm )
 {
@@ -1540,6 +1571,10 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient,
       if (cp.error)
          goto fail;
 
+      if (cp.vaos->base.key.viewport) {
+         emit_viewport(&cp);
+      }
+
       /* Emit output...  TODO: do this eagerly after the last write to a
        * given output.
        */
@@ -1665,11 +1700,25 @@ static void vaos_set_constants( struct draw_vs_varient *varient,
 }
 
 
+static void vaos_set_viewport( struct draw_vs_varient *varient,
+                               const struct pipe_viewport_state *viewport )
+{
+   struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
+
+   memcpy(vaos->machine->scale, viewport->scale, 4 * sizeof(float));
+   memcpy(vaos->machine->translate, viewport->translate, 4 * sizeof(float));
+}
+
+
+
 static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs,
                                                  const struct draw_vs_varient_key *key )
 {
    struct draw_vs_varient_aos_sse *vaos = CALLOC_STRUCT(draw_vs_varient_aos_sse);
 
+   if (key->clip)
+      return NULL;
+
    if (!vaos)
       goto fail;
    
@@ -1677,6 +1726,7 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs,
    vaos->base.vs = vs;
    vaos->base.set_input = vaos_set_buffer;
    vaos->base.set_constants = vaos_set_constants;
+   vaos->base.set_viewport = vaos_set_viewport;
    vaos->base.destroy = vaos_destroy;
    vaos->base.run_linear = vaos_run_linear;
    vaos->base.run_elts = vaos_run_elts;
index 1d8a055a904cbbabf24b35a6944f791192a58323..16fef6451c4c09e1795426a45cb015f960e8ed04 100644 (file)
@@ -68,8 +68,13 @@ struct aos_machine {
    float immediate[MAX_IMMEDIATES][4]; /* fixme -- should just be a pointer */
    float internal [MAX_INTERNALS ][4];
 
-   unsigned fpu_round_nearest;
-   unsigned fpu_round_neg_inf;
+   float scale[4];              /* viewport */
+   float translate[4];          /* viewport */
+
+   ushort fpu_round_nearest;
+   ushort fpu_round_neg_inf;
+   ushort fpu_restore;
+   ushort fpucntl;              /* one of FPU_* above */
 
    struct {
       const void *input_ptr;
index 0581c3042f7e56b20e849682519ea34c9ac27f85..7781782ae84b483a2deb1a1c399a12ed1fc7fa65 100644 (file)
@@ -156,8 +156,8 @@ draw_create_vs_sse(struct draw_context *draw,
    tgsi_scan_shader(templ->tokens, &vs->base.info);
 
    vs->base.draw = draw;
-   vs->base.create_varient = draw_vs_varient_generic;
-//   vs->base.create_varient = draw_vs_varient_aos_sse;
+   vs->base.create_varient = draw_vs_varient_aos_sse;
+//   vs->base.create_varient = draw_vs_varient_generic;
    vs->base.prepare = vs_sse_prepare;
    vs->base.run_linear = vs_sse_run_linear;
    vs->base.delete = vs_sse_delete;
index d27b0f61874773aad8cc7a30e3d3309a373747b4..f6f621a74816f71bde58be9cf74e8c7d693f5dce 100644 (file)
@@ -167,6 +167,12 @@ static void vsvg_run_linear( struct draw_vs_varient *varient,
 
 
 
+
+static void vsvg_set_viewport( struct draw_vs_varient *varient,
+                               const struct pipe_viewport_state *viewport )
+{
+}
+
 static void vsvg_destroy( struct draw_vs_varient *varient )
 {
    FREE(varient);
@@ -179,6 +185,9 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs,
    unsigned i;
    struct translate_key fetch, emit;
 
+   if (key->viewport || key->clip)
+      return NULL;
+
    struct draw_vs_varient_generic *vsvg = CALLOC_STRUCT( draw_vs_varient_generic );
    if (vsvg == NULL)
       return NULL;
@@ -187,6 +196,7 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs,
    vsvg->base.vs = vs;
    vsvg->base.set_input     = vsvg_set_input;
    vsvg->base.set_constants = vsvg_set_constants;
+   vsvg->base.set_viewport  = vsvg_set_viewport;
    vsvg->base.run_elts      = vsvg_run_elts;
    vsvg->base.run_linear    = vsvg_run_linear;
    vsvg->base.destroy       = vsvg_destroy;