Merge branch 'gallium-nopointsizeminmax'

Conflicts:
	src/gallium/drivers/nv10/nv10_state.c
	src/gallium/drivers/nv20/nv20_state.c
	src/gallium/drivers/nv50/nv50_program.c
This commit is contained in:
Roland Scheidegger
2010-02-09 19:32:21 +01:00
28 changed files with 1381 additions and 104 deletions

View File

@@ -105,7 +105,7 @@ draw_need_pipeline(const struct draw_context *draw,
return TRUE;
/* point sprites */
if (rasterizer->point_sprite && draw->pipeline.point_sprite)
if (rasterizer->sprite_coord_enable && draw->pipeline.point_sprite)
return TRUE;
}
@@ -165,7 +165,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
&& !draw->rasterizer->line_smooth);
/* drawing large points? */
if (draw->rasterizer->point_sprite && draw->pipeline.point_sprite)
if (draw->rasterizer->sprite_coord_enable && draw->pipeline.point_sprite)
wide_points = TRUE;
else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
wide_points = FALSE;
@@ -197,7 +197,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
precalc_flat = TRUE;
}
if (wide_points || draw->rasterizer->point_sprite) {
if (wide_points || draw->rasterizer->sprite_coord_enable) {
draw->pipeline.wide_point->next = next;
next = draw->pipeline.wide_point;
}

View File

@@ -64,15 +64,14 @@ struct widepoint_stage {
struct draw_stage stage;
float half_point_size;
float point_size_min;
float point_size_max;
float xbias;
float ybias;
uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS];
uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS];
uint texcoord_enable[PIPE_MAX_SHADER_OUTPUTS];
uint num_texcoords;
uint texcoord_mode;
int psize_slot;
@@ -98,10 +97,10 @@ static void set_texcoords(const struct widepoint_stage *wide,
{
uint i;
for (i = 0; i < wide->num_texcoords; i++) {
if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) {
if (wide->texcoord_enable[i]) {
uint j = wide->texcoord_slot[i];
v->data[j][0] = tc[0];
if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT)
if (wide->texcoord_mode == PIPE_SPRITE_COORD_LOWER_LEFT)
v->data[j][1] = 1.0f - tc[1];
else
v->data[j][1] = tc[1];
@@ -129,9 +128,10 @@ static void set_texcoords(const struct widepoint_stage *wide,
static void widepoint_point( struct draw_stage *stage,
struct prim_header *header )
{
/* XXX should take point_quad_rasterization into account? */
const struct widepoint_stage *wide = widepoint_stage(stage);
const unsigned pos = draw_current_shader_position_output(stage->draw);
const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite;
const boolean sprite = (boolean) stage->draw->rasterizer->sprite_coord_enable;
float half_size;
float left_adj, right_adj, bot_adj, top_adj;
@@ -151,13 +151,6 @@ static void widepoint_point( struct draw_stage *stage,
/* point size is either per-vertex or fixed size */
if (wide->psize_slot >= 0) {
half_size = header->v[0]->data[wide->psize_slot][0];
/* XXX: temporary -- do this in the vertex shader??
*/
half_size = CLAMP(half_size,
wide->point_size_min,
wide->point_size_max);
half_size *= 0.5f;
}
else {
@@ -222,8 +215,6 @@ static void widepoint_first_point( struct draw_stage *stage,
struct draw_context *draw = stage->draw;
wide->half_point_size = 0.5f * draw->rasterizer->point_size;
wide->point_size_min = draw->rasterizer->point_size_min;
wide->point_size_max = draw->rasterizer->point_size_max;
wide->xbias = 0.0;
wide->ybias = 0.0;
@@ -233,21 +224,22 @@ static void widepoint_first_point( struct draw_stage *stage,
/* XXX we won't know the real size if it's computed by the vertex shader! */
if ((draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) ||
(draw->rasterizer->point_sprite && draw->pipeline.point_sprite)) {
(draw->rasterizer->sprite_coord_enable && draw->pipeline.point_sprite)) {
stage->point = widepoint_point;
}
else {
stage->point = draw_pipe_passthrough_point;
}
if (draw->rasterizer->point_sprite) {
if (draw->rasterizer->sprite_coord_enable) {
/* find vertex shader texcoord outputs */
const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
uint i, j = 0;
wide->texcoord_mode = draw->rasterizer->sprite_coord_mode;
for (i = 0; i < vs->info.num_outputs; i++) {
if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
wide->texcoord_slot[j] = i;
wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j];
wide->texcoord_enable[j] = (draw->rasterizer->sprite_coord_enable >> j) & 1;
j++;
}
}

View File

@@ -119,18 +119,20 @@ point_size_per_vertex
Whether vertices have a point size element.
point_size
The size of points, if not specified per-vertex.
point_size_min
The minimum size of points.
point_size_max
The maximum size of points.
point_sprite
Whether points are drawn as sprites (textured quads)
sprite_coord_enable
Specifies if a coord has its texture coordinates replaced or not. This
is a packed bitfield containing the enable for all coords - if all are 0
point sprites are effectively disabled, though points may still be
rendered slightly different according to point_quad_rasterization.
If any coord is non-zero, point_smooth should be disabled, and
point_quad_rasterization enabled.
If enabled, the four vertices of the resulting quad will be assigned
texture coordinates, according to sprite_coord_mode.
sprite_coord_mode
Specifies how the value for each shader output should be computed when
drawing sprites. If PIPE_SPRITE_COORD_NONE, don't change the vertex
shader output. Otherwise, the four vertices of the resulting quad will
be assigned texture coordinates. For PIPE_SPRITE_COORD_LOWER_LEFT, the
lower left vertex will have coordinate (0,0,0,1).
drawing sprites, for each coord which has sprite_coord_enable set.
For PIPE_SPRITE_COORD_LOWER_LEFT, the lower left vertex will have
coordinate (0,0,0,1).
For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left vertex will have
coordinate (0,0,0,1).
This state is needed by :ref:`Draw` because that's where each
@@ -139,7 +141,15 @@ sprite_coord_mode
sprite rendering.
Note that when geometry shaders are available, this state could be
removed. A special geometry shader defined by the state tracker could
converts the incoming points into quads with the proper texture coords.
convert the incoming points into quads with the proper texture coords.
point_quad_rasterization
This determines if points should be rasterized as quads or points.
d3d always uses quad rasterization for points, regardless if point sprites
are enabled or not, but OGL has different rules. If point_quad_rasterization
is set, point_smooth should be disabled, and points will be rendered as
squares even if multisample is enabled.
sprite_coord_enable should be zero if point_quad_rasterization is not
enabled.
scissor
Whether the scissor test is enabled.

View File

@@ -1380,10 +1380,8 @@ TGSI_SEMANTIC_PSIZE
"""""""""""""""""""
PSIZE, or point size, is used to specify point sizes per-vertex. It should
be in ``(p, n, x, f)`` format, where ``p`` is the point size, ``n`` is the minimum
size, ``x`` is the maximum size, and ``f`` is the fade threshold.
XXX this is arb_vp. is this what we actually do? should double-check...
be in ``(s, 0, 0, 1)`` format, where ``s`` is the (possibly clamped) point size.
Only the first component matters when writing from the vertex shader.
When using this semantic, be sure to set the appropriate state in the
:ref:`rasterizer` first.

View File

@@ -127,6 +127,7 @@ static enum pipe_error compile_sf_prog( struct brw_context *brw,
static enum pipe_error upload_sf_prog(struct brw_context *brw)
{
const struct brw_fs_signature *sig = &brw->curr.fragment_shader->signature;
const struct pipe_rasterizer_state *rast = &brw->curr.rast->templ;
struct brw_sf_prog_key key;
enum pipe_error ret;
unsigned i;
@@ -165,8 +166,8 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw)
case PIPE_PRIM_TRIANGLES:
/* PIPE_NEW_RAST
*/
if (brw->curr.rast->templ.fill_cw != PIPE_POLYGON_MODE_FILL ||
brw->curr.rast->templ.fill_ccw != PIPE_POLYGON_MODE_FILL)
if (rast->fill_cw != PIPE_POLYGON_MODE_FILL ||
rast->fill_ccw != PIPE_POLYGON_MODE_FILL)
key.primitive = SF_UNFILLED_TRIS;
else
key.primitive = SF_TRIANGLES;
@@ -179,14 +180,14 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw)
break;
}
key.do_point_sprite = brw->curr.rast->templ.point_sprite;
key.sprite_origin_lower_left = 0; /* XXX: ctx->Point.SpriteOrigin - fix rast state */
key.do_flat_shading = brw->curr.rast->templ.flatshade;
key.do_twoside_color = brw->curr.rast->templ.light_twoside;
key.do_point_sprite = rast->sprite_coord_enable ? 1 : 0;
key.sprite_origin_lower_left = (rast->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT);
key.point_coord_replace_attrs = rast->sprite_coord_enable;
key.do_flat_shading = rast->flatshade;
key.do_twoside_color = rast->light_twoside;
if (key.do_twoside_color) {
key.frontface_ccw = (brw->curr.rast->templ.front_winding ==
PIPE_WINDING_CCW);
key.frontface_ccw = (rast->front_winding == PIPE_WINDING_CCW);
}
if (brw_search_cache(&brw->cache, BRW_SF_PROG,

View File

@@ -123,12 +123,10 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
key->line_last_pixel_enable = rast->line_last_pixel;
key->gl_rasterization_rules = rast->gl_rasterization_rules;
key->point_sprite = rast->point_sprite;
key->point_sprite = rast->sprite_coord_enable ? 1 : 0;
key->point_attenuated = rast->point_size_per_vertex;
key->point_size = CLAMP(rast->point_size,
rast->point_size_min,
rast->point_size_max);
key->point_size = rast->point_size;
}
static enum pipe_error

View File

@@ -0,0 +1,590 @@
#include "draw/draw_context.h"
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/p_inlines.h"
#include "tgsi/tgsi_parse.h"
#include "nv10_context.h"
#include "nv10_state.h"
static void *
nv10_blend_state_create(struct pipe_context *pipe,
const struct pipe_blend_state *cso)
{
struct nv10_blend_state *cb;
cb = MALLOC(sizeof(struct nv10_blend_state));
cb->b_enable = cso->blend_enable ? 1 : 0;
cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
(nvgl_blend_func(cso->rgb_src_factor)));
cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
(nvgl_blend_func(cso->rgb_dst_factor)));
cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));
cb->d_enable = cso->dither ? 1 : 0;
return (void *)cb;
}
static void
nv10_blend_state_bind(struct pipe_context *pipe, void *blend)
{
struct nv10_context *nv10 = nv10_context(pipe);
nv10->blend = (struct nv10_blend_state*)blend;
nv10->dirty |= NV10_NEW_BLEND;
}
static void
nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
static INLINE unsigned
wrap_mode(unsigned wrap) {
unsigned ret;
switch (wrap) {
case PIPE_TEX_WRAP_REPEAT:
ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT;
break;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
ret = NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT;
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_CLAMP:
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
case PIPE_TEX_WRAP_MIRROR_CLAMP:
default:
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT;
break;
}
return ret >> NV10TCL_TX_FORMAT_WRAP_S_SHIFT;
}
static void *
nv10_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso)
{
struct nv10_sampler_state *ps;
uint32_t filter = 0;
ps = MALLOC(sizeof(struct nv10_sampler_state));
ps->wrap = ((wrap_mode(cso->wrap_s) << NV10TCL_TX_FORMAT_WRAP_S_SHIFT) |
(wrap_mode(cso->wrap_t) << NV10TCL_TX_FORMAT_WRAP_T_SHIFT));
ps->en = 0;
if (cso->max_anisotropy > 1.0) {
/* no idea, binary driver sets it, works without it.. meh.. */
ps->wrap |= (1 << 5);
/* if (cso->max_anisotropy >= 16.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_16X;
} else
if (cso->max_anisotropy >= 12.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_12X;
} else
if (cso->max_anisotropy >= 10.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_10X;
} else
if (cso->max_anisotropy >= 8.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_8X;
} else
if (cso->max_anisotropy >= 6.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_6X;
} else
if (cso->max_anisotropy >= 4.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_4X;
} else {
ps->en |= NV10TCL_TX_ENABLE_ANISO_2X;
}*/
}
switch (cso->mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
filter |= NV10TCL_TX_FILTER_MAGNIFY_LINEAR;
break;
case PIPE_TEX_FILTER_NEAREST:
default:
filter |= NV10TCL_TX_FILTER_MAGNIFY_NEAREST;
break;
}
switch (cso->min_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR;
break;
}
break;
case PIPE_TEX_FILTER_NEAREST:
default:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST;
break;
}
break;
}
ps->filt = filter;
/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
switch (cso->compare_func) {
case PIPE_FUNC_NEVER:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
break;
case PIPE_FUNC_GREATER:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
break;
case PIPE_FUNC_EQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
break;
case PIPE_FUNC_GEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
break;
case PIPE_FUNC_LESS:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
break;
case PIPE_FUNC_NOTEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
break;
case PIPE_FUNC_LEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
break;
case PIPE_FUNC_ALWAYS:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
break;
default:
break;
}
}*/
ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
(float_to_ubyte(cso->border_color[0]) << 16) |
(float_to_ubyte(cso->border_color[1]) << 8) |
(float_to_ubyte(cso->border_color[2]) << 0));
return (void *)ps;
}
static void
nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
{
struct nv10_context *nv10 = nv10_context(pipe);
unsigned unit;
for (unit = 0; unit < nr; unit++) {
nv10->tex_sampler[unit] = sampler[unit];
nv10->dirty_samplers |= (1 << unit);
}
}
static void
nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
static void
nv10_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
struct pipe_texture **miptree)
{
struct nv10_context *nv10 = nv10_context(pipe);
unsigned unit;
for (unit = 0; unit < nr; unit++) {
nv10->tex_miptree[unit] = (struct nv10_miptree *)miptree[unit];
nv10->dirty_samplers |= (1 << unit);
}
}
static void *
nv10_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
struct nv10_rasterizer_state *rs;
int i;
/*XXX: ignored:
* light_twoside
* offset_cw/ccw -nohw
* scissor
* point_smooth -nohw
* multisample
* offset_units / offset_scale
*/
rs = MALLOC(sizeof(struct nv10_rasterizer_state));
rs->templ = cso;
rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01;
rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff;
rs->line_smooth_en = cso->line_smooth ? 1 : 0;
rs->point_size = *(uint32_t*)&cso->point_size;
rs->poly_smooth_en = cso->poly_smooth ? 1 : 0;
if (cso->front_winding == PIPE_WINDING_CCW) {
rs->front_face = NV10TCL_FRONT_FACE_CCW;
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw);
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw);
} else {
rs->front_face = NV10TCL_FRONT_FACE_CW;
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw);
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw);
}
switch (cso->cull_mode) {
case PIPE_WINDING_CCW:
rs->cull_face_en = 1;
if (cso->front_winding == PIPE_WINDING_CCW)
rs->cull_face = NV10TCL_CULL_FACE_FRONT;
else
rs->cull_face = NV10TCL_CULL_FACE_BACK;
break;
case PIPE_WINDING_CW:
rs->cull_face_en = 1;
if (cso->front_winding == PIPE_WINDING_CW)
rs->cull_face = NV10TCL_CULL_FACE_FRONT;
else
rs->cull_face = NV10TCL_CULL_FACE_BACK;
break;
case PIPE_WINDING_BOTH:
rs->cull_face_en = 1;
rs->cull_face = NV10TCL_CULL_FACE_FRONT_AND_BACK;
break;
case PIPE_WINDING_NONE:
default:
rs->cull_face_en = 0;
rs->cull_face = 0;
break;
}
if (cso->sprite_coord_enable) {
rs->point_sprite = (1 << 0);
for (i = 0; i < 8; i++) {
if ((cso->sprite_coord_enable >> i) & 1)
rs->point_sprite |= (1 << (8 + i));
}
} else {
rs->point_sprite = 0;
}
return (void *)rs;
}
static void
nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast)
{
struct nv10_context *nv10 = nv10_context(pipe);
nv10->rast = (struct nv10_rasterizer_state*)rast;
draw_set_rasterizer_state(nv10->draw, (nv10->rast ? nv10->rast->templ : NULL));
nv10->dirty |= NV10_NEW_RAST;
}
static void
nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
static void *
nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *cso)
{
struct nv10_depth_stencil_alpha_state *hw;
hw = MALLOC(sizeof(struct nv10_depth_stencil_alpha_state));
hw->depth.func = nvgl_comparison_op(cso->depth.func);
hw->depth.write_enable = cso->depth.writemask ? 1 : 0;
hw->depth.test_enable = cso->depth.enabled ? 1 : 0;
hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0;
hw->stencil.wmask = cso->stencil[0].writemask;
hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func);
hw->stencil.ref = cso->stencil[0].ref_value;
hw->stencil.vmask = cso->stencil[0].valuemask;
hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op);
hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op);
hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op);
hw->alpha.enabled = cso->alpha.enabled ? 1 : 0;
hw->alpha.func = nvgl_comparison_op(cso->alpha.func);
hw->alpha.ref = float_to_ubyte(cso->alpha.ref_value);
return (void *)hw;
}
static void
nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa)
{
struct nv10_context *nv10 = nv10_context(pipe);
nv10->dsa = (struct nv10_depth_stencil_alpha_state*)dsa;
nv10->dirty |= NV10_NEW_DSA;
}
static void
nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
static void *
nv10_vp_state_create(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
struct nv10_context *nv10 = nv10_context(pipe);
return draw_create_vertex_shader(nv10->draw, templ);
}
static void
nv10_vp_state_bind(struct pipe_context *pipe, void *shader)
{
struct nv10_context *nv10 = nv10_context(pipe);
draw_bind_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader);
nv10->dirty |= NV10_NEW_VERTPROG;
}
static void
nv10_vp_state_delete(struct pipe_context *pipe, void *shader)
{
struct nv10_context *nv10 = nv10_context(pipe);
draw_delete_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader);
}
static void *
nv10_fp_state_create(struct pipe_context *pipe,
const struct pipe_shader_state *cso)
{
struct nv10_fragment_program *fp;
fp = CALLOC(1, sizeof(struct nv10_fragment_program));
fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
tgsi_scan_shader(cso->tokens, &fp->info);
return (void *)fp;
}
static void
nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_fragment_program *fp = hwcso;
nv10->fragprog.current = fp;
nv10->dirty |= NV10_NEW_FRAGPROG;
}
static void
nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_fragment_program *fp = hwcso;
nv10_fragprog_destroy(nv10, fp);
FREE((void*)fp->pipe.tokens);
FREE(fp);
}
static void
nv10_set_blend_color(struct pipe_context *pipe,
const struct pipe_blend_color *bcol)
{
struct nv10_context *nv10 = nv10_context(pipe);
nv10->blend_color = (struct pipe_blend_color*)bcol;
nv10->dirty |= NV10_NEW_BLENDCOL;
}
static void
nv10_set_clip_state(struct pipe_context *pipe,
const struct pipe_clip_state *clip)
{
struct nv10_context *nv10 = nv10_context(pipe);
draw_set_clip_state(nv10->draw, clip);
}
static void
nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
const struct pipe_constant_buffer *buf )
{
struct nv10_context *nv10 = nv10_context(pipe);
struct pipe_screen *pscreen = pipe->screen;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
if (buf) {
void *mapped;
if (buf->buffer && buf->buffer->size &&
(mapped = pipe_buffer_map(pscreen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)))
{
memcpy(nv10->constbuf[shader], mapped, buf->buffer->size);
nv10->constbuf_nr[shader] =
buf->buffer->size / (4 * sizeof(float));
pipe_buffer_unmap(pscreen, buf->buffer);
}
}
}
static void
nv10_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct nv10_context *nv10 = nv10_context(pipe);
nv10->framebuffer = (struct pipe_framebuffer_state*)fb;
nv10->dirty |= NV10_NEW_FRAMEBUFFER;
}
static void
nv10_set_polygon_stipple(struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple)
{
NOUVEAU_ERR("line stipple hahaha\n");
}
static void
nv10_set_scissor_state(struct pipe_context *pipe,
const struct pipe_scissor_state *s)
{
struct nv10_context *nv10 = nv10_context(pipe);
nv10->scissor = (struct pipe_scissor_state*)s;
nv10->dirty |= NV10_NEW_SCISSOR;
}
static void
nv10_set_viewport_state(struct pipe_context *pipe,
const struct pipe_viewport_state *vpt)
{
struct nv10_context *nv10 = nv10_context(pipe);
nv10->viewport = (struct pipe_viewport_state*)vpt;
draw_set_viewport_state(nv10->draw, nv10->viewport);
nv10->dirty |= NV10_NEW_VIEWPORT;
}
static void
nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
const struct pipe_vertex_buffer *vb)
{
struct nv10_context *nv10 = nv10_context(pipe);
memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count);
nv10->dirty |= NV10_NEW_VTXARRAYS;
draw_set_vertex_buffers(nv10->draw, count, vb);
}
static void
nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count,
const struct pipe_vertex_element *ve)
{
struct nv10_context *nv10 = nv10_context(pipe);
memcpy(nv10->vtxelt, ve, sizeof(*ve) * count);
nv10->dirty |= NV10_NEW_VTXARRAYS;
draw_set_vertex_elements(nv10->draw, count, ve);
}
void
nv10_init_state_functions(struct nv10_context *nv10)
{
nv10->pipe.create_blend_state = nv10_blend_state_create;
nv10->pipe.bind_blend_state = nv10_blend_state_bind;
nv10->pipe.delete_blend_state = nv10_blend_state_delete;
nv10->pipe.create_sampler_state = nv10_sampler_state_create;
nv10->pipe.bind_fragment_sampler_states = nv10_sampler_state_bind;
nv10->pipe.delete_sampler_state = nv10_sampler_state_delete;
nv10->pipe.set_fragment_sampler_textures = nv10_set_sampler_texture;
nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create;
nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind;
nv10->pipe.delete_rasterizer_state = nv10_rasterizer_state_delete;
nv10->pipe.create_depth_stencil_alpha_state =
nv10_depth_stencil_alpha_state_create;
nv10->pipe.bind_depth_stencil_alpha_state =
nv10_depth_stencil_alpha_state_bind;
nv10->pipe.delete_depth_stencil_alpha_state =
nv10_depth_stencil_alpha_state_delete;
nv10->pipe.create_vs_state = nv10_vp_state_create;
nv10->pipe.bind_vs_state = nv10_vp_state_bind;
nv10->pipe.delete_vs_state = nv10_vp_state_delete;
nv10->pipe.create_fs_state = nv10_fp_state_create;
nv10->pipe.bind_fs_state = nv10_fp_state_bind;
nv10->pipe.delete_fs_state = nv10_fp_state_delete;
nv10->pipe.set_blend_color = nv10_set_blend_color;
nv10->pipe.set_clip_state = nv10_set_clip_state;
nv10->pipe.set_constant_buffer = nv10_set_constant_buffer;
nv10->pipe.set_framebuffer_state = nv10_set_framebuffer_state;
nv10->pipe.set_polygon_stipple = nv10_set_polygon_stipple;
nv10->pipe.set_scissor_state = nv10_set_scissor_state;
nv10->pipe.set_viewport_state = nv10_set_viewport_state;
nv10->pipe.set_vertex_buffers = nv10_set_vertex_buffers;
nv10->pipe.set_vertex_elements = nv10_set_vertex_elements;
}

View File

@@ -0,0 +1,583 @@
#include "draw/draw_context.h"
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/p_inlines.h"
#include "tgsi/tgsi_parse.h"
#include "nv20_context.h"
#include "nv20_state.h"
static void *
nv20_blend_state_create(struct pipe_context *pipe,
const struct pipe_blend_state *cso)
{
struct nv20_blend_state *cb;
cb = MALLOC(sizeof(struct nv20_blend_state));
cb->b_enable = cso->blend_enable ? 1 : 0;
cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
(nvgl_blend_func(cso->rgb_src_factor)));
cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
(nvgl_blend_func(cso->rgb_dst_factor)));
cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));
cb->d_enable = cso->dither ? 1 : 0;
return (void *)cb;
}
static void
nv20_blend_state_bind(struct pipe_context *pipe, void *blend)
{
struct nv20_context *nv20 = nv20_context(pipe);
nv20->blend = (struct nv20_blend_state*)blend;
nv20->dirty |= NV20_NEW_BLEND;
}
static void
nv20_blend_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
static INLINE unsigned
wrap_mode(unsigned wrap) {
unsigned ret;
switch (wrap) {
case PIPE_TEX_WRAP_REPEAT:
ret = NV20TCL_TX_WRAP_S_REPEAT;
break;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
ret = NV20TCL_TX_WRAP_S_MIRRORED_REPEAT;
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
ret = NV20TCL_TX_WRAP_S_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
ret = NV20TCL_TX_WRAP_S_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_CLAMP:
ret = NV20TCL_TX_WRAP_S_CLAMP;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
case PIPE_TEX_WRAP_MIRROR_CLAMP:
default:
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
ret = NV20TCL_TX_WRAP_S_REPEAT;
break;
}
return (ret >> NV20TCL_TX_WRAP_S_SHIFT);
}
static void *
nv20_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso)
{
struct nv20_sampler_state *ps;
uint32_t filter = 0;
ps = MALLOC(sizeof(struct nv20_sampler_state));
ps->wrap = ((wrap_mode(cso->wrap_s) << NV20TCL_TX_WRAP_S_SHIFT) |
(wrap_mode(cso->wrap_t) << NV20TCL_TX_WRAP_T_SHIFT));
ps->en = 0;
if (cso->max_anisotropy > 1.0) {
/* no idea, binary driver sets it, works without it.. meh.. */
ps->wrap |= (1 << 5);
/* if (cso->max_anisotropy >= 8.0) {
ps->en |= NV20TCL_TX_ENABLE_ANISO_8X;
} else
if (cso->max_anisotropy >= 4.0) {
ps->en |= NV20TCL_TX_ENABLE_ANISO_4X;
} else {
ps->en |= NV20TCL_TX_ENABLE_ANISO_2X;
}*/
}
switch (cso->mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
filter |= NV20TCL_TX_FILTER_MAGNIFY_LINEAR;
break;
case PIPE_TEX_FILTER_NEAREST:
default:
filter |= NV20TCL_TX_FILTER_MAGNIFY_NEAREST;
break;
}
switch (cso->min_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |=
NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV20TCL_TX_FILTER_MINIFY_LINEAR;
break;
}
break;
case PIPE_TEX_FILTER_NEAREST:
default:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |=
NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |=
NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV20TCL_TX_FILTER_MINIFY_NEAREST;
break;
}
break;
}
ps->filt = filter;
/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
switch (cso->compare_func) {
case PIPE_FUNC_NEVER:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
break;
case PIPE_FUNC_GREATER:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
break;
case PIPE_FUNC_EQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
break;
case PIPE_FUNC_GEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
break;
case PIPE_FUNC_LESS:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
break;
case PIPE_FUNC_NOTEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
break;
case PIPE_FUNC_LEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
break;
case PIPE_FUNC_ALWAYS:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
break;
default:
break;
}
}*/
ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
(float_to_ubyte(cso->border_color[0]) << 16) |
(float_to_ubyte(cso->border_color[1]) << 8) |
(float_to_ubyte(cso->border_color[2]) << 0));
return (void *)ps;
}
static void
nv20_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
{
struct nv20_context *nv20 = nv20_context(pipe);
unsigned unit;
for (unit = 0; unit < nr; unit++) {
nv20->tex_sampler[unit] = sampler[unit];
nv20->dirty_samplers |= (1 << unit);
}
}
static void
nv20_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
static void
nv20_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
struct pipe_texture **miptree)
{
struct nv20_context *nv20 = nv20_context(pipe);
unsigned unit;
for (unit = 0; unit < nr; unit++) {
nv20->tex_miptree[unit] = (struct nv20_miptree *)miptree[unit];
nv20->dirty_samplers |= (1 << unit);
}
}
static void *
nv20_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
struct nv20_rasterizer_state *rs;
int i;
/*XXX: ignored:
* light_twoside
* offset_cw/ccw -nohw
* scissor
* point_smooth -nohw
* multisample
* offset_units / offset_scale
*/
rs = MALLOC(sizeof(struct nv20_rasterizer_state));
rs->templ = cso;
rs->shade_model = cso->flatshade ? NV20TCL_SHADE_MODEL_FLAT :
NV20TCL_SHADE_MODEL_SMOOTH;
rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff;
rs->line_smooth_en = cso->line_smooth ? 1 : 0;
/* XXX: nv20 and nv25 different! */
rs->point_size = *(uint32_t*)&cso->point_size;
rs->poly_smooth_en = cso->poly_smooth ? 1 : 0;
if (cso->front_winding == PIPE_WINDING_CCW) {
rs->front_face = NV20TCL_FRONT_FACE_CCW;
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw);
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw);
} else {
rs->front_face = NV20TCL_FRONT_FACE_CW;
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw);
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw);
}
switch (cso->cull_mode) {
case PIPE_WINDING_CCW:
rs->cull_face_en = 1;
if (cso->front_winding == PIPE_WINDING_CCW)
rs->cull_face = NV20TCL_CULL_FACE_FRONT;
else
rs->cull_face = NV20TCL_CULL_FACE_BACK;
break;
case PIPE_WINDING_CW:
rs->cull_face_en = 1;
if (cso->front_winding == PIPE_WINDING_CW)
rs->cull_face = NV20TCL_CULL_FACE_FRONT;
else
rs->cull_face = NV20TCL_CULL_FACE_BACK;
break;
case PIPE_WINDING_BOTH:
rs->cull_face_en = 1;
rs->cull_face = NV20TCL_CULL_FACE_FRONT_AND_BACK;
break;
case PIPE_WINDING_NONE:
default:
rs->cull_face_en = 0;
rs->cull_face = 0;
break;
}
if (cso->sprite_coord_enable) {
rs->point_sprite = (1 << 0);
for (i = 0; i < 8; i++) {
if ((cso->sprite_coord_enable >> i) & 1)
rs->point_sprite |= (1 << (8 + i));
}
} else {
rs->point_sprite = 0;
}
return (void *)rs;
}
static void
nv20_rasterizer_state_bind(struct pipe_context *pipe, void *rast)
{
struct nv20_context *nv20 = nv20_context(pipe);
nv20->rast = (struct nv20_rasterizer_state*)rast;
draw_set_rasterizer_state(nv20->draw, (nv20->rast ? nv20->rast->templ : NULL));
nv20->dirty |= NV20_NEW_RAST;
}
static void
nv20_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
static void *
nv20_depth_stencil_alpha_state_create(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *cso)
{
struct nv20_depth_stencil_alpha_state *hw;
hw = MALLOC(sizeof(struct nv20_depth_stencil_alpha_state));
hw->depth.func = nvgl_comparison_op(cso->depth.func);
hw->depth.write_enable = cso->depth.writemask ? 1 : 0;
hw->depth.test_enable = cso->depth.enabled ? 1 : 0;
hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0;
hw->stencil.wmask = cso->stencil[0].writemask;
hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func);
hw->stencil.ref = cso->stencil[0].ref_value;
hw->stencil.vmask = cso->stencil[0].valuemask;
hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op);
hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op);
hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op);
hw->alpha.enabled = cso->alpha.enabled ? 1 : 0;
hw->alpha.func = nvgl_comparison_op(cso->alpha.func);
hw->alpha.ref = float_to_ubyte(cso->alpha.ref_value);
return (void *)hw;
}
static void
nv20_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa)
{
struct nv20_context *nv20 = nv20_context(pipe);
nv20->dsa = (struct nv20_depth_stencil_alpha_state*)dsa;
nv20->dirty |= NV20_NEW_DSA;
}
static void
nv20_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
static void *
nv20_vp_state_create(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
struct nv20_context *nv20 = nv20_context(pipe);
return draw_create_vertex_shader(nv20->draw, templ);
}
static void
nv20_vp_state_bind(struct pipe_context *pipe, void *shader)
{
struct nv20_context *nv20 = nv20_context(pipe);
draw_bind_vertex_shader(nv20->draw, (struct draw_vertex_shader *) shader);
nv20->dirty |= NV20_NEW_VERTPROG;
}
static void
nv20_vp_state_delete(struct pipe_context *pipe, void *shader)
{
struct nv20_context *nv20 = nv20_context(pipe);
draw_delete_vertex_shader(nv20->draw, (struct draw_vertex_shader *) shader);
}
static void *
nv20_fp_state_create(struct pipe_context *pipe,
const struct pipe_shader_state *cso)
{
struct nv20_fragment_program *fp;
fp = CALLOC(1, sizeof(struct nv20_fragment_program));
fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
tgsi_scan_shader(cso->tokens, &fp->info);
return (void *)fp;
}
static void
nv20_fp_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv20_context *nv20 = nv20_context(pipe);
struct nv20_fragment_program *fp = hwcso;
nv20->fragprog.current = fp;
nv20->dirty |= NV20_NEW_FRAGPROG;
}
static void
nv20_fp_state_delete(struct pipe_context *pipe, void *hwcso)
{
struct nv20_context *nv20 = nv20_context(pipe);
struct nv20_fragment_program *fp = hwcso;
nv20_fragprog_destroy(nv20, fp);
FREE((void*)fp->pipe.tokens);
FREE(fp);
}
static void
nv20_set_blend_color(struct pipe_context *pipe,
const struct pipe_blend_color *bcol)
{
struct nv20_context *nv20 = nv20_context(pipe);
nv20->blend_color = (struct pipe_blend_color*)bcol;
nv20->dirty |= NV20_NEW_BLENDCOL;
}
static void
nv20_set_clip_state(struct pipe_context *pipe,
const struct pipe_clip_state *clip)
{
struct nv20_context *nv20 = nv20_context(pipe);
draw_set_clip_state(nv20->draw, clip);
}
static void
nv20_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
const struct pipe_constant_buffer *buf )
{
struct nv20_context *nv20 = nv20_context(pipe);
struct pipe_screen *pscreen = pipe->screen;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
if (buf) {
void *mapped;
if (buf->buffer && buf->buffer->size &&
(mapped = pipe_buffer_map(pscreen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)))
{
memcpy(nv20->constbuf[shader], mapped, buf->buffer->size);
nv20->constbuf_nr[shader] =
buf->buffer->size / (4 * sizeof(float));
pipe_buffer_unmap(pscreen, buf->buffer);
}
}
}
static void
nv20_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct nv20_context *nv20 = nv20_context(pipe);
nv20->framebuffer = (struct pipe_framebuffer_state*)fb;
nv20->dirty |= NV20_NEW_FRAMEBUFFER;
}
static void
nv20_set_polygon_stipple(struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple)
{
NOUVEAU_ERR("line stipple hahaha\n");
}
static void
nv20_set_scissor_state(struct pipe_context *pipe,
const struct pipe_scissor_state *s)
{
struct nv20_context *nv20 = nv20_context(pipe);
nv20->scissor = (struct pipe_scissor_state*)s;
nv20->dirty |= NV20_NEW_SCISSOR;
}
static void
nv20_set_viewport_state(struct pipe_context *pipe,
const struct pipe_viewport_state *vpt)
{
struct nv20_context *nv20 = nv20_context(pipe);
nv20->viewport = (struct pipe_viewport_state*)vpt;
draw_set_viewport_state(nv20->draw, nv20->viewport);
nv20->dirty |= NV20_NEW_VIEWPORT;
}
static void
nv20_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
const struct pipe_vertex_buffer *vb)
{
struct nv20_context *nv20 = nv20_context(pipe);
memcpy(nv20->vtxbuf, vb, sizeof(*vb) * count);
nv20->dirty |= NV20_NEW_VTXARRAYS;
draw_set_vertex_buffers(nv20->draw, count, vb);
}
static void
nv20_set_vertex_elements(struct pipe_context *pipe, unsigned count,
const struct pipe_vertex_element *ve)
{
struct nv20_context *nv20 = nv20_context(pipe);
memcpy(nv20->vtxelt, ve, sizeof(*ve) * count);
nv20->dirty |= NV20_NEW_VTXARRAYS;
draw_set_vertex_elements(nv20->draw, count, ve);
}
void
nv20_init_state_functions(struct nv20_context *nv20)
{
nv20->pipe.create_blend_state = nv20_blend_state_create;
nv20->pipe.bind_blend_state = nv20_blend_state_bind;
nv20->pipe.delete_blend_state = nv20_blend_state_delete;
nv20->pipe.create_sampler_state = nv20_sampler_state_create;
nv20->pipe.bind_fragment_sampler_states = nv20_sampler_state_bind;
nv20->pipe.delete_sampler_state = nv20_sampler_state_delete;
nv20->pipe.set_fragment_sampler_textures = nv20_set_sampler_texture;
nv20->pipe.create_rasterizer_state = nv20_rasterizer_state_create;
nv20->pipe.bind_rasterizer_state = nv20_rasterizer_state_bind;
nv20->pipe.delete_rasterizer_state = nv20_rasterizer_state_delete;
nv20->pipe.create_depth_stencil_alpha_state =
nv20_depth_stencil_alpha_state_create;
nv20->pipe.bind_depth_stencil_alpha_state =
nv20_depth_stencil_alpha_state_bind;
nv20->pipe.delete_depth_stencil_alpha_state =
nv20_depth_stencil_alpha_state_delete;
nv20->pipe.create_vs_state = nv20_vp_state_create;
nv20->pipe.bind_vs_state = nv20_vp_state_bind;
nv20->pipe.delete_vs_state = nv20_vp_state_delete;
nv20->pipe.create_fs_state = nv20_fp_state_create;
nv20->pipe.bind_fs_state = nv20_fp_state_bind;
nv20->pipe.delete_fs_state = nv20_fp_state_delete;
nv20->pipe.set_blend_color = nv20_set_blend_color;
nv20->pipe.set_clip_state = nv20_set_clip_state;
nv20->pipe.set_constant_buffer = nv20_set_constant_buffer;
nv20->pipe.set_framebuffer_state = nv20_set_framebuffer_state;
nv20->pipe.set_polygon_stipple = nv20_set_polygon_stipple;
nv20->pipe.set_scissor_state = nv20_set_scissor_state;
nv20->pipe.set_viewport_state = nv20_set_viewport_state;
nv20->pipe.set_vertex_buffers = nv20_set_vertex_buffers;
nv20->pipe.set_vertex_elements = nv20_set_vertex_elements;
}

View File

@@ -391,11 +391,11 @@ nv30_rasterizer_state_create(struct pipe_context *pipe,
}
so_method(so, rankine, NV34TCL_POINT_SPRITE, 1);
if (cso->point_sprite) {
if (cso->point_quad_rasterization) {
unsigned psctl = (1 << 0), i;
for (i = 0; i < 8; i++) {
if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE)
if ((cso->sprite_coord_enable >> i) & 1)
psctl |= (1 << (8 + i));
}

View File

@@ -401,11 +401,11 @@ nv40_rasterizer_state_create(struct pipe_context *pipe,
}
so_method(so, curie, NV40TCL_POINT_SPRITE, 1);
if (cso->point_sprite) {
if (cso->point_quad_rasterization) {
unsigned psctl = (1 << 0), i;
for (i = 0; i < 8; i++) {
if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE)
if ((cso->sprite_coord_enable >> i) & 1)
psctl |= (1 << (8 + i));
}

View File

@@ -4406,16 +4406,14 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base)
vp->cfg.out[j].si == fp->cfg.in[i].si)
break;
if (j < vp->cfg.out_nr) {
ubyte mode = nv50->rasterizer->pipe.sprite_coord_mode[
vp->cfg.out[j].si];
if (j < vp->info.num_outputs) {
ubyte enable =
(nv50->rasterizer->pipe.sprite_coord_enable >> vp->cfg.out[j].si) & 1;
if (mode == PIPE_SPRITE_COORD_NONE) {
if (enable == 0) {
m += n;
continue;
} else
if (mode == PIPE_SPRITE_COORD_LOWER_LEFT)
origin = 0;
}
}
/* this is either PointCoord or replaced by sprite coords */
@@ -4426,7 +4424,7 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base)
++m;
}
}
return origin;
return (nv50->rasterizer->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT ? 0 : origin);
}
static int
@@ -4570,7 +4568,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_NOPERSPECTIVE_BITMAP(0), 4);
so_datap (so, lin, 4);
if (nv50->rasterizer->pipe.point_sprite) {
if (nv50->rasterizer->pipe.sprite_coord_enable) {
so_method(so, tesla, NV50TCL_POINT_SPRITE_CTRL, 1);
so_data (so,
nv50_pntc_replace(nv50, pcrd, (reg[4] >> 8) & 0xff));

View File

@@ -342,7 +342,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
so_data (so, fui(cso->point_size));
so_method(so, tesla, NV50TCL_POINT_SPRITE_ENABLE, 1);
so_data (so, cso->point_sprite);
so_data (so, cso->point_quad_rasterization ? 1 : 0);
so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3);
if (cso->front_winding == PIPE_WINDING_CCW) {

View File

@@ -628,10 +628,12 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->point_size = pack_float_16_6x(state->point_size) |
(pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT);
rs->point_minmax =
((int)(state->point_size_min * 6.0) <<
/* set hw limits - clamping done by state tracker in vs or point_size
XXX always need to emit this? */
rs->point_minmax =
((int)(0.0 * 6.0) <<
R300_GA_POINT_MINMAX_MIN_SHIFT) |
((int)(state->point_size_max * 6.0) <<
((int)(4096.0 * 6.0) <<
R300_GA_POINT_MINMAX_MAX_SHIFT);
rs->line_control = pack_float_16_6x(state->line_width) |

View File

@@ -166,7 +166,7 @@ init_pipe_state(struct sp_mpeg12_context *ctx)
rast.scissor = 0;
rast.poly_smooth = 0;
rast.poly_stipple_enable = 0;
rast.point_sprite = 0;
rast.sprite_coord_enable = 0;
rast.point_size_per_vertex = 0;
rast.multisample = 0;
rast.line_smooth = 0;
@@ -177,10 +177,10 @@ init_pipe_state(struct sp_mpeg12_context *ctx)
rast.bypass_vs_clip_and_viewport = 0;
rast.line_width = 1;
rast.point_smooth = 0;
rast.point_quad_rasterization = 0;
rast.point_size = 1;
rast.offset_units = 1;
rast.offset_scale = 1;
/*rast.sprite_coord_mode[i] = ;*/
ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);

View File

@@ -37,6 +37,7 @@
#define SVGA_TEX_UNITS 8
#define SVGA_MAX_POINTSIZE 80.0
struct draw_vertex_shader;
struct svga_shader_result;
@@ -145,8 +146,6 @@ struct svga_rasterizer_state {
float slopescaledepthbias;
float depthbias;
float pointsize;
float pointsize_min;
float pointsize_max;
unsigned hw_unfilled:16; /* PIPE_POLYGON_MODE_x */
unsigned need_pipeline:16; /* which prims do we need help for? */

View File

@@ -70,7 +70,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
/* light_twoside - XXX: need fragment shader varient */
/* poly_smooth - XXX: no fallback available */
/* poly_stipple_enable - draw module */
/* point_sprite - ? */
/* sprite_coord_enable - ? */
/* point_quad_rasterization - ? */
/* point_size_per_vertex - ? */
/* sprite_coord_mode - ??? */
/* bypass_vs_viewport_and_clip - handled by viewport setup */
@@ -87,8 +88,6 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
rast->antialiasedlineenable = templ->line_smooth;
rast->lastpixel = templ->line_last_pixel;
rast->pointsize = templ->point_size;
rast->pointsize_min = templ->point_size_min;
rast->pointsize_max = templ->point_size_max;
rast->hw_unfilled = PIPE_POLYGON_MODE_FILL;
/* Use swtnl + decomposition implement these:

View File

@@ -101,7 +101,7 @@ svga_get_paramf(struct pipe_screen *screen, int param)
/* Keep this to a reasonable size to avoid failures in
* conform/pntaa.c:
*/
return 80.0;
return SVGA_MAX_POINTSIZE;
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
return 4.0;

View File

@@ -193,8 +193,9 @@ static int emit_rss( struct svga_context *svga,
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
EMIT_RS_FLOAT( svga, curr->pointsize_min, POINTSIZEMIN, fail );
EMIT_RS_FLOAT( svga, curr->pointsize_max, POINTSIZEMAX, fail );
/* XXX still need to set this? */
EMIT_RS_FLOAT( svga, 0.0, POINTSIZEMIN, fail );
EMIT_RS_FLOAT( svga, SVGA_MAX_POINTSIZE, POINTSIZEMAX, fail );
}
if (dirty & (SVGA_NEW_RAST | SVGA_NEW_FRAME_BUFFER | SVGA_NEW_NEED_PIPELINE))

View File

@@ -112,7 +112,9 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state)
trace_dump_member(bool, state, poly_smooth);
trace_dump_member(bool, state, poly_stipple_enable);
trace_dump_member(bool, state, point_smooth);
trace_dump_member(bool, state, point_sprite);
trace_dump_member(uint, state, sprite_coord_enable);
trace_dump_member(bool, state, sprite_coord_mode);
trace_dump_member(bool, state, point_quad_rasterization);
trace_dump_member(bool, state, point_size_per_vertex);
trace_dump_member(bool, state, multisample);
trace_dump_member(bool, state, line_smooth);
@@ -126,13 +128,9 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state)
trace_dump_member(float, state, line_width);
trace_dump_member(float, state, point_size);
trace_dump_member(float, state, point_size_min);
trace_dump_member(float, state, point_size_max);
trace_dump_member(float, state, offset_units);
trace_dump_member(float, state, offset_scale);
trace_dump_member_array(uint, state, sprite_coord_mode);
trace_dump_struct_end();
}

View File

@@ -364,9 +364,8 @@ enum pipe_transfer_usage {
/**
* Point sprite coord modes
*/
#define PIPE_SPRITE_COORD_NONE 0
#define PIPE_SPRITE_COORD_UPPER_LEFT 1
#define PIPE_SPRITE_COORD_LOWER_LEFT 2
#define PIPE_SPRITE_COORD_UPPER_LEFT 0
#define PIPE_SPRITE_COORD_LOWER_LEFT 1
/**

View File

@@ -102,7 +102,9 @@ struct pipe_rasterizer_state
unsigned poly_smooth:1;
unsigned poly_stipple_enable:1;
unsigned point_smooth:1;
unsigned point_sprite:1;
unsigned sprite_coord_enable:PIPE_MAX_SHADER_OUTPUTS;
unsigned sprite_coord_mode:1; /**< PIPE_SPRITE_COORD_ */
unsigned point_quad_rasterization:1; /** points rasterized as quads or points */
unsigned point_size_per_vertex:1; /**< size computed in vertex shader */
unsigned multisample:1; /* XXX maybe more ms state in future */
unsigned line_smooth:1;
@@ -142,11 +144,8 @@ struct pipe_rasterizer_state
float line_width;
float point_size; /**< used when no per-vertex size */
float point_size_min; /* XXX - temporary, will go away */
float point_size_max; /* XXX - temporary, will go away */
float offset_units;
float offset_scale;
ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
};

View File

@@ -113,7 +113,7 @@ struct_factories = {
member_array_factories = {
"pipe_rasterizer_state": {"sprite_coord_mode": gallium.ByteArray},
#"pipe_rasterizer_state": {"sprite_coord_mode": gallium.ByteArray},
"pipe_poly_stipple": {"stipple": gallium.UnsignedArray},
"pipe_viewport_state": {"scale": gallium.FloatArray, "translate": gallium.FloatArray},
#"pipe_clip_state": {"ucp": gallium.FloatArray},

View File

@@ -1496,7 +1496,7 @@ static void build_texture_transform( struct tnl_program *p )
static void build_atten_pointsize( struct tnl_program *p )
{
struct ureg eye = get_eye_position_z(p);
struct ureg state_size = register_param1(p, STATE_POINT_SIZE);
struct ureg state_size = register_param2(p, STATE_INTERNAL, STATE_POINT_SIZE_CLAMPED);
struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION);
struct ureg out = register_output(p, VERT_RESULT_PSIZ);
struct ureg ut = get_temp(p);

View File

@@ -445,6 +445,61 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2);
return;
case STATE_POINT_SIZE_CLAMPED:
{
/* this includes implementation dependent limits, to avoid
* another potentially necessary clamp.
* Note: for sprites, point smooth (point AA) is ignored
* and we'll clamp to MinPointSizeAA and MaxPointSize, because we
* expect drivers will want to say their minimum for AA size is 0.0
* but for non-AA it's 1.0 (because normal points with size below 1.0
* need to get rounded up to 1.0, hence never disappear). GL does
* not specify max clamp size for sprites, other than it needs to be
* at least as large as max AA size, hence use non-AA size there.
*/
GLfloat minImplSize;
GLfloat maxImplSize;
if (ctx->Point.PointSprite) {
minImplSize = ctx->Const.MinPointSizeAA;
maxImplSize = ctx->Const.MaxPointSize;
}
else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
minImplSize = ctx->Const.MinPointSizeAA;
maxImplSize = ctx->Const.MaxPointSizeAA;
}
else {
minImplSize = ctx->Const.MinPointSize;
maxImplSize = ctx->Const.MaxPointSize;
}
value[0] = ctx->Point.Size;
value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize;
value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize;
value[3] = ctx->Point.Threshold;
}
return;
case STATE_POINT_SIZE_IMPL_CLAMP:
{
/* for implementation clamp only in vs */
GLfloat minImplSize;
GLfloat maxImplSize;
if (ctx->Point.PointSprite) {
minImplSize = ctx->Const.MinPointSizeAA;
maxImplSize = ctx->Const.MaxPointSize;
}
else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
minImplSize = ctx->Const.MinPointSizeAA;
maxImplSize = ctx->Const.MaxPointSizeAA;
}
else {
minImplSize = ctx->Const.MinPointSize;
maxImplSize = ctx->Const.MaxPointSize;
}
value[0] = ctx->Point.Size;
value[1] = minImplSize;
value[2] = maxImplSize;
value[3] = ctx->Point.Threshold;
}
return;
case STATE_LIGHT_SPOT_DIR_NORMALIZED:
{
/* here, state[2] is the light number */
@@ -640,6 +695,9 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
return _NEW_TEXTURE;
case STATE_FOG_PARAMS_OPTIMIZED:
return _NEW_FOG;
case STATE_POINT_SIZE_CLAMPED:
case STATE_POINT_SIZE_IMPL_CLAMP:
return _NEW_POINT | _NEW_MULTISAMPLE;
case STATE_LIGHT_SPOT_DIR_NORMALIZED:
case STATE_LIGHT_POSITION:
case STATE_LIGHT_POSITION_NORMALIZED:
@@ -831,6 +889,12 @@ append_token(char *dst, gl_state_index k)
case STATE_FOG_PARAMS_OPTIMIZED:
append(dst, "fogParamsOptimized");
break;
case STATE_POINT_SIZE_CLAMPED:
append(dst, "pointSizeClamped");
break;
case STATE_POINT_SIZE_IMPL_CLAMP:
append(dst, "pointSizeImplClamp");
break;
case STATE_LIGHT_SPOT_DIR_NORMALIZED:
append(dst, "lightSpotDirNormalized");
break;

View File

@@ -108,6 +108,8 @@ typedef enum gl_state_index_ {
STATE_NORMAL_SCALE,
STATE_TEXRECT_SCALE,
STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */
STATE_POINT_SIZE_CLAMPED, /* includes implementation dependent size clamp */
STATE_POINT_SIZE_IMPL_CLAMP, /* for implementation clamp only in vs */
STATE_LIGHT_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */
STATE_LIGHT_POSITION, /* object vs eye space */
STATE_LIGHT_POSITION_NORMALIZED, /* object vs eye space */

View File

@@ -188,22 +188,21 @@ static void update_raster_state( struct st_context *st )
*/
raster->point_size = ctx->Point.Size;
raster->point_size_min = 0; /* temporary, will go away */
raster->point_size_max = 1000; /* temporary, will go away */
if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag)
raster->point_smooth = 1;
raster->point_smooth = ctx->Point.SmoothFlag;
raster->point_sprite = ctx->Point.PointSprite;
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
if (ctx->Point.CoordReplace[i]) {
if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
(st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_UPPER_LEFT;
else
raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_LOWER_LEFT;
}
else {
raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_NONE;
if (ctx->Point.PointSprite) {
if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
(st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
else
raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
if (ctx->Point.CoordReplace[i]) {
raster->sprite_coord_enable |= 1 << i;
}
}
raster->point_quad_rasterization = 1;
}
/* ST_NEW_VERTEX_PROGRAM

View File

@@ -113,6 +113,15 @@ void st_init_limits(struct st_context *st)
= _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH));
c->MaxPointSizeAA
= _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA));
/* called after _mesa_create_context/_mesa_init_point, fix default user
* settable max point size up
*/
st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA);
/* these are not queryable. Note that GL basically mandates a 1.0 minimum
* for non-aa sizes, but we can go down to 0.0 for aa points.
*/
c->MinPointSize = 1.0f;
c->MinPointSizeAA = 0.0f;
c->MaxTextureMaxAnisotropy
= _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY));

View File

@@ -62,6 +62,10 @@ struct st_translate {
struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
struct ureg_dst address[1];
struct ureg_src samplers[PIPE_MAX_SAMPLERS];
struct ureg_dst psizregreal;
struct ureg_src pointSizeConst;
GLint psizoutindex;
GLboolean prevInstWrotePsiz;
const GLuint *inputMapping;
const GLuint *outputMapping;
@@ -150,6 +154,8 @@ dst_register( struct st_translate *t,
return t->temps[index];
case PROGRAM_OUTPUT:
if (index == t->psizoutindex)
t->prevInstWrotePsiz = GL_TRUE;
return t->outputs[t->outputMapping[index]];
case PROGRAM_ADDRESS:
@@ -816,6 +822,8 @@ st_translate_mesa_program(
t->inputMapping = inputMapping;
t->outputMapping = outputMapping;
t->ureg = ureg;
t->psizoutindex = -1;
t->prevInstWrotePsiz = GL_FALSE;
/*_mesa_print_program(program);*/
@@ -928,6 +936,21 @@ st_translate_mesa_program(
t->outputs[i] = ureg_DECL_output( ureg,
outputSemanticName[i],
outputSemanticIndex[i] );
if ((outputSemanticName[i] == TGSI_SEMANTIC_PSIZE) && program->Id) {
static const gl_state_index pointSizeClampState[STATE_LENGTH]
= { STATE_INTERNAL, STATE_POINT_SIZE_IMPL_CLAMP, 0, 0, 0 };
/* XXX: note we are modifying the incoming shader here! Need to
* do this before emitting the constant decls below, or this
* will be missed:
*/
unsigned pointSizeClampConst = _mesa_add_state_reference(program->Parameters,
pointSizeClampState);
struct ureg_dst psizregtemp = ureg_DECL_temporary( ureg );
t->pointSizeConst = ureg_DECL_constant( ureg, pointSizeClampConst );
t->psizregreal = t->outputs[i];
t->psizoutindex = i;
t->outputs[i] = psizregtemp;
}
}
if (passthrough_edgeflags)
emit_edgeflags( t, program );
@@ -995,6 +1018,19 @@ st_translate_mesa_program(
for (i = 0; i < program->NumInstructions; i++) {
set_insn_start( t, ureg_get_instruction_number( ureg ));
compile_instruction( t, &program->Instructions[i] );
/* note can't do that easily at the end of prog due to
possible early return */
if (t->prevInstWrotePsiz && program->Id) {
set_insn_start( t, ureg_get_instruction_number( ureg ));
ureg_MAX( t->ureg, ureg_writemask(t->outputs[t->psizoutindex], WRITEMASK_X),
ureg_src(t->outputs[t->psizoutindex]),
ureg_swizzle(t->pointSizeConst, 1,1,1,1));
ureg_MIN( t->ureg, ureg_writemask(t->psizregreal, WRITEMASK_X),
ureg_src(t->outputs[t->psizoutindex]),
ureg_swizzle(t->pointSizeConst, 2,2,2,2));
}
t->prevInstWrotePsiz = GL_FALSE;
}
/* Fix up all emitted labels: