summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_point.c80
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c12
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_rasterizer.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h2
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c15
9 files changed, 88 insertions, 39 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 6674d281d1e..ea7002aafcf 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -490,12 +490,14 @@ void
lp_setup_set_point_state( struct lp_setup_context *setup,
float point_size,
boolean point_size_per_vertex,
- uint sprite)
+ uint sprite_coord_enable,
+ uint sprite_coord_origin)
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
setup->point_size = point_size;
- setup->sprite = sprite;
+ setup->sprite_coord_enable = sprite_coord_enable;
+ setup->sprite_coord_origin = sprite_coord_origin;
setup->point_size_per_vertex = point_size_per_vertex;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index b94061b7d49..81ff43f8adc 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -107,7 +107,8 @@ void
lp_setup_set_point_state( struct lp_setup_context *setup,
float point_size,
boolean point_size_per_vertex,
- uint sprite);
+ uint sprite_coord_enable,
+ uint sprite_coord_origin);
void
lp_setup_set_fs_inputs( struct lp_setup_context *setup,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 80b356476ab..8506ed2dc9e 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -73,7 +73,7 @@ struct lp_setup_context
uint prim;
uint vertex_size;
uint nr_vertices;
- uint sprite;
+ uint sprite_coord_enable, sprite_coord_origin;
uint vertex_buffer_size;
void *vertex_buffer;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index 55389871518..774a3c80dad 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -52,26 +52,30 @@ struct point_info {
/**
* Compute a0 for a constant-valued coefficient (GL_FLAT shading).
*/
-static void constant_coef( struct lp_setup_context *setup,
- struct lp_rast_triangle *point,
- unsigned slot,
- const float value,
- unsigned i )
+static void
+constant_coef(struct lp_setup_context *setup,
+ struct lp_rast_triangle *point,
+ unsigned slot,
+ const float value,
+ unsigned i)
{
point->inputs.a0[slot][i] = value;
point->inputs.dadx[slot][i] = 0.0f;
point->inputs.dady[slot][i] = 0.0f;
}
-static void perspective_coef( struct lp_setup_context *setup,
- struct lp_rast_triangle *point,
- const struct point_info *info,
- unsigned slot,
- unsigned vert_attr,
- unsigned i)
+
+static void
+perspective_coef(struct lp_setup_context *setup,
+ struct lp_rast_triangle *point,
+ const struct point_info *info,
+ unsigned slot,
+ unsigned vert_attr,
+ unsigned i,
+ unsigned sprite_coord_origin)
{
- if (i == 0) {
- float dadx = FIXED_ONE / (float)info->dx12;
+ if (i == 0) {
+ float dadx = FIXED_ONE / (float)info->dx12;
float dady = 0.0f;
point->inputs.dadx[slot][i] = dadx;
point->inputs.dady[slot][i] = dady;
@@ -79,30 +83,30 @@ static void perspective_coef( struct lp_setup_context *setup,
(dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
dady * ((float)info->v0[0][1] - setup->pixel_offset)));
}
-
else if (i == 1) {
- float dadx = 0.0f;
- float dady = FIXED_ONE / (float)info->dx12;
-
+ float dadx = 0.0f;
+ float dady = FIXED_ONE / (float)info->dx12;
+
+ if (sprite_coord_origin == PIPE_SPRITE_COORD_LOWER_LEFT) {
+ dady = -dady;
+ }
+
point->inputs.dadx[slot][i] = dadx;
point->inputs.dady[slot][i] = dady;
point->inputs.a0[slot][i] = (0.5 -
- (dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
- dady * ((float)info->v0[0][1] - setup->pixel_offset)));
+ (dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
+ dady * ((float)info->v0[0][1] - setup->pixel_offset)));
}
-
else if (i == 2) {
point->inputs.a0[slot][i] = 0.0f;
point->inputs.dadx[slot][i] = 0.0f;
point->inputs.dady[slot][i] = 0.0f;
}
-
else if (i == 3) {
point->inputs.a0[slot][i] = 1.0f;
point->inputs.dadx[slot][i] = 0.0f;
point->inputs.dady[slot][i] = 0.0f;
}
-
}
@@ -144,6 +148,7 @@ setup_point_fragcoord_coef(struct lp_setup_context *setup,
}
}
+
/**
* Compute the point->coef[] array dadx, dady, a0 values.
*/
@@ -152,6 +157,7 @@ setup_point_coefficients( struct lp_setup_context *setup,
struct lp_rast_triangle *point,
const struct point_info *info)
{
+ const struct lp_fragment_shader *shader = setup->fs.current.variant->shader;
unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ;
unsigned slot;
@@ -172,17 +178,25 @@ setup_point_coefficients( struct lp_setup_context *setup,
fragcoord_usage_mask |= usage_mask;
break;
+ case LP_INTERP_LINEAR:
+ /* Sprite tex coords may use linear interpolation someday */
+ /* fall-through */
+
case LP_INTERP_PERSPECTIVE:
- /* For point sprite textures */
- if (setup->fs.current.variant->shader->info.input_semantic_name[slot]
- == TGSI_SEMANTIC_GENERIC)
- {
- int index = setup->fs.current.variant->shader->info.input_semantic_index[slot];
-
- if (setup->sprite & (1 << index)) {
+ /* check if the sprite coord flag is set for this attribute.
+ * If so, set it up so it up so x any y vary from 0 to 1.
+ */
+ if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_GENERIC) {
+ const int index = shader->info.input_semantic_index[slot];
+ /* Note that sprite_coord enable is a bitfield of
+ * PIPE_MAX_SHADER_OUTPUTS bits.
+ */
+ if (index < PIPE_MAX_SHADER_OUTPUTS &&
+ (setup->sprite_coord_enable & (1 << index))) {
for (i = 0; i < NUM_CHANNELS; i++)
if (usage_mask & (1 << i))
- perspective_coef(setup, point, info, slot+1, vert_attr, i);
+ perspective_coef(setup, point, info, slot+1, vert_attr, i,
+ setup->sprite_coord_origin);
fragcoord_usage_mask |= TGSI_WRITEMASK_W;
break;
}
@@ -203,6 +217,7 @@ setup_point_coefficients( struct lp_setup_context *setup,
fragcoord_usage_mask);
}
+
static INLINE int
subpixel_snap(float a)
{
@@ -322,8 +337,9 @@ try_setup_point( struct lp_setup_context *setup,
}
-static void lp_setup_point( struct lp_setup_context *setup,
- const float (*v0)[4] )
+static void
+lp_setup_point(struct lp_setup_context *setup,
+ const float (*v0)[4])
{
if (!try_setup_point( setup, v0 ))
{
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index e54dd9f0a3c..fb673db6d0f 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -886,6 +886,7 @@ static void *
llvmpipe_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct lp_fragment_shader *shader;
int nr_samplers;
@@ -902,6 +903,12 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
/* we need to keep a local copy of the tokens */
shader->base.tokens = tgsi_dup_tokens(templ->tokens);
+ shader->draw_data = draw_create_fragment_shader(llvmpipe->draw, templ);
+ if (shader->draw_data == NULL) {
+ FREE((void *) shader->base.tokens);
+ return NULL;
+ }
+
nr_samplers = shader->info.file_max[TGSI_FILE_SAMPLER] + 1;
shader->variant_key_size = Offset(struct lp_fragment_shader_variant_key,
@@ -938,6 +945,9 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
draw_flush(llvmpipe->draw);
+ draw_bind_fragment_shader(llvmpipe->draw,
+ (llvmpipe->fs ? llvmpipe->fs->draw_data : NULL));
+
llvmpipe->fs = fs;
llvmpipe->dirty |= LP_NEW_FS;
@@ -995,6 +1005,8 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
li = next;
}
+ draw_delete_fragment_shader(llvmpipe->draw, shader->draw_data);
+
assert(shader->variants_cached == 0);
FREE((void *) shader->base.tokens);
FREE(shader);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h
index 2914e7d7efd..4999b8dca1a 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.h
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h
@@ -100,6 +100,8 @@ struct lp_fragment_shader
struct lp_fs_variant_list_item variants;
+ struct draw_fragment_shader *draw_data;
+
/* For debugging/profiling purposes */
unsigned variant_key_size;
unsigned no;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
index 0bad7320f3e..dbd73812e45 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -78,8 +78,9 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
lp_setup_set_point_state( llvmpipe->setup,
llvmpipe->rasterizer->point_size,
llvmpipe->rasterizer->point_size_per_vertex,
- llvmpipe->rasterizer->sprite_coord_enable);
- }
+ llvmpipe->rasterizer->sprite_coord_enable,
+ llvmpipe->rasterizer->sprite_coord_mode);
+ }
llvmpipe->dirty |= LP_NEW_RASTERIZER;
}
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 39d204de8a9..c5d61f840f2 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -70,6 +70,8 @@ struct sp_fragment_shader {
struct tgsi_shader_info info;
+ struct draw_fragment_shader *draw_shader;
+
boolean origin_lower_left; /**< fragment shader uses lower left position origin? */
boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index ded242d3dc5..50bc2eea5ff 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -60,7 +60,15 @@ softpipe_create_fs_state(struct pipe_context *pipe,
state = softpipe_create_fs_exec( softpipe, templ );
}
- assert(state);
+ if (!state)
+ return NULL;
+
+ /* draw's fs state */
+ state->draw_shader = draw_create_fragment_shader(softpipe->draw, templ);
+ if (!state->draw_shader) {
+ state->delete( state );
+ return NULL;
+ }
/* get/save the summary info for this shader */
tgsi_scan_shader(templ->tokens, &state->info);
@@ -90,6 +98,9 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
softpipe->fs = fs;
+ draw_bind_fragment_shader(softpipe->draw,
+ (softpipe->fs ? softpipe->fs->draw_shader : NULL));
+
softpipe->dirty |= SP_NEW_FS;
}
@@ -109,6 +120,8 @@ softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
tgsi_exec_machine_bind_shader(softpipe->fs_machine, NULL, 0, NULL);
}
+ draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
+
state->delete( state );
}