diff options
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.c | 21 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.h | 19 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 34 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.h | 4 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_context.h | 6 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state.h | 1 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_derived.c | 4 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 52 | 
8 files changed, 134 insertions, 7 deletions
| diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 4ef0783f3e..429cb973c2 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -79,13 +79,16 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)     /* struct lp_jit_context */     { -      LLVMTypeRef elem_types[4]; +      LLVMTypeRef elem_types[8];        LLVMTypeRef context_type;        elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */ -      elem_types[1] = LLVMFloatType();                     /* alpha_ref_value */ -      elem_types[2] = LLVMPointerType(LLVMInt8Type(), 0);  /* blend_color */ -      elem_types[3] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */ +      elem_types[1] = LLVMFloatType();                     /* alpha_ref_value */      elem_types[2] = LLVMFloatType();                     /* scissor_xmin */ +      elem_types[3] = LLVMFloatType();                     /* scissor_ymin */ +      elem_types[4] = LLVMFloatType();                     /* scissor_xmax */ +      elem_types[5] = LLVMFloatType();                     /* scissor_ymax */ +      elem_types[6] = LLVMPointerType(LLVMInt8Type(), 0);  /* blend_color */ +      elem_types[7] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */        context_type = LLVMStructType(elem_types, Elements(elem_types), 0); @@ -93,8 +96,16 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)                               screen->target, context_type, 0);        LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,                               screen->target, context_type, 1); -      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color, +      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmin,                               screen->target, context_type, 2); +      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymin, +                             screen->target, context_type, 3); +      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmax, +                             screen->target, context_type, 4); +      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymax, +                             screen->target, context_type, 5); +      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color, +                             screen->target, context_type, 6);        LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,                               screen->target, context_type,                               LP_JIT_CONTEXT_TEXTURES_INDEX); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 3b316914b0..9cbe1bd3b1 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -79,6 +79,9 @@ struct lp_jit_context     float alpha_ref_value; +   /** floats, not ints */ +   float scissor_xmin, scissor_ymin, scissor_xmax, scissor_ymax; +     /* FIXME: store (also?) in floats */     uint8_t *blend_color; @@ -92,10 +95,22 @@ struct lp_jit_context  #define lp_jit_context_alpha_ref_value(_builder, _ptr) \     lp_build_struct_get(_builder, _ptr, 1, "alpha_ref_value") +#define lp_jit_context_scissor_xmin_value(_builder, _ptr) \ +   lp_build_struct_get(_builder, _ptr, 2, "scissor_xmin") + +#define lp_jit_context_scissor_ymin_value(_builder, _ptr) \ +   lp_build_struct_get(_builder, _ptr, 3, "scissor_ymin") + +#define lp_jit_context_scissor_xmax_value(_builder, _ptr) \ +   lp_build_struct_get(_builder, _ptr, 4, "scissor_xmax") + +#define lp_jit_context_scissor_ymax_value(_builder, _ptr) \ +   lp_build_struct_get(_builder, _ptr, 5, "scissor_ymax") +  #define lp_jit_context_blend_color(_builder, _ptr) \ -   lp_build_struct_get(_builder, _ptr, 2, "blend_color") +   lp_build_struct_get(_builder, _ptr, 6, "blend_color") -#define LP_JIT_CONTEXT_TEXTURES_INDEX 3 +#define LP_JIT_CONTEXT_TEXTURES_INDEX 7  #define lp_jit_context_textures(_builder, _ptr) \     lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures") diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 649e97992b..284337e825 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -413,6 +413,21 @@ lp_setup_set_blend_color( struct setup_context *setup,  } +void +lp_setup_set_scissor( struct setup_context *setup, +                      const struct pipe_scissor_state *scissor ) +{ +   LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + +   assert(scissor); + +   if (memcmp(&setup->scissor.current, scissor, sizeof(*scissor)) != 0) { +      setup->scissor.current = *scissor; /* struct copy */ +      setup->dirty |= LP_SETUP_NEW_SCISSOR; +   } +} + +  void   lp_setup_set_flatshade_first( struct setup_context *setup,                                boolean flatshade_first ) @@ -534,6 +549,25 @@ lp_setup_update_state( struct setup_context *setup )        setup->dirty |= LP_SETUP_NEW_FS;     } +   if (setup->dirty & LP_SETUP_NEW_SCISSOR) { +      float *stored; + +      stored = lp_scene_alloc_aligned(scene, 4 * sizeof(int32_t), 16); + +      stored[0] = (float) setup->scissor.current.minx; +      stored[1] = (float) setup->scissor.current.miny; +      stored[2] = (float) setup->scissor.current.maxx; +      stored[3] = (float) setup->scissor.current.maxy; + +      setup->scissor.stored = stored; + +      setup->fs.current.jit_context.scissor_xmin = stored[0]; +      setup->fs.current.jit_context.scissor_ymin = stored[1]; +      setup->fs.current.jit_context.scissor_xmax = stored[2]; +      setup->fs.current.jit_context.scissor_ymax = stored[3]; + +      setup->dirty |= LP_SETUP_NEW_FS; +   }     if(setup->dirty & LP_SETUP_NEW_CONSTANTS) {        struct pipe_buffer *buffer = setup->constants.current; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 429abeba43..c7ef3d394a 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -114,6 +114,10 @@ lp_setup_set_blend_color( struct setup_context *setup,                            const struct pipe_blend_color *blend_color );  void +lp_setup_set_scissor( struct setup_context *setup, +                      const struct pipe_scissor_state *scissor ); + +void  lp_setup_set_sampler_textures( struct setup_context *setup,                                 unsigned num, struct pipe_texture **texture); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index e6f6f0e0bb..fc0aef1376 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -45,6 +45,7 @@  #define LP_SETUP_NEW_FS          0x01  #define LP_SETUP_NEW_CONSTANTS   0x02  #define LP_SETUP_NEW_BLEND_COLOR 0x04 +#define LP_SETUP_NEW_SCISSOR     0x08  struct lp_scene_queue; @@ -122,6 +123,11 @@ struct setup_context        uint8_t *stored;     } blend_color; +   struct { +      struct pipe_scissor_state current; +      const void *stored; +   } scissor; +     unsigned dirty;   /**< bitmask of LP_SETUP_NEW_x bits */     void (*point)( struct setup_context *, diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 4c6747bb2b..ddb152c074 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -72,6 +72,7 @@ struct lp_fragment_shader_variant_key     enum pipe_format zsbuf_format;     unsigned nr_cbufs:8;     unsigned flatshade:1; +   unsigned scissor:1;     struct {        ubyte colormask; diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 2c349fdb1d..28af477914 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -160,6 +160,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )     if (llvmpipe->dirty & (LP_NEW_FS |                            LP_NEW_BLEND | +                          LP_NEW_SCISSOR |                            LP_NEW_DEPTH_STENCIL_ALPHA |                            LP_NEW_RASTERIZER |                            LP_NEW_SAMPLER | @@ -170,6 +171,9 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )        lp_setup_set_blend_color(llvmpipe->setup,                                 &llvmpipe->blend_color); +   if (llvmpipe->dirty & LP_NEW_SCISSOR) +      lp_setup_set_scissor(llvmpipe->setup, &llvmpipe->scissor); +     if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA)        lp_setup_set_alpha_ref_value(llvmpipe->setup,                                      llvmpipe->depth_stencil->alpha.ref_value); diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 26a2d6cc23..d12d3f6091 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -304,6 +304,51 @@ generate_tri_edge_mask(LLVMBuilderRef builder,  } +static LLVMValueRef +generate_scissor_test(LLVMBuilderRef builder, +                      LLVMValueRef context_ptr, +                      const struct lp_build_interp_soa_context *interp, +                      struct lp_type type) +{ +   LLVMTypeRef vec_type = lp_build_vec_type(type); +   LLVMValueRef xpos = interp->pos[0], ypos = interp->pos[1]; +   LLVMValueRef xmin, ymin, xmax, ymax; +   LLVMValueRef m0, m1, m2, m3, m; + +   /* xpos, ypos contain the window coords for the four pixels in the quad */ +   assert(xpos); +   assert(ypos); + +   /* get the current scissor bounds, convert to vectors */ +   xmin = lp_jit_context_scissor_xmin_value(builder, context_ptr); +   xmin = lp_build_broadcast(builder, vec_type, xmin); + +   ymin = lp_jit_context_scissor_ymin_value(builder, context_ptr); +   ymin = lp_build_broadcast(builder, vec_type, ymin); + +   xmax = lp_jit_context_scissor_xmax_value(builder, context_ptr); +   xmax = lp_build_broadcast(builder, vec_type, xmax); + +   ymax = lp_jit_context_scissor_ymax_value(builder, context_ptr); +   ymax = lp_build_broadcast(builder, vec_type, ymax); + +   /* compare the fragment's position coordinates against the scissor bounds */ +   m0 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, xpos, xmin); +   m1 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, ypos, ymin); +   m2 = lp_build_compare(builder, type, PIPE_FUNC_LESS, xpos, xmax); +   m3 = lp_build_compare(builder, type, PIPE_FUNC_LESS, ypos, ymax); + +   /* AND all the masks together */ +   m = LLVMBuildAnd(builder, m0, m1, ""); +   m = LLVMBuildAnd(builder, m, m2, ""); +   m = LLVMBuildAnd(builder, m, m3, ""); + +   lp_build_name(m, "scissormask"); + +   return m; +} + +  /**   * Generate the fragment shader, depth/stencil test, and alpha tests.   * \param i  which quad in the tile, in range [0,3] @@ -372,6 +417,11 @@ generate_fs(struct llvmpipe_context *lp,     /* 'mask' will control execution based on quad's pixel alive/killed state */     lp_build_mask_begin(&mask, flow, type, *pmask); +   if (key->scissor) { +      LLVMValueRef smask = +         generate_scissor_test(builder, context_ptr, interp, type); +      lp_build_mask_update(&mask, smask); +   }     early_depth_test =        key->depth.enabled && @@ -968,6 +1018,7 @@ make_variant_key(struct llvmpipe_context *lp,     /* alpha.ref_value is passed in jit_context */     key->flatshade = lp->rasterizer->flatshade; +   key->scissor = lp->rasterizer->scissor;     if (lp->framebuffer.nr_cbufs) {        memcpy(&key->blend, lp->blend, sizeof key->blend); @@ -1033,6 +1084,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)              key.blend.colormask == 0xf &&              !key.alpha.enabled &&              !key.depth.enabled && +            !key.scissor &&              !shader->info.uses_kill              ? TRUE : FALSE; | 
