diff options
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 11 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_gs.c | 13 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_gs.h | 1 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 7 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 4 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 1 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_vs.c | 16 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_vs.h | 3 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_vs_exec.c | 8 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_vs_llvm.c | 1 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_vs_varient.c | 6 | ||||
| -rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 53 | ||||
| -rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 10 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_context.h | 1 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_quad_fs.c | 7 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_state_fs.c | 2 | 
16 files changed, 117 insertions, 27 deletions
| diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index c127f74188..995b675b9a 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -288,12 +288,19 @@ draw_set_mapped_constant_buffer(struct draw_context *draw,                  shader_type == PIPE_SHADER_GEOMETRY);     debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS); -   if (shader_type == PIPE_SHADER_VERTEX) { +   switch (shader_type) { +   case PIPE_SHADER_VERTEX:        draw->pt.user.vs_constants[slot] = buffer; +      draw->pt.user.vs_constants_size[slot] = size;        draw_vs_set_constants(draw, slot, buffer, size); -   } else if (shader_type == PIPE_SHADER_GEOMETRY) { +      break; +   case PIPE_SHADER_GEOMETRY:        draw->pt.user.gs_constants[slot] = buffer; +      draw->pt.user.gs_constants_size[slot] = size;        draw_gs_set_constants(draw, slot, buffer, size); +      break; +   default: +      assert(0 && "invalid shader type in draw_set_mapped_constant_buffer");     }  } diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index 0c590f936b..a36321d910 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -75,7 +75,7 @@ draw_gs_set_constants(struct draw_context *draw,                        const void *constants,                        unsigned size)  { -   /* noop */ +   debug_printf("draw_gs_set_constants() not implemented yet!\n");  } @@ -394,8 +394,13 @@ static void gs_tri_adj(struct draw_geometry_shader *shader,     const ushort *elts = input_prims->elts;  #include "draw_gs_tmp.h" + +/** + * Execute geometry shader using TGSI interpreter. + */  int draw_geometry_shader_run(struct draw_geometry_shader *shader,                               const void *constants[PIPE_MAX_CONSTANT_BUFFERS],  +                             const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],                                const struct draw_vertex_info *input_verts,                               const struct draw_prim_info *input_prim,                               struct draw_vertex_info *output_verts, @@ -405,7 +410,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,     unsigned input_stride = input_verts->vertex_size;     unsigned vertex_size = input_verts->vertex_size;     struct tgsi_exec_machine *machine = shader->machine; -   unsigned int i;     unsigned num_input_verts = input_prim->linear ?                                input_verts->count :                                input_prim->count; @@ -447,9 +451,8 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,     }     shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned)); -   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { -      machine->Consts[i] = constants[i]; -   } +   tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, +                                  constants, constants_size);     if (input_prim->linear)        gs_run(shader, input_prim, input_verts, diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h index 06f4b822a2..67bc1aa73f 100644 --- a/src/gallium/auxiliary/draw/draw_gs.h +++ b/src/gallium/auxiliary/draw/draw_gs.h @@ -73,6 +73,7 @@ struct draw_geometry_shader {   */  int draw_geometry_shader_run(struct draw_geometry_shader *shader,                               const void *constants[PIPE_MAX_CONSTANT_BUFFERS],  +                             const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],                                const struct draw_vertex_info *input_verts,                               const struct draw_prim_info *input_prim,                               struct draw_vertex_info *output_verts, diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 058aeedc17..397d4bf653 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -163,9 +163,11 @@ struct draw_context           /** vertex arrays */           const void *vbuffer[PIPE_MAX_ATTRIBS]; -         /** constant buffer (for vertex/geometry shader) */ +         /** constant buffers (for vertex/geometry shader) */           const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS]; +         unsigned vs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];           const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS]; +         unsigned gs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];        } user;        boolean test_fse;         /* enable FSE even though its not correct (eg for softpipe) */ @@ -198,6 +200,7 @@ struct draw_context     struct pipe_viewport_state viewport;     boolean identity_viewport; +   /** Vertex shader state */     struct {        struct draw_vertex_shader *vertex_shader;        uint num_vs_outputs;  /**< convenience, from vertex_shader */ @@ -227,6 +230,7 @@ struct draw_context        struct translate_cache *emit_cache;     } vs; +   /** Geometry shader state */     struct {        struct draw_geometry_shader *geometry_shader;        uint num_gs_outputs;  /**< convenience, from geometry_shader */ @@ -239,6 +243,7 @@ struct draw_context        struct tgsi_sampler **samplers;     } gs; +   /** Stream output (vertex feedback) state */     struct {        struct pipe_stream_output_state state;        void *buffers[PIPE_MAX_SO_BUFFERS]; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 121dfc414a..5b16c3788e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -176,6 +176,7 @@ static void emit(struct pt_emit *emit,  static void draw_vertex_shader_run(struct draw_vertex_shader *vshader,                                     const void *constants[PIPE_MAX_CONSTANT_BUFFERS],  +                                   unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],                                     const struct draw_vertex_info *input_verts,                                     struct draw_vertex_info *output_verts )  { @@ -190,6 +191,7 @@ static void draw_vertex_shader_run(struct draw_vertex_shader *vshader,                         (const float (*)[4])input_verts->verts->data,                         (      float (*)[4])output_verts->verts->data,                         constants, +                       const_size,                         input_verts->count,                         input_verts->vertex_size,                         input_verts->vertex_size); @@ -236,6 +238,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,     if (fpme->opt & PT_SHADE) {        draw_vertex_shader_run(vshader,                               draw->pt.user.vs_constants, +                             draw->pt.user.vs_constants_size,                               vert_info,                               &vs_vert_info); @@ -246,6 +249,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,     if ((fpme->opt & PT_SHADE) && gshader) {        draw_geometry_shader_run(gshader,                                 draw->pt.user.gs_constants, +                               draw->pt.user.gs_constants_size,                                 vert_info,                                 prim_info,                                 &gs_vert_info, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index 5c9db12086..4b99bee86a 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -254,6 +254,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,     if ((opt & PT_SHADE) && gshader) {        draw_geometry_shader_run(gshader,                                 draw->pt.user.gs_constants, +                               draw->pt.user.gs_constants_size,                                 vert_info,                                 prim_info,                                 &gs_vert_info, diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 57ea63fc06..fb665b08ff 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -48,18 +48,30 @@  DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE) + +/** + * Set a vertex shader constant buffer. + * \param slot  which constant buffer in [0, PIPE_MAX_CONSTANT_BUFFERS-1] + * \param constants  the mapped buffer + * \param size  size of buffer in bytes + */  void  draw_vs_set_constants(struct draw_context *draw,                        unsigned slot,                        const void *constants,                        unsigned size)  { -   if (((uintptr_t)constants) & 0xf) { +   const int alignment = 16; + +   /* check if buffer is 16-byte aligned */ +   if (((uintptr_t)constants) & (alignment - 1)) { +      /* if not, copy the constants into a new, 16-byte aligned buffer */        if (size > draw->vs.const_storage_size[slot]) {           if (draw->vs.aligned_constant_storage[slot]) {              align_free((void *)draw->vs.aligned_constant_storage[slot]);           } -         draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16); +         draw->vs.aligned_constant_storage[slot] = +            align_malloc(size, alignment);        }        assert(constants);        memcpy((void *)draw->vs.aligned_constant_storage[slot], diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index a731994523..f9a038788f 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -133,7 +133,8 @@ struct draw_vertex_shader {     void (*run_linear)( struct draw_vertex_shader *shader,  		       const float (*input)[4],  		       float (*output)[4], -                      const void *constants[PIPE_MAX_CONSTANT_BUFFERS], +                       const void *constants[PIPE_MAX_CONSTANT_BUFFERS], +                       const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],  		       unsigned count,  		       unsigned input_stride,  		       unsigned output_stride ); diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index bc34d390da..dab3eb1ca8 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -85,7 +85,8 @@ static void  vs_exec_run_linear( struct draw_vertex_shader *shader,  		    const float (*input)[4],  		    float (*output)[4], -                   const void *constants[PIPE_MAX_CONSTANT_BUFFERS], +                    const void *constants[PIPE_MAX_CONSTANT_BUFFERS], +                    const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],  		    unsigned count,  		    unsigned input_stride,  		    unsigned output_stride ) @@ -95,9 +96,8 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,     unsigned int i, j;     unsigned slot; -   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { -      machine->Consts[i] = constants[i]; -   } +   tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, +                                  constants, const_size);     for (i = 0; i < count; i += MAX_TGSI_VERTICES) {        unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 6c13df7913..d13ad24fff 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -49,6 +49,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *shader,  		    const float (*input)[4],  		    float (*output)[4],                      const void *constants[PIPE_MAX_CONSTANT_BUFFERS], +                    const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],  		    unsigned count,  		    unsigned input_stride,  		    unsigned output_stride ) diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 6eb26927f2..eacd160187 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -149,7 +149,8 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient,     vsvg->base.vs->run_linear( vsvg->base.vs,                                 temp_buffer,                                temp_buffer, -                             vsvg->base.vs->draw->pt.user.vs_constants, +                              vsvg->base.vs->draw->pt.user.vs_constants, +                              vsvg->base.vs->draw->pt.user.vs_constants_size,                                count,                                temp_vertex_stride,                                 temp_vertex_stride); @@ -214,7 +215,8 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient,     vsvg->base.vs->run_linear( vsvg->base.vs,                                 temp_buffer,                                temp_buffer, -                             vsvg->base.vs->draw->pt.user.vs_constants, +                              vsvg->base.vs->draw->pt.user.vs_constants, +                              vsvg->base.vs->draw->pt.user.vs_constants_size,                                count,                                temp_vertex_stride,                                 temp_vertex_stride); diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 5275faa5e2..6fcbf4f212 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -557,6 +557,23 @@ print_temp(const struct tgsi_exec_machine *mach, uint index)  #endif +void +tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach, +                               unsigned num_bufs, +                               const void **bufs, +                               const unsigned *buf_sizes) +{ +   unsigned i; + +   for (i = 0; i < num_bufs; i++) { +      mach->Consts[i] = bufs[i]; +      mach->ConstsSize[i] = buf_sizes[i]; +   } +} + + + +  /**   * Check if there's a potential src/dst register data dependency when   * using SOA execution. @@ -632,6 +649,11 @@ tgsi_exec_machine_bind_shader(     util_init_math(); +   if (numSamplers) { +      assert(samplers); +      assert(samplers[0]); +   } +     mach->Tokens = tokens;     mach->Samplers = samplers; @@ -1040,6 +1062,8 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,  {     uint i; +   assert(swizzle < 4); +     switch (file) {     case TGSI_FILE_CONSTANT:        for (i = 0; i < QUAD_SIZE; i++) { @@ -1049,9 +1073,23 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,           if (index->i[i] < 0) {              chan->u[i] = 0;           } else { -            const uint *p = (const uint *)mach->Consts[index2D->i[i]]; - -            chan->u[i] = p[index->i[i] * 4 + swizzle]; +            /* NOTE: copying the const value as a uint instead of float */ +            const uint constbuf = index2D->i[i]; +            const uint *buf = (const uint *)mach->Consts[constbuf]; +            const int pos = index->i[i] * 4 + swizzle; +            /* const buffer bounds check */ +            if (pos < 0 || pos >= mach->ConstsSize[constbuf]) { +               if (0) { +                  /* Debug: print warning */ +                  static int count = 0; +                  if (count++ < 100) +                     debug_printf("TGSI Exec: const buffer index %d" +                                  " out of bounds\n", pos); +               } +               chan->u[i] = 0; +            } +            else +               chan->u[i] = buf[pos];           }        }        break; @@ -1065,9 +1103,10 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,                           index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i],                           index2D->i[i], index->i[i]);                           }*/ -         chan->u[i] = mach->Inputs[index2D->i[i] * -                                   TGSI_EXEC_MAX_INPUT_ATTRIBS + -                                   index->i[i]].xyzw[swizzle].u[i]; +         int pos = index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]; +         assert(pos >= 0); +         assert(pos < Elements(mach->Inputs)); +         chan->u[i] = mach->Inputs[pos].xyzw[swizzle].u[i];        }        break; @@ -1187,7 +1226,7 @@ fetch_source(const struct tgsi_exec_machine *mach,        index2.i[1] =        index2.i[2] =        index2.i[3] = reg->Indirect.Index; - +      assert(reg->Indirect.File == TGSI_FILE_ADDRESS);        /* get current value of address register[swizzle] */        swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, CHAN_X );        fetch_src_file_channel(mach, diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index ccf80ca6fd..6dee362d58 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -253,7 +253,10 @@ struct tgsi_exec_machine     struct tgsi_sampler           **Samplers;     unsigned                      ImmLimit; +     const void *Consts[PIPE_MAX_CONSTANT_BUFFERS]; +   unsigned ConstsSize[PIPE_MAX_CONSTANT_BUFFERS]; +     const struct tgsi_token       *Tokens;   /**< Declarations, instructions */     unsigned                      Processor; /**< TGSI_PROCESSOR_x */ @@ -367,6 +370,13 @@ tgsi_set_exec_mask(struct tgsi_exec_machine *mach,  } +extern void +tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach, +                               unsigned num_bufs, +                               const void **bufs, +                               const unsigned *buf_sizes); + +  #if defined __cplusplus  } /* extern "C" */  #endif diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index c5f53cfa61..9361a3df09 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -112,6 +112,7 @@ struct softpipe_context {     /** Mapped constant buffers */     const void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; +   unsigned const_buffer_size[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];     /** Vertex format */     struct vertex_info vertex_info; diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index d240bcbf3b..90f4787d59 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -111,9 +111,10 @@ shade_quads(struct quad_stage *qs,     struct tgsi_exec_machine *machine = softpipe->fs_machine;     unsigned i, nr_quads = 0; -   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { -      machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i]; -   } +   tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, +                         softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], +                         softpipe->const_buffer_size[PIPE_SHADER_FRAGMENT]); +     machine->InterpCoefs = quads[0]->coef;     for (i = 0; i < nr; i++) { diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 3fbf1f2578..ded242d3dc 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -195,6 +195,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,     }     softpipe->mapped_constants[shader][index] = data; +   softpipe->const_buffer_size[shader][index] = size; +     softpipe->dirty |= SP_NEW_CONSTANTS;  } | 
