Merge branch 'sprite-coord'
This commit is contained in:
@@ -8,6 +8,7 @@ C_SOURCES = \
|
|||||||
cso_cache/cso_context.c \
|
cso_cache/cso_context.c \
|
||||||
cso_cache/cso_hash.c \
|
cso_cache/cso_hash.c \
|
||||||
draw/draw_context.c \
|
draw/draw_context.c \
|
||||||
|
draw/draw_fs.c \
|
||||||
draw/draw_gs.c \
|
draw/draw_gs.c \
|
||||||
draw/draw_pipe.c \
|
draw/draw_pipe.c \
|
||||||
draw/draw_pipe_aaline.c \
|
draw/draw_pipe_aaline.c \
|
||||||
|
@@ -54,6 +54,7 @@ source = [
|
|||||||
'cso_cache/cso_context.c',
|
'cso_cache/cso_context.c',
|
||||||
'cso_cache/cso_hash.c',
|
'cso_cache/cso_hash.c',
|
||||||
'draw/draw_context.c',
|
'draw/draw_context.c',
|
||||||
|
'draw/draw_fs.c',
|
||||||
'draw/draw_gs.c',
|
'draw/draw_gs.c',
|
||||||
'draw/draw_pipe.c',
|
'draw/draw_pipe.c',
|
||||||
'draw/draw_pipe_aaline.c',
|
'draw/draw_pipe_aaline.c',
|
||||||
|
@@ -413,6 +413,42 @@ draw_set_force_passthrough( struct draw_context *draw, boolean enable )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate an extra vertex/geometry shader vertex attribute.
|
||||||
|
* This is used by some of the optional draw module stages such
|
||||||
|
* as wide_point which may need to allocate additional generic/texcoord
|
||||||
|
* attributes.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
draw_alloc_extra_vertex_attrib(struct draw_context *draw,
|
||||||
|
uint semantic_name, uint semantic_index)
|
||||||
|
{
|
||||||
|
const int num_outputs = draw_current_shader_outputs(draw);
|
||||||
|
const int n = draw->extra_shader_outputs.num;
|
||||||
|
|
||||||
|
assert(n < Elements(draw->extra_shader_outputs.semantic_name));
|
||||||
|
|
||||||
|
draw->extra_shader_outputs.semantic_name[n] = semantic_name;
|
||||||
|
draw->extra_shader_outputs.semantic_index[n] = semantic_index;
|
||||||
|
draw->extra_shader_outputs.slot[n] = num_outputs + n;
|
||||||
|
draw->extra_shader_outputs.num++;
|
||||||
|
|
||||||
|
return draw->extra_shader_outputs.slot[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all extra vertex attributes that were allocated with
|
||||||
|
* draw_alloc_extra_vertex_attrib().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
draw_remove_extra_vertex_attribs(struct draw_context *draw)
|
||||||
|
{
|
||||||
|
draw->extra_shader_outputs.num = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask the draw module for the location/slot of the given vertex attribute in
|
* Ask the draw module for the location/slot of the given vertex attribute in
|
||||||
* a post-transformed vertex.
|
* a post-transformed vertex.
|
||||||
@@ -446,12 +482,12 @@ draw_find_shader_output(const struct draw_context *draw,
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX there may be more than one extra vertex attrib.
|
/* Search the extra vertex attributes */
|
||||||
* For example, simulated gl_FragCoord and gl_PointCoord.
|
for (i = 0; i < draw->extra_shader_outputs.num; i++) {
|
||||||
*/
|
if (draw->extra_shader_outputs.semantic_name[i] == semantic_name &&
|
||||||
if (draw->extra_shader_outputs.semantic_name == semantic_name &&
|
draw->extra_shader_outputs.semantic_index[i] == semantic_index) {
|
||||||
draw->extra_shader_outputs.semantic_index == semantic_index) {
|
return draw->extra_shader_outputs.slot[i];
|
||||||
return draw->extra_shader_outputs.slot;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -470,16 +506,18 @@ draw_find_shader_output(const struct draw_context *draw,
|
|||||||
uint
|
uint
|
||||||
draw_num_shader_outputs(const struct draw_context *draw)
|
draw_num_shader_outputs(const struct draw_context *draw)
|
||||||
{
|
{
|
||||||
uint count = draw->vs.vertex_shader->info.num_outputs;
|
uint count;
|
||||||
|
|
||||||
/* If a geometry shader is present, its outputs go to the
|
/* If a geometry shader is present, its outputs go to the
|
||||||
* driver, else the vertex shader's outputs.
|
* driver, else the vertex shader's outputs.
|
||||||
*/
|
*/
|
||||||
if (draw->gs.geometry_shader)
|
if (draw->gs.geometry_shader)
|
||||||
count = draw->gs.geometry_shader->info.num_outputs;
|
count = draw->gs.geometry_shader->info.num_outputs;
|
||||||
|
else
|
||||||
|
count = draw->vs.vertex_shader->info.num_outputs;
|
||||||
|
|
||||||
|
count += draw->extra_shader_outputs.num;
|
||||||
|
|
||||||
if (draw->extra_shader_outputs.slot > 0)
|
|
||||||
count++;
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,6 +46,7 @@ struct draw_context;
|
|||||||
struct draw_stage;
|
struct draw_stage;
|
||||||
struct draw_vertex_shader;
|
struct draw_vertex_shader;
|
||||||
struct draw_geometry_shader;
|
struct draw_geometry_shader;
|
||||||
|
struct draw_fragment_shader;
|
||||||
struct tgsi_sampler;
|
struct tgsi_sampler;
|
||||||
|
|
||||||
#define DRAW_MAX_TEXTURE_LEVELS 13 /* 4K x 4K for now */
|
#define DRAW_MAX_TEXTURE_LEVELS 13 /* 4K x 4K for now */
|
||||||
@@ -137,6 +138,17 @@ void draw_delete_vertex_shader(struct draw_context *draw,
|
|||||||
struct draw_vertex_shader *dvs);
|
struct draw_vertex_shader *dvs);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fragment shader functions
|
||||||
|
*/
|
||||||
|
struct draw_fragment_shader *
|
||||||
|
draw_create_fragment_shader(struct draw_context *draw,
|
||||||
|
const struct pipe_shader_state *shader);
|
||||||
|
void draw_bind_fragment_shader(struct draw_context *draw,
|
||||||
|
struct draw_fragment_shader *dvs);
|
||||||
|
void draw_delete_fragment_shader(struct draw_context *draw,
|
||||||
|
struct draw_fragment_shader *dvs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Geometry shader functions
|
* Geometry shader functions
|
||||||
*/
|
*/
|
||||||
|
@@ -688,10 +688,9 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
|
|||||||
aaline->tex_slot = draw_current_shader_outputs(draw);
|
aaline->tex_slot = draw_current_shader_outputs(draw);
|
||||||
aaline->pos_slot = draw_current_shader_position_output(draw);;
|
aaline->pos_slot = draw_current_shader_position_output(draw);;
|
||||||
|
|
||||||
/* advertise the extra post-transformed vertex attribute */
|
/* allocate the extra post-transformed vertex attribute */
|
||||||
draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
|
(void) draw_alloc_extra_vertex_attrib(draw, TGSI_SEMANTIC_GENERIC,
|
||||||
draw->extra_shader_outputs.semantic_index = aaline->fs->generic_attrib;
|
aaline->fs->generic_attrib);
|
||||||
draw->extra_shader_outputs.slot = aaline->tex_slot;
|
|
||||||
|
|
||||||
/* how many samplers? */
|
/* how many samplers? */
|
||||||
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
|
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
|
||||||
@@ -744,7 +743,7 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
|
|||||||
|
|
||||||
draw->suspend_flushing = FALSE;
|
draw->suspend_flushing = FALSE;
|
||||||
|
|
||||||
draw->extra_shader_outputs.slot = 0;
|
draw_remove_extra_vertex_attribs(draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -701,9 +701,9 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
|
|||||||
|
|
||||||
aapoint->pos_slot = draw_current_shader_position_output(draw);
|
aapoint->pos_slot = draw_current_shader_position_output(draw);
|
||||||
|
|
||||||
draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
|
/* allocate the extra post-transformed vertex attribute */
|
||||||
draw->extra_shader_outputs.semantic_index = aapoint->fs->generic_attrib;
|
(void) draw_alloc_extra_vertex_attrib(draw, TGSI_SEMANTIC_GENERIC,
|
||||||
draw->extra_shader_outputs.slot = aapoint->tex_slot;
|
aapoint->fs->generic_attrib);
|
||||||
|
|
||||||
/* find psize slot in post-transform vertex */
|
/* find psize slot in post-transform vertex */
|
||||||
aapoint->psize_slot = -1;
|
aapoint->psize_slot = -1;
|
||||||
@@ -754,7 +754,7 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
|
|||||||
|
|
||||||
draw->suspend_flushing = FALSE;
|
draw->suspend_flushing = FALSE;
|
||||||
|
|
||||||
draw->extra_shader_outputs.slot = 0;
|
draw_remove_extra_vertex_attribs(draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -172,7 +172,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
|
|||||||
wide_lines = (rast->line_width > draw->pipeline.wide_line_threshold
|
wide_lines = (rast->line_width > draw->pipeline.wide_line_threshold
|
||||||
&& !rast->line_smooth);
|
&& !rast->line_smooth);
|
||||||
|
|
||||||
/* drawing large points? */
|
/* drawing large/sprite points (but not AA points)? */
|
||||||
if (rast->sprite_coord_enable && draw->pipeline.point_sprite)
|
if (rast->sprite_coord_enable && draw->pipeline.point_sprite)
|
||||||
wide_points = TRUE;
|
wide_points = TRUE;
|
||||||
else if (rast->point_smooth && draw->pipeline.aapoint)
|
else if (rast->point_smooth && draw->pipeline.aapoint)
|
||||||
@@ -207,7 +207,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
|
|||||||
precalc_flat = TRUE;
|
precalc_flat = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wide_points || rast->sprite_coord_enable) {
|
if (wide_points) {
|
||||||
draw->pipeline.wide_point->next = next;
|
draw->pipeline.wide_point->next = next;
|
||||||
next = draw->pipeline.wide_point;
|
next = draw->pipeline.wide_point;
|
||||||
}
|
}
|
||||||
|
@@ -57,26 +57,24 @@
|
|||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
#include "pipe/p_shader_tokens.h"
|
#include "pipe/p_shader_tokens.h"
|
||||||
|
#include "draw_fs.h"
|
||||||
#include "draw_vs.h"
|
#include "draw_vs.h"
|
||||||
#include "draw_pipe.h"
|
#include "draw_pipe.h"
|
||||||
|
|
||||||
|
|
||||||
struct widepoint_stage {
|
struct widepoint_stage {
|
||||||
struct draw_stage stage;
|
struct draw_stage stage; /**< base class */
|
||||||
|
|
||||||
float half_point_size;
|
float half_point_size;
|
||||||
|
|
||||||
float xbias;
|
float xbias;
|
||||||
float ybias;
|
float ybias;
|
||||||
|
|
||||||
uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS];
|
/** for automatic texcoord generation/replacement */
|
||||||
uint texcoord_enable[PIPE_MAX_SHADER_OUTPUTS];
|
uint num_texcoord_gen;
|
||||||
uint num_texcoords;
|
uint texcoord_gen_slot[PIPE_MAX_SHADER_OUTPUTS];
|
||||||
uint texcoord_mode;
|
|
||||||
|
|
||||||
int psize_slot;
|
int psize_slot;
|
||||||
|
|
||||||
int point_coord_fs_input; /**< input for pointcoord */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -96,30 +94,20 @@ widepoint_stage( struct draw_stage *stage )
|
|||||||
static void set_texcoords(const struct widepoint_stage *wide,
|
static void set_texcoords(const struct widepoint_stage *wide,
|
||||||
struct vertex_header *v, const float tc[4])
|
struct vertex_header *v, const float tc[4])
|
||||||
{
|
{
|
||||||
|
const struct draw_context *draw = wide->stage.draw;
|
||||||
|
const struct pipe_rasterizer_state *rast = draw->rasterizer;
|
||||||
|
const uint texcoord_mode = rast->sprite_coord_mode;
|
||||||
uint i;
|
uint i;
|
||||||
for (i = 0; i < wide->num_texcoords; i++) {
|
|
||||||
if (wide->texcoord_enable[i]) {
|
|
||||||
uint j = wide->texcoord_slot[i];
|
|
||||||
v->data[j][0] = tc[0];
|
|
||||||
if (wide->texcoord_mode == PIPE_SPRITE_COORD_LOWER_LEFT)
|
|
||||||
v->data[j][1] = 1.0f - tc[1];
|
|
||||||
else
|
|
||||||
v->data[j][1] = tc[1];
|
|
||||||
v->data[j][2] = tc[2];
|
|
||||||
v->data[j][3] = tc[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wide->point_coord_fs_input >= 0) {
|
for (i = 0; i < wide->num_texcoord_gen; i++) {
|
||||||
/* put gl_PointCoord into the extra vertex slot */
|
const uint slot = wide->texcoord_gen_slot[i];
|
||||||
uint slot = wide->stage.draw->extra_shader_outputs.slot;
|
|
||||||
v->data[slot][0] = tc[0];
|
v->data[slot][0] = tc[0];
|
||||||
if (wide->texcoord_mode == PIPE_SPRITE_COORD_LOWER_LEFT)
|
if (texcoord_mode == PIPE_SPRITE_COORD_LOWER_LEFT)
|
||||||
v->data[slot][1] = 1.0f - tc[1];
|
v->data[slot][1] = 1.0f - tc[1];
|
||||||
else
|
else
|
||||||
v->data[slot][1] = tc[1];
|
v->data[slot][1] = tc[1];
|
||||||
v->data[slot][2] = 0.0F;
|
v->data[slot][2] = tc[2];
|
||||||
v->data[slot][3] = 1.0F;
|
v->data[slot][3] = tc[3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,18 +189,9 @@ static void widepoint_point( struct draw_stage *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static void
|
||||||
find_pntc_input_attrib(struct draw_context *draw)
|
widepoint_first_point(struct draw_stage *stage,
|
||||||
{
|
struct prim_header *header)
|
||||||
/* Scan the fragment program's input decls to find the pointcoord
|
|
||||||
* attribute. The xy components will store the point coord.
|
|
||||||
*/
|
|
||||||
return 0; /* XXX fix this */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void widepoint_first_point( struct draw_stage *stage,
|
|
||||||
struct prim_header *header )
|
|
||||||
{
|
{
|
||||||
struct widepoint_stage *wide = widepoint_stage(stage);
|
struct widepoint_stage *wide = widepoint_stage(stage);
|
||||||
struct draw_context *draw = stage->draw;
|
struct draw_context *draw = stage->draw;
|
||||||
@@ -244,31 +223,49 @@ static void widepoint_first_point( struct draw_stage *stage,
|
|||||||
stage->point = draw_pipe_passthrough_point;
|
stage->point = draw_pipe_passthrough_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_remove_extra_vertex_attribs(draw);
|
||||||
|
|
||||||
if (rast->point_quad_rasterization) {
|
if (rast->point_quad_rasterization) {
|
||||||
/* find vertex shader texcoord outputs */
|
const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
|
||||||
const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
|
uint i;
|
||||||
uint i, j = 0;
|
|
||||||
wide->texcoord_mode = rast->sprite_coord_mode;
|
wide->num_texcoord_gen = 0;
|
||||||
for (i = 0; i < vs->info.num_outputs; i++) {
|
|
||||||
if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
|
/* Loop over fragment shader inputs looking for generic inputs
|
||||||
wide->texcoord_slot[j] = i;
|
* for which bit 'k' in sprite_coord_enable is set.
|
||||||
wide->texcoord_enable[j] = (rast->sprite_coord_enable >> j) & 1;
|
*/
|
||||||
j++;
|
for (i = 0; i < fs->info.num_inputs; i++) {
|
||||||
|
if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
|
||||||
|
const int generic_index = fs->info.input_semantic_index[i];
|
||||||
|
/* Note that sprite_coord enable is a bitfield of
|
||||||
|
* PIPE_MAX_SHADER_OUTPUTS bits.
|
||||||
|
*/
|
||||||
|
if (generic_index < PIPE_MAX_SHADER_OUTPUTS &&
|
||||||
|
(rast->sprite_coord_enable & (1 << generic_index))) {
|
||||||
|
/* OK, this generic attribute needs to be replaced with a
|
||||||
|
* texcoord (see above).
|
||||||
|
*/
|
||||||
|
int slot = draw_find_shader_output(draw,
|
||||||
|
TGSI_SEMANTIC_GENERIC,
|
||||||
|
generic_index);
|
||||||
|
|
||||||
|
if (slot > 0) {
|
||||||
|
/* there's already a post-vertex shader attribute
|
||||||
|
* for this fragment shader input attribute.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* need to allocate a new post-vertex shader attribute */
|
||||||
|
slot = draw_alloc_extra_vertex_attrib(draw,
|
||||||
|
TGSI_SEMANTIC_GENERIC,
|
||||||
|
generic_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add this slot to the texcoord-gen list */
|
||||||
|
wide->texcoord_gen_slot[wide->num_texcoord_gen++] = slot;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wide->num_texcoords = j;
|
|
||||||
|
|
||||||
/* find fragment shader PointCoord input */
|
|
||||||
wide->point_coord_fs_input = find_pntc_input_attrib(draw);
|
|
||||||
|
|
||||||
/* setup extra vp output (point coord implemented as a texcoord) */
|
|
||||||
draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
|
|
||||||
draw->extra_shader_outputs.semantic_index = 0;
|
|
||||||
draw->extra_shader_outputs.slot = draw_current_shader_outputs(draw);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
wide->point_coord_fs_input = -1;
|
|
||||||
draw->extra_shader_outputs.slot = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wide->psize_slot = -1;
|
wide->psize_slot = -1;
|
||||||
@@ -295,7 +292,8 @@ static void widepoint_flush( struct draw_stage *stage, unsigned flags )
|
|||||||
|
|
||||||
stage->point = widepoint_first_point;
|
stage->point = widepoint_first_point;
|
||||||
stage->next->flush( stage->next, flags );
|
stage->next->flush( stage->next, flags );
|
||||||
stage->draw->extra_shader_outputs.slot = 0;
|
|
||||||
|
draw_remove_extra_vertex_attribs(draw);
|
||||||
|
|
||||||
/* restore original rasterizer state */
|
/* restore original rasterizer state */
|
||||||
if (draw->rast_handle) {
|
if (draw->rast_handle) {
|
||||||
|
@@ -250,6 +250,11 @@ struct draw_context
|
|||||||
struct tgsi_sampler **samplers;
|
struct tgsi_sampler **samplers;
|
||||||
} gs;
|
} gs;
|
||||||
|
|
||||||
|
/** Fragment shader state */
|
||||||
|
struct {
|
||||||
|
struct draw_fragment_shader *fragment_shader;
|
||||||
|
} fs;
|
||||||
|
|
||||||
/** Stream output (vertex feedback) state */
|
/** Stream output (vertex feedback) state */
|
||||||
struct {
|
struct {
|
||||||
struct pipe_stream_output_state state;
|
struct pipe_stream_output_state state;
|
||||||
@@ -266,9 +271,10 @@ struct draw_context
|
|||||||
/* If a prim stage introduces new vertex attributes, they'll be stored here
|
/* If a prim stage introduces new vertex attributes, they'll be stored here
|
||||||
*/
|
*/
|
||||||
struct {
|
struct {
|
||||||
uint semantic_name;
|
uint num;
|
||||||
uint semantic_index;
|
uint semantic_name[10];
|
||||||
int slot;
|
uint semantic_index[10];
|
||||||
|
uint slot[10];
|
||||||
} extra_shader_outputs;
|
} extra_shader_outputs;
|
||||||
|
|
||||||
unsigned reduced_prim;
|
unsigned reduced_prim;
|
||||||
@@ -362,6 +368,11 @@ void draw_gs_destroy( struct draw_context *draw );
|
|||||||
uint draw_current_shader_outputs(const struct draw_context *draw);
|
uint draw_current_shader_outputs(const struct draw_context *draw);
|
||||||
uint draw_current_shader_position_output(const struct draw_context *draw);
|
uint draw_current_shader_position_output(const struct draw_context *draw);
|
||||||
|
|
||||||
|
int draw_alloc_extra_vertex_attrib(struct draw_context *draw,
|
||||||
|
uint semantic_name, uint semantic_index);
|
||||||
|
void draw_remove_extra_vertex_attribs(struct draw_context *draw);
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Vertex processing (was passthrough) code:
|
* Vertex processing (was passthrough) code:
|
||||||
*/
|
*/
|
||||||
|
@@ -124,17 +124,24 @@ Points
|
|||||||
sprite_coord_enable
|
sprite_coord_enable
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Specifies if a texture unit has its texture coordinates replaced or not. This
|
Controls automatic texture coordinate generation for rendering sprite points.
|
||||||
is a packed bitfield containing the enable for all texcoords -- if all bits
|
|
||||||
are zero, point sprites are effectively disabled.
|
When bit k in the sprite_coord_enable bitfield is set, then generic
|
||||||
|
input k to the fragment shader will get an automatically computed
|
||||||
|
texture coordinate.
|
||||||
|
|
||||||
|
The texture coordinate will be of the form (s, t, 0, 1) where s varies
|
||||||
|
from 0 to 1 from left to right while t varies from 0 to 1 according to
|
||||||
|
the state of 'sprite_coord_mode' (see below).
|
||||||
|
|
||||||
If any bit is set, then point_smooth MUST be disabled (there are no
|
If any bit is set, then point_smooth MUST be disabled (there are no
|
||||||
round sprites) and point_quad_rasterization MUST be true (sprites are
|
round sprites) and point_quad_rasterization MUST be true (sprites are
|
||||||
always rasterized as quads). Any mismatch between these states should
|
always rasterized as quads). Any mismatch between these states should
|
||||||
be considered a bug in the state-tracker.
|
be considered a bug in the state-tracker.
|
||||||
|
|
||||||
If enabled, the four vertices of the resulting quad will be assigned
|
This feature is implemented in the :ref:`Draw` module but may also be
|
||||||
texture coordinates, according to sprite_coord_mode.
|
implemented natively by GPUs or implemented with a geometry shader.
|
||||||
|
|
||||||
|
|
||||||
sprite_coord_mode
|
sprite_coord_mode
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
@@ -145,6 +152,7 @@ have coordinates (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left
|
|||||||
vertex will have coordinates (0,0,0,1).
|
vertex will have coordinates (0,0,0,1).
|
||||||
This state is used by :ref:`Draw` to generate texcoords.
|
This state is used by :ref:`Draw` to generate texcoords.
|
||||||
|
|
||||||
|
|
||||||
point_quad_rasterization
|
point_quad_rasterization
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
128
src/gallium/docs/source/pipeline.txt
Normal file
128
src/gallium/docs/source/pipeline.txt
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
XXX this could be converted/formatted for Sphinx someday.
|
||||||
|
XXX do not use tabs in this file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
position ]
|
||||||
|
primary/secondary colors ]
|
||||||
|
generics (normals, ]
|
||||||
|
texcoords, fog) ] User vertices / arrays
|
||||||
|
point size ]
|
||||||
|
edge flag ]
|
||||||
|
primitive ID } System-generated values
|
||||||
|
vertex ID }
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+-------------------+
|
||||||
|
| Vertex shader |
|
||||||
|
+-------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
position
|
||||||
|
clip distance
|
||||||
|
generics
|
||||||
|
front/back & primary/secondary colors
|
||||||
|
point size
|
||||||
|
edge flag
|
||||||
|
primitive ID
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+------------------------+
|
||||||
|
| Geometry shader |
|
||||||
|
| (consume vertex ID) |
|
||||||
|
| (may change prim type) |
|
||||||
|
+------------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
[...]
|
||||||
|
fb layer
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+--------------------------+
|
||||||
|
| Clipper |
|
||||||
|
| (consume clip distances) |
|
||||||
|
+--------------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+-------------------+
|
||||||
|
| Polygon Culling |
|
||||||
|
+-------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+-----------------------+
|
||||||
|
| Choose front or |
|
||||||
|
| back face color |
|
||||||
|
| (consume other color) |
|
||||||
|
+-----------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
[...]
|
||||||
|
primary/secondary colors only
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+-------------------+
|
||||||
|
| Polygon Offset |
|
||||||
|
+-------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+----------------------+
|
||||||
|
| Unfilled polygons |
|
||||||
|
| (consume edge flags) |
|
||||||
|
| (change prim type) |
|
||||||
|
+----------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
position
|
||||||
|
generics
|
||||||
|
primary/secondary colors
|
||||||
|
point size
|
||||||
|
primitive ID
|
||||||
|
fb layer
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+---------------------------------+
|
||||||
|
| Optional Draw module helpers |
|
||||||
|
| * Polygon Stipple |
|
||||||
|
| * Line Stipple |
|
||||||
|
| * Line AA/smooth (as tris) |
|
||||||
|
| * Wide lines (as tris) |
|
||||||
|
| * Wide points/sprites (as tris) |
|
||||||
|
| * Point AA/smooth (as tris) |
|
||||||
|
| (NOTE: these stages may emit |
|
||||||
|
| new/extra generic attributes |
|
||||||
|
| such as texcoords) |
|
||||||
|
+---------------------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
position ]
|
||||||
|
generics (+ new/extra ones) ]
|
||||||
|
primary/secondary colors ] Software rast vertices
|
||||||
|
point size ]
|
||||||
|
primitive ID ]
|
||||||
|
fb layer ]
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+---------------------+
|
||||||
|
| Triangle/Line/Point |
|
||||||
|
| Rasterization |
|
||||||
|
+---------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
generic attribs
|
||||||
|
primary/secondary colors
|
||||||
|
primitive ID
|
||||||
|
fragment win coord pos } System-generated values
|
||||||
|
front/back face flag }
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
+-------------------+
|
||||||
|
| Fragment shader |
|
||||||
|
+-------------------+
|
||||||
|
| | |
|
||||||
|
V V V
|
||||||
|
zero or more colors
|
||||||
|
zero or one Z value
|
||||||
|
|
||||||
|
|
||||||
|
NOTE: The instance ID is not shown. It can be imagined to be a global variable
|
||||||
|
accessible to all shader stages.
|
@@ -490,12 +490,14 @@ void
|
|||||||
lp_setup_set_point_state( struct lp_setup_context *setup,
|
lp_setup_set_point_state( struct lp_setup_context *setup,
|
||||||
float point_size,
|
float point_size,
|
||||||
boolean point_size_per_vertex,
|
boolean point_size_per_vertex,
|
||||||
uint sprite)
|
uint sprite_coord_enable,
|
||||||
|
uint sprite_coord_origin)
|
||||||
{
|
{
|
||||||
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
|
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
setup->point_size = point_size;
|
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;
|
setup->point_size_per_vertex = point_size_per_vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -107,7 +107,8 @@ void
|
|||||||
lp_setup_set_point_state( struct lp_setup_context *setup,
|
lp_setup_set_point_state( struct lp_setup_context *setup,
|
||||||
float point_size,
|
float point_size,
|
||||||
boolean point_size_per_vertex,
|
boolean point_size_per_vertex,
|
||||||
uint sprite);
|
uint sprite_coord_enable,
|
||||||
|
uint sprite_coord_origin);
|
||||||
|
|
||||||
void
|
void
|
||||||
lp_setup_set_fs_inputs( struct lp_setup_context *setup,
|
lp_setup_set_fs_inputs( struct lp_setup_context *setup,
|
||||||
|
@@ -73,7 +73,7 @@ struct lp_setup_context
|
|||||||
uint prim;
|
uint prim;
|
||||||
uint vertex_size;
|
uint vertex_size;
|
||||||
uint nr_vertices;
|
uint nr_vertices;
|
||||||
uint sprite;
|
uint sprite_coord_enable, sprite_coord_origin;
|
||||||
uint vertex_buffer_size;
|
uint vertex_buffer_size;
|
||||||
void *vertex_buffer;
|
void *vertex_buffer;
|
||||||
|
|
||||||
|
@@ -52,26 +52,30 @@ struct point_info {
|
|||||||
/**
|
/**
|
||||||
* Compute a0 for a constant-valued coefficient (GL_FLAT shading).
|
* Compute a0 for a constant-valued coefficient (GL_FLAT shading).
|
||||||
*/
|
*/
|
||||||
static void constant_coef( struct lp_setup_context *setup,
|
static void
|
||||||
struct lp_rast_triangle *point,
|
constant_coef(struct lp_setup_context *setup,
|
||||||
unsigned slot,
|
struct lp_rast_triangle *point,
|
||||||
const float value,
|
unsigned slot,
|
||||||
unsigned i )
|
const float value,
|
||||||
|
unsigned i)
|
||||||
{
|
{
|
||||||
point->inputs.a0[slot][i] = value;
|
point->inputs.a0[slot][i] = value;
|
||||||
point->inputs.dadx[slot][i] = 0.0f;
|
point->inputs.dadx[slot][i] = 0.0f;
|
||||||
point->inputs.dady[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,
|
static void
|
||||||
const struct point_info *info,
|
perspective_coef(struct lp_setup_context *setup,
|
||||||
unsigned slot,
|
struct lp_rast_triangle *point,
|
||||||
unsigned vert_attr,
|
const struct point_info *info,
|
||||||
unsigned i)
|
unsigned slot,
|
||||||
|
unsigned vert_attr,
|
||||||
|
unsigned i,
|
||||||
|
unsigned sprite_coord_origin)
|
||||||
{
|
{
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
float dadx = FIXED_ONE / (float)info->dx12;
|
float dadx = FIXED_ONE / (float)info->dx12;
|
||||||
float dady = 0.0f;
|
float dady = 0.0f;
|
||||||
point->inputs.dadx[slot][i] = dadx;
|
point->inputs.dadx[slot][i] = dadx;
|
||||||
point->inputs.dady[slot][i] = dady;
|
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) +
|
(dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
|
||||||
dady * ((float)info->v0[0][1] - setup->pixel_offset)));
|
dady * ((float)info->v0[0][1] - setup->pixel_offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (i == 1) {
|
else if (i == 1) {
|
||||||
float dadx = 0.0f;
|
float dadx = 0.0f;
|
||||||
float dady = FIXED_ONE / (float)info->dx12;
|
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.dadx[slot][i] = dadx;
|
||||||
point->inputs.dady[slot][i] = dady;
|
point->inputs.dady[slot][i] = dady;
|
||||||
point->inputs.a0[slot][i] = (0.5 -
|
point->inputs.a0[slot][i] = (0.5 -
|
||||||
(dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
|
(dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
|
||||||
dady * ((float)info->v0[0][1] - setup->pixel_offset)));
|
dady * ((float)info->v0[0][1] - setup->pixel_offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (i == 2) {
|
else if (i == 2) {
|
||||||
point->inputs.a0[slot][i] = 0.0f;
|
point->inputs.a0[slot][i] = 0.0f;
|
||||||
point->inputs.dadx[slot][i] = 0.0f;
|
point->inputs.dadx[slot][i] = 0.0f;
|
||||||
point->inputs.dady[slot][i] = 0.0f;
|
point->inputs.dady[slot][i] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (i == 3) {
|
else if (i == 3) {
|
||||||
point->inputs.a0[slot][i] = 1.0f;
|
point->inputs.a0[slot][i] = 1.0f;
|
||||||
point->inputs.dadx[slot][i] = 0.0f;
|
point->inputs.dadx[slot][i] = 0.0f;
|
||||||
point->inputs.dady[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.
|
* 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,
|
struct lp_rast_triangle *point,
|
||||||
const struct point_info *info)
|
const struct point_info *info)
|
||||||
{
|
{
|
||||||
|
const struct lp_fragment_shader *shader = setup->fs.current.variant->shader;
|
||||||
unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ;
|
unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ;
|
||||||
unsigned slot;
|
unsigned slot;
|
||||||
|
|
||||||
@@ -172,17 +178,25 @@ setup_point_coefficients( struct lp_setup_context *setup,
|
|||||||
fragcoord_usage_mask |= usage_mask;
|
fragcoord_usage_mask |= usage_mask;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LP_INTERP_LINEAR:
|
||||||
|
/* Sprite tex coords may use linear interpolation someday */
|
||||||
|
/* fall-through */
|
||||||
|
|
||||||
case LP_INTERP_PERSPECTIVE:
|
case LP_INTERP_PERSPECTIVE:
|
||||||
/* For point sprite textures */
|
/* check if the sprite coord flag is set for this attribute.
|
||||||
if (setup->fs.current.variant->shader->info.input_semantic_name[slot]
|
* If so, set it up so it up so x any y vary from 0 to 1.
|
||||||
== TGSI_SEMANTIC_GENERIC)
|
*/
|
||||||
{
|
if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_GENERIC) {
|
||||||
int index = setup->fs.current.variant->shader->info.input_semantic_index[slot];
|
const int index = shader->info.input_semantic_index[slot];
|
||||||
|
/* Note that sprite_coord enable is a bitfield of
|
||||||
if (setup->sprite & (1 << index)) {
|
* PIPE_MAX_SHADER_OUTPUTS bits.
|
||||||
|
*/
|
||||||
|
if (index < PIPE_MAX_SHADER_OUTPUTS &&
|
||||||
|
(setup->sprite_coord_enable & (1 << index))) {
|
||||||
for (i = 0; i < NUM_CHANNELS; i++)
|
for (i = 0; i < NUM_CHANNELS; i++)
|
||||||
if (usage_mask & (1 << 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;
|
fragcoord_usage_mask |= TGSI_WRITEMASK_W;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -203,6 +217,7 @@ setup_point_coefficients( struct lp_setup_context *setup,
|
|||||||
fragcoord_usage_mask);
|
fragcoord_usage_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static INLINE int
|
static INLINE int
|
||||||
subpixel_snap(float a)
|
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,
|
static void
|
||||||
const float (*v0)[4] )
|
lp_setup_point(struct lp_setup_context *setup,
|
||||||
|
const float (*v0)[4])
|
||||||
{
|
{
|
||||||
if (!try_setup_point( setup, v0 ))
|
if (!try_setup_point( setup, v0 ))
|
||||||
{
|
{
|
||||||
|
@@ -886,6 +886,7 @@ static void *
|
|||||||
llvmpipe_create_fs_state(struct pipe_context *pipe,
|
llvmpipe_create_fs_state(struct pipe_context *pipe,
|
||||||
const struct pipe_shader_state *templ)
|
const struct pipe_shader_state *templ)
|
||||||
{
|
{
|
||||||
|
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||||
struct lp_fragment_shader *shader;
|
struct lp_fragment_shader *shader;
|
||||||
int nr_samplers;
|
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 */
|
/* we need to keep a local copy of the tokens */
|
||||||
shader->base.tokens = tgsi_dup_tokens(templ->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;
|
nr_samplers = shader->info.file_max[TGSI_FILE_SAMPLER] + 1;
|
||||||
|
|
||||||
shader->variant_key_size = Offset(struct lp_fragment_shader_variant_key,
|
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_flush(llvmpipe->draw);
|
||||||
|
|
||||||
|
draw_bind_fragment_shader(llvmpipe->draw,
|
||||||
|
(llvmpipe->fs ? llvmpipe->fs->draw_data : NULL));
|
||||||
|
|
||||||
llvmpipe->fs = fs;
|
llvmpipe->fs = fs;
|
||||||
|
|
||||||
llvmpipe->dirty |= LP_NEW_FS;
|
llvmpipe->dirty |= LP_NEW_FS;
|
||||||
@@ -995,6 +1005,8 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
|
|||||||
li = next;
|
li = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_delete_fragment_shader(llvmpipe->draw, shader->draw_data);
|
||||||
|
|
||||||
assert(shader->variants_cached == 0);
|
assert(shader->variants_cached == 0);
|
||||||
FREE((void *) shader->base.tokens);
|
FREE((void *) shader->base.tokens);
|
||||||
FREE(shader);
|
FREE(shader);
|
||||||
|
@@ -100,6 +100,8 @@ struct lp_fragment_shader
|
|||||||
|
|
||||||
struct lp_fs_variant_list_item variants;
|
struct lp_fs_variant_list_item variants;
|
||||||
|
|
||||||
|
struct draw_fragment_shader *draw_data;
|
||||||
|
|
||||||
/* For debugging/profiling purposes */
|
/* For debugging/profiling purposes */
|
||||||
unsigned variant_key_size;
|
unsigned variant_key_size;
|
||||||
unsigned no;
|
unsigned no;
|
||||||
|
@@ -78,8 +78,9 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
|
|||||||
lp_setup_set_point_state( llvmpipe->setup,
|
lp_setup_set_point_state( llvmpipe->setup,
|
||||||
llvmpipe->rasterizer->point_size,
|
llvmpipe->rasterizer->point_size,
|
||||||
llvmpipe->rasterizer->point_size_per_vertex,
|
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;
|
llvmpipe->dirty |= LP_NEW_RASTERIZER;
|
||||||
}
|
}
|
||||||
|
@@ -70,6 +70,8 @@ struct sp_fragment_shader {
|
|||||||
|
|
||||||
struct tgsi_shader_info info;
|
struct tgsi_shader_info info;
|
||||||
|
|
||||||
|
struct draw_fragment_shader *draw_shader;
|
||||||
|
|
||||||
boolean origin_lower_left; /**< fragment shader uses lower left position origin? */
|
boolean origin_lower_left; /**< fragment shader uses lower left position origin? */
|
||||||
boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */
|
boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */
|
||||||
|
|
||||||
|
@@ -60,7 +60,15 @@ softpipe_create_fs_state(struct pipe_context *pipe,
|
|||||||
state = softpipe_create_fs_exec( softpipe, templ );
|
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 */
|
/* get/save the summary info for this shader */
|
||||||
tgsi_scan_shader(templ->tokens, &state->info);
|
tgsi_scan_shader(templ->tokens, &state->info);
|
||||||
@@ -90,6 +98,9 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
|
|||||||
|
|
||||||
softpipe->fs = fs;
|
softpipe->fs = fs;
|
||||||
|
|
||||||
|
draw_bind_fragment_shader(softpipe->draw,
|
||||||
|
(softpipe->fs ? softpipe->fs->draw_shader : NULL));
|
||||||
|
|
||||||
softpipe->dirty |= SP_NEW_FS;
|
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);
|
tgsi_exec_machine_bind_shader(softpipe->fs_machine, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
|
||||||
|
|
||||||
state->delete( state );
|
state->delete( state );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -60,6 +60,7 @@ static void update_raster_state( struct st_context *st )
|
|||||||
GLcontext *ctx = st->ctx;
|
GLcontext *ctx = st->ctx;
|
||||||
struct pipe_rasterizer_state *raster = &st->state.rasterizer;
|
struct pipe_rasterizer_state *raster = &st->state.rasterizer;
|
||||||
const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
|
const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
|
||||||
|
const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current;
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
memset(raster, 0, sizeof(*raster));
|
memset(raster, 0, sizeof(*raster));
|
||||||
@@ -175,17 +176,30 @@ static void update_raster_state( struct st_context *st )
|
|||||||
if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag)
|
if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag)
|
||||||
raster->point_smooth = 1;
|
raster->point_smooth = 1;
|
||||||
|
|
||||||
|
/* _NEW_POINT | _NEW_PROGRAM
|
||||||
|
*/
|
||||||
if (ctx->Point.PointSprite) {
|
if (ctx->Point.PointSprite) {
|
||||||
|
/* origin */
|
||||||
if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
|
if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
|
||||||
(st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
|
(st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
|
||||||
raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
|
raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
|
||||||
else
|
else
|
||||||
raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;
|
raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;
|
||||||
|
|
||||||
|
/* Coord replacement flags. If bit 'k' is set that means
|
||||||
|
* that we need to replace GENERIC[k] attrib with an automatically
|
||||||
|
* computed texture coord.
|
||||||
|
*/
|
||||||
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
|
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
|
||||||
if (ctx->Point.CoordReplace[i]) {
|
if (ctx->Point.CoordReplace[i]) {
|
||||||
raster->sprite_coord_enable |= 1 << i;
|
raster->sprite_coord_enable |= 1 << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fragProg->Base.InputsRead & FRAG_BIT_PNTC) {
|
||||||
|
raster->sprite_coord_enable |=
|
||||||
|
1 << (FRAG_ATTRIB_PNTC - FRAG_ATTRIB_TEX0);
|
||||||
|
}
|
||||||
|
|
||||||
raster->point_quad_rasterization = 1;
|
raster->point_quad_rasterization = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -338,17 +338,6 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
input_semantic_index[slot] = 0;
|
input_semantic_index[slot] = 0;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
|
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_PNTC:
|
|
||||||
/* This is a hack. We really need a new semantic label for
|
|
||||||
* point coord. The draw module needs to know which fragment
|
|
||||||
* shader input is the point coord attribute so that it can set
|
|
||||||
* up the right vertex attribute values.
|
|
||||||
*/
|
|
||||||
input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
|
||||||
input_semantic_index[slot] = 0;
|
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* In most cases, there is nothing special about these
|
/* In most cases, there is nothing special about these
|
||||||
* inputs, so adopt a convention to use the generic
|
* inputs, so adopt a convention to use the generic
|
||||||
* semantic name and the mesa FRAG_ATTRIB_ number as the
|
* semantic name and the mesa FRAG_ATTRIB_ number as the
|
||||||
@@ -364,6 +353,7 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
* zero or be restricted to a particular range -- nobody
|
* zero or be restricted to a particular range -- nobody
|
||||||
* should be building tables based on semantic index.
|
* should be building tables based on semantic index.
|
||||||
*/
|
*/
|
||||||
|
case FRAG_ATTRIB_PNTC:
|
||||||
case FRAG_ATTRIB_TEX0:
|
case FRAG_ATTRIB_TEX0:
|
||||||
case FRAG_ATTRIB_TEX1:
|
case FRAG_ATTRIB_TEX1:
|
||||||
case FRAG_ATTRIB_TEX2:
|
case FRAG_ATTRIB_TEX2:
|
||||||
@@ -380,7 +370,10 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
assert(attr >= FRAG_ATTRIB_TEX0);
|
assert(attr >= FRAG_ATTRIB_TEX0);
|
||||||
input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
|
input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
|
||||||
input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
if (attr == FRAG_ATTRIB_PNTC)
|
||||||
|
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
||||||
|
else
|
||||||
|
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user