Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
This commit is contained in:
@@ -70,8 +70,11 @@ static void Key(unsigned char key, int x, int y)
|
||||
|
||||
static void Draw(void)
|
||||
{
|
||||
glColorMask(1,1,1,1);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
/* right triangle: green */
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(0,1,0);
|
||||
glVertex3f( 0.9, -0.9, -30.0);
|
||||
@@ -81,6 +84,7 @@ static void Draw(void)
|
||||
|
||||
glColorMask(1,0,1,0);
|
||||
|
||||
/* left triangle: white&mask: purple middle region: white */
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(1,1,1);
|
||||
glVertex3f(-0.9, -0.9, -30.0);
|
||||
|
||||
@@ -102,8 +102,6 @@ static void cso_release_all( struct cso_context *ctx )
|
||||
|
||||
void cso_destroy_context( struct cso_context *ctx )
|
||||
{
|
||||
debug_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (ctx)
|
||||
cso_release_all( ctx );
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ static void *cso_data_allocate_node(struct cso_hash_data *hash)
|
||||
return MALLOC(hash->nodeSize);
|
||||
}
|
||||
|
||||
static void cso_data_free_node(struct cso_node *node)
|
||||
static void cso_free_node(struct cso_node *node)
|
||||
{
|
||||
FREE(node);
|
||||
}
|
||||
@@ -248,7 +248,7 @@ void cso_hash_delete(struct cso_hash *hash)
|
||||
struct cso_node *cur = *bucket++;
|
||||
while (cur != e_for_x) {
|
||||
struct cso_node *next = cur->next;
|
||||
cso_data_free_node(cur);
|
||||
cso_free_node(cur);
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
@@ -367,7 +367,7 @@ void * cso_hash_take(struct cso_hash *hash,
|
||||
if (*node != hash->data.e) {
|
||||
void *t = (*node)->value;
|
||||
struct cso_node *next = (*node)->next;
|
||||
cso_data_free_node(*node);
|
||||
cso_free_node(*node);
|
||||
*node = next;
|
||||
--hash->data.d->size;
|
||||
cso_data_has_shrunk(hash->data.d);
|
||||
@@ -393,3 +393,22 @@ int cso_hash_size(struct cso_hash *hash)
|
||||
{
|
||||
return hash->data.d->size;
|
||||
}
|
||||
|
||||
struct cso_hash_iter cso_hash_erase(struct cso_hash *hash, struct cso_hash_iter iter)
|
||||
{
|
||||
struct cso_hash_iter ret = iter;
|
||||
struct cso_node *node = iter.node;
|
||||
struct cso_node **node_ptr;
|
||||
|
||||
if (node == hash->data.e)
|
||||
return iter;
|
||||
|
||||
ret = cso_hash_iter_next(ret);
|
||||
node_ptr = (struct cso_node**)(&hash->data.d->buckets[node->key % hash->data.d->numBuckets]);
|
||||
while (*node_ptr != node)
|
||||
node_ptr = &(*node_ptr)->next;
|
||||
*node_ptr = node->next;
|
||||
cso_free_node(node);
|
||||
--hash->data.d->size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -26,19 +26,20 @@
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
This file provides a hash implementation that is capable of dealing
|
||||
with collisions. It stores colliding entries in linked list. All
|
||||
functions operating on the hash return an iterator. The iterator
|
||||
itself points to the collision list. If there wasn't any collision
|
||||
the list will have just one entry, otherwise client code should
|
||||
iterate over the entries to find the exact entry among ones that
|
||||
had the same key (e.g. memcmp could be used on the data to check
|
||||
that)
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Zack Rusin <zack@tungstengraphics.com>
|
||||
*/
|
||||
* @file
|
||||
* Hash table implementation.
|
||||
*
|
||||
* This file provides a hash implementation that is capable of dealing
|
||||
* with collisions. It stores colliding entries in linked list. All
|
||||
* functions operating on the hash return an iterator. The iterator
|
||||
* itself points to the collision list. If there wasn't any collision
|
||||
* the list will have just one entry, otherwise client code should
|
||||
* iterate over the entries to find the exact entry among ones that
|
||||
* had the same key (e.g. memcmp could be used on the data to check
|
||||
* that)
|
||||
*
|
||||
* @author Zack Rusin <zack@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef CSO_HASH_H
|
||||
#define CSO_HASH_H
|
||||
@@ -48,24 +49,50 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
struct cso_hash;
|
||||
struct cso_node;
|
||||
|
||||
|
||||
struct cso_hash_iter {
|
||||
struct cso_hash *hash;
|
||||
struct cso_node *node;
|
||||
};
|
||||
|
||||
|
||||
struct cso_hash *cso_hash_create(void);
|
||||
void cso_hash_delete(struct cso_hash *hash);
|
||||
|
||||
|
||||
int cso_hash_size(struct cso_hash *hash);
|
||||
|
||||
|
||||
/**
|
||||
* Adds a data with the given key to the hash. If entry with the given
|
||||
* key is already in the hash, this current entry is instered before it
|
||||
* in the collision list.
|
||||
* Function returns iterator pointing to the inserted item in the hash.
|
||||
*/
|
||||
struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key,
|
||||
void *data);
|
||||
/**
|
||||
* Removes the item pointed to by the current iterator from the hash.
|
||||
* Note that the data itself is not erased and if it was a malloc'ed pointer
|
||||
* it will have to be freed after calling this function by the callee.
|
||||
* Function returns iterator pointing to the item after the removed one in
|
||||
* the hash.
|
||||
*/
|
||||
struct cso_hash_iter cso_hash_erase(struct cso_hash *hash, struct cso_hash_iter iter);
|
||||
|
||||
void *cso_hash_take(struct cso_hash *hash, unsigned key);
|
||||
|
||||
|
||||
|
||||
struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash);
|
||||
|
||||
/**
|
||||
* Return an iterator pointing to the first entry in the collision list.
|
||||
*/
|
||||
struct cso_hash_iter cso_hash_find(struct cso_hash *hash, unsigned key);
|
||||
|
||||
|
||||
@@ -73,11 +100,15 @@ int cso_hash_iter_is_null(struct cso_hash_iter iter);
|
||||
unsigned cso_hash_iter_key(struct cso_hash_iter iter);
|
||||
void *cso_hash_iter_data(struct cso_hash_iter iter);
|
||||
|
||||
|
||||
struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter);
|
||||
struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter);
|
||||
|
||||
|
||||
/* KW: a convenience routine:
|
||||
/**
|
||||
* Convenience routine to iterate over the collision list while doing a memory
|
||||
* comparison to see which entry in the list is a direct copy of our template
|
||||
* and returns that entry.
|
||||
*/
|
||||
void *cso_hash_find_data_from_template( struct cso_hash *hash,
|
||||
unsigned hash_key,
|
||||
|
||||
@@ -15,6 +15,7 @@ C_SOURCES = \
|
||||
draw_debug.c \
|
||||
draw_flatshade.c \
|
||||
draw_offset.c \
|
||||
draw_passthrough.c \
|
||||
draw_prim.c \
|
||||
draw_pstipple.c \
|
||||
draw_stipple.c \
|
||||
|
||||
@@ -14,9 +14,9 @@ draw = env.ConvenienceLibrary(
|
||||
'draw_debug.c',
|
||||
'draw_flatshade.c',
|
||||
'draw_offset.c',
|
||||
'draw_passthrough.c',
|
||||
'draw_prim.c',
|
||||
'draw_pstipple.c',
|
||||
'draw_passthrough.c',
|
||||
'draw_stipple.c',
|
||||
'draw_twoside.c',
|
||||
'draw_unfilled.c',
|
||||
|
||||
@@ -340,12 +340,6 @@ generate_aaline_fs(struct aaline_stage *aaline)
|
||||
tgsi_dump(aaline_fs.tokens, 0);
|
||||
#endif
|
||||
|
||||
#if 1 /* XXX remove */
|
||||
aaline_fs.input_semantic_name[aaline_fs.num_inputs] = TGSI_SEMANTIC_GENERIC;
|
||||
aaline_fs.input_semantic_index[aaline_fs.num_inputs] = transform.maxGeneric + 1;
|
||||
aaline_fs.num_inputs++;
|
||||
#endif
|
||||
|
||||
aaline->fs->aaline_fs
|
||||
= aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
|
||||
|
||||
|
||||
@@ -514,12 +514,6 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
|
||||
tgsi_dump(aapoint_fs.tokens, 0);
|
||||
#endif
|
||||
|
||||
#if 1 /* XXX remove */
|
||||
aapoint_fs.input_semantic_name[aapoint_fs.num_inputs] = TGSI_SEMANTIC_GENERIC;
|
||||
aapoint_fs.input_semantic_index[aapoint_fs.num_inputs] = transform.maxGeneric + 1;
|
||||
aapoint_fs.num_inputs++;
|
||||
#endif
|
||||
|
||||
aapoint->fs->aapoint_fs
|
||||
= aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
|
||||
|
||||
|
||||
@@ -85,6 +85,8 @@ struct draw_context *draw_create( void )
|
||||
/* these defaults are oriented toward the needs of softpipe */
|
||||
draw->wide_point_threshold = 1000000.0; /* infinity */
|
||||
draw->wide_line_threshold = 1.0;
|
||||
draw->line_stipple = TRUE;
|
||||
draw->point_sprite = TRUE;
|
||||
|
||||
draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */
|
||||
|
||||
@@ -254,6 +256,28 @@ draw_wide_line_threshold(struct draw_context *draw, float threshold)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells the draw module whether or not to implement line stipple.
|
||||
*/
|
||||
void
|
||||
draw_enable_line_stipple(struct draw_context *draw, boolean enable)
|
||||
{
|
||||
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
||||
draw->line_stipple = enable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells draw module whether to convert points to quads for sprite mode.
|
||||
*/
|
||||
void
|
||||
draw_enable_point_sprites(struct draw_context *draw, boolean enable)
|
||||
{
|
||||
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
||||
draw->point_sprite = enable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ask the draw module for the location/slot of the given vertex attribute in
|
||||
* a post-transformed vertex.
|
||||
@@ -299,7 +323,7 @@ uint
|
||||
draw_num_vs_outputs(struct draw_context *draw)
|
||||
{
|
||||
uint count = draw->vertex_shader->info.num_outputs;
|
||||
if (draw->extra_vp_outputs.slot >= 0)
|
||||
if (draw->extra_vp_outputs.slot > 0)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,11 @@ void draw_wide_point_threshold(struct draw_context *draw, float threshold);
|
||||
|
||||
void draw_wide_line_threshold(struct draw_context *draw, float threshold);
|
||||
|
||||
void draw_enable_line_stipple(struct draw_context *draw, boolean enable);
|
||||
|
||||
void draw_enable_point_sprites(struct draw_context *draw, boolean enable);
|
||||
|
||||
|
||||
boolean draw_use_sse(struct draw_context *draw);
|
||||
|
||||
void
|
||||
|
||||
@@ -66,6 +66,95 @@
|
||||
#include "draw/draw_vertex.h"
|
||||
|
||||
|
||||
/**
|
||||
* General-purpose fetch from user's vertex arrays, emit to driver's
|
||||
* vertex buffer.
|
||||
*
|
||||
* XXX this is totally temporary.
|
||||
*/
|
||||
static void
|
||||
fetch_store_general( struct draw_context *draw,
|
||||
float *out,
|
||||
unsigned start,
|
||||
unsigned count )
|
||||
{
|
||||
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
|
||||
const unsigned nr_attrs = vinfo->num_attribs;
|
||||
uint i, j;
|
||||
|
||||
const unsigned *pitch = draw->vertex_fetch.pitch;
|
||||
const ubyte **src = draw->vertex_fetch.src_ptr;
|
||||
|
||||
for (i = start; i < count; i++) {
|
||||
for (j = 0; j < nr_attrs; j++) {
|
||||
const uint jj = vinfo->src_index[j];
|
||||
const enum pipe_format srcFormat = draw->vertex_element[jj].src_format;
|
||||
const ubyte *from = src[jj] + i * pitch[jj];
|
||||
float attrib[4];
|
||||
|
||||
switch (srcFormat) {
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
{
|
||||
float *f = (float *) from;
|
||||
attrib[0] = f[0];
|
||||
attrib[1] = f[1];
|
||||
attrib[2] = f[2];
|
||||
attrib[3] = f[3];
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
||||
{
|
||||
float *f = (float *) from;
|
||||
attrib[0] = f[0];
|
||||
attrib[1] = f[1];
|
||||
attrib[2] = f[2];
|
||||
attrib[3] = 1.0;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32_FLOAT:
|
||||
{
|
||||
float *f = (float *) from;
|
||||
attrib[0] = f[0];
|
||||
attrib[1] = f[1];
|
||||
attrib[2] = 0.0;
|
||||
attrib[3] = 1.0;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_R32_FLOAT:
|
||||
{
|
||||
float *f = (float *) from;
|
||||
attrib[0] = f[0];
|
||||
attrib[1] = 0.0;
|
||||
attrib[2] = 0.0;
|
||||
attrib[3] = 1.0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
/* XXX this will probably only work for softpipe */
|
||||
switch (vinfo->emit[j]) {
|
||||
case EMIT_HEADER:
|
||||
memset(out, 0, sizeof(struct vertex_header));
|
||||
out += sizeof(struct vertex_header) / 4;
|
||||
break;
|
||||
case EMIT_4F:
|
||||
out[0] = attrib[0];
|
||||
out[1] = attrib[1];
|
||||
out[2] = attrib[2];
|
||||
out[3] = attrib[3];
|
||||
out += 4;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Example of a fetch/emit passthrough shader which could be
|
||||
* generated when bypass_clipping is enabled on a passthrough vertex
|
||||
@@ -116,7 +205,6 @@ static void fetch_xyz_rgb_st( struct draw_context *draw,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static boolean update_shader( struct draw_context *draw )
|
||||
{
|
||||
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
|
||||
@@ -143,11 +231,15 @@ static boolean update_shader( struct draw_context *draw )
|
||||
|
||||
/* Just trying to figure out how this would work:
|
||||
*/
|
||||
if (nr_attrs == 3 &&
|
||||
0 /* some other tests */)
|
||||
if (draw->rasterizer->bypass_vs ||
|
||||
(nr_attrs == 3 && 0 /* some other tests */))
|
||||
{
|
||||
#if 0
|
||||
draw->vertex_fetch.pt_fetch = fetch_xyz_rgb_st;
|
||||
assert(vinfo->size == 10);
|
||||
#else
|
||||
draw->vertex_fetch.pt_fetch = fetch_store_general;
|
||||
#endif
|
||||
/*assert(vinfo->size == 10);*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -175,7 +267,6 @@ static boolean set_prim( struct draw_context *draw,
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean
|
||||
draw_passthrough_arrays(struct draw_context *draw,
|
||||
unsigned prim,
|
||||
@@ -184,10 +275,13 @@ draw_passthrough_arrays(struct draw_context *draw,
|
||||
{
|
||||
float *hw_verts;
|
||||
|
||||
if (draw_need_pipeline(draw))
|
||||
return FALSE;
|
||||
|
||||
if (!set_prim(draw, prim))
|
||||
return FALSE;
|
||||
|
||||
if (!update_shader( draw ))
|
||||
if (!update_shader(draw))
|
||||
return FALSE;
|
||||
|
||||
hw_verts = draw->render->allocate_vertices( draw->render,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
*/
|
||||
|
||||
#include "pipe/p_debug.h"
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
#include "draw_private.h"
|
||||
#include "draw_context.h"
|
||||
@@ -118,7 +119,42 @@ static void draw_prim_queue_flush( struct draw_context *draw )
|
||||
draw_vertex_cache_unreference( draw );
|
||||
}
|
||||
|
||||
static INLINE void fetch_and_store(struct draw_context *draw)
|
||||
{
|
||||
/* run vertex shader on vertex cache entries, four per invokation */
|
||||
#if 0
|
||||
{
|
||||
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
|
||||
memcpy(draw->vs.queue[0].vertex, draw->vs.queue[i + j].elt,
|
||||
count * vinfo->size);
|
||||
}
|
||||
#elif 0
|
||||
unsigned i;
|
||||
|
||||
draw_update_vertex_fetch(draw);
|
||||
for (i = 0; i < draw->vs.queue_nr; i += 4) {
|
||||
struct vertex_header *dests[4];
|
||||
unsigned elts[4];
|
||||
struct tgsi_exec_machine *machine = &draw->machine;
|
||||
int j, n = MIN2(4, draw->vs.queue_nr - i);
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
elts[j] = draw->vs.queue[i + j].elt;
|
||||
dests[j] = draw->vs.queue[i + j].vertex;
|
||||
}
|
||||
|
||||
for ( ; j < 4; j++) {
|
||||
elts[j] = elts[0];
|
||||
dests[j] = draw->vs.queue[i + j].vertex;
|
||||
}
|
||||
//fetch directly into dests
|
||||
draw->vertex_fetch.fetch_func(draw, machine, dests, count);
|
||||
}
|
||||
#endif
|
||||
|
||||
draw->vs.post_nr = draw->vs.queue_nr;
|
||||
draw->vs.queue_nr = 0;
|
||||
}
|
||||
|
||||
void draw_do_flush( struct draw_context *draw, unsigned flags )
|
||||
{
|
||||
@@ -134,7 +170,10 @@ void draw_do_flush( struct draw_context *draw, unsigned flags )
|
||||
|
||||
if (flags >= DRAW_FLUSH_SHADER_QUEUE) {
|
||||
if (draw->vs.queue_nr)
|
||||
(*draw->shader_queue_flush)(draw);
|
||||
if (draw->rasterizer->bypass_vs)
|
||||
fetch_and_store(draw);
|
||||
else
|
||||
(*draw->shader_queue_flush)(draw);
|
||||
|
||||
if (flags >= DRAW_FLUSH_PRIM_QUEUE) {
|
||||
if (draw->pq.queue_nr)
|
||||
@@ -485,7 +524,11 @@ draw_arrays(struct draw_context *draw, unsigned prim,
|
||||
}
|
||||
|
||||
/* drawing done here: */
|
||||
draw_prim(draw, prim, start, count);
|
||||
if (!draw->rasterizer->bypass_vs ||
|
||||
!draw_passthrough_arrays(draw, prim, start, count)) {
|
||||
/* we have to run the whole pipeline */
|
||||
draw_prim(draw, prim, start, count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -238,6 +238,8 @@ struct draw_context
|
||||
|
||||
float wide_point_threshold; /**< convert pnts to tris if larger than this */
|
||||
float wide_line_threshold; /**< convert lines to tris if wider than this */
|
||||
boolean line_stipple; /**< do line stipple? */
|
||||
boolean point_sprite; /**< convert points to quads for sprites? */
|
||||
boolean use_sse;
|
||||
|
||||
/* If a prim stage introduces new vertex attributes, they'll be stored here
|
||||
@@ -344,10 +346,10 @@ extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw );
|
||||
|
||||
extern void draw_vertex_shader_queue_flush( struct draw_context *draw );
|
||||
|
||||
struct tgsi_exec_machine;
|
||||
|
||||
extern void draw_update_vertex_fetch( struct draw_context *draw );
|
||||
|
||||
extern boolean draw_need_pipeline(const struct draw_context *draw);
|
||||
|
||||
|
||||
/* Prototype/hack
|
||||
*/
|
||||
|
||||
@@ -324,21 +324,13 @@ generate_pstip_fs(struct pstip_stage *pstip)
|
||||
(struct tgsi_token *) pstip_fs.tokens,
|
||||
MAX, &transform.base);
|
||||
|
||||
#if 1 /* DEBUG */
|
||||
#if 0 /* DEBUG */
|
||||
tgsi_dump(orig_fs->tokens, 0);
|
||||
tgsi_dump(pstip_fs.tokens, 0);
|
||||
#endif
|
||||
|
||||
pstip->sampler_unit = transform.maxSampler + 1;
|
||||
|
||||
#if 1 /* XXX remove */
|
||||
if (transform.wincoordInput < 0) {
|
||||
pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION;
|
||||
pstip_fs.input_semantic_index[pstip_fs.num_inputs] = (ubyte)transform.maxInput;
|
||||
pstip_fs.num_inputs++;
|
||||
}
|
||||
#endif
|
||||
|
||||
pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
|
||||
}
|
||||
|
||||
@@ -488,16 +480,16 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
|
||||
struct pipe_context *pipe = pstip->pipe;
|
||||
uint num_samplers;
|
||||
|
||||
/* how many samplers? */
|
||||
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
|
||||
num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
|
||||
num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1);
|
||||
|
||||
assert(stage->draw->rasterizer->poly_stipple_enable);
|
||||
|
||||
/* bind our fragprog */
|
||||
bind_pstip_fragment_shader(pstip);
|
||||
|
||||
/* how many samplers? */
|
||||
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
|
||||
num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
|
||||
num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1);
|
||||
|
||||
/* plug in our sampler, texture */
|
||||
pstip->state.samplers[pstip->sampler_unit] = pstip->sampler_cso;
|
||||
pstip->state.textures[pstip->sampler_unit] = pstip->texture;
|
||||
|
||||
@@ -33,6 +33,63 @@
|
||||
#include "draw_private.h"
|
||||
|
||||
|
||||
/**
|
||||
* Check if we need any special pipeline stages, or whether prims/verts
|
||||
* can go through untouched.
|
||||
*/
|
||||
boolean
|
||||
draw_need_pipeline(const struct draw_context *draw)
|
||||
{
|
||||
/* clipping */
|
||||
if (!draw->rasterizer->bypass_clipping)
|
||||
return TRUE;
|
||||
|
||||
/* vertex shader */
|
||||
if (!draw->rasterizer->bypass_vs)
|
||||
return TRUE;
|
||||
|
||||
/* line stipple */
|
||||
if (draw->rasterizer->line_stipple_enable && draw->line_stipple)
|
||||
return TRUE;
|
||||
|
||||
/* wide lines */
|
||||
if (draw->rasterizer->line_width > draw->wide_line_threshold)
|
||||
return TRUE;
|
||||
|
||||
/* large points */
|
||||
if (draw->rasterizer->point_size > draw->wide_point_threshold)
|
||||
return TRUE;
|
||||
|
||||
/* AA lines */
|
||||
if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
|
||||
return TRUE;
|
||||
|
||||
/* AA points */
|
||||
if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
|
||||
return TRUE;
|
||||
|
||||
/* polygon stipple */
|
||||
if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
|
||||
return TRUE;
|
||||
|
||||
/* polygon offset */
|
||||
if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw)
|
||||
return TRUE;
|
||||
|
||||
/* point sprites */
|
||||
if (draw->rasterizer->point_sprite && draw->point_sprite)
|
||||
return TRUE;
|
||||
|
||||
/* two-side lighting */
|
||||
if (draw->rasterizer->light_twoside)
|
||||
return TRUE;
|
||||
|
||||
/* polygon cull */
|
||||
if (draw->rasterizer->cull_mode)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -57,7 +114,9 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
|
||||
&& !draw->rasterizer->line_smooth);
|
||||
|
||||
/* drawing large points? */
|
||||
if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
|
||||
if (draw->rasterizer->point_sprite && draw->point_sprite)
|
||||
wide_points = TRUE;
|
||||
else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
|
||||
wide_points = FALSE;
|
||||
else if (draw->rasterizer->point_size > draw->wide_point_threshold)
|
||||
wide_points = TRUE;
|
||||
@@ -92,7 +151,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
|
||||
next = draw->pipeline.wide_point;
|
||||
}
|
||||
|
||||
if (draw->rasterizer->line_stipple_enable) {
|
||||
if (draw->rasterizer->line_stipple_enable && draw->line_stipple) {
|
||||
draw->pipeline.stipple->next = next;
|
||||
next = draw->pipeline.stipple;
|
||||
precalc_flat = 1; /* only needed for lines really */
|
||||
|
||||
@@ -225,6 +225,11 @@ emit_vertex( struct vbuf_stage *vbuf,
|
||||
vbuf->vertex_ptr += vinfo->size;
|
||||
count += vinfo->size;
|
||||
break;
|
||||
case EMIT_HEADER:
|
||||
memcpy(vbuf->vertex_ptr, vertex, sizeof(*vertex));
|
||||
*vbuf->vertex_ptr += sizeof(*vertex) / 4;
|
||||
count += sizeof(*vertex) / 4;
|
||||
break;
|
||||
case EMIT_1F:
|
||||
*vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
|
||||
count++;
|
||||
|
||||
@@ -52,6 +52,9 @@ draw_compute_vertex_size(struct vertex_info *vinfo)
|
||||
switch (vinfo->emit[i]) {
|
||||
case EMIT_OMIT:
|
||||
break;
|
||||
case EMIT_HEADER:
|
||||
vinfo->size += sizeof(struct vertex_header) / 4;
|
||||
break;
|
||||
case EMIT_4UB:
|
||||
/* fall-through */
|
||||
case EMIT_1F_PSIZE:
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
enum attrib_emit {
|
||||
EMIT_OMIT, /**< don't emit the attribute */
|
||||
EMIT_ALL, /**< emit whole post-xform vertex, w/ header */
|
||||
EMIT_HEADER, /**< emit vertex_header struct (XXX temp?) */
|
||||
EMIT_1F,
|
||||
EMIT_1F_PSIZE, /**< insert constant point size */
|
||||
EMIT_2F,
|
||||
|
||||
@@ -263,6 +263,14 @@ void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EMIT_HEADER:
|
||||
/* XXX emit new DRAW_EMIT_HEADER attribute??? */
|
||||
attrs[nr_attrs].attrib = 0;
|
||||
attrs[nr_attrs].format = DRAW_EMIT_PAD;
|
||||
attrs[nr_attrs].offset = offsetof(struct vertex_header, data);
|
||||
count += offsetof(struct vertex_header, data)/4;
|
||||
nr_attrs++;
|
||||
break;
|
||||
case EMIT_1F:
|
||||
attrs[nr_attrs].attrib = j;
|
||||
attrs[nr_attrs].format = DRAW_EMIT_1F;
|
||||
|
||||
@@ -166,6 +166,19 @@ vs_exec_run( struct draw_vertex_shader *shader,
|
||||
vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j];
|
||||
vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j];
|
||||
}
|
||||
|
||||
#if 0 /*DEBUG*/
|
||||
printf("Post xform vert:\n");
|
||||
for (slot = 0; slot < draw->num_vs_outputs; slot++) {
|
||||
printf("%d: %f %f %f %f\n", slot,
|
||||
vOut[j]->data[slot][0],
|
||||
vOut[j]->data[slot][1],
|
||||
vOut[j]->data[slot][2],
|
||||
vOut[j]->data[slot][3]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} /* loop over vertices */
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,8 @@ static void widepoint_first_point( struct draw_stage *stage,
|
||||
wide->half_point_size = 0.5f * draw->rasterizer->point_size;
|
||||
|
||||
/* XXX we won't know the real size if it's computed by the vertex shader! */
|
||||
if (draw->rasterizer->point_size > draw->wide_point_threshold) {
|
||||
if ((draw->rasterizer->point_size > draw->wide_point_threshold) ||
|
||||
(draw->rasterizer->point_sprite && draw->point_sprite)) {
|
||||
stage->point = widepoint_point;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -143,8 +143,16 @@ std::vector<llvm::Value*> InstructionsSoa::extractVector(llvm::Value *vector)
|
||||
|
||||
void InstructionsSoa::createFunctionMap()
|
||||
{
|
||||
m_functionsMap[TGSI_OPCODE_DP3] = "dp3";
|
||||
m_functionsMap[TGSI_OPCODE_DP4] = "dp4";
|
||||
m_functionsMap[TGSI_OPCODE_DP3] = "dp3";
|
||||
m_functionsMap[TGSI_OPCODE_DP4] = "dp4";
|
||||
m_functionsMap[TGSI_OPCODE_POWER] = "pow";
|
||||
}
|
||||
|
||||
void InstructionsSoa::createDependencies()
|
||||
{
|
||||
std::vector<std::string> powDeps(1);
|
||||
powDeps[0] = "powf";
|
||||
m_builtinDependencies["pow"] = powDeps;
|
||||
}
|
||||
|
||||
llvm::Function * InstructionsSoa::function(int op)
|
||||
@@ -154,15 +162,14 @@ llvm::Function * InstructionsSoa::function(int op)
|
||||
|
||||
std::string name = m_functionsMap[op];
|
||||
|
||||
std::vector<std::string> deps = m_builtinDependencies[name];
|
||||
for (unsigned int i = 0; i < deps.size(); ++i) {
|
||||
injectFunction(m_builtins->getFunction(deps[i]));
|
||||
}
|
||||
|
||||
llvm::Function *originalFunc = m_builtins->getFunction(name);
|
||||
llvm::Function *func = CloneFunction(originalFunc);
|
||||
currentModule()->getFunctionList().push_back(func);
|
||||
std::cout << "Func parent is "<<func->getParent()
|
||||
<<", cur is "<<currentModule() <<std::endl;
|
||||
func->dump();
|
||||
//func->setParent(currentModule());
|
||||
m_functions[op] = func;
|
||||
return func;
|
||||
injectFunction(originalFunc, op);
|
||||
return m_functions[op];
|
||||
}
|
||||
|
||||
llvm::Module * InstructionsSoa::currentModule() const
|
||||
@@ -177,6 +184,7 @@ llvm::Module * InstructionsSoa::currentModule() const
|
||||
void InstructionsSoa::createBuiltins()
|
||||
{
|
||||
m_builtins = createSoaBuiltins();
|
||||
createDependencies();
|
||||
}
|
||||
|
||||
std::vector<llvm::Value*> InstructionsSoa::dp3(const std::vector<llvm::Value*> in1,
|
||||
@@ -304,3 +312,71 @@ std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std
|
||||
|
||||
return allocaToResult(allocaPtr);
|
||||
}
|
||||
|
||||
std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> in1,
|
||||
const std::vector<llvm::Value*> in2)
|
||||
{
|
||||
llvm::Function *func = function(TGSI_OPCODE_POWER);
|
||||
return callBuiltin(func, in1, in2);
|
||||
}
|
||||
|
||||
void checkFunction(Function *func)
|
||||
{
|
||||
for (Function::const_iterator BI = func->begin(), BE = func->end();
|
||||
BI != BE; ++BI) {
|
||||
const BasicBlock &BB = *BI;
|
||||
for (BasicBlock::const_iterator II = BB.begin(), IE = BB.end();
|
||||
II != IE; ++II) {
|
||||
const Instruction &I = *II;
|
||||
std::cout<< "Instr = "<<I;
|
||||
for (unsigned op = 0, E = I.getNumOperands(); op != E; ++op) {
|
||||
const Value *Op = I.getOperand(op);
|
||||
std::cout<< "\top = "<<Op<<"("<<op<<")"<<std::endl;
|
||||
//I->setOperand(op, V);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op)
|
||||
{
|
||||
assert(originalFunc);
|
||||
std::cout << "injecting function originalFunc " <<originalFunc->getName() <<std::endl;
|
||||
if (op != TGSI_OPCODE_LAST) {
|
||||
/* in this case it's possible the function has been already
|
||||
* injected as part of the dependency chain, which gets
|
||||
* injected below */
|
||||
llvm::Function *func = currentModule()->getFunction(originalFunc->getName());
|
||||
if (func) {
|
||||
m_functions[op] = func;
|
||||
return;
|
||||
}
|
||||
}
|
||||
llvm::Function *func = 0;
|
||||
if (originalFunc->isDeclaration()) {
|
||||
std::cout << "function decleration" <<std::endl;
|
||||
func = new Function(originalFunc->getFunctionType(), GlobalValue::ExternalLinkage,
|
||||
originalFunc->getName(), currentModule());
|
||||
func->setCallingConv(CallingConv::C);
|
||||
const ParamAttrsList *pal = 0;
|
||||
func->setParamAttrs(pal);
|
||||
currentModule()->dump();
|
||||
} else {
|
||||
DenseMap<const Value*, Value *> val;
|
||||
val[m_builtins->getFunction("powf")] = currentModule()->getFunction("powf");
|
||||
std::cout <<" replacing "<<m_builtins->getFunction("powf")
|
||||
<<", with " <<currentModule()->getFunction("powf")<<std::endl;
|
||||
func = CloneFunction(originalFunc, val);
|
||||
std::cout<<"1111-------------------------------"<<std::endl;
|
||||
checkFunction(originalFunc);
|
||||
std::cout<<"2222-------------------------------"<<std::endl;
|
||||
checkFunction(func);
|
||||
std::cout <<"XXXX = " <<val[m_builtins->getFunction("powf")]<<std::endl;
|
||||
currentModule()->getFunctionList().push_back(func);
|
||||
std::cout << "Func parent is "<<func->getParent()
|
||||
<<", cur is "<<currentModule() <<std::endl;
|
||||
}
|
||||
if (op != TGSI_OPCODE_LAST) {
|
||||
m_functions[op] = func;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#ifndef INSTRUCTIONSSOA_H
|
||||
#define INSTRUCTIONSSOA_H
|
||||
|
||||
#include <pipe/p_shader_tokens.h>
|
||||
#include <llvm/Support/LLVMBuilder.h>
|
||||
|
||||
#include <map>
|
||||
@@ -59,6 +60,8 @@ public:
|
||||
const std::vector<llvm::Value*> in3);
|
||||
std::vector<llvm::Value*> mul(const std::vector<llvm::Value*> in1,
|
||||
const std::vector<llvm::Value*> in2);
|
||||
std::vector<llvm::Value*> pow(const std::vector<llvm::Value*> in1,
|
||||
const std::vector<llvm::Value*> in2);
|
||||
void end();
|
||||
|
||||
std::vector<llvm::Value*> extractVector(llvm::Value *vector);
|
||||
@@ -68,6 +71,7 @@ private:
|
||||
llvm::Value *z, llvm::Value *w);
|
||||
void createFunctionMap();
|
||||
void createBuiltins();
|
||||
void createDependencies();
|
||||
llvm::Function *function(int);
|
||||
llvm::Module *currentModule() const;
|
||||
llvm::Value *allocaTemp();
|
||||
@@ -81,6 +85,7 @@ private:
|
||||
const std::vector<llvm::Value*> in1,
|
||||
const std::vector<llvm::Value*> in2,
|
||||
const std::vector<llvm::Value*> in3);
|
||||
void injectFunction(llvm::Function *originalFunc, int op = TGSI_OPCODE_LAST);
|
||||
private:
|
||||
llvm::LLVMFoldingBuilder m_builder;
|
||||
StorageSoa *m_storage;
|
||||
@@ -88,6 +93,7 @@ private:
|
||||
std::map<int, std::string> m_functionsMap;
|
||||
std::map<int, llvm::Function*> m_functions;
|
||||
llvm::Module *m_builtins;
|
||||
std::map<std::string, std::vector<std::string> > m_builtinDependencies;
|
||||
|
||||
private:
|
||||
mutable int m_idx;
|
||||
|
||||
@@ -60,6 +60,24 @@ void dp4(float4 *res,
|
||||
res[3] = dot;
|
||||
}
|
||||
|
||||
extern float powf(float num, float p);
|
||||
|
||||
void pow(float4 *res,
|
||||
float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w,
|
||||
float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w)
|
||||
{
|
||||
float4 p;
|
||||
p.x = powf(tmp0x.x, tmp1x.x);
|
||||
p.y = powf(tmp0x.y, tmp1x.y);
|
||||
p.z = powf(tmp0x.z, tmp1x.z);
|
||||
p.w = powf(tmp0x.w, tmp1x.w);
|
||||
|
||||
res[0] = p;
|
||||
res[1] = p;
|
||||
res[2] = p;
|
||||
res[3] = p;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void yo(float4 *out, float4 *in)
|
||||
{
|
||||
|
||||
@@ -588,40 +588,6 @@ translate_instruction(llvm::Module *module,
|
||||
break;
|
||||
case TGSI_OPCODE_NOP:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXBEM:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXBEML:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXREG2AR:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X2PAD:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X2TEX:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3PAD:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3TEX:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3SPEC:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3VSPEC:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXREG2GB:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXREG2RGB:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXDP3TEX:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXDP3:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X2DEPTH:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXDEPTH:
|
||||
break;
|
||||
case TGSI_OPCODE_BEM:
|
||||
break;
|
||||
case TGSI_OPCODE_M4X3:
|
||||
break;
|
||||
case TGSI_OPCODE_M3X4:
|
||||
@@ -806,6 +772,7 @@ translate_instructionir(llvm::Module *module,
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_POWER: {
|
||||
out = instr->pow(inputs[0], inputs[1]);
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_CROSSPRODUCT: {
|
||||
@@ -980,40 +947,6 @@ translate_instructionir(llvm::Module *module,
|
||||
break;
|
||||
case TGSI_OPCODE_NOP:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXBEM:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXBEML:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXREG2AR:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X2PAD:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X2TEX:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3PAD:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3TEX:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3SPEC:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3VSPEC:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXREG2GB:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXREG2RGB:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXDP3TEX:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXDP3:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X3:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXM3X2DEPTH:
|
||||
break;
|
||||
case TGSI_OPCODE_TEXDEPTH:
|
||||
break;
|
||||
case TGSI_OPCODE_BEM:
|
||||
break;
|
||||
case TGSI_OPCODE_M4X3:
|
||||
break;
|
||||
case TGSI_OPCODE_M3X4:
|
||||
|
||||
@@ -1516,11 +1516,41 @@ exec_instruction(
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_EXP:
|
||||
assert (0);
|
||||
debug_printf("TGSI: EXP opcode not implemented\n");
|
||||
/* from ARB_v_p:
|
||||
tmp = ScalarLoad(op0);
|
||||
result.x = 2^floor(tmp);
|
||||
result.y = tmp - floor(tmp);
|
||||
result.z = RoughApprox2ToX(tmp);
|
||||
result.w = 1.0;
|
||||
*/
|
||||
#if 0
|
||||
/* something like this: */
|
||||
FETCH( &r[0], 0, CHAN_X );
|
||||
micro_exp2( &r[0], &r[0] );
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
STORE( &r[0], 0, chan_index );
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_LOG:
|
||||
assert (0);
|
||||
debug_printf("TGSI: LOG opcode not implemented\n");
|
||||
/* from ARB_v_p:
|
||||
tmp = fabs(ScalarLoad(op0));
|
||||
result.x = floor(log2(tmp));
|
||||
result.y = tmp / 2^(floor(log2(tmp)));
|
||||
result.z = RoughApproxLog2(tmp);
|
||||
result.w = 1.0;
|
||||
*/
|
||||
#if 0
|
||||
/* something like this: */
|
||||
FETCH( &r[0], 0, CHAN_X );
|
||||
micro_lg2( &r[0], &r[0] );
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
STORE( &r[0], 0, chan_index );
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_MUL:
|
||||
|
||||
@@ -1821,7 +1821,11 @@ emit_instruction(
|
||||
STORE( func, *inst, 5, 0, CHAN_Z );
|
||||
}
|
||||
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
|
||||
FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C );
|
||||
emit_tempf(
|
||||
func,
|
||||
0,
|
||||
TGSI_EXEC_TEMP_ONE_I,
|
||||
TGSI_EXEC_TEMP_ONE_C );
|
||||
STORE( func, *inst, 0, 0, CHAN_W );
|
||||
}
|
||||
break;
|
||||
@@ -2021,11 +2025,19 @@ emit_instruction(
|
||||
STORE( func, *inst, 0, 0, CHAN_Y );
|
||||
}
|
||||
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) {
|
||||
FETCH( func, *inst, 0, TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C );
|
||||
emit_tempf(
|
||||
func,
|
||||
0,
|
||||
TGSI_EXEC_TEMP_00000000_I,
|
||||
TGSI_EXEC_TEMP_00000000_C );
|
||||
STORE( func, *inst, 0, 0, CHAN_Z );
|
||||
}
|
||||
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
|
||||
FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C );
|
||||
emit_tempf(
|
||||
func,
|
||||
0,
|
||||
TGSI_EXEC_TEMP_ONE_I,
|
||||
TGSI_EXEC_TEMP_ONE_C );
|
||||
STORE( func, *inst, 0, 0, CHAN_W );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -324,7 +324,7 @@ static const char *TGSI_IMMS_SHORT[] =
|
||||
"FLT32"
|
||||
};
|
||||
|
||||
static const char *TGSI_OPCODES[] =
|
||||
static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] =
|
||||
{
|
||||
"OPCODE_ARL",
|
||||
"OPCODE_MOV",
|
||||
@@ -380,6 +380,7 @@ static const char *TGSI_OPCODES[] =
|
||||
"OPCODE_STR",
|
||||
"OPCODE_TEX",
|
||||
"OPCODE_TXD",
|
||||
"OPCODE_TXP",
|
||||
"OPCODE_UP2H",
|
||||
"OPCODE_UP2US",
|
||||
"OPCODE_UP4B",
|
||||
@@ -433,23 +434,6 @@ static const char *TGSI_OPCODES[] =
|
||||
"OPCODE_NOISE3",
|
||||
"OPCODE_NOISE4",
|
||||
"OPCODE_NOP",
|
||||
"OPCODE_TEXBEM",
|
||||
"OPCODE_TEXBEML",
|
||||
"OPCODE_TEXREG2AR",
|
||||
"OPCODE_TEXM3X2PAD",
|
||||
"OPCODE_TEXM3X2TEX",
|
||||
"OPCODE_TEXM3X3PAD",
|
||||
"OPCODE_TEXM3X3TEX",
|
||||
"OPCODE_TEXM3X3SPEC",
|
||||
"OPCODE_TEXM3X3VSPEC",
|
||||
"OPCODE_TEXREG2GB",
|
||||
"OPCODE_TEXREG2RGB",
|
||||
"OPCODE_TEXDP3TEX",
|
||||
"OPCODE_TEXDP3",
|
||||
"OPCODE_TEXM3X3",
|
||||
"OPCODE_TEXM3X2DEPTH",
|
||||
"OPCODE_TEXDEPTH",
|
||||
"OPCODE_BEM",
|
||||
"OPCODE_M4X3",
|
||||
"OPCODE_M3X4",
|
||||
"OPCODE_M3X3",
|
||||
@@ -459,11 +443,10 @@ static const char *TGSI_OPCODES[] =
|
||||
"OPCODE_IFC",
|
||||
"OPCODE_BREAKC",
|
||||
"OPCODE_KIL",
|
||||
"OPCODE_END",
|
||||
"OPCODE_TXP"
|
||||
"OPCODE_END"
|
||||
};
|
||||
|
||||
static const char *TGSI_OPCODES_SHORT[] =
|
||||
static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] =
|
||||
{
|
||||
"ARL",
|
||||
"MOV",
|
||||
@@ -519,6 +502,7 @@ static const char *TGSI_OPCODES_SHORT[] =
|
||||
"STR",
|
||||
"TEX",
|
||||
"TXD",
|
||||
"TXP",
|
||||
"UP2H",
|
||||
"UP2US",
|
||||
"UP4B",
|
||||
@@ -572,23 +556,6 @@ static const char *TGSI_OPCODES_SHORT[] =
|
||||
"NOISE3",
|
||||
"NOISE4",
|
||||
"NOP",
|
||||
"TEXBEM",
|
||||
"TEXBEML",
|
||||
"TEXREG2AR",
|
||||
"TEXM3X2PAD",
|
||||
"TEXM3X2TEX",
|
||||
"TEXM3X3PAD",
|
||||
"TEXM3X3TEX",
|
||||
"TEXM3X3SPEC",
|
||||
"TEXM3X3VSPEC",
|
||||
"TEXREG2GB",
|
||||
"TEXREG2RGB",
|
||||
"TEXDP3TEX",
|
||||
"TEXDP3",
|
||||
"TEXM3X3",
|
||||
"TEXM3X2DEPTH",
|
||||
"TEXDEPTH",
|
||||
"BEM",
|
||||
"M4X3",
|
||||
"M3X4",
|
||||
"M3X3",
|
||||
@@ -598,8 +565,7 @@ static const char *TGSI_OPCODES_SHORT[] =
|
||||
"IFC",
|
||||
"BREAKC",
|
||||
"KIL",
|
||||
"END",
|
||||
"TXP"
|
||||
"END"
|
||||
};
|
||||
|
||||
static const char *TGSI_SATS[] =
|
||||
@@ -1597,3 +1563,25 @@ tgsi_dump_str(
|
||||
|
||||
*str = dump.text;
|
||||
}
|
||||
|
||||
|
||||
void tgsi_debug_dump( struct tgsi_token *tokens )
|
||||
{
|
||||
char *str, *p;
|
||||
|
||||
tgsi_dump_str( &str, tokens, 0 );
|
||||
|
||||
p = str;
|
||||
while (p != NULL)
|
||||
{
|
||||
char *end = strchr( p, '\n' );
|
||||
if (end != NULL)
|
||||
{
|
||||
*end++ = '\0';
|
||||
}
|
||||
debug_printf( "%s\n", p );
|
||||
p = end;
|
||||
}
|
||||
|
||||
FREE( str );
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ tgsi_dump_str(
|
||||
const struct tgsi_token *tokens,
|
||||
unsigned flags );
|
||||
|
||||
/* Dump to debug_printf()
|
||||
*/
|
||||
void tgsi_debug_dump( struct tgsi_token *tokens );
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -56,7 +56,7 @@ struct tgsi_full_immediate
|
||||
};
|
||||
|
||||
#define TGSI_FULL_MAX_DST_REGISTERS 2
|
||||
#define TGSI_FULL_MAX_SRC_REGISTERS 3
|
||||
#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
|
||||
|
||||
struct tgsi_full_instruction
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ C_SOURCES = \
|
||||
p_tile.c \
|
||||
p_util.c \
|
||||
u_handle_table.c \
|
||||
u_hash_table.c \
|
||||
u_mm.c \
|
||||
u_snprintf.c
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ util = env.ConvenienceLibrary(
|
||||
'p_tile.c',
|
||||
'p_util.c',
|
||||
'u_handle_table.c',
|
||||
'u_hash_table.c',
|
||||
'u_mm.c',
|
||||
'u_snprintf.c',
|
||||
])
|
||||
|
||||
@@ -109,20 +109,30 @@ enum {
|
||||
/* Check for aborts enabled. */
|
||||
static unsigned abort_en()
|
||||
{
|
||||
if (!mapped_config_file)
|
||||
{
|
||||
/* Open an 8 byte file for configuration data. */
|
||||
mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file);
|
||||
}
|
||||
/* An value of "0" (ascii) in the configuration file will clear the first 8 bits in the test byte. */
|
||||
/* An value of "1" (ascii) in the configuration file will set the first bit in the test byte. */
|
||||
/* An value of "2" (ascii) in the configuration file will set the second bit in the test byte. */
|
||||
return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn;
|
||||
if (!mapped_config_file)
|
||||
{
|
||||
/* Open an 8 byte file for configuration data. */
|
||||
mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file);
|
||||
}
|
||||
|
||||
/* A value of "0" (ascii) in the configuration file will clear the
|
||||
* first 8 bits in the test byte.
|
||||
*
|
||||
* A value of "1" (ascii) in the configuration file will set the
|
||||
* first bit in the test byte.
|
||||
*
|
||||
* A value of "2" (ascii) in the configuration file will set the
|
||||
* second bit in the test byte.
|
||||
*
|
||||
* Currently the only interesting values are 0 and 1, which clear
|
||||
* and set abort-on-assert behaviour respectively.
|
||||
*/
|
||||
return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn;
|
||||
}
|
||||
#else /* WIN32 */
|
||||
static unsigned abort_en()
|
||||
{
|
||||
return !GETENV("GALLIUM_ABORT_ON_ASSERT");
|
||||
return !GETENV("GALLIUM_ABORT_ON_ASSERT");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Generic handle table implementation.
|
||||
*
|
||||
* @author José Fonseca <jrfonseca@tungstengraphics.com>
|
||||
@@ -90,6 +91,39 @@ handle_table_set_destroy(struct handle_table *ht,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resize the table if necessary
|
||||
*/
|
||||
static INLINE int
|
||||
handle_table_resize(struct handle_table *ht,
|
||||
unsigned minimum_size)
|
||||
{
|
||||
unsigned new_size;
|
||||
void **new_objects;
|
||||
|
||||
if(ht->size > minimum_size)
|
||||
return ht->size;
|
||||
|
||||
new_size = ht->size;
|
||||
while(!(new_size > minimum_size))
|
||||
new_size *= 2;
|
||||
assert(new_size);
|
||||
|
||||
new_objects = (void **)REALLOC((void *)ht->objects,
|
||||
ht->size*sizeof(void *),
|
||||
new_size*sizeof(void *));
|
||||
if(!new_objects)
|
||||
return 0;
|
||||
|
||||
memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
|
||||
|
||||
ht->size = new_size;
|
||||
ht->objects = new_objects;
|
||||
|
||||
return ht->size;
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
handle_table_add(struct handle_table *ht,
|
||||
void *object)
|
||||
@@ -109,34 +143,17 @@ handle_table_add(struct handle_table *ht,
|
||||
++ht->filled;
|
||||
}
|
||||
|
||||
/* grow the table */
|
||||
if(ht->filled == ht->size) {
|
||||
unsigned new_size;
|
||||
void **new_objects;
|
||||
|
||||
new_size = ht->size*2;
|
||||
assert(new_size);
|
||||
|
||||
new_objects = (void **)REALLOC((void *)ht->objects,
|
||||
ht->size*sizeof(void *),
|
||||
new_size*sizeof(void *));
|
||||
if(!new_objects)
|
||||
return 0;
|
||||
|
||||
memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
|
||||
|
||||
ht->size = new_size;
|
||||
ht->objects = new_objects;
|
||||
}
|
||||
|
||||
index = ht->filled;
|
||||
|
||||
handle = index + 1;
|
||||
|
||||
/* check integer overflow */
|
||||
if(!handle)
|
||||
return 0;
|
||||
|
||||
/* grow the table if necessary */
|
||||
if(!handle_table_resize(ht, index))
|
||||
return 0;
|
||||
|
||||
assert(!ht->objects[index]);
|
||||
ht->objects[index] = object;
|
||||
++ht->filled;
|
||||
@@ -145,6 +162,36 @@ handle_table_add(struct handle_table *ht,
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
handle_table_set(struct handle_table *ht,
|
||||
unsigned handle,
|
||||
void *object)
|
||||
{
|
||||
unsigned index;
|
||||
|
||||
assert(ht);
|
||||
assert(handle > 0);
|
||||
assert(handle <= ht->size);
|
||||
if(!handle || handle > ht->size)
|
||||
return 0;
|
||||
|
||||
assert(object);
|
||||
if(!object)
|
||||
return 0;
|
||||
|
||||
index = handle - 1;
|
||||
|
||||
/* grow the table if necessary */
|
||||
if(!handle_table_resize(ht, index))
|
||||
return 0;
|
||||
|
||||
assert(!ht->objects[index]);
|
||||
ht->objects[index] = object;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
handle_table_get(struct handle_table *ht,
|
||||
unsigned handle)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Generic handle table.
|
||||
*
|
||||
* @author José Fonseca <jrfonseca@tungstengraphics.com>
|
||||
@@ -42,6 +43,8 @@ extern "C" {
|
||||
|
||||
/**
|
||||
* Abstract data type to map integer handles to objects.
|
||||
*
|
||||
* Also referred as "pointer array".
|
||||
*/
|
||||
struct handle_table;
|
||||
|
||||
@@ -70,6 +73,14 @@ unsigned
|
||||
handle_table_add(struct handle_table *ht,
|
||||
void *object);
|
||||
|
||||
/**
|
||||
* Returns zero on failure (out of memory).
|
||||
*/
|
||||
unsigned
|
||||
handle_table_set(struct handle_table *ht,
|
||||
unsigned handle,
|
||||
void *object);
|
||||
|
||||
/**
|
||||
* Fetch an existing object.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* General purpose hash table implementation.
|
||||
*
|
||||
* Just uses the cso_hash for now, but it might be better switch to a linear
|
||||
* probing hash table implementation at some point -- as it is said they have
|
||||
* better lookup and cache performance and it appears to be possible to write
|
||||
* a lock-free implementation of such hash tables .
|
||||
*
|
||||
* @author José Fonseca <jrfonseca@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_debug.h"
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
#include "cso_cache/cso_hash.h"
|
||||
#include "u_hash_table.h"
|
||||
|
||||
|
||||
struct hash_table
|
||||
{
|
||||
struct cso_hash *cso;
|
||||
|
||||
/** Hash function */
|
||||
unsigned (*hash)(void *key);
|
||||
|
||||
/** Compare two keys */
|
||||
int (*compare)(void *key1, void *key2);
|
||||
|
||||
/* TODO: key, value destructors? */
|
||||
};
|
||||
|
||||
|
||||
struct hash_table_item
|
||||
{
|
||||
void *key;
|
||||
void *value;
|
||||
};
|
||||
|
||||
|
||||
struct hash_table *
|
||||
hash_table_create(unsigned (*hash)(void *key),
|
||||
int (*compare)(void *key1, void *key2))
|
||||
{
|
||||
struct hash_table *ht;
|
||||
|
||||
ht = MALLOC_STRUCT(hash_table);
|
||||
if(!ht)
|
||||
return NULL;
|
||||
|
||||
ht->cso = cso_hash_create();
|
||||
if(!ht->cso) {
|
||||
FREE(ht);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ht->hash = hash;
|
||||
ht->compare = compare;
|
||||
|
||||
return ht;
|
||||
}
|
||||
|
||||
|
||||
static struct hash_table_item *
|
||||
hash_table_find_item(struct hash_table *ht,
|
||||
void *key,
|
||||
unsigned key_hash)
|
||||
{
|
||||
struct cso_hash_iter iter;
|
||||
struct hash_table_item *item;
|
||||
|
||||
iter = cso_hash_find(ht->cso, key_hash);
|
||||
while (!cso_hash_iter_is_null(iter)) {
|
||||
item = (struct hash_table_item *)cso_hash_iter_data(iter);
|
||||
if (!ht->compare(item->key, key))
|
||||
return item;
|
||||
iter = cso_hash_iter_next(iter);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
enum pipe_error
|
||||
hash_table_set(struct hash_table *ht,
|
||||
void *key,
|
||||
void *value)
|
||||
{
|
||||
unsigned key_hash;
|
||||
struct hash_table_item *item;
|
||||
|
||||
assert(ht);
|
||||
|
||||
key_hash = ht->hash(key);
|
||||
|
||||
item = hash_table_find_item(ht, key, key_hash);
|
||||
if(item) {
|
||||
/* TODO: key/value destruction? */
|
||||
item->value = value;
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
item = MALLOC_STRUCT(hash_table_item);
|
||||
if(!item)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
item->key = key;
|
||||
item->value = value;
|
||||
|
||||
cso_hash_insert(ht->cso, key_hash, item);
|
||||
/* FIXME: there is no OOM propagation in cso_hash */
|
||||
if(0) {
|
||||
FREE(item);
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
hash_table_get(struct hash_table *ht,
|
||||
void *key)
|
||||
{
|
||||
unsigned key_hash;
|
||||
struct hash_table_item *item;
|
||||
|
||||
assert(ht);
|
||||
|
||||
key_hash = ht->hash(key);
|
||||
|
||||
item = hash_table_find_item(ht, key, key_hash);
|
||||
if(!item)
|
||||
return NULL;
|
||||
|
||||
return item->value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hash_table_remove(struct hash_table *ht,
|
||||
void *key)
|
||||
{
|
||||
unsigned key_hash;
|
||||
struct hash_table_item *item;
|
||||
|
||||
assert(ht);
|
||||
|
||||
key_hash = ht->hash(key);
|
||||
|
||||
item = hash_table_find_item(ht, key, key_hash);
|
||||
if(!item)
|
||||
return;
|
||||
|
||||
/* FIXME: cso_hash_take takes the first element of the collision list
|
||||
* indiscriminately, so we can not take the item down. */
|
||||
item->value = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hash_table_destroy(struct hash_table *ht)
|
||||
{
|
||||
assert(ht);
|
||||
|
||||
cso_hash_delete(ht->cso);
|
||||
|
||||
FREE(ht);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* General purpose hash table.
|
||||
*
|
||||
* @author José Fonseca <jrfonseca@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef U_HASH_TABLE_H_
|
||||
#define U_HASH_TABLE_H_
|
||||
|
||||
|
||||
#include "pipe/p_error.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Generic purpose hash table.
|
||||
*/
|
||||
struct hash_table;
|
||||
|
||||
|
||||
/**
|
||||
* Create an hash table.
|
||||
*
|
||||
* @param hash hash function
|
||||
* @param compare should return 0 for two equal keys.
|
||||
*/
|
||||
struct hash_table *
|
||||
hash_table_create(unsigned (*hash)(void *key),
|
||||
int (*compare)(void *key1, void *key2));
|
||||
|
||||
|
||||
enum pipe_error
|
||||
hash_table_set(struct hash_table *ht,
|
||||
void *key,
|
||||
void *value);
|
||||
|
||||
void *
|
||||
hash_table_get(struct hash_table *ht,
|
||||
void *key);
|
||||
|
||||
|
||||
void
|
||||
hash_table_remove(struct hash_table *ht,
|
||||
void *key);
|
||||
|
||||
|
||||
void
|
||||
hash_table_destroy(struct hash_table *ht);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* U_HASH_TABLE_H_ */
|
||||
@@ -37,13 +37,14 @@
|
||||
#include "cell_winsys.h"
|
||||
#include "cell/common.h"
|
||||
#include "rtasm/rtasm_ppc_spe.h"
|
||||
|
||||
#include "tgsi/util/tgsi_scan.h"
|
||||
|
||||
struct cell_vbuf_render;
|
||||
|
||||
struct cell_vertex_shader_state
|
||||
{
|
||||
struct pipe_shader_state shader;
|
||||
struct tgsi_shader_info info;
|
||||
void *draw_data;
|
||||
};
|
||||
|
||||
@@ -51,6 +52,7 @@ struct cell_vertex_shader_state
|
||||
struct cell_fragment_shader_state
|
||||
{
|
||||
struct pipe_shader_state shader;
|
||||
struct tgsi_shader_info info;
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
@@ -36,14 +36,14 @@
|
||||
|
||||
|
||||
static int
|
||||
find_vs_output(const struct pipe_shader_state *vs,
|
||||
find_vs_output(const struct cell_vertex_shader_state *vs,
|
||||
uint semantic_name,
|
||||
uint semantic_index)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < vs->num_outputs; i++) {
|
||||
if (vs->output_semantic_name[i] == semantic_name &&
|
||||
vs->output_semantic_index[i] == semantic_index)
|
||||
for (i = 0; i < vs->info.num_outputs; i++) {
|
||||
if (vs->info.output_semantic_name[i] == semantic_name &&
|
||||
vs->info.output_semantic_index[i] == semantic_index)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@@ -58,8 +58,8 @@ find_vs_output(const struct pipe_shader_state *vs,
|
||||
static void
|
||||
calculate_vertex_layout( struct cell_context *cell )
|
||||
{
|
||||
const struct pipe_shader_state *vs = &cell->vs->shader;
|
||||
const struct pipe_shader_state *fs = &cell->fs->shader;
|
||||
const struct cell_vertex_shader_state *vs = cell->vs;
|
||||
const struct cell_fragment_shader_state *fs = cell->fs;
|
||||
const enum interp_mode colorInterp
|
||||
= cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
|
||||
struct vertex_info *vinfo = &cell->vertex_info;
|
||||
@@ -91,15 +91,15 @@ calculate_vertex_layout( struct cell_context *cell )
|
||||
* Loop over fragment shader inputs, searching for the matching output
|
||||
* from the vertex shader.
|
||||
*/
|
||||
for (i = 0; i < fs->num_inputs; i++) {
|
||||
switch (fs->input_semantic_name[i]) {
|
||||
for (i = 0; i < fs->info.num_inputs; i++) {
|
||||
switch (fs->info.input_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
/* already done above */
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
|
||||
fs->input_semantic_index[i]);
|
||||
fs->info.input_semantic_index[i]);
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
|
||||
break;
|
||||
@@ -117,7 +117,7 @@ calculate_vertex_layout( struct cell_context *cell )
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
/* this includes texcoords and varying vars */
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
|
||||
fs->input_semantic_index[i]);
|
||||
fs->info.input_semantic_index[i]);
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
||||
break;
|
||||
|
||||
@@ -54,27 +54,7 @@ cell_create_fs_state(struct pipe_context *pipe,
|
||||
|
||||
state->shader = *templ;
|
||||
|
||||
#if 0
|
||||
if (cell->dump_fs) {
|
||||
tgsi_dump(state->shader.tokens, 0);
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__386__)
|
||||
if (cell->use_sse) {
|
||||
x86_init_func( &state->sse2_program );
|
||||
tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MESA_LLVM
|
||||
state->llvm_prog = 0;
|
||||
if (!gallivm_global_cpu_engine()) {
|
||||
gallivm_cpu_engine_create(state->llvm_prog);
|
||||
}
|
||||
else
|
||||
gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog);
|
||||
#endif
|
||||
#endif
|
||||
tgsi_scan_shader(templ->tokens, &state->info);
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -113,6 +93,7 @@ cell_create_vs_state(struct pipe_context *pipe,
|
||||
return NULL;
|
||||
|
||||
state->shader = *templ;
|
||||
tgsi_scan_shader(templ->tokens, &state->info);
|
||||
|
||||
state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader);
|
||||
if (state->draw_data == NULL) {
|
||||
|
||||
@@ -672,7 +672,7 @@ fetch_texel( struct spu_sampler *sampler,
|
||||
static void
|
||||
exec_tex(struct spu_exec_machine *mach,
|
||||
const struct tgsi_full_instruction *inst,
|
||||
boolean biasLod)
|
||||
boolean biasLod, boolean projected)
|
||||
{
|
||||
const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
|
||||
union spu_exec_channel r[8];
|
||||
@@ -686,17 +686,9 @@ exec_tex(struct spu_exec_machine *mach,
|
||||
|
||||
FETCH(&r[0], 0, CHAN_X);
|
||||
|
||||
switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) {
|
||||
case TGSI_EXTSWIZZLE_W:
|
||||
if (projected) {
|
||||
FETCH(&r[1], 0, CHAN_W);
|
||||
r[0].q = micro_div(r[0].q, r[1].q);
|
||||
break;
|
||||
|
||||
case TGSI_EXTSWIZZLE_ONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
|
||||
if (biasLod) {
|
||||
@@ -718,19 +710,11 @@ exec_tex(struct spu_exec_machine *mach,
|
||||
FETCH(&r[1], 0, CHAN_Y);
|
||||
FETCH(&r[2], 0, CHAN_Z);
|
||||
|
||||
switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) {
|
||||
case TGSI_EXTSWIZZLE_W:
|
||||
if (projected) {
|
||||
FETCH(&r[3], 0, CHAN_W);
|
||||
r[0].q = micro_div(r[0].q, r[3].q);
|
||||
r[1].q = micro_div(r[1].q, r[3].q);
|
||||
r[2].q = micro_div(r[2].q, r[3].q);
|
||||
break;
|
||||
|
||||
case TGSI_EXTSWIZZLE_ONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
|
||||
if (biasLod) {
|
||||
@@ -752,19 +736,11 @@ exec_tex(struct spu_exec_machine *mach,
|
||||
FETCH(&r[1], 0, CHAN_Y);
|
||||
FETCH(&r[2], 0, CHAN_Z);
|
||||
|
||||
switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) {
|
||||
case TGSI_EXTSWIZZLE_W:
|
||||
if (projected) {
|
||||
FETCH(&r[3], 0, CHAN_W);
|
||||
r[0].q = micro_div(r[0].q, r[3].q);
|
||||
r[1].q = micro_div(r[1].q, r[3].q);
|
||||
r[2].q = micro_div(r[2].q, r[3].q);
|
||||
break;
|
||||
|
||||
case TGSI_EXTSWIZZLE_ONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
|
||||
if (biasLod) {
|
||||
@@ -1450,14 +1426,14 @@ exec_instruction(
|
||||
/* simple texture lookup */
|
||||
/* src[0] = texcoord */
|
||||
/* src[1] = sampler unit */
|
||||
exec_tex(mach, inst, FALSE);
|
||||
exec_tex(mach, inst, FALSE, FALSE);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_TXB:
|
||||
/* Texture lookup with lod bias */
|
||||
/* src[0] = texcoord (src[0].w = load bias) */
|
||||
/* src[1] = sampler unit */
|
||||
exec_tex(mach, inst, TRUE);
|
||||
exec_tex(mach, inst, TRUE, FALSE);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_TXD:
|
||||
@@ -1473,7 +1449,14 @@ exec_instruction(
|
||||
/* Texture lookup with explit LOD */
|
||||
/* src[0] = texcoord (src[0].w = load bias) */
|
||||
/* src[1] = sampler unit */
|
||||
exec_tex(mach, inst, TRUE);
|
||||
exec_tex(mach, inst, TRUE, FALSE);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_TXP:
|
||||
/* Texture lookup with projection
|
||||
/* src[0] = texcoord (src[0].w = projection) */
|
||||
/* src[1] = sampler unit */
|
||||
exec_tex(mach, inst, TRUE, TRUE);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_UP2H:
|
||||
|
||||
@@ -516,7 +516,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
|
||||
* stays the same. In that case we should only be updating the first
|
||||
* N constants, leaving any extras from shader translation alone.
|
||||
*/
|
||||
{
|
||||
if (buf) {
|
||||
void *mapped;
|
||||
if (buf->size &&
|
||||
(mapped = ws->buffer_map(ws, buf->buffer,
|
||||
|
||||
@@ -55,6 +55,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
||||
|
||||
if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) {
|
||||
sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue);
|
||||
softpipe->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_CLEAR;
|
||||
#if TILE_CLEAR_OPTIMIZATION
|
||||
return;
|
||||
#endif
|
||||
@@ -63,6 +64,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
||||
for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
|
||||
if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) {
|
||||
sp_tile_cache_clear(softpipe->cbuf_cache[i], clearValue);
|
||||
softpipe->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_CLEAR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,243 +1,243 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Author:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "sp_clear.h"
|
||||
#include "sp_context.h"
|
||||
#include "sp_flush.h"
|
||||
#include "sp_prim_setup.h"
|
||||
#include "sp_prim_vbuf.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_surface.h"
|
||||
#include "sp_tile_cache.h"
|
||||
#include "sp_texture.h"
|
||||
#include "sp_winsys.h"
|
||||
#include "sp_query.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Map any drawing surfaces which aren't already mapped
|
||||
*/
|
||||
void
|
||||
softpipe_map_surfaces(struct softpipe_context *sp)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
|
||||
sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
|
||||
}
|
||||
|
||||
sp_tile_cache_map_surfaces(sp->zsbuf_cache);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unmap any mapped drawing surfaces
|
||||
*/
|
||||
void
|
||||
softpipe_unmap_surfaces(struct softpipe_context *sp)
|
||||
{
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < sp->framebuffer.num_cbufs; i++)
|
||||
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
|
||||
sp_flush_tile_cache(sp, sp->zsbuf_cache);
|
||||
|
||||
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
|
||||
sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
|
||||
}
|
||||
sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
|
||||
}
|
||||
|
||||
|
||||
static void softpipe_destroy( struct pipe_context *pipe )
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context( pipe );
|
||||
struct pipe_winsys *ws = pipe->winsys;
|
||||
uint i;
|
||||
|
||||
draw_destroy( softpipe->draw );
|
||||
|
||||
softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
|
||||
softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
|
||||
softpipe->quad.shade->destroy( softpipe->quad.shade );
|
||||
softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
|
||||
softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
|
||||
softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );
|
||||
softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
|
||||
softpipe->quad.coverage->destroy( softpipe->quad.coverage );
|
||||
softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );
|
||||
softpipe->quad.blend->destroy( softpipe->quad.blend );
|
||||
softpipe->quad.colormask->destroy( softpipe->quad.colormask );
|
||||
softpipe->quad.output->destroy( softpipe->quad.output );
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
|
||||
sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
|
||||
sp_destroy_tile_cache(softpipe->zsbuf_cache);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
sp_destroy_tile_cache(softpipe->tex_cache[i]);
|
||||
|
||||
for (i = 0; i < Elements(softpipe->constants); i++) {
|
||||
if (softpipe->constants[i].buffer) {
|
||||
pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
FREE( softpipe );
|
||||
}
|
||||
|
||||
|
||||
struct pipe_context *
|
||||
softpipe_create( struct pipe_screen *screen,
|
||||
struct pipe_winsys *pipe_winsys,
|
||||
struct softpipe_winsys *softpipe_winsys )
|
||||
{
|
||||
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
|
||||
uint i;
|
||||
|
||||
#if defined(__i386__) || defined(__386__)
|
||||
softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;
|
||||
#else
|
||||
softpipe->use_sse = FALSE;
|
||||
#endif
|
||||
|
||||
softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;
|
||||
|
||||
softpipe->pipe.winsys = pipe_winsys;
|
||||
softpipe->pipe.screen = screen;
|
||||
softpipe->pipe.destroy = softpipe_destroy;
|
||||
|
||||
/* state setters */
|
||||
softpipe->pipe.create_blend_state = softpipe_create_blend_state;
|
||||
softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
|
||||
softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
|
||||
|
||||
softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
|
||||
softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states;
|
||||
softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
|
||||
|
||||
softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
|
||||
softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state;
|
||||
softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;
|
||||
|
||||
softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
|
||||
softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state;
|
||||
softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
|
||||
|
||||
softpipe->pipe.create_fs_state = softpipe_create_fs_state;
|
||||
softpipe->pipe.bind_fs_state = softpipe_bind_fs_state;
|
||||
softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
|
||||
|
||||
softpipe->pipe.create_vs_state = softpipe_create_vs_state;
|
||||
softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
|
||||
softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
|
||||
|
||||
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
|
||||
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
|
||||
softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
|
||||
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
|
||||
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
|
||||
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
|
||||
softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures;
|
||||
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
|
||||
|
||||
softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;
|
||||
softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;
|
||||
|
||||
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
|
||||
softpipe->pipe.draw_elements = softpipe_draw_elements;
|
||||
|
||||
softpipe->pipe.clear = softpipe_clear;
|
||||
softpipe->pipe.flush = softpipe_flush;
|
||||
|
||||
softpipe_init_query_funcs( softpipe );
|
||||
softpipe_init_texture_funcs( softpipe );
|
||||
|
||||
/*
|
||||
* Alloc caches for accessing drawing surfaces and textures.
|
||||
* Must be before quad stage setup!
|
||||
*/
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
|
||||
softpipe->cbuf_cache[i] = sp_create_tile_cache();
|
||||
softpipe->zsbuf_cache = sp_create_tile_cache();
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
softpipe->tex_cache[i] = sp_create_tile_cache();
|
||||
|
||||
|
||||
/* setup quad rendering stages */
|
||||
softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
|
||||
softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
|
||||
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
|
||||
softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
|
||||
softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
|
||||
softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
|
||||
softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
|
||||
softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
|
||||
softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
|
||||
softpipe->quad.blend = sp_quad_blend_stage(softpipe);
|
||||
softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
|
||||
softpipe->quad.output = sp_quad_output_stage(softpipe);
|
||||
|
||||
softpipe->winsys = softpipe_winsys;
|
||||
|
||||
/*
|
||||
* Create drawing context and plug our rendering stage into it.
|
||||
*/
|
||||
softpipe->draw = draw_create();
|
||||
assert(softpipe->draw);
|
||||
softpipe->setup = sp_draw_render_stage(softpipe);
|
||||
|
||||
if (GETENV( "SP_VBUF" ) != NULL) {
|
||||
sp_init_vbuf(softpipe);
|
||||
}
|
||||
else {
|
||||
draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
|
||||
}
|
||||
|
||||
/* plug in AA line/point stages */
|
||||
draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
|
||||
draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
|
||||
|
||||
#if USE_DRAW_STAGE_PSTIPPLE
|
||||
/* Do polygon stipple w/ texture map + frag prog? */
|
||||
draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
|
||||
#endif
|
||||
|
||||
sp_init_surface_functions(softpipe);
|
||||
|
||||
return &softpipe->pipe;
|
||||
}
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Author:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "sp_clear.h"
|
||||
#include "sp_context.h"
|
||||
#include "sp_flush.h"
|
||||
#include "sp_prim_setup.h"
|
||||
#include "sp_prim_vbuf.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_surface.h"
|
||||
#include "sp_tile_cache.h"
|
||||
#include "sp_texture.h"
|
||||
#include "sp_winsys.h"
|
||||
#include "sp_query.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Map any drawing surfaces which aren't already mapped
|
||||
*/
|
||||
void
|
||||
softpipe_map_surfaces(struct softpipe_context *sp)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
|
||||
sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
|
||||
}
|
||||
|
||||
sp_tile_cache_map_surfaces(sp->zsbuf_cache);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unmap any mapped drawing surfaces
|
||||
*/
|
||||
void
|
||||
softpipe_unmap_surfaces(struct softpipe_context *sp)
|
||||
{
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < sp->framebuffer.num_cbufs; i++)
|
||||
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
|
||||
sp_flush_tile_cache(sp, sp->zsbuf_cache);
|
||||
|
||||
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
|
||||
sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
|
||||
}
|
||||
sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
|
||||
}
|
||||
|
||||
|
||||
static void softpipe_destroy( struct pipe_context *pipe )
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context( pipe );
|
||||
struct pipe_winsys *ws = pipe->winsys;
|
||||
uint i;
|
||||
|
||||
draw_destroy( softpipe->draw );
|
||||
|
||||
softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
|
||||
softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
|
||||
softpipe->quad.shade->destroy( softpipe->quad.shade );
|
||||
softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
|
||||
softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
|
||||
softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );
|
||||
softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
|
||||
softpipe->quad.coverage->destroy( softpipe->quad.coverage );
|
||||
softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );
|
||||
softpipe->quad.blend->destroy( softpipe->quad.blend );
|
||||
softpipe->quad.colormask->destroy( softpipe->quad.colormask );
|
||||
softpipe->quad.output->destroy( softpipe->quad.output );
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
|
||||
sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
|
||||
sp_destroy_tile_cache(softpipe->zsbuf_cache);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
sp_destroy_tile_cache(softpipe->tex_cache[i]);
|
||||
|
||||
for (i = 0; i < Elements(softpipe->constants); i++) {
|
||||
if (softpipe->constants[i].buffer) {
|
||||
pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
FREE( softpipe );
|
||||
}
|
||||
|
||||
|
||||
struct pipe_context *
|
||||
softpipe_create( struct pipe_screen *screen,
|
||||
struct pipe_winsys *pipe_winsys,
|
||||
struct softpipe_winsys *softpipe_winsys )
|
||||
{
|
||||
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
|
||||
uint i;
|
||||
|
||||
#if defined(__i386__) || defined(__386__)
|
||||
softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;
|
||||
#else
|
||||
softpipe->use_sse = FALSE;
|
||||
#endif
|
||||
|
||||
softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;
|
||||
|
||||
softpipe->pipe.winsys = pipe_winsys;
|
||||
softpipe->pipe.screen = screen;
|
||||
softpipe->pipe.destroy = softpipe_destroy;
|
||||
|
||||
/* state setters */
|
||||
softpipe->pipe.create_blend_state = softpipe_create_blend_state;
|
||||
softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
|
||||
softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
|
||||
|
||||
softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
|
||||
softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states;
|
||||
softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
|
||||
|
||||
softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
|
||||
softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state;
|
||||
softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;
|
||||
|
||||
softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
|
||||
softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state;
|
||||
softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
|
||||
|
||||
softpipe->pipe.create_fs_state = softpipe_create_fs_state;
|
||||
softpipe->pipe.bind_fs_state = softpipe_bind_fs_state;
|
||||
softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
|
||||
|
||||
softpipe->pipe.create_vs_state = softpipe_create_vs_state;
|
||||
softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
|
||||
softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
|
||||
|
||||
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
|
||||
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
|
||||
softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
|
||||
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
|
||||
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
|
||||
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
|
||||
softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures;
|
||||
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
|
||||
|
||||
softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;
|
||||
softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;
|
||||
|
||||
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
|
||||
softpipe->pipe.draw_elements = softpipe_draw_elements;
|
||||
|
||||
softpipe->pipe.clear = softpipe_clear;
|
||||
softpipe->pipe.flush = softpipe_flush;
|
||||
|
||||
softpipe_init_query_funcs( softpipe );
|
||||
softpipe_init_texture_funcs( softpipe );
|
||||
|
||||
/*
|
||||
* Alloc caches for accessing drawing surfaces and textures.
|
||||
* Must be before quad stage setup!
|
||||
*/
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
|
||||
softpipe->cbuf_cache[i] = sp_create_tile_cache();
|
||||
softpipe->zsbuf_cache = sp_create_tile_cache();
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
softpipe->tex_cache[i] = sp_create_tile_cache();
|
||||
|
||||
|
||||
/* setup quad rendering stages */
|
||||
softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
|
||||
softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
|
||||
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
|
||||
softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
|
||||
softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
|
||||
softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
|
||||
softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
|
||||
softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
|
||||
softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
|
||||
softpipe->quad.blend = sp_quad_blend_stage(softpipe);
|
||||
softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
|
||||
softpipe->quad.output = sp_quad_output_stage(softpipe);
|
||||
|
||||
softpipe->winsys = softpipe_winsys;
|
||||
|
||||
/*
|
||||
* Create drawing context and plug our rendering stage into it.
|
||||
*/
|
||||
softpipe->draw = draw_create();
|
||||
assert(softpipe->draw);
|
||||
softpipe->setup = sp_draw_render_stage(softpipe);
|
||||
|
||||
if (GETENV( "SP_VBUF" ) != NULL) {
|
||||
sp_init_vbuf(softpipe);
|
||||
}
|
||||
else {
|
||||
draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
|
||||
}
|
||||
|
||||
/* plug in AA line/point stages */
|
||||
draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
|
||||
draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
|
||||
|
||||
#if USE_DRAW_STAGE_PSTIPPLE
|
||||
/* Do polygon stipple w/ texture map + frag prog? */
|
||||
draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
|
||||
#endif
|
||||
|
||||
sp_init_surface_functions(softpipe);
|
||||
|
||||
return &softpipe->pipe;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,14 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp)
|
||||
{
|
||||
struct pipe_winsys *ws = sp->pipe.winsys;
|
||||
uint i;
|
||||
|
||||
/* really need to flush all prims since the vert/frag shaders const buffers
|
||||
* are going away now.
|
||||
*/
|
||||
draw_flush(sp->draw);
|
||||
|
||||
draw_set_mapped_constant_buffer(sp->draw, NULL);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (sp->constants[i].size)
|
||||
ws->buffer_unmap(ws, sp->constants[i].buffer);
|
||||
|
||||
@@ -1164,11 +1164,22 @@ static void setup_begin( struct draw_stage *stage )
|
||||
struct setup_stage *setup = setup_stage(stage);
|
||||
struct softpipe_context *sp = setup->softpipe;
|
||||
const struct sp_fragment_shader *fs = setup->softpipe->fs;
|
||||
uint i;
|
||||
|
||||
if (sp->dirty) {
|
||||
softpipe_update_derived(sp);
|
||||
}
|
||||
|
||||
/* Mark surfaces as defined now */
|
||||
for (i = 0; i < sp->framebuffer.num_cbufs; i++){
|
||||
if (sp->framebuffer.cbufs[i]) {
|
||||
sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED;
|
||||
}
|
||||
}
|
||||
if (sp->framebuffer.zsbuf) {
|
||||
sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED;
|
||||
}
|
||||
|
||||
setup->quad.nr_attrs = fs->info.num_inputs;
|
||||
|
||||
sp->quad.first->begin(sp->quad.first);
|
||||
|
||||
@@ -183,6 +183,60 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is hit when the draw module is working in pass-through mode.
|
||||
* It's up to us to convert the vertex array into point/line/tri prims.
|
||||
*/
|
||||
static void
|
||||
sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
||||
{
|
||||
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
|
||||
struct softpipe_context *softpipe = cvbr->softpipe;
|
||||
struct draw_stage *setup = softpipe->setup;
|
||||
struct prim_header prim;
|
||||
const void *vertex_buffer = cvbr->vertex_buffer;
|
||||
const unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float);
|
||||
unsigned i;
|
||||
|
||||
prim.det = 0;
|
||||
prim.reset_line_stipple = 0;
|
||||
prim.edgeflags = 0;
|
||||
prim.pad = 0;
|
||||
|
||||
#define VERTEX(I) \
|
||||
(struct vertex_header *) ((char *) vertex_buffer + (I) * vertex_size)
|
||||
|
||||
switch (cvbr->prim) {
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
assert(nr % 3 == 0);
|
||||
for (i = 0; i < nr; i += 3) {
|
||||
prim.v[0] = VERTEX(i + 0);
|
||||
prim.v[1] = VERTEX(i + 1);
|
||||
prim.v[2] = VERTEX(i + 2);
|
||||
calc_det(&prim);
|
||||
setup->tri( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_POLYGON:
|
||||
/* draw as tri fan */
|
||||
for (i = 2; i < nr; i++) {
|
||||
prim.v[0] = VERTEX(0);
|
||||
prim.v[1] = VERTEX(i - 1);
|
||||
prim.v[2] = VERTEX(i);
|
||||
calc_det(&prim);
|
||||
setup->tri( setup, &prim );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* XXX finish remaining prim types */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#undef VERTEX
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
sp_vbuf_destroy(struct vbuf_render *vbr)
|
||||
{
|
||||
@@ -210,6 +264,7 @@ sp_init_vbuf(struct softpipe_context *sp)
|
||||
sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices;
|
||||
sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive;
|
||||
sp->vbuf_render->base.draw = sp_vbuf_draw;
|
||||
sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays;
|
||||
sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices;
|
||||
sp->vbuf_render->base.destroy = sp_vbuf_destroy;
|
||||
|
||||
@@ -218,4 +273,6 @@ sp_init_vbuf(struct softpipe_context *sp)
|
||||
sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base);
|
||||
|
||||
draw_set_rasterize_stage(sp->draw, sp->vbuf);
|
||||
|
||||
draw_set_render(sp->draw, &sp->vbuf_render->base);
|
||||
}
|
||||
|
||||
@@ -1,209 +1,209 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Vertices are just an array of floats, with all the attributes
|
||||
* packed. We currently assume a layout like:
|
||||
*
|
||||
* attr[0][0..3] - window position
|
||||
* attr[1..n][0..3] - remaining attributes.
|
||||
*
|
||||
* Attributes are assumed to be 4 floats wide but are packed so that
|
||||
* all the enabled attributes run contiguously.
|
||||
*/
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_headers.h"
|
||||
#include "sp_quad.h"
|
||||
#include "sp_texture.h"
|
||||
#include "sp_tex_sample.h"
|
||||
|
||||
|
||||
struct quad_shade_stage
|
||||
{
|
||||
struct quad_stage stage;
|
||||
struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];
|
||||
struct tgsi_exec_machine machine;
|
||||
struct tgsi_exec_vector *inputs, *outputs;
|
||||
int colorOutSlot, depthOutSlot;
|
||||
};
|
||||
|
||||
|
||||
/** cast wrapper */
|
||||
static INLINE struct quad_shade_stage *
|
||||
quad_shade_stage(struct quad_stage *qs)
|
||||
{
|
||||
return (struct quad_shade_stage *) qs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Execute fragment shader for the four fragments in the quad.
|
||||
*/
|
||||
static void
|
||||
shade_quad(
|
||||
struct quad_stage *qs,
|
||||
struct quad_header *quad )
|
||||
{
|
||||
struct quad_shade_stage *qss = quad_shade_stage( qs );
|
||||
struct softpipe_context *softpipe = qs->softpipe;
|
||||
struct tgsi_exec_machine *machine = &qss->machine;
|
||||
|
||||
/* Consts do not require 16 byte alignment. */
|
||||
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
|
||||
|
||||
machine->InterpCoefs = quad->coef;
|
||||
|
||||
/* run shader */
|
||||
quad->mask &= softpipe->fs->run( softpipe->fs,
|
||||
&qss->machine,
|
||||
quad );
|
||||
|
||||
/* store result color */
|
||||
if (qss->colorOutSlot >= 0) {
|
||||
/* XXX need to handle multiple color outputs someday */
|
||||
assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
|
||||
== TGSI_SEMANTIC_COLOR);
|
||||
memcpy(
|
||||
quad->outputs.color,
|
||||
&machine->Outputs[qss->colorOutSlot].xyzw[0].f[0],
|
||||
sizeof( quad->outputs.color ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX the following code for updating quad->outputs.depth
|
||||
* isn't really needed if we did early z testing.
|
||||
*/
|
||||
|
||||
/* store result Z */
|
||||
if (qss->depthOutSlot >= 0) {
|
||||
/* output[slot] is new Z */
|
||||
uint i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* copy input Z (which was interpolated by the executor) to output Z */
|
||||
uint i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];
|
||||
/* XXX not sure the above line is always correct. The following
|
||||
* might be better:
|
||||
quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i];
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/* shader may cull fragments */
|
||||
if( quad->mask ) {
|
||||
qs->next->run( qs->next, quad );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-primitive (or per-begin?) setup
|
||||
*/
|
||||
static void shade_begin(struct quad_stage *qs)
|
||||
{
|
||||
struct quad_shade_stage *qss = quad_shade_stage(qs);
|
||||
struct softpipe_context *softpipe = qs->softpipe;
|
||||
unsigned i;
|
||||
unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers);
|
||||
|
||||
/* set TGSI sampler state that varies */
|
||||
for (i = 0; i < num; i++) {
|
||||
qss->samplers[i].state = softpipe->sampler[i];
|
||||
qss->samplers[i].texture = softpipe->texture[i];
|
||||
}
|
||||
|
||||
/* find output slots for depth, color */
|
||||
qss->colorOutSlot = -1;
|
||||
qss->depthOutSlot = -1;
|
||||
for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {
|
||||
switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
qss->depthOutSlot = i;
|
||||
break;
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
qss->colorOutSlot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
softpipe->fs->prepare( softpipe->fs,
|
||||
&qss->machine,
|
||||
qss->samplers );
|
||||
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void shade_destroy(struct quad_stage *qs)
|
||||
{
|
||||
struct quad_shade_stage *qss = (struct quad_shade_stage *) qs;
|
||||
|
||||
tgsi_exec_machine_free_data(&qss->machine);
|
||||
FREE( qss->inputs );
|
||||
FREE( qss->outputs );
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
|
||||
{
|
||||
struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
|
||||
uint i;
|
||||
|
||||
/* allocate storage for program inputs/outputs, aligned to 16 bytes */
|
||||
qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);
|
||||
qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16);
|
||||
qss->machine.Inputs = align16(qss->inputs);
|
||||
qss->machine.Outputs = align16(qss->outputs);
|
||||
|
||||
qss->stage.softpipe = softpipe;
|
||||
qss->stage.begin = shade_begin;
|
||||
qss->stage.run = shade_quad;
|
||||
qss->stage.destroy = shade_destroy;
|
||||
|
||||
/* set TGSI sampler state that's constant */
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
|
||||
assert(softpipe->tex_cache[i]);
|
||||
qss->samplers[i].get_samples = sp_get_samples;
|
||||
qss->samplers[i].pipe = &softpipe->pipe;
|
||||
qss->samplers[i].cache = softpipe->tex_cache[i];
|
||||
}
|
||||
|
||||
tgsi_exec_machine_init( &qss->machine );
|
||||
|
||||
return &qss->stage;
|
||||
}
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Vertices are just an array of floats, with all the attributes
|
||||
* packed. We currently assume a layout like:
|
||||
*
|
||||
* attr[0][0..3] - window position
|
||||
* attr[1..n][0..3] - remaining attributes.
|
||||
*
|
||||
* Attributes are assumed to be 4 floats wide but are packed so that
|
||||
* all the enabled attributes run contiguously.
|
||||
*/
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_headers.h"
|
||||
#include "sp_quad.h"
|
||||
#include "sp_texture.h"
|
||||
#include "sp_tex_sample.h"
|
||||
|
||||
|
||||
struct quad_shade_stage
|
||||
{
|
||||
struct quad_stage stage;
|
||||
struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];
|
||||
struct tgsi_exec_machine machine;
|
||||
struct tgsi_exec_vector *inputs, *outputs;
|
||||
int colorOutSlot, depthOutSlot;
|
||||
};
|
||||
|
||||
|
||||
/** cast wrapper */
|
||||
static INLINE struct quad_shade_stage *
|
||||
quad_shade_stage(struct quad_stage *qs)
|
||||
{
|
||||
return (struct quad_shade_stage *) qs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Execute fragment shader for the four fragments in the quad.
|
||||
*/
|
||||
static void
|
||||
shade_quad(
|
||||
struct quad_stage *qs,
|
||||
struct quad_header *quad )
|
||||
{
|
||||
struct quad_shade_stage *qss = quad_shade_stage( qs );
|
||||
struct softpipe_context *softpipe = qs->softpipe;
|
||||
struct tgsi_exec_machine *machine = &qss->machine;
|
||||
|
||||
/* Consts do not require 16 byte alignment. */
|
||||
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
|
||||
|
||||
machine->InterpCoefs = quad->coef;
|
||||
|
||||
/* run shader */
|
||||
quad->mask &= softpipe->fs->run( softpipe->fs,
|
||||
&qss->machine,
|
||||
quad );
|
||||
|
||||
/* store result color */
|
||||
if (qss->colorOutSlot >= 0) {
|
||||
/* XXX need to handle multiple color outputs someday */
|
||||
assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
|
||||
== TGSI_SEMANTIC_COLOR);
|
||||
memcpy(
|
||||
quad->outputs.color,
|
||||
&machine->Outputs[qss->colorOutSlot].xyzw[0].f[0],
|
||||
sizeof( quad->outputs.color ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX the following code for updating quad->outputs.depth
|
||||
* isn't really needed if we did early z testing.
|
||||
*/
|
||||
|
||||
/* store result Z */
|
||||
if (qss->depthOutSlot >= 0) {
|
||||
/* output[slot] is new Z */
|
||||
uint i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* copy input Z (which was interpolated by the executor) to output Z */
|
||||
uint i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];
|
||||
/* XXX not sure the above line is always correct. The following
|
||||
* might be better:
|
||||
quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i];
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/* shader may cull fragments */
|
||||
if( quad->mask ) {
|
||||
qs->next->run( qs->next, quad );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-primitive (or per-begin?) setup
|
||||
*/
|
||||
static void shade_begin(struct quad_stage *qs)
|
||||
{
|
||||
struct quad_shade_stage *qss = quad_shade_stage(qs);
|
||||
struct softpipe_context *softpipe = qs->softpipe;
|
||||
unsigned i;
|
||||
unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers);
|
||||
|
||||
/* set TGSI sampler state that varies */
|
||||
for (i = 0; i < num; i++) {
|
||||
qss->samplers[i].state = softpipe->sampler[i];
|
||||
qss->samplers[i].texture = softpipe->texture[i];
|
||||
}
|
||||
|
||||
/* find output slots for depth, color */
|
||||
qss->colorOutSlot = -1;
|
||||
qss->depthOutSlot = -1;
|
||||
for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {
|
||||
switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
qss->depthOutSlot = i;
|
||||
break;
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
qss->colorOutSlot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
softpipe->fs->prepare( softpipe->fs,
|
||||
&qss->machine,
|
||||
qss->samplers );
|
||||
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void shade_destroy(struct quad_stage *qs)
|
||||
{
|
||||
struct quad_shade_stage *qss = (struct quad_shade_stage *) qs;
|
||||
|
||||
tgsi_exec_machine_free_data(&qss->machine);
|
||||
FREE( qss->inputs );
|
||||
FREE( qss->outputs );
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
|
||||
{
|
||||
struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
|
||||
uint i;
|
||||
|
||||
/* allocate storage for program inputs/outputs, aligned to 16 bytes */
|
||||
qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);
|
||||
qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16);
|
||||
qss->machine.Inputs = align16(qss->inputs);
|
||||
qss->machine.Outputs = align16(qss->outputs);
|
||||
|
||||
qss->stage.softpipe = softpipe;
|
||||
qss->stage.begin = shade_begin;
|
||||
qss->stage.run = shade_quad;
|
||||
qss->stage.destroy = shade_destroy;
|
||||
|
||||
/* set TGSI sampler state that's constant */
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
|
||||
assert(softpipe->tex_cache[i]);
|
||||
qss->samplers[i].get_samples = sp_get_samples;
|
||||
qss->samplers[i].pipe = &softpipe->pipe;
|
||||
qss->samplers[i].cache = softpipe->tex_cache[i];
|
||||
}
|
||||
|
||||
tgsi_exec_machine_init( &qss->machine );
|
||||
|
||||
return &qss->stage;
|
||||
}
|
||||
|
||||
@@ -1,195 +1,195 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef SP_STATE_H
|
||||
#define SP_STATE_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "tgsi/util/tgsi_scan.h"
|
||||
|
||||
|
||||
#define SP_NEW_VIEWPORT 0x1
|
||||
#define SP_NEW_RASTERIZER 0x2
|
||||
#define SP_NEW_FS 0x4
|
||||
#define SP_NEW_BLEND 0x8
|
||||
#define SP_NEW_CLIP 0x10
|
||||
#define SP_NEW_SCISSOR 0x20
|
||||
#define SP_NEW_STIPPLE 0x40
|
||||
#define SP_NEW_FRAMEBUFFER 0x80
|
||||
#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100
|
||||
#define SP_NEW_CONSTANTS 0x200
|
||||
#define SP_NEW_SAMPLER 0x400
|
||||
#define SP_NEW_TEXTURE 0x800
|
||||
#define SP_NEW_VERTEX 0x1000
|
||||
#define SP_NEW_VS 0x2000
|
||||
#define SP_NEW_QUERY 0x4000
|
||||
|
||||
|
||||
struct tgsi_sampler;
|
||||
struct tgsi_exec_machine;
|
||||
|
||||
|
||||
/** Subclass of pipe_shader_state (though it doesn't really need to be).
|
||||
*
|
||||
* This is starting to look an awful lot like a quad pipeline stage...
|
||||
*/
|
||||
struct sp_fragment_shader {
|
||||
struct pipe_shader_state shader;
|
||||
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
void (*prepare)( const struct sp_fragment_shader *shader,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct tgsi_sampler *samplers);
|
||||
|
||||
/* Run the shader - this interface will get cleaned up in the
|
||||
* future:
|
||||
*/
|
||||
unsigned (*run)( const struct sp_fragment_shader *shader,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct quad_header *quad );
|
||||
|
||||
|
||||
void (*delete)( struct sp_fragment_shader * );
|
||||
};
|
||||
|
||||
struct vertex_info;
|
||||
|
||||
/** Subclass of pipe_shader_state */
|
||||
struct sp_vertex_shader {
|
||||
struct pipe_shader_state shader;
|
||||
struct draw_vertex_shader *draw_data;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void *
|
||||
softpipe_create_blend_state(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
void softpipe_bind_blend_state(struct pipe_context *,
|
||||
void *);
|
||||
void softpipe_delete_blend_state(struct pipe_context *,
|
||||
void *);
|
||||
|
||||
void *
|
||||
softpipe_create_sampler_state(struct pipe_context *,
|
||||
const struct pipe_sampler_state *);
|
||||
void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
|
||||
void softpipe_delete_sampler_state(struct pipe_context *, void *);
|
||||
|
||||
void *
|
||||
softpipe_create_depth_stencil_state(struct pipe_context *,
|
||||
const struct pipe_depth_stencil_alpha_state *);
|
||||
void softpipe_bind_depth_stencil_state(struct pipe_context *, void *);
|
||||
void softpipe_delete_depth_stencil_state(struct pipe_context *, void *);
|
||||
|
||||
void *
|
||||
softpipe_create_rasterizer_state(struct pipe_context *,
|
||||
const struct pipe_rasterizer_state *);
|
||||
void softpipe_bind_rasterizer_state(struct pipe_context *, void *);
|
||||
void softpipe_delete_rasterizer_state(struct pipe_context *, void *);
|
||||
|
||||
void softpipe_set_framebuffer_state( struct pipe_context *,
|
||||
const struct pipe_framebuffer_state * );
|
||||
|
||||
void softpipe_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color );
|
||||
|
||||
void softpipe_set_clip_state( struct pipe_context *,
|
||||
const struct pipe_clip_state * );
|
||||
|
||||
void softpipe_set_constant_buffer(struct pipe_context *,
|
||||
uint shader, uint index,
|
||||
const struct pipe_constant_buffer *buf);
|
||||
|
||||
void *softpipe_create_fs_state(struct pipe_context *,
|
||||
const struct pipe_shader_state *);
|
||||
void softpipe_bind_fs_state(struct pipe_context *, void *);
|
||||
void softpipe_delete_fs_state(struct pipe_context *, void *);
|
||||
void *softpipe_create_vs_state(struct pipe_context *,
|
||||
const struct pipe_shader_state *);
|
||||
void softpipe_bind_vs_state(struct pipe_context *, void *);
|
||||
void softpipe_delete_vs_state(struct pipe_context *, void *);
|
||||
|
||||
void softpipe_set_polygon_stipple( struct pipe_context *,
|
||||
const struct pipe_poly_stipple * );
|
||||
|
||||
void softpipe_set_scissor_state( struct pipe_context *,
|
||||
const struct pipe_scissor_state * );
|
||||
|
||||
void softpipe_set_sampler_textures( struct pipe_context *,
|
||||
unsigned num,
|
||||
struct pipe_texture ** );
|
||||
|
||||
void softpipe_set_viewport_state( struct pipe_context *,
|
||||
const struct pipe_viewport_state * );
|
||||
|
||||
void softpipe_set_vertex_element(struct pipe_context *,
|
||||
unsigned index,
|
||||
const struct pipe_vertex_element *);
|
||||
|
||||
void softpipe_set_vertex_buffer(struct pipe_context *,
|
||||
unsigned index,
|
||||
const struct pipe_vertex_buffer *);
|
||||
|
||||
|
||||
void softpipe_update_derived( struct softpipe_context *softpipe );
|
||||
|
||||
|
||||
boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
|
||||
unsigned start, unsigned count);
|
||||
|
||||
boolean softpipe_draw_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned mode, unsigned start, unsigned count);
|
||||
|
||||
|
||||
void
|
||||
softpipe_map_surfaces(struct softpipe_context *sp);
|
||||
|
||||
void
|
||||
softpipe_unmap_surfaces(struct softpipe_context *sp);
|
||||
|
||||
void
|
||||
softpipe_map_texture_surfaces(struct softpipe_context *sp);
|
||||
|
||||
void
|
||||
softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
|
||||
|
||||
|
||||
struct vertex_info *
|
||||
softpipe_get_vertex_info(struct softpipe_context *softpipe);
|
||||
|
||||
struct vertex_info *
|
||||
softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
|
||||
|
||||
|
||||
#endif
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef SP_STATE_H
|
||||
#define SP_STATE_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "tgsi/util/tgsi_scan.h"
|
||||
|
||||
|
||||
#define SP_NEW_VIEWPORT 0x1
|
||||
#define SP_NEW_RASTERIZER 0x2
|
||||
#define SP_NEW_FS 0x4
|
||||
#define SP_NEW_BLEND 0x8
|
||||
#define SP_NEW_CLIP 0x10
|
||||
#define SP_NEW_SCISSOR 0x20
|
||||
#define SP_NEW_STIPPLE 0x40
|
||||
#define SP_NEW_FRAMEBUFFER 0x80
|
||||
#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100
|
||||
#define SP_NEW_CONSTANTS 0x200
|
||||
#define SP_NEW_SAMPLER 0x400
|
||||
#define SP_NEW_TEXTURE 0x800
|
||||
#define SP_NEW_VERTEX 0x1000
|
||||
#define SP_NEW_VS 0x2000
|
||||
#define SP_NEW_QUERY 0x4000
|
||||
|
||||
|
||||
struct tgsi_sampler;
|
||||
struct tgsi_exec_machine;
|
||||
|
||||
|
||||
/** Subclass of pipe_shader_state (though it doesn't really need to be).
|
||||
*
|
||||
* This is starting to look an awful lot like a quad pipeline stage...
|
||||
*/
|
||||
struct sp_fragment_shader {
|
||||
struct pipe_shader_state shader;
|
||||
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
void (*prepare)( const struct sp_fragment_shader *shader,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct tgsi_sampler *samplers);
|
||||
|
||||
/* Run the shader - this interface will get cleaned up in the
|
||||
* future:
|
||||
*/
|
||||
unsigned (*run)( const struct sp_fragment_shader *shader,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct quad_header *quad );
|
||||
|
||||
|
||||
void (*delete)( struct sp_fragment_shader * );
|
||||
};
|
||||
|
||||
struct vertex_info;
|
||||
|
||||
/** Subclass of pipe_shader_state */
|
||||
struct sp_vertex_shader {
|
||||
struct pipe_shader_state shader;
|
||||
struct draw_vertex_shader *draw_data;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void *
|
||||
softpipe_create_blend_state(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
void softpipe_bind_blend_state(struct pipe_context *,
|
||||
void *);
|
||||
void softpipe_delete_blend_state(struct pipe_context *,
|
||||
void *);
|
||||
|
||||
void *
|
||||
softpipe_create_sampler_state(struct pipe_context *,
|
||||
const struct pipe_sampler_state *);
|
||||
void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
|
||||
void softpipe_delete_sampler_state(struct pipe_context *, void *);
|
||||
|
||||
void *
|
||||
softpipe_create_depth_stencil_state(struct pipe_context *,
|
||||
const struct pipe_depth_stencil_alpha_state *);
|
||||
void softpipe_bind_depth_stencil_state(struct pipe_context *, void *);
|
||||
void softpipe_delete_depth_stencil_state(struct pipe_context *, void *);
|
||||
|
||||
void *
|
||||
softpipe_create_rasterizer_state(struct pipe_context *,
|
||||
const struct pipe_rasterizer_state *);
|
||||
void softpipe_bind_rasterizer_state(struct pipe_context *, void *);
|
||||
void softpipe_delete_rasterizer_state(struct pipe_context *, void *);
|
||||
|
||||
void softpipe_set_framebuffer_state( struct pipe_context *,
|
||||
const struct pipe_framebuffer_state * );
|
||||
|
||||
void softpipe_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color );
|
||||
|
||||
void softpipe_set_clip_state( struct pipe_context *,
|
||||
const struct pipe_clip_state * );
|
||||
|
||||
void softpipe_set_constant_buffer(struct pipe_context *,
|
||||
uint shader, uint index,
|
||||
const struct pipe_constant_buffer *buf);
|
||||
|
||||
void *softpipe_create_fs_state(struct pipe_context *,
|
||||
const struct pipe_shader_state *);
|
||||
void softpipe_bind_fs_state(struct pipe_context *, void *);
|
||||
void softpipe_delete_fs_state(struct pipe_context *, void *);
|
||||
void *softpipe_create_vs_state(struct pipe_context *,
|
||||
const struct pipe_shader_state *);
|
||||
void softpipe_bind_vs_state(struct pipe_context *, void *);
|
||||
void softpipe_delete_vs_state(struct pipe_context *, void *);
|
||||
|
||||
void softpipe_set_polygon_stipple( struct pipe_context *,
|
||||
const struct pipe_poly_stipple * );
|
||||
|
||||
void softpipe_set_scissor_state( struct pipe_context *,
|
||||
const struct pipe_scissor_state * );
|
||||
|
||||
void softpipe_set_sampler_textures( struct pipe_context *,
|
||||
unsigned num,
|
||||
struct pipe_texture ** );
|
||||
|
||||
void softpipe_set_viewport_state( struct pipe_context *,
|
||||
const struct pipe_viewport_state * );
|
||||
|
||||
void softpipe_set_vertex_element(struct pipe_context *,
|
||||
unsigned index,
|
||||
const struct pipe_vertex_element *);
|
||||
|
||||
void softpipe_set_vertex_buffer(struct pipe_context *,
|
||||
unsigned index,
|
||||
const struct pipe_vertex_buffer *);
|
||||
|
||||
|
||||
void softpipe_update_derived( struct softpipe_context *softpipe );
|
||||
|
||||
|
||||
boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
|
||||
unsigned start, unsigned count);
|
||||
|
||||
boolean softpipe_draw_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned mode, unsigned start, unsigned count);
|
||||
|
||||
|
||||
void
|
||||
softpipe_map_surfaces(struct softpipe_context *sp);
|
||||
|
||||
void
|
||||
softpipe_unmap_surfaces(struct softpipe_context *sp);
|
||||
|
||||
void
|
||||
softpipe_map_texture_surfaces(struct softpipe_context *sp);
|
||||
|
||||
void
|
||||
softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
|
||||
|
||||
|
||||
struct vertex_info *
|
||||
softpipe_get_vertex_info(struct softpipe_context *softpipe);
|
||||
|
||||
struct vertex_info *
|
||||
softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -71,11 +71,25 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
|
||||
* simply emit the whole post-xform vertex as-is:
|
||||
*/
|
||||
struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
|
||||
#if 0
|
||||
vinfo_vbuf->num_attribs = 0;
|
||||
/* special-case to allow memcpy of whole vertex */
|
||||
draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
|
||||
/* size in dwords or floats */
|
||||
vinfo_vbuf->size = 4 * draw_num_vs_outputs(softpipe->draw)
|
||||
+ sizeof(struct vertex_header) / 4;
|
||||
#else
|
||||
/* for pass-through mode, we need a more explicit list of attribs */
|
||||
const uint num = draw_num_vs_outputs(softpipe->draw);
|
||||
uint i;
|
||||
|
||||
vinfo_vbuf->num_attribs = 0;
|
||||
draw_emit_vertex_attr(vinfo_vbuf, EMIT_HEADER, INTERP_NONE, 0);
|
||||
for (i = 0; i < num; i++) {
|
||||
draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
|
||||
}
|
||||
draw_compute_vertex_size(vinfo_vbuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,202 +1,202 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
* Michel Dänzer <michel@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
||||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_texture.h"
|
||||
#include "sp_tile_cache.h"
|
||||
|
||||
|
||||
/* Simple, maximally packed layout.
|
||||
*/
|
||||
|
||||
static unsigned minify( unsigned d )
|
||||
{
|
||||
return MAX2(1, d>>1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_texture_layout(struct softpipe_texture * spt)
|
||||
{
|
||||
struct pipe_texture *pt = &spt->base;
|
||||
unsigned level;
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned depth = pt->depth[0];
|
||||
|
||||
spt->buffer_size = 0;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
pt->width[level] = width;
|
||||
pt->height[level] = height;
|
||||
pt->depth[level] = depth;
|
||||
|
||||
spt->level_offset[level] = spt->buffer_size;
|
||||
|
||||
spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
|
||||
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
|
||||
width * pt->cpp;
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_texture *
|
||||
softpipe_texture_create_screen(struct pipe_screen *screen,
|
||||
const struct pipe_texture *templat)
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
|
||||
if (!spt)
|
||||
return NULL;
|
||||
|
||||
spt->base = *templat;
|
||||
spt->base.refcount = 1;
|
||||
spt->base.screen = screen;
|
||||
|
||||
softpipe_texture_layout(spt);
|
||||
|
||||
spt->buffer = ws->buffer_create(ws, 32,
|
||||
PIPE_BUFFER_USAGE_PIXEL,
|
||||
spt->buffer_size);
|
||||
if (!spt->buffer) {
|
||||
FREE(spt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(spt->base.refcount == 1);
|
||||
|
||||
return &spt->base;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_texture_release_screen(struct pipe_screen *screen,
|
||||
struct pipe_texture **pt)
|
||||
{
|
||||
if (!*pt)
|
||||
return;
|
||||
|
||||
/*
|
||||
DBG("%s %p refcount will be %d\n",
|
||||
__FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
|
||||
*/
|
||||
if (--(*pt)->refcount <= 0) {
|
||||
struct softpipe_texture *spt = softpipe_texture(*pt);
|
||||
|
||||
/*
|
||||
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
|
||||
*/
|
||||
|
||||
pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
|
||||
|
||||
FREE(spt);
|
||||
}
|
||||
*pt = NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_surface *
|
||||
softpipe_get_tex_surface_screen(struct pipe_screen *screen,
|
||||
struct pipe_texture *pt,
|
||||
unsigned face, unsigned level, unsigned zslice)
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct softpipe_texture *spt = softpipe_texture(pt);
|
||||
struct pipe_surface *ps;
|
||||
|
||||
assert(level <= pt->last_level);
|
||||
|
||||
ps = ws->surface_alloc(ws);
|
||||
if (ps) {
|
||||
assert(ps->refcount);
|
||||
assert(ps->winsys);
|
||||
pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
|
||||
ps->format = pt->format;
|
||||
ps->cpp = pt->cpp;
|
||||
ps->width = pt->width[level];
|
||||
ps->height = pt->height[level];
|
||||
ps->pitch = ps->width;
|
||||
ps->offset = spt->level_offset[level];
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
|
||||
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
|
||||
(pt->compressed ? ps->height/4 : ps->height) *
|
||||
ps->width * ps->cpp;
|
||||
}
|
||||
else {
|
||||
assert(face == 0);
|
||||
assert(zslice == 0);
|
||||
}
|
||||
}
|
||||
return ps;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_texture_update(struct pipe_context *pipe,
|
||||
struct pipe_texture *texture)
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
uint unit;
|
||||
for (unit = 0; unit < softpipe->num_textures; unit++) {
|
||||
if (softpipe->texture[unit] == texture) {
|
||||
sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
softpipe_init_texture_funcs( struct softpipe_context *softpipe )
|
||||
{
|
||||
softpipe->pipe.texture_update = softpipe_texture_update;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
|
||||
{
|
||||
screen->texture_create = softpipe_texture_create_screen;
|
||||
screen->texture_release = softpipe_texture_release_screen;
|
||||
screen->get_tex_surface = softpipe_get_tex_surface_screen;
|
||||
}
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
* Michel Dänzer <michel@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
||||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_texture.h"
|
||||
#include "sp_tile_cache.h"
|
||||
|
||||
|
||||
/* Simple, maximally packed layout.
|
||||
*/
|
||||
|
||||
static unsigned minify( unsigned d )
|
||||
{
|
||||
return MAX2(1, d>>1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_texture_layout(struct softpipe_texture * spt)
|
||||
{
|
||||
struct pipe_texture *pt = &spt->base;
|
||||
unsigned level;
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned depth = pt->depth[0];
|
||||
|
||||
spt->buffer_size = 0;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
pt->width[level] = width;
|
||||
pt->height[level] = height;
|
||||
pt->depth[level] = depth;
|
||||
|
||||
spt->level_offset[level] = spt->buffer_size;
|
||||
|
||||
spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
|
||||
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
|
||||
width * pt->cpp;
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_texture *
|
||||
softpipe_texture_create_screen(struct pipe_screen *screen,
|
||||
const struct pipe_texture *templat)
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
|
||||
if (!spt)
|
||||
return NULL;
|
||||
|
||||
spt->base = *templat;
|
||||
spt->base.refcount = 1;
|
||||
spt->base.screen = screen;
|
||||
|
||||
softpipe_texture_layout(spt);
|
||||
|
||||
spt->buffer = ws->buffer_create(ws, 32,
|
||||
PIPE_BUFFER_USAGE_PIXEL,
|
||||
spt->buffer_size);
|
||||
if (!spt->buffer) {
|
||||
FREE(spt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(spt->base.refcount == 1);
|
||||
|
||||
return &spt->base;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_texture_release_screen(struct pipe_screen *screen,
|
||||
struct pipe_texture **pt)
|
||||
{
|
||||
if (!*pt)
|
||||
return;
|
||||
|
||||
/*
|
||||
DBG("%s %p refcount will be %d\n",
|
||||
__FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
|
||||
*/
|
||||
if (--(*pt)->refcount <= 0) {
|
||||
struct softpipe_texture *spt = softpipe_texture(*pt);
|
||||
|
||||
/*
|
||||
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
|
||||
*/
|
||||
|
||||
pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
|
||||
|
||||
FREE(spt);
|
||||
}
|
||||
*pt = NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_surface *
|
||||
softpipe_get_tex_surface_screen(struct pipe_screen *screen,
|
||||
struct pipe_texture *pt,
|
||||
unsigned face, unsigned level, unsigned zslice)
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct softpipe_texture *spt = softpipe_texture(pt);
|
||||
struct pipe_surface *ps;
|
||||
|
||||
assert(level <= pt->last_level);
|
||||
|
||||
ps = ws->surface_alloc(ws);
|
||||
if (ps) {
|
||||
assert(ps->refcount);
|
||||
assert(ps->winsys);
|
||||
pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
|
||||
ps->format = pt->format;
|
||||
ps->cpp = pt->cpp;
|
||||
ps->width = pt->width[level];
|
||||
ps->height = pt->height[level];
|
||||
ps->pitch = ps->width;
|
||||
ps->offset = spt->level_offset[level];
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
|
||||
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
|
||||
(pt->compressed ? ps->height/4 : ps->height) *
|
||||
ps->width * ps->cpp;
|
||||
}
|
||||
else {
|
||||
assert(face == 0);
|
||||
assert(zslice == 0);
|
||||
}
|
||||
}
|
||||
return ps;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_texture_update(struct pipe_context *pipe,
|
||||
struct pipe_texture *texture)
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
uint unit;
|
||||
for (unit = 0; unit < softpipe->num_textures; unit++) {
|
||||
if (softpipe->texture[unit] == texture) {
|
||||
sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
softpipe_init_texture_funcs( struct softpipe_context *softpipe )
|
||||
{
|
||||
softpipe->pipe.texture_update = softpipe_texture_update;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
|
||||
{
|
||||
screen->texture_create = softpipe_texture_create_screen;
|
||||
screen->texture_release = softpipe_texture_release_screen;
|
||||
screen->get_tex_surface = softpipe_get_tex_surface_screen;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,8 @@ uint32_t debug_mask_get(uint32_t uuid);
|
||||
* @code
|
||||
* #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier
|
||||
*
|
||||
* static inline mydriver_debug(uint32_t what, const char *format, ...)
|
||||
* static void inline
|
||||
* mydriver_debug(uint32_t what, const char *format, ...)
|
||||
* {
|
||||
* #ifdef DEBUG
|
||||
* va_list ap;
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Gallium error codes.
|
||||
*
|
||||
* @author José Fonseca <jrfonseca@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef P_ERROR_H_
|
||||
#define P_ERROR_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Gallium error codes.
|
||||
*
|
||||
* - A zero value always means success.
|
||||
* - A negative value always means failure.
|
||||
* - The meaning of a positive value is function dependent.
|
||||
*/
|
||||
enum pipe_error {
|
||||
PIPE_OK = 0,
|
||||
PIPE_ERROR = -1, /**< Generic error */
|
||||
PIPE_ERROR_BAD_INPUT = -2,
|
||||
PIPE_ERROR_OUT_OF_MEMORY = -3,
|
||||
PIPE_ERROR_RETRY = -4
|
||||
/* TODO */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* P_ERROR_H_ */
|
||||
@@ -227,22 +227,22 @@ struct tgsi_immediate_float32
|
||||
#define TGSI_OPCODE_STR 51
|
||||
#define TGSI_OPCODE_TEX 52
|
||||
#define TGSI_OPCODE_TXD 53
|
||||
#define TGSI_OPCODE_TXP 134
|
||||
#define TGSI_OPCODE_UP2H 54
|
||||
#define TGSI_OPCODE_UP2US 55
|
||||
#define TGSI_OPCODE_UP4B 56
|
||||
#define TGSI_OPCODE_UP4UB 57
|
||||
#define TGSI_OPCODE_X2D 58
|
||||
#define TGSI_OPCODE_TXP 54
|
||||
#define TGSI_OPCODE_UP2H 55
|
||||
#define TGSI_OPCODE_UP2US 56
|
||||
#define TGSI_OPCODE_UP4B 57
|
||||
#define TGSI_OPCODE_UP4UB 58
|
||||
#define TGSI_OPCODE_X2D 59
|
||||
|
||||
/*
|
||||
* GL_NV_vertex_program2
|
||||
*/
|
||||
#define TGSI_OPCODE_ARA 59
|
||||
#define TGSI_OPCODE_ARR 60
|
||||
#define TGSI_OPCODE_BRA 61
|
||||
#define TGSI_OPCODE_CAL 62
|
||||
#define TGSI_OPCODE_RET 63
|
||||
#define TGSI_OPCODE_SSG 64
|
||||
#define TGSI_OPCODE_ARA 60
|
||||
#define TGSI_OPCODE_ARR 61
|
||||
#define TGSI_OPCODE_BRA 62
|
||||
#define TGSI_OPCODE_CAL 63
|
||||
#define TGSI_OPCODE_RET 64
|
||||
#define TGSI_OPCODE_SSG 65
|
||||
|
||||
/*
|
||||
* GL_ARB_vertex_program
|
||||
@@ -253,9 +253,9 @@ struct tgsi_immediate_float32
|
||||
/*
|
||||
* GL_ARB_fragment_program
|
||||
*/
|
||||
#define TGSI_OPCODE_CMP 65
|
||||
#define TGSI_OPCODE_SCS 66
|
||||
#define TGSI_OPCODE_TXB 67
|
||||
#define TGSI_OPCODE_CMP 66
|
||||
#define TGSI_OPCODE_SCS 67
|
||||
#define TGSI_OPCODE_TXB 68
|
||||
|
||||
/*
|
||||
* GL_NV_fragment_program_option
|
||||
@@ -265,19 +265,19 @@ struct tgsi_immediate_float32
|
||||
/*
|
||||
* GL_NV_fragment_program2
|
||||
*/
|
||||
#define TGSI_OPCODE_NRM 68
|
||||
#define TGSI_OPCODE_DIV 69
|
||||
#define TGSI_OPCODE_DP2 70
|
||||
#define TGSI_OPCODE_NRM 69
|
||||
#define TGSI_OPCODE_DIV 70
|
||||
#define TGSI_OPCODE_DP2 71
|
||||
#define TGSI_OPCODE_DP2A TGSI_OPCODE_DOT2ADD
|
||||
#define TGSI_OPCODE_TXL 71
|
||||
#define TGSI_OPCODE_BRK 72
|
||||
#define TGSI_OPCODE_IF 73
|
||||
#define TGSI_OPCODE_LOOP 74
|
||||
#define TGSI_OPCODE_REP 75
|
||||
#define TGSI_OPCODE_ELSE 76
|
||||
#define TGSI_OPCODE_ENDIF 77
|
||||
#define TGSI_OPCODE_ENDLOOP 78
|
||||
#define TGSI_OPCODE_ENDREP 79
|
||||
#define TGSI_OPCODE_TXL 72
|
||||
#define TGSI_OPCODE_BRK 73
|
||||
#define TGSI_OPCODE_IF 74
|
||||
#define TGSI_OPCODE_LOOP 75
|
||||
#define TGSI_OPCODE_REP 76
|
||||
#define TGSI_OPCODE_ELSE 77
|
||||
#define TGSI_OPCODE_ENDIF 78
|
||||
#define TGSI_OPCODE_ENDLOOP 79
|
||||
#define TGSI_OPCODE_ENDREP 80
|
||||
|
||||
/*
|
||||
* GL_NV_vertex_program2_option
|
||||
@@ -286,26 +286,26 @@ struct tgsi_immediate_float32
|
||||
/*
|
||||
* GL_NV_vertex_program3
|
||||
*/
|
||||
#define TGSI_OPCODE_PUSHA 80
|
||||
#define TGSI_OPCODE_POPA 81
|
||||
#define TGSI_OPCODE_PUSHA 81
|
||||
#define TGSI_OPCODE_POPA 82
|
||||
|
||||
/*
|
||||
* GL_NV_gpu_program4
|
||||
*/
|
||||
#define TGSI_OPCODE_CEIL 82
|
||||
#define TGSI_OPCODE_I2F 83
|
||||
#define TGSI_OPCODE_NOT 84
|
||||
#define TGSI_OPCODE_TRUNC 85
|
||||
#define TGSI_OPCODE_SHL 86
|
||||
#define TGSI_OPCODE_SHR 87
|
||||
#define TGSI_OPCODE_AND 88
|
||||
#define TGSI_OPCODE_OR 89
|
||||
#define TGSI_OPCODE_MOD 90
|
||||
#define TGSI_OPCODE_XOR 91
|
||||
#define TGSI_OPCODE_SAD 92
|
||||
#define TGSI_OPCODE_TXF 93
|
||||
#define TGSI_OPCODE_TXQ 94
|
||||
#define TGSI_OPCODE_CONT 95
|
||||
#define TGSI_OPCODE_CEIL 83
|
||||
#define TGSI_OPCODE_I2F 84
|
||||
#define TGSI_OPCODE_NOT 85
|
||||
#define TGSI_OPCODE_TRUNC 86
|
||||
#define TGSI_OPCODE_SHL 87
|
||||
#define TGSI_OPCODE_SHR 88
|
||||
#define TGSI_OPCODE_AND 89
|
||||
#define TGSI_OPCODE_OR 90
|
||||
#define TGSI_OPCODE_MOD 91
|
||||
#define TGSI_OPCODE_XOR 92
|
||||
#define TGSI_OPCODE_SAD 93
|
||||
#define TGSI_OPCODE_TXF 94
|
||||
#define TGSI_OPCODE_TXQ 95
|
||||
#define TGSI_OPCODE_CONT 96
|
||||
|
||||
/*
|
||||
* GL_NV_vertex_program4
|
||||
@@ -321,72 +321,53 @@ struct tgsi_immediate_float32
|
||||
* GL_NV_geometry_program4
|
||||
*/
|
||||
/* Same as GL_NV_gpu_program4 */
|
||||
#define TGSI_OPCODE_EMIT 96
|
||||
#define TGSI_OPCODE_ENDPRIM 97
|
||||
#define TGSI_OPCODE_EMIT 97
|
||||
#define TGSI_OPCODE_ENDPRIM 98
|
||||
|
||||
/*
|
||||
* GLSL
|
||||
*/
|
||||
#define TGSI_OPCODE_BGNLOOP2 98
|
||||
#define TGSI_OPCODE_BGNSUB 99
|
||||
#define TGSI_OPCODE_ENDLOOP2 100
|
||||
#define TGSI_OPCODE_ENDSUB 101
|
||||
#define TGSI_OPCODE_BGNLOOP2 99
|
||||
#define TGSI_OPCODE_BGNSUB 100
|
||||
#define TGSI_OPCODE_ENDLOOP2 101
|
||||
#define TGSI_OPCODE_ENDSUB 102
|
||||
#define TGSI_OPCODE_INT TGSI_OPCODE_TRUNC
|
||||
#define TGSI_OPCODE_NOISE1 102
|
||||
#define TGSI_OPCODE_NOISE2 103
|
||||
#define TGSI_OPCODE_NOISE3 104
|
||||
#define TGSI_OPCODE_NOISE4 105
|
||||
#define TGSI_OPCODE_NOP 106
|
||||
#define TGSI_OPCODE_NOISE1 103
|
||||
#define TGSI_OPCODE_NOISE2 104
|
||||
#define TGSI_OPCODE_NOISE3 105
|
||||
#define TGSI_OPCODE_NOISE4 106
|
||||
#define TGSI_OPCODE_NOP 107
|
||||
|
||||
/*
|
||||
* ps_1_1
|
||||
*/
|
||||
#define TGSI_OPCODE_TEXCOORD TGSI_OPCODE_NOP
|
||||
#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KILP
|
||||
#define TGSI_OPCODE_TEXBEM 107
|
||||
#define TGSI_OPCODE_TEXBEML 108
|
||||
#define TGSI_OPCODE_TEXREG2AR 109
|
||||
#define TGSI_OPCODE_TEXM3X2PAD 110
|
||||
#define TGSI_OPCODE_TEXM3X2TEX 111
|
||||
#define TGSI_OPCODE_TEXM3X3PAD 112
|
||||
#define TGSI_OPCODE_TEXM3X3TEX 113
|
||||
#define TGSI_OPCODE_TEXM3X3SPEC 114
|
||||
#define TGSI_OPCODE_TEXM3X3VSPEC 115
|
||||
|
||||
/*
|
||||
* ps_1_2
|
||||
*/
|
||||
#define TGSI_OPCODE_TEXREG2GB 116
|
||||
#define TGSI_OPCODE_TEXREG2RGB 117
|
||||
#define TGSI_OPCODE_TEXDP3TEX 118
|
||||
#define TGSI_OPCODE_TEXDP3 119
|
||||
#define TGSI_OPCODE_TEXM3X3 120
|
||||
/* CMP - use TGSI_OPCODE_CND0 */
|
||||
|
||||
/*
|
||||
* ps_1_3
|
||||
*/
|
||||
#define TGSI_OPCODE_TEXM3X2DEPTH 121
|
||||
/* CMP - use TGSI_OPCODE_CND0 */
|
||||
|
||||
/*
|
||||
* ps_1_4
|
||||
*/
|
||||
#define TGSI_OPCODE_TEXCRD TGSI_OPCODE_TEXCOORD
|
||||
#define TGSI_OPCODE_TEXLD TGSI_OPCODE_TEX
|
||||
#define TGSI_OPCODE_TEXDEPTH 122
|
||||
#define TGSI_OPCODE_BEM 123
|
||||
|
||||
/*
|
||||
* ps_2_0
|
||||
*/
|
||||
#define TGSI_OPCODE_M4X4 TGSI_OPCODE_MULTIPLYMATRIX
|
||||
#define TGSI_OPCODE_M4X3 124
|
||||
#define TGSI_OPCODE_M3X4 125
|
||||
#define TGSI_OPCODE_M3X3 126
|
||||
#define TGSI_OPCODE_M3X2 127
|
||||
#define TGSI_OPCODE_M4X3 108
|
||||
#define TGSI_OPCODE_M3X4 109
|
||||
#define TGSI_OPCODE_M3X3 110
|
||||
#define TGSI_OPCODE_M3X2 111
|
||||
#define TGSI_OPCODE_CRS TGSI_OPCODE_XPD
|
||||
#define TGSI_OPCODE_NRM4 128
|
||||
#define TGSI_OPCODE_NRM4 112
|
||||
#define TGSI_OPCODE_SINCOS TGSI_OPCODE_SCS
|
||||
#define TGSI_OPCODE_TEXLDB TGSI_OPCODE_TXB
|
||||
#define TGSI_OPCODE_DP2ADD TGSI_OPCODE_DP2A
|
||||
@@ -395,10 +376,10 @@ struct tgsi_immediate_float32
|
||||
* ps_2_x
|
||||
*/
|
||||
#define TGSI_OPCODE_CALL TGSI_OPCODE_CAL
|
||||
#define TGSI_OPCODE_CALLNZ 129
|
||||
#define TGSI_OPCODE_IFC 130
|
||||
#define TGSI_OPCODE_CALLNZ 113
|
||||
#define TGSI_OPCODE_IFC 114
|
||||
#define TGSI_OPCODE_BREAK TGSI_OPCODE_BRK
|
||||
#define TGSI_OPCODE_BREAKC 131
|
||||
#define TGSI_OPCODE_BREAKC 115
|
||||
#define TGSI_OPCODE_DSX TGSI_OPCODE_DDX
|
||||
#define TGSI_OPCODE_DSY TGSI_OPCODE_DDY
|
||||
#define TGSI_OPCODE_TEXLDD TGSI_OPCODE_TXD
|
||||
@@ -419,10 +400,10 @@ struct tgsi_immediate_float32
|
||||
* vs_2_x
|
||||
*/
|
||||
|
||||
#define TGSI_OPCODE_KIL 132 /* unpredicated kill */
|
||||
#define TGSI_OPCODE_END 133 /* aka HALT */
|
||||
#define TGSI_OPCODE_KIL 116 /* unpredicated kill */
|
||||
#define TGSI_OPCODE_END 117 /* aka HALT */
|
||||
|
||||
#define TGSI_OPCODE_LAST 135
|
||||
#define TGSI_OPCODE_LAST 118
|
||||
|
||||
#define TGSI_SAT_NONE 0 /* do not saturate */
|
||||
#define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */
|
||||
|
||||
@@ -110,6 +110,7 @@ struct pipe_rasterizer_state
|
||||
unsigned line_stipple_pattern:16;
|
||||
unsigned line_last_pixel:1;
|
||||
unsigned bypass_clipping:1;
|
||||
unsigned bypass_vs:1; /**< vertices are already fully transformed */
|
||||
unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */
|
||||
|
||||
float line_width;
|
||||
@@ -162,13 +163,6 @@ struct pipe_constant_buffer
|
||||
struct pipe_shader_state
|
||||
{
|
||||
const struct tgsi_token *tokens;
|
||||
/* XXX these are going away */
|
||||
ubyte num_inputs;
|
||||
ubyte num_outputs;
|
||||
ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */
|
||||
ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
|
||||
ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */
|
||||
ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -18,3 +18,7 @@ subdirs:
|
||||
|
||||
clean:
|
||||
rm -f `find . -name \*.[oa]`
|
||||
|
||||
|
||||
# Dummy install target
|
||||
install:
|
||||
|
||||
@@ -1398,12 +1398,13 @@ static void build_pointsize( struct tnl_program *p )
|
||||
/* 1 / sqrt(factor) */
|
||||
emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut );
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
/* out = pointSize / sqrt(factor) */
|
||||
emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size);
|
||||
#else
|
||||
/* not sure, might make sense to do clamping here,
|
||||
but it's not done in t_vb_points neither */
|
||||
/* this is a good place to clamp the point size since there's likely
|
||||
* no hardware registers to clamp point size at rasterization time.
|
||||
*/
|
||||
emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size);
|
||||
emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y));
|
||||
emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z));
|
||||
|
||||
@@ -1087,7 +1087,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
|
||||
slang_operation_copy(inlined, fun->body);
|
||||
|
||||
/*** XXX review this */
|
||||
assert(inlined->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE);
|
||||
assert(inlined->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE);
|
||||
inlined->type = SLANG_OPER_BLOCK_NEW_SCOPE;
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -677,6 +677,7 @@ static struct prog_instruction *
|
||||
emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
{
|
||||
struct prog_instruction *inst;
|
||||
slang_ir_node tmpNode;
|
||||
|
||||
assert(n->Opcode == IR_CLAMP);
|
||||
/* ch[0] = value
|
||||
@@ -722,18 +723,27 @@ emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
emit(emitInfo, n->Children[1]);
|
||||
emit(emitInfo, n->Children[2]);
|
||||
|
||||
/* Some GPUs don't allow reading from output registers. So if the
|
||||
* dest for this clamp() is an output reg, we can't use that reg for
|
||||
* the intermediate result. Use a temp register instead.
|
||||
*/
|
||||
_mesa_bzero(&tmpNode, sizeof(tmpNode));
|
||||
alloc_temp_storage(emitInfo, &tmpNode, n->Store->Size);
|
||||
|
||||
/* tmp = max(ch[0], ch[1]) */
|
||||
inst = new_instruction(emitInfo, OPCODE_MAX);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
storage_to_dst_reg(&inst->DstReg, tmpNode.Store, n->Writemask);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store);
|
||||
storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store);
|
||||
|
||||
/* tmp = min(tmp, ch[2]) */
|
||||
/* n->dest = min(tmp, ch[2]) */
|
||||
inst = new_instruction(emitInfo, OPCODE_MIN);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Store);
|
||||
storage_to_src_reg(&inst->SrcReg[0], tmpNode.Store);
|
||||
storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store);
|
||||
|
||||
free_temp_storage(emitInfo->vt, &tmpNode);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
@@ -223,7 +223,12 @@ static void update_raster_state( struct st_context *st )
|
||||
raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
if (!raster->point_size_per_vertex) {
|
||||
/* clamp size now */
|
||||
raster->point_size = CLAMP(ctx->Point.Size,
|
||||
ctx->Point.MinSize,
|
||||
ctx->Point.MaxSize);
|
||||
}
|
||||
|
||||
/* _NEW_LINE
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,8 @@
|
||||
#include "cso_cache/cso_context.h"
|
||||
|
||||
|
||||
|
||||
/* XXX for testing draw module vertex passthrough: */
|
||||
#define TEST_DRAW_PASSTHROUGH 0
|
||||
|
||||
|
||||
static GLuint
|
||||
@@ -229,6 +230,12 @@ draw_quad(GLcontext *ctx,
|
||||
GLfloat verts[4][2][4]; /* four verts, two attribs, XYZW */
|
||||
GLuint i;
|
||||
|
||||
#if TEST_DRAW_PASSTHROUGH
|
||||
/* invert Y coords (may be off by one pixel) */
|
||||
y0 = ctx->DrawBuffer->Height - y0;
|
||||
y1 = ctx->DrawBuffer->Height - y1;
|
||||
#endif
|
||||
|
||||
/* positions */
|
||||
verts[0][0][0] = x0;
|
||||
verts[0][0][1] = y0;
|
||||
@@ -252,7 +259,13 @@ draw_quad(GLcontext *ctx,
|
||||
verts[i][1][3] = color[3];
|
||||
}
|
||||
|
||||
st_draw_vertices(ctx, PIPE_PRIM_QUADS, 4, (float *) verts, 2, GL_FALSE);
|
||||
st_draw_vertices(ctx, PIPE_PRIM_POLYGON, 4, (float *) verts, 2,
|
||||
#if TEST_DRAW_PASSTHROUGH
|
||||
GL_TRUE
|
||||
#else
|
||||
GL_FALSE
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -335,6 +348,10 @@ clear_with_quad(GLcontext *ctx,
|
||||
*/
|
||||
if (ctx->Scissor.Enabled)
|
||||
raster.scissor = 1;
|
||||
#endif
|
||||
#if TEST_DRAW_PASSTHROUGH
|
||||
raster.bypass_clipping = 1;
|
||||
raster.bypass_vs = 1;
|
||||
#endif
|
||||
cso_set_rasterizer(st->cso_context, &raster);
|
||||
}
|
||||
@@ -348,6 +365,7 @@ clear_with_quad(GLcontext *ctx,
|
||||
pipe->bind_fs_state(pipe, stfp->driver_shader);
|
||||
}
|
||||
|
||||
#if !TEST_DRAW_PASSTHROUGH
|
||||
/* vertex shader state: color/position pass-through */
|
||||
{
|
||||
static struct st_vertex_program *stvp = NULL;
|
||||
@@ -356,7 +374,9 @@ clear_with_quad(GLcontext *ctx,
|
||||
}
|
||||
pipe->bind_vs_state(pipe, stvp->driver_shader);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !TEST_DRAW_PASSTHROUGH
|
||||
/* viewport state: viewport matching window dims */
|
||||
{
|
||||
const float width = ctx->DrawBuffer->Width;
|
||||
@@ -372,6 +392,7 @@ clear_with_quad(GLcontext *ctx,
|
||||
vp.translate[3] = 0.0;
|
||||
pipe->set_viewport_state(pipe, &vp);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* draw quad matching scissor rect (XXX verify coord round-off) */
|
||||
draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor);
|
||||
|
||||
@@ -178,6 +178,11 @@ static void st_program_string_notify( GLcontext *ctx,
|
||||
|
||||
stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
|
||||
|
||||
if (stfp->state.tokens) {
|
||||
FREE((void *) stfp->state.tokens);
|
||||
stfp->state.tokens = NULL;
|
||||
}
|
||||
|
||||
if (st->fp == stfp)
|
||||
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
|
||||
}
|
||||
@@ -201,6 +206,11 @@ static void st_program_string_notify( GLcontext *ctx,
|
||||
|
||||
stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
|
||||
|
||||
if (stvp->state.tokens) {
|
||||
FREE((void *) stvp->state.tokens);
|
||||
stvp->state.tokens = NULL;
|
||||
}
|
||||
|
||||
if (st->vp == stvp)
|
||||
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
|
||||
}
|
||||
|
||||
@@ -52,10 +52,12 @@ st_print_current(void)
|
||||
struct st_context *st = ctx->st;
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
printf("Vertex Transform Inputs:\n");
|
||||
for (i = 0; i < st->vp->state.num_inputs; i++) {
|
||||
printf(" Slot %d: VERT_ATTRIB_%d\n", i, st->vp->index_to_input[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
tgsi_dump( st->vp->state.tokens, 0 );
|
||||
if (st->vp->Base.Base.Parameters)
|
||||
|
||||
@@ -223,7 +223,7 @@ st_draw_vbo(GLcontext *ctx,
|
||||
/* loop over TGSI shader inputs to determine vertex buffer
|
||||
* and attribute info
|
||||
*/
|
||||
for (attr = 0; attr < vs->num_inputs; attr++) {
|
||||
for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) {
|
||||
const GLuint mesaAttr = vp->index_to_input[attr];
|
||||
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
|
||||
struct pipe_vertex_element velement;
|
||||
@@ -333,7 +333,7 @@ st_draw_vbo(GLcontext *ctx,
|
||||
}
|
||||
|
||||
/* unreference buffers (frees wrapped user-space buffer objects) */
|
||||
for (attr = 0; attr < vs->num_inputs; attr++) {
|
||||
for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) {
|
||||
pipe_buffer_reference(winsys, &vbuffer[attr].buffer, NULL);
|
||||
assert(!vbuffer[attr].buffer);
|
||||
pipe->set_vertex_buffer(pipe, attr, &vbuffer[attr]);
|
||||
@@ -502,7 +502,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
|
||||
/* loop over TGSI shader inputs to determine vertex buffer
|
||||
* and attribute info
|
||||
*/
|
||||
for (attr = 0; attr < vs->num_inputs; attr++) {
|
||||
for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) {
|
||||
const GLuint mesaAttr = vp->index_to_input[attr];
|
||||
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
|
||||
struct pipe_vertex_element velement;
|
||||
|
||||
@@ -85,6 +85,14 @@ st_translate_vertex_program(struct st_context *st,
|
||||
GLuint num_generic = 0;
|
||||
GLuint num_tokens;
|
||||
|
||||
ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
|
||||
ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
|
||||
uint vs_num_inputs = 0;
|
||||
|
||||
ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
|
||||
ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
|
||||
uint vs_num_outputs = 0;
|
||||
|
||||
memset(&vs, 0, sizeof(vs));
|
||||
|
||||
/*
|
||||
@@ -93,36 +101,36 @@ st_translate_vertex_program(struct st_context *st,
|
||||
*/
|
||||
for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
|
||||
if (stvp->Base.Base.InputsRead & (1 << attr)) {
|
||||
const GLuint slot = vs.num_inputs;
|
||||
const GLuint slot = vs_num_inputs;
|
||||
|
||||
vs.num_inputs++;
|
||||
vs_num_inputs++;
|
||||
|
||||
stvp->input_to_index[attr] = slot;
|
||||
stvp->index_to_input[slot] = attr;
|
||||
|
||||
switch (attr) {
|
||||
case VERT_ATTRIB_POS:
|
||||
vs.input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
||||
vs.input_semantic_index[slot] = 0;
|
||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
||||
vs_input_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_ATTRIB_WEIGHT:
|
||||
/* fall-through */
|
||||
case VERT_ATTRIB_NORMAL:
|
||||
/* just label as a generic */
|
||||
vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs.input_semantic_index[slot] = 0;
|
||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs_input_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_ATTRIB_COLOR0:
|
||||
vs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
vs.input_semantic_index[slot] = 0;
|
||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
vs_input_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_ATTRIB_COLOR1:
|
||||
vs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
vs.input_semantic_index[slot] = 1;
|
||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
vs_input_semantic_index[slot] = 1;
|
||||
break;
|
||||
case VERT_ATTRIB_FOG:
|
||||
vs.input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||
vs.input_semantic_index[slot] = 0;
|
||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||
vs_input_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_ATTRIB_TEX0:
|
||||
case VERT_ATTRIB_TEX1:
|
||||
@@ -132,8 +140,8 @@ st_translate_vertex_program(struct st_context *st,
|
||||
case VERT_ATTRIB_TEX5:
|
||||
case VERT_ATTRIB_TEX6:
|
||||
case VERT_ATTRIB_TEX7:
|
||||
vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs.input_semantic_index[slot] = num_generic++;
|
||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs_input_semantic_index[slot] = num_generic++;
|
||||
break;
|
||||
case VERT_ATTRIB_GENERIC0:
|
||||
case VERT_ATTRIB_GENERIC1:
|
||||
@@ -144,8 +152,8 @@ st_translate_vertex_program(struct st_context *st,
|
||||
case VERT_ATTRIB_GENERIC6:
|
||||
case VERT_ATTRIB_GENERIC7:
|
||||
assert(attr < VERT_ATTRIB_MAX);
|
||||
vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs.input_semantic_index[slot] = num_generic++;
|
||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs_input_semantic_index[slot] = num_generic++;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@@ -155,8 +163,8 @@ st_translate_vertex_program(struct st_context *st,
|
||||
|
||||
/* initialize output semantics to defaults */
|
||||
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
|
||||
vs.output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
|
||||
vs.output_semantic_index[i] = 0;
|
||||
vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
|
||||
vs_output_semantic_index[i] = 0;
|
||||
}
|
||||
|
||||
num_generic = 0;
|
||||
@@ -173,8 +181,8 @@ st_translate_vertex_program(struct st_context *st,
|
||||
assert(slot != ~0);
|
||||
}
|
||||
else {
|
||||
slot = vs.num_outputs;
|
||||
vs.num_outputs++;
|
||||
slot = vs_num_outputs;
|
||||
vs_num_outputs++;
|
||||
defaultOutputMapping[attr] = slot;
|
||||
}
|
||||
|
||||
@@ -185,32 +193,32 @@ st_translate_vertex_program(struct st_context *st,
|
||||
switch (attr) {
|
||||
case VERT_RESULT_HPOS:
|
||||
assert(slot == 0);
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
||||
vs.output_semantic_index[slot] = 0;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
||||
vs_output_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_RESULT_COL0:
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
vs.output_semantic_index[slot] = 0;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
vs_output_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_RESULT_COL1:
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
vs.output_semantic_index[slot] = 1;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
vs_output_semantic_index[slot] = 1;
|
||||
break;
|
||||
case VERT_RESULT_BFC0:
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
|
||||
vs.output_semantic_index[slot] = 0;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
|
||||
vs_output_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_RESULT_BFC1:
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
|
||||
vs.output_semantic_index[slot] = 1;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
|
||||
vs_output_semantic_index[slot] = 1;
|
||||
break;
|
||||
case VERT_RESULT_FOGC:
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||
vs.output_semantic_index[slot] = 0;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||
vs_output_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_RESULT_PSIZ:
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
|
||||
vs.output_semantic_index[slot] = 0;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
|
||||
vs_output_semantic_index[slot] = 0;
|
||||
break;
|
||||
case VERT_RESULT_EDGE:
|
||||
assert(0);
|
||||
@@ -223,30 +231,30 @@ st_translate_vertex_program(struct st_context *st,
|
||||
case VERT_RESULT_TEX5:
|
||||
case VERT_RESULT_TEX6:
|
||||
case VERT_RESULT_TEX7:
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs.output_semantic_index[slot] = num_generic++;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs_output_semantic_index[slot] = num_generic++;
|
||||
break;
|
||||
case VERT_RESULT_VAR0:
|
||||
/* fall-through */
|
||||
default:
|
||||
assert(attr - VERT_RESULT_VAR0 < MAX_VARYING);
|
||||
vs.output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs.output_semantic_index[slot] = num_generic++;
|
||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
vs_output_semantic_index[slot] = num_generic++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(vs.output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
|
||||
assert(vs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
|
||||
|
||||
|
||||
if (outputMapping) {
|
||||
/* find max output slot referenced to compute vs.num_outputs */
|
||||
/* find max output slot referenced to compute vs_num_outputs */
|
||||
GLuint maxSlot = 0;
|
||||
for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
|
||||
if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
|
||||
maxSlot = outputMapping[attr];
|
||||
}
|
||||
vs.num_outputs = maxSlot + 1;
|
||||
vs_num_outputs = maxSlot + 1;
|
||||
}
|
||||
else {
|
||||
outputMapping = defaultOutputMapping;
|
||||
@@ -257,22 +265,23 @@ st_translate_vertex_program(struct st_context *st,
|
||||
num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_VERTEX,
|
||||
&stvp->Base.Base,
|
||||
/* inputs */
|
||||
vs.num_inputs,
|
||||
vs_num_inputs,
|
||||
stvp->input_to_index,
|
||||
vs.input_semantic_name,
|
||||
vs.input_semantic_index,
|
||||
vs_input_semantic_name,
|
||||
vs_input_semantic_index,
|
||||
NULL,
|
||||
/* outputs */
|
||||
vs.num_outputs,
|
||||
vs_num_outputs,
|
||||
outputMapping,
|
||||
vs.output_semantic_name,
|
||||
vs.output_semantic_index,
|
||||
vs_output_semantic_name,
|
||||
vs_output_semantic_index,
|
||||
/* tokenized result */
|
||||
tokens, ST_MAX_SHADER_TOKENS);
|
||||
|
||||
vs.tokens = (struct tgsi_token *)
|
||||
mem_dup(tokens, num_tokens * sizeof(tokens[0]));
|
||||
|
||||
stvp->num_inputs = vs_num_inputs;
|
||||
stvp->state = vs; /* struct copy */
|
||||
stvp->driver_shader = pipe->create_vs_state(pipe, &vs);
|
||||
|
||||
@@ -310,6 +319,14 @@ st_translate_fragment_program(struct st_context *st,
|
||||
GLuint num_generic = 0;
|
||||
GLuint num_tokens;
|
||||
|
||||
ubyte fs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
|
||||
ubyte fs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
|
||||
uint fs_num_inputs = 0;
|
||||
|
||||
ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
|
||||
ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
|
||||
uint fs_num_outputs = 0;
|
||||
|
||||
memset(&fs, 0, sizeof(fs));
|
||||
|
||||
/* which vertex output goes to the first fragment input: */
|
||||
@@ -323,33 +340,33 @@ st_translate_fragment_program(struct st_context *st,
|
||||
*/
|
||||
for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
|
||||
if (inputsRead & (1 << attr)) {
|
||||
const GLuint slot = fs.num_inputs;
|
||||
const GLuint slot = fs_num_inputs;
|
||||
|
||||
defaultInputMapping[attr] = slot;
|
||||
|
||||
stfp->input_map[slot] = vslot++;
|
||||
|
||||
fs.num_inputs++;
|
||||
fs_num_inputs++;
|
||||
|
||||
switch (attr) {
|
||||
case FRAG_ATTRIB_WPOS:
|
||||
fs.input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
||||
fs.input_semantic_index[slot] = 0;
|
||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
||||
fs_input_semantic_index[slot] = 0;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
||||
break;
|
||||
case FRAG_ATTRIB_COL0:
|
||||
fs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
fs.input_semantic_index[slot] = 0;
|
||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
fs_input_semantic_index[slot] = 0;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
||||
break;
|
||||
case FRAG_ATTRIB_COL1:
|
||||
fs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
fs.input_semantic_index[slot] = 1;
|
||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||
fs_input_semantic_index[slot] = 1;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
||||
break;
|
||||
case FRAG_ATTRIB_FOGC:
|
||||
fs.input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||
fs.input_semantic_index[slot] = 0;
|
||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||
fs_input_semantic_index[slot] = 0;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
break;
|
||||
case FRAG_ATTRIB_TEX0:
|
||||
@@ -360,15 +377,15 @@ st_translate_fragment_program(struct st_context *st,
|
||||
case FRAG_ATTRIB_TEX5:
|
||||
case FRAG_ATTRIB_TEX6:
|
||||
case FRAG_ATTRIB_TEX7:
|
||||
fs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
fs.input_semantic_index[slot] = num_generic++;
|
||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
fs_input_semantic_index[slot] = num_generic++;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
break;
|
||||
case FRAG_ATTRIB_VAR0:
|
||||
/* fall-through */
|
||||
default:
|
||||
fs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
fs.input_semantic_index[slot] = num_generic++;
|
||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
fs_input_semantic_index[slot] = num_generic++;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
}
|
||||
}
|
||||
@@ -383,10 +400,10 @@ st_translate_fragment_program(struct st_context *st,
|
||||
|
||||
/* if z is written, emit that first */
|
||||
if (outputsWritten & (1 << FRAG_RESULT_DEPR)) {
|
||||
fs.output_semantic_name[fs.num_outputs] = TGSI_SEMANTIC_POSITION;
|
||||
fs.output_semantic_index[fs.num_outputs] = 0;
|
||||
outputMapping[FRAG_RESULT_DEPR] = fs.num_outputs;
|
||||
fs.num_outputs++;
|
||||
fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION;
|
||||
fs_output_semantic_index[fs_num_outputs] = 0;
|
||||
outputMapping[FRAG_RESULT_DEPR] = fs_num_outputs;
|
||||
fs_num_outputs++;
|
||||
outputsWritten &= ~(1 << FRAG_RESULT_DEPR);
|
||||
}
|
||||
|
||||
@@ -399,15 +416,15 @@ st_translate_fragment_program(struct st_context *st,
|
||||
assert(0);
|
||||
break;
|
||||
case FRAG_RESULT_COLR:
|
||||
fs.output_semantic_name[fs.num_outputs] = TGSI_SEMANTIC_COLOR;
|
||||
fs.output_semantic_index[fs.num_outputs] = numColors;
|
||||
outputMapping[attr] = fs.num_outputs;
|
||||
fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
|
||||
fs_output_semantic_index[fs_num_outputs] = numColors;
|
||||
outputMapping[attr] = fs_num_outputs;
|
||||
numColors++;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
fs.num_outputs++;
|
||||
fs_num_outputs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -420,16 +437,16 @@ st_translate_fragment_program(struct st_context *st,
|
||||
num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_FRAGMENT,
|
||||
&stfp->Base.Base,
|
||||
/* inputs */
|
||||
fs.num_inputs,
|
||||
fs_num_inputs,
|
||||
inputMapping,
|
||||
fs.input_semantic_name,
|
||||
fs.input_semantic_index,
|
||||
fs_input_semantic_name,
|
||||
fs_input_semantic_index,
|
||||
interpMode,
|
||||
/* outputs */
|
||||
fs.num_outputs,
|
||||
fs_num_outputs,
|
||||
outputMapping,
|
||||
fs.output_semantic_name,
|
||||
fs.output_semantic_index,
|
||||
fs_output_semantic_name,
|
||||
fs_output_semantic_index,
|
||||
/* tokenized result */
|
||||
tokens, ST_MAX_SHADER_TOKENS);
|
||||
|
||||
|
||||
@@ -85,6 +85,8 @@ struct st_vertex_program
|
||||
/** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */
|
||||
GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
|
||||
|
||||
GLuint num_inputs;
|
||||
|
||||
struct pipe_shader_state state;
|
||||
struct pipe_shader_state *driver_shader;
|
||||
|
||||
|
||||
@@ -309,23 +309,16 @@ static void vbo_exec_fixup_vertex( GLcontext *ctx,
|
||||
GLuint attr, GLuint sz )
|
||||
{
|
||||
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
|
||||
static const GLfloat id[4] = { 0, 0, 0, 1 };
|
||||
int i;
|
||||
|
||||
if (exec->vtx.prim_count == 0) {
|
||||
GLfloat *current = (GLfloat *)vbo_context(ctx)->currval[attr].Ptr;
|
||||
exec->vtx.attrptr[attr] = current;
|
||||
memcpy(current, id, sizeof(id));
|
||||
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
|
||||
return;
|
||||
}
|
||||
else if (sz > exec->vtx.attrsz[attr]) {
|
||||
if (sz > exec->vtx.attrsz[attr]) {
|
||||
/* New size is larger. Need to flush existing vertices and get
|
||||
* an enlarged vertex format.
|
||||
*/
|
||||
vbo_exec_wrap_upgrade_vertex( exec, attr, sz );
|
||||
}
|
||||
else if (sz < exec->vtx.active_sz[attr]) {
|
||||
static const GLfloat id[4] = { 0, 0, 0, 1 };
|
||||
|
||||
/* New size is smaller - just need to fill in some
|
||||
* zeros. Don't need to flush or wrap.
|
||||
|
||||
Reference in New Issue
Block a user