mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-28 08:40:37 +02:00
svga: implement point sprite suppport
Emit the SVGA3D_RS_POINTSPRITEENABLE render state. When sprite_coord_mode=PIPE_SPRITE_COORD_LOWER_LEFT emit extra frag shader code to invert the Y coordinate of the incoming texcoord.
This commit is contained in:
parent
9a41ecaddd
commit
2f40e4aac7
8 changed files with 119 additions and 4 deletions
|
|
@ -141,6 +141,7 @@ struct svga_rasterizer_state {
|
|||
unsigned multisampleantialias:1;
|
||||
unsigned antialiasedlineenable:1;
|
||||
unsigned lastpixel:1;
|
||||
unsigned pointsprite:1;
|
||||
|
||||
unsigned linepattern;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
|
|||
rast->multisampleantialias = templ->multisample;
|
||||
rast->antialiasedlineenable = templ->line_smooth;
|
||||
rast->lastpixel = templ->line_last_pixel;
|
||||
rast->pointsprite = templ->sprite_coord_enable != 0x0;
|
||||
rast->pointsize = templ->point_size;
|
||||
rast->hw_unfilled = PIPE_POLYGON_MODE_FILL;
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,15 @@ static int make_fs_key( const struct svga_context *svga,
|
|||
}
|
||||
}
|
||||
|
||||
/* sprite coord gen state */
|
||||
for (i = 0; i < svga->curr.num_samplers; ++i) {
|
||||
key->tex[i].sprite_texgen =
|
||||
svga->curr.rast->templ.sprite_coord_enable & (1 << i);
|
||||
}
|
||||
|
||||
key->sprite_origin_lower_left = (svga->curr.rast->templ.sprite_coord_mode
|
||||
== PIPE_SPRITE_COORD_LOWER_LEFT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ static int emit_rss( struct svga_context *svga,
|
|||
/* XXX still need to set this? */
|
||||
EMIT_RS_FLOAT( svga, 0.0, POINTSIZEMIN, fail );
|
||||
EMIT_RS_FLOAT( svga, SVGA_MAX_POINTSIZE, POINTSIZEMAX, fail );
|
||||
EMIT_RS( svga, curr->pointsprite, POINTSPRITEENABLE, fail);
|
||||
}
|
||||
|
||||
if (dirty & (SVGA_NEW_RAST | SVGA_NEW_FRAME_BUFFER | SVGA_NEW_NEED_PIPELINE))
|
||||
|
|
|
|||
|
|
@ -52,12 +52,14 @@ struct svga_fs_compile_key
|
|||
unsigned white_fragments:1;
|
||||
unsigned num_textures:8;
|
||||
unsigned num_unnormalized_coords:8;
|
||||
unsigned sprite_origin_lower_left:1;
|
||||
struct {
|
||||
unsigned compare_mode:1;
|
||||
unsigned compare_func:3;
|
||||
unsigned unnormalized:1;
|
||||
unsigned width_height_idx:7;
|
||||
unsigned texture_target:8;
|
||||
unsigned sprite_texgen:1;
|
||||
} tex[PIPE_MAX_SAMPLERS];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -234,7 +234,36 @@ static boolean ps30_input( struct svga_shader_emitter *emit,
|
|||
emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
|
||||
reg = dst( emit->input_map[idx] );
|
||||
|
||||
return emit_decl( emit, reg, usage, index );
|
||||
if (!emit_decl( emit, reg, usage, index ))
|
||||
return FALSE;
|
||||
|
||||
if (semantic.Name == TGSI_SEMANTIC_GENERIC &&
|
||||
emit->key.fkey.sprite_origin_lower_left &&
|
||||
index >= 1 &&
|
||||
emit->key.fkey.tex[index - 1].sprite_texgen) {
|
||||
/* This is a sprite texture coord with lower-left origin.
|
||||
* We need to invert the texture T coordinate since the SVGA3D
|
||||
* device only supports an upper-left origin.
|
||||
*/
|
||||
unsigned unit = index - 1;
|
||||
|
||||
emit->inverted_texcoords |= (1 << unit);
|
||||
|
||||
/* save original texcoord reg */
|
||||
emit->ps_true_texcoord[unit] = emit->input_map[idx];
|
||||
|
||||
/* this temp register will be the results of the MAD instruction */
|
||||
emit->ps_inverted_texcoord[unit] =
|
||||
src_register(SVGA3DREG_TEMP, emit->nr_hw_temp);
|
||||
emit->nr_hw_temp++;
|
||||
|
||||
emit->ps_inverted_texcoord_input[unit] = idx;
|
||||
|
||||
/* replace input_map entry with the temp register */
|
||||
emit->input_map[idx] = emit->ps_inverted_texcoord[unit];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,11 @@ struct svga_shader_emitter
|
|||
boolean created_sincos_consts;
|
||||
int sincos_consts_idx;
|
||||
|
||||
unsigned inverted_texcoords; /**< bitmask of which texcoords are flipped */
|
||||
struct src_register ps_true_texcoord[PIPE_MAX_ATTRIBS];
|
||||
struct src_register ps_inverted_texcoord[PIPE_MAX_ATTRIBS];
|
||||
unsigned ps_inverted_texcoord_input[PIPE_MAX_ATTRIBS];
|
||||
|
||||
unsigned label[32];
|
||||
unsigned nr_labels;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "pipe/p_shader_tokens.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "svga_tgsi_emit.h"
|
||||
#include "svga_context.h"
|
||||
|
|
@ -623,8 +624,11 @@ create_zero_immediate( struct svga_shader_emitter *emit )
|
|||
{
|
||||
unsigned idx = emit->nr_hw_float_const++;
|
||||
|
||||
/* Emit the constant (0, 0, -1, 1) and use swizzling to generate
|
||||
* other useful vectors.
|
||||
*/
|
||||
if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
|
||||
idx, 0, 0, 0, 1 ))
|
||||
idx, 0, 0, -1, 1 ))
|
||||
return FALSE;
|
||||
|
||||
emit->zero_immediate_idx = idx;
|
||||
|
|
@ -731,8 +735,20 @@ get_zero_immediate( struct svga_shader_emitter *emit )
|
|||
{
|
||||
assert(emit->created_zero_immediate);
|
||||
assert(emit->zero_immediate_idx >= 0);
|
||||
return src_register( SVGA3DREG_CONST,
|
||||
emit->zero_immediate_idx );
|
||||
return swizzle(src_register( SVGA3DREG_CONST,
|
||||
emit->zero_immediate_idx),
|
||||
0, 0, 0, 3);
|
||||
}
|
||||
|
||||
/* returns {1, 1, 1, -1} immediate */
|
||||
static INLINE struct src_register
|
||||
get_pos_neg_one_immediate( struct svga_shader_emitter *emit )
|
||||
{
|
||||
assert(emit->created_zero_immediate);
|
||||
assert(emit->zero_immediate_idx >= 0);
|
||||
return swizzle(src_register( SVGA3DREG_CONST,
|
||||
emit->zero_immediate_idx),
|
||||
3, 3, 3, 2);
|
||||
}
|
||||
|
||||
/* returns the loop const */
|
||||
|
|
@ -2849,6 +2865,50 @@ static boolean emit_frontface( struct svga_shader_emitter *emit )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit code to invert the T component of the incoming texture coordinate.
|
||||
* This is used for drawing point sprites when
|
||||
* pipe_rasterizer_state::sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT.
|
||||
*/
|
||||
static boolean emit_inverted_texcoords( struct svga_shader_emitter *emit )
|
||||
{
|
||||
struct src_register zero = get_zero_immediate(emit);
|
||||
struct src_register pos_neg_one = get_pos_neg_one_immediate( emit );
|
||||
unsigned inverted_texcoords = emit->inverted_texcoords;
|
||||
|
||||
while (inverted_texcoords) {
|
||||
const unsigned unit = ffs(inverted_texcoords) - 1;
|
||||
|
||||
assert(emit->inverted_texcoords & (1 << unit));
|
||||
|
||||
assert(unit < Elements(emit->ps_true_texcoord));
|
||||
|
||||
assert(unit < Elements(emit->ps_inverted_texcoord_input));
|
||||
|
||||
assert(emit->ps_inverted_texcoord_input[unit]
|
||||
< Elements(emit->input_map));
|
||||
|
||||
/* inverted = coord * (1, -1, 1, 1) + (0, 1, 0, 0) */
|
||||
if (!submit_op3(emit,
|
||||
inst_token(SVGA3DOP_MAD),
|
||||
dst(emit->ps_inverted_texcoord[unit]),
|
||||
emit->ps_true_texcoord[unit],
|
||||
swizzle(pos_neg_one, 0, 3, 0, 0), /* (1, -1, 1, 1) */
|
||||
swizzle(zero, 0, 3, 0, 0))) /* (0, 1, 0, 0) */
|
||||
return FALSE;
|
||||
|
||||
/* Reassign the input_map entry to the new texcoord register */
|
||||
emit->input_map[emit->ps_inverted_texcoord_input[unit]] =
|
||||
emit->ps_inverted_texcoord[unit];
|
||||
|
||||
inverted_texcoords &= ~(1 << unit);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static INLINE boolean
|
||||
needs_to_create_zero( struct svga_shader_emitter *emit )
|
||||
{
|
||||
|
|
@ -2871,6 +2931,9 @@ needs_to_create_zero( struct svga_shader_emitter *emit )
|
|||
emit->info.opcode_count[TGSI_OPCODE_SSG] >= 1 ||
|
||||
emit->info.opcode_count[TGSI_OPCODE_LIT] >= 1)
|
||||
return TRUE;
|
||||
|
||||
if (emit->inverted_texcoords)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (emit->unit == PIPE_SHADER_VERTEX) {
|
||||
|
|
@ -3036,6 +3099,10 @@ static boolean svga_shader_emit_helpers( struct svga_shader_emitter *emit )
|
|||
if (!emit_frontface( emit ))
|
||||
return FALSE;
|
||||
}
|
||||
if (emit->inverted_texcoords) {
|
||||
if (!emit_inverted_texcoords( emit ))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue