Merge commit 'origin/master' into gallium-sw-api-2

This commit is contained in:
Keith Whitwell 2010-03-10 08:29:27 +00:00
commit 155fbcb0ed
138 changed files with 4043 additions and 2897 deletions

View File

@ -551,7 +551,6 @@ class Context(Object):
data = vbuf.buffer.read() data = vbuf.buffer.read()
values = unpack_from(format, data, offset) values = unpack_from(format, data, offset)
sys.stdout.write('\t\t{' + ', '.join(map(str, values)) + '},\n') sys.stdout.write('\t\t{' + ', '.join(map(str, values)) + '},\n')
assert len(values) == velem.nr_components
sys.stdout.write('\t},\n') sys.stdout.write('\t},\n')
sys.stdout.flush() sys.stdout.flush()

View File

@ -36,8 +36,8 @@ Display( void )
/* draw to user framebuffer */ /* draw to user framebuffer */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
@ -161,7 +161,7 @@ Init( void )
assert(i == MyFB); assert(i == MyFB);
CheckError(__LINE__); CheckError(__LINE__);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_RENDERBUFFER_EXT, MyRB); GL_RENDERBUFFER_EXT, MyRB);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);

View File

@ -40,8 +40,8 @@ Display( void )
/* draw to user framebuffer */ /* draw to user framebuffer */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
@ -163,7 +163,7 @@ Init( void )
glGenRenderbuffersEXT(1, &ColorRb); glGenRenderbuffersEXT(1, &ColorRb);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb);
assert(glIsRenderbufferEXT(ColorRb)); assert(glIsRenderbufferEXT(ColorRb));
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_RENDERBUFFER_EXT, ColorRb); GL_RENDERBUFFER_EXT, ColorRb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);

View File

@ -50,8 +50,8 @@ Display( void )
/* draw to user framebuffer */ /* draw to user framebuffer */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
@ -189,7 +189,7 @@ Init( void )
glGenRenderbuffersEXT(1, &ColorRb); glGenRenderbuffersEXT(1, &ColorRb);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb);
assert(glIsRenderbufferEXT(ColorRb)); assert(glIsRenderbufferEXT(ColorRb));
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_RENDERBUFFER_EXT, ColorRb); GL_RENDERBUFFER_EXT, ColorRb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);

View File

@ -43,6 +43,7 @@ struct cso_cache {
struct cso_hash *vs_hash; struct cso_hash *vs_hash;
struct cso_hash *rasterizer_hash; struct cso_hash *rasterizer_hash;
struct cso_hash *sampler_hash; struct cso_hash *sampler_hash;
struct cso_hash *velements_hash;
int max_size; int max_size;
cso_sanitize_callback sanitize_cb; cso_sanitize_callback sanitize_cb;
@ -108,6 +109,9 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_
case CSO_VERTEX_SHADER: case CSO_VERTEX_SHADER:
hash = sc->vs_hash; hash = sc->vs_hash;
break; break;
case CSO_VELEMENTS:
hash = sc->velements_hash;
break;
} }
return hash; return hash;
@ -161,6 +165,13 @@ static void delete_vs_state(void *state, void *data)
FREE(state); FREE(state);
} }
static void delete_velements(void *state, void *data)
{
struct cso_velements *cso = (struct cso_velements *)state;
if (cso->delete_state)
cso->delete_state(cso->context, cso->data);
FREE(state);
}
static INLINE void delete_cso(void *state, enum cso_cache_type type) static INLINE void delete_cso(void *state, enum cso_cache_type type)
{ {
@ -183,6 +194,9 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type)
case CSO_VERTEX_SHADER: case CSO_VERTEX_SHADER:
delete_vs_state(state, 0); delete_vs_state(state, 0);
break; break;
case CSO_VELEMENTS:
delete_velements(state, 0);
break;
default: default:
assert(0); assert(0);
FREE(state); FREE(state);
@ -294,6 +308,7 @@ struct cso_cache *cso_cache_create(void)
sc->rasterizer_hash = cso_hash_create(); sc->rasterizer_hash = cso_hash_create();
sc->fs_hash = cso_hash_create(); sc->fs_hash = cso_hash_create();
sc->vs_hash = cso_hash_create(); sc->vs_hash = cso_hash_create();
sc->velements_hash = cso_hash_create();
sc->sanitize_cb = sanitize_cb; sc->sanitize_cb = sanitize_cb;
sc->sanitize_data = 0; sc->sanitize_data = 0;
@ -325,6 +340,9 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
case CSO_VERTEX_SHADER: case CSO_VERTEX_SHADER:
hash = sc->vs_hash; hash = sc->vs_hash;
break; break;
case CSO_VELEMENTS:
hash = sc->velements_hash;
break;
} }
iter = cso_hash_first_node(hash); iter = cso_hash_first_node(hash);
@ -351,6 +369,7 @@ void cso_cache_delete(struct cso_cache *sc)
cso_for_each_state(sc, CSO_VERTEX_SHADER, delete_vs_state, 0); cso_for_each_state(sc, CSO_VERTEX_SHADER, delete_vs_state, 0);
cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0); cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0);
cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0); cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0);
cso_for_each_state(sc, CSO_VELEMENTS, delete_velements, 0);
cso_hash_delete(sc->blend_hash); cso_hash_delete(sc->blend_hash);
cso_hash_delete(sc->sampler_hash); cso_hash_delete(sc->sampler_hash);
@ -358,6 +377,7 @@ void cso_cache_delete(struct cso_cache *sc)
cso_hash_delete(sc->rasterizer_hash); cso_hash_delete(sc->rasterizer_hash);
cso_hash_delete(sc->fs_hash); cso_hash_delete(sc->fs_hash);
cso_hash_delete(sc->vs_hash); cso_hash_delete(sc->vs_hash);
cso_hash_delete(sc->velements_hash);
FREE(sc); FREE(sc);
} }
@ -372,6 +392,7 @@ void cso_set_maximum_cache_size(struct cso_cache *sc, int number)
sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size); sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size);
sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size); sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size);
sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size); sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size);
sanitize_hash(sc, sc->velements_hash, CSO_VELEMENTS, sc->max_size);
} }
int cso_maximum_cache_size(const struct cso_cache *sc) int cso_maximum_cache_size(const struct cso_cache *sc)

View File

@ -53,6 +53,7 @@
* - rasterizer (old setup) * - rasterizer (old setup)
* - sampler * - sampler
* - vertex shader * - vertex shader
* - vertex elements
* *
* Things that are not constant state objects include: * Things that are not constant state objects include:
* - blend_color * - blend_color
@ -90,7 +91,8 @@ enum cso_cache_type {
CSO_DEPTH_STENCIL_ALPHA, CSO_DEPTH_STENCIL_ALPHA,
CSO_RASTERIZER, CSO_RASTERIZER,
CSO_FRAGMENT_SHADER, CSO_FRAGMENT_SHADER,
CSO_VERTEX_SHADER CSO_VERTEX_SHADER,
CSO_VELEMENTS
}; };
typedef void (*cso_state_callback)(void *ctx, void *obj); typedef void (*cso_state_callback)(void *ctx, void *obj);
@ -144,6 +146,18 @@ struct cso_sampler {
struct pipe_context *context; struct pipe_context *context;
}; };
struct cso_velems_state {
unsigned count;
struct pipe_vertex_element velems[PIPE_MAX_ATTRIBS];
};
struct cso_velements {
struct cso_velems_state state;
void *data;
cso_state_callback delete_state;
struct pipe_context *context;
};
unsigned cso_construct_key(void *item, int item_size); unsigned cso_construct_key(void *item, int item_size);
struct cso_cache *cso_cache_create(void); struct cso_cache *cso_cache_create(void);

View File

@ -89,6 +89,7 @@ struct cso_context {
void *rasterizer, *rasterizer_saved; void *rasterizer, *rasterizer_saved;
void *fragment_shader, *fragment_shader_saved, *geometry_shader; void *fragment_shader, *fragment_shader_saved, *geometry_shader;
void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved; void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved;
void *velements, *velements_saved;
struct pipe_clip_state clip; struct pipe_clip_state clip;
struct pipe_clip_state clip_saved; struct pipe_clip_state clip_saved;
@ -174,6 +175,20 @@ static boolean delete_vs_state(struct cso_context *ctx, void *state)
return FALSE; return FALSE;
} }
static boolean delete_vertex_elements(struct cso_context *ctx,
void *state)
{
struct cso_velements *cso = (struct cso_velements *)state;
if (ctx->velements == cso->data)
return FALSE;
if (cso->delete_state)
cso->delete_state(cso->context, cso->data);
FREE(state);
return TRUE;
}
static INLINE boolean delete_cso(struct cso_context *ctx, static INLINE boolean delete_cso(struct cso_context *ctx,
void *state, enum cso_cache_type type) void *state, enum cso_cache_type type)
@ -197,6 +212,9 @@ static INLINE boolean delete_cso(struct cso_context *ctx,
case CSO_VERTEX_SHADER: case CSO_VERTEX_SHADER:
return delete_vs_state(ctx, state); return delete_vs_state(ctx, state);
break; break;
case CSO_VELEMENTS:
return delete_vertex_elements(ctx, state);
break;
default: default:
assert(0); assert(0);
FREE(state); FREE(state);
@ -271,6 +289,7 @@ void cso_release_all( struct cso_context *ctx )
ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL ); ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL );
ctx->pipe->bind_fs_state( ctx->pipe, NULL ); ctx->pipe->bind_fs_state( ctx->pipe, NULL );
ctx->pipe->bind_vs_state( ctx->pipe, NULL ); ctx->pipe->bind_vs_state( ctx->pipe, NULL );
ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
} }
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
@ -1130,7 +1149,6 @@ void cso_restore_geometry_shader(struct cso_context *ctx)
ctx->geometry_shader_saved = NULL; ctx->geometry_shader_saved = NULL;
} }
/* clip state */ /* clip state */
static INLINE void static INLINE void
@ -1180,3 +1198,66 @@ cso_restore_clip(struct cso_context *ctx)
ctx->pipe->set_clip_state(ctx->pipe, &ctx->clip_saved); ctx->pipe->set_clip_state(ctx->pipe, &ctx->clip_saved);
} }
} }
enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
unsigned count,
const struct pipe_vertex_element *states)
{
unsigned key_size, hash_key;
struct cso_hash_iter iter;
void *handle;
struct cso_velems_state velems_state;
/* need to include the count into the stored state data too.
Otherwise first few count pipe_vertex_elements could be identical even if count
is different, and there's no guarantee the hash would be different in that
case neither */
key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned);
velems_state.count = count;
memcpy(velems_state.velems, states, sizeof(struct pipe_vertex_element) * count);
hash_key = cso_construct_key((void*)&velems_state, key_size);
iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS, (void*)&velems_state, key_size);
if (cso_hash_iter_is_null(iter)) {
struct cso_velements *cso = MALLOC(sizeof(struct cso_velements));
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
memcpy(&cso->state, &velems_state, key_size);
cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count, &cso->state.velems[0]);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_vertex_elements_state;
cso->context = ctx->pipe;
iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso);
if (cso_hash_iter_is_null(iter)) {
FREE(cso);
return PIPE_ERROR_OUT_OF_MEMORY;
}
handle = cso->data;
}
else {
handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
}
if (ctx->velements != handle) {
ctx->velements = handle;
ctx->pipe->bind_vertex_elements_state(ctx->pipe, handle);
}
return PIPE_OK;
}
void cso_save_vertex_elements(struct cso_context *ctx)
{
assert(!ctx->velements_saved);
ctx->velements_saved = ctx->velements;
}
void cso_restore_vertex_elements(struct cso_context *ctx)
{
if (ctx->velements != ctx->velements_saved) {
ctx->velements = ctx->velements_saved;
ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved);
}
ctx->velements_saved = NULL;
}

View File

@ -122,6 +122,12 @@ void
cso_restore_vertex_sampler_textures(struct cso_context *cso); cso_restore_vertex_sampler_textures(struct cso_context *cso);
enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
unsigned count,
const struct pipe_vertex_element *states);
void cso_save_vertex_elements(struct cso_context *ctx);
void cso_restore_vertex_elements(struct cso_context *ctx);
/* These aren't really sensible -- most of the time the api provides /* These aren't really sensible -- most of the time the api provides
* object semantics for shaders anyway, and the cases where it doesn't * object semantics for shaders anyway, and the cases where it doesn't
@ -157,7 +163,6 @@ void cso_save_geometry_shader(struct cso_context *cso);
void cso_restore_geometry_shader(struct cso_context *cso); void cso_restore_geometry_shader(struct cso_context *cso);
enum pipe_error cso_set_framebuffer(struct cso_context *cso, enum pipe_error cso_set_framebuffer(struct cso_context *cso,
const struct pipe_framebuffer_state *fb); const struct pipe_framebuffer_state *fb);
void cso_save_framebuffer(struct cso_context *cso); void cso_save_framebuffer(struct cso_context *cso);

View File

@ -307,9 +307,8 @@ draw_arrays_instanced(struct draw_context *draw,
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0); tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
debug_printf("Elements:\n"); debug_printf("Elements:\n");
for (i = 0; i < draw->pt.nr_vertex_elements; i++) { for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
debug_printf(" format=%s comps=%u\n", debug_printf(" format=%s\n",
util_format_name(draw->pt.vertex_element[i].src_format), util_format_name(draw->pt.vertex_element[i].src_format));
draw->pt.vertex_element[i].nr_components);
} }
debug_printf("Buffers:\n"); debug_printf("Buffers:\n");
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {

View File

@ -644,13 +644,26 @@ lp_build_abs(struct lp_build_context *bld,
if(type.floating) { if(type.floating) {
/* Mask out the sign bit */ /* Mask out the sign bit */
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); if (type.length == 1) {
unsigned long long absMask = ~(1ULL << (type.width - 1)); LLVMTypeRef int_type = LLVMIntType(type.width);
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask)); LLVMTypeRef float_type = LLVMFloatType();
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); unsigned long long absMask = ~(1ULL << (type.width - 1));
a = LLVMBuildAnd(bld->builder, a, mask, ""); LLVMValueRef mask = LLVMConstInt(int_type, absMask, 0);
a = LLVMBuildBitCast(bld->builder, a, vec_type, ""); a = LLVMBuildBitCast(bld->builder, a, int_type, "");
return a; a = LLVMBuildAnd(bld->builder, a, mask, "");
a = LLVMBuildBitCast(bld->builder, a, float_type, "");
return a;
}
else {
/* vector of floats */
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
unsigned long long absMask = ~(1ULL << (type.width - 1));
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
a = LLVMBuildAnd(bld->builder, a, mask, "");
a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
return a;
}
} }
if(type.width*type.length == 128 && util_cpu_caps.has_ssse3) { if(type.width*type.length == 128 && util_cpu_caps.has_ssse3) {
@ -753,7 +766,7 @@ lp_build_set_sign(struct lp_build_context *bld,
/** /**
* Convert vector of int to vector of float. * Convert vector of (or scalar) int to vector of (or scalar) float.
*/ */
LLVMValueRef LLVMValueRef
lp_build_int_to_float(struct lp_build_context *bld, lp_build_int_to_float(struct lp_build_context *bld,
@ -764,7 +777,11 @@ lp_build_int_to_float(struct lp_build_context *bld,
assert(type.floating); assert(type.floating);
/*assert(lp_check_value(type, a));*/ /*assert(lp_check_value(type, a));*/
{ if (type.length == 1) {
LLVMTypeRef float_type = LLVMFloatType();
return LLVMBuildSIToFP(bld->builder, a, float_type, "");
}
else {
LLVMTypeRef vec_type = lp_build_vec_type(type); LLVMTypeRef vec_type = lp_build_vec_type(type);
/*LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);*/ /*LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);*/
LLVMValueRef res; LLVMValueRef res;
@ -921,12 +938,18 @@ lp_build_itrunc(struct lp_build_context *bld,
LLVMValueRef a) LLVMValueRef a)
{ {
const struct lp_type type = bld->type; const struct lp_type type = bld->type;
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
assert(type.floating); assert(type.floating);
assert(lp_check_value(type, a));
return LLVMBuildFPToSI(bld->builder, a, int_vec_type, ""); if (type.length == 1) {
LLVMTypeRef int_type = LLVMIntType(type.width);
return LLVMBuildFPTrunc(bld->builder, a, int_type, "");
}
else {
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
assert(lp_check_value(type, a));
return LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
}
} }
@ -939,6 +962,15 @@ lp_build_iround(struct lp_build_context *bld,
LLVMValueRef res; LLVMValueRef res;
assert(type.floating); assert(type.floating);
if (type.length == 1) {
/* scalar float to int */
LLVMTypeRef int_type = LLVMIntType(type.width);
/* XXX we want rounding here! */
res = LLVMBuildFPToSI(bld->builder, a, int_type, "");
return res;
}
assert(lp_check_value(type, a)); assert(lp_check_value(type, a));
if(util_cpu_caps.has_sse4_1) { if(util_cpu_caps.has_sse4_1) {
@ -1207,6 +1239,7 @@ lp_build_polynomial(struct lp_build_context *bld,
unsigned num_coeffs) unsigned num_coeffs)
{ {
const struct lp_type type = bld->type; const struct lp_type type = bld->type;
LLVMTypeRef float_type = LLVMFloatType();
LLVMValueRef res = NULL; LLVMValueRef res = NULL;
unsigned i; unsigned i;
@ -1216,7 +1249,13 @@ lp_build_polynomial(struct lp_build_context *bld,
__FUNCTION__); __FUNCTION__);
for (i = num_coeffs; i--; ) { for (i = num_coeffs; i--; ) {
LLVMValueRef coeff = lp_build_const_scalar(type, coeffs[i]); LLVMValueRef coeff;
if (type.length == 1)
coeff = LLVMConstReal(float_type, coeffs[i]);
else
coeff = lp_build_const_scalar(type, coeffs[i]);
if(res) if(res)
res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res)); res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res));
else else
@ -1410,11 +1449,87 @@ lp_build_log2_approx(struct lp_build_context *bld,
} }
/** scalar version of above function */
static void
lp_build_float_log2_approx(struct lp_build_context *bld,
LLVMValueRef x,
LLVMValueRef *p_exp,
LLVMValueRef *p_floor_log2,
LLVMValueRef *p_log2)
{
const struct lp_type type = bld->type;
LLVMTypeRef float_type = LLVMFloatType();
LLVMTypeRef int_type = LLVMIntType(type.width);
LLVMValueRef expmask = LLVMConstInt(int_type, 0x7f800000, 0);
LLVMValueRef mantmask = LLVMConstInt(int_type, 0x007fffff, 0);
LLVMValueRef one = LLVMConstBitCast(bld->one, int_type);
LLVMValueRef i = NULL;
LLVMValueRef exp = NULL;
LLVMValueRef mant = NULL;
LLVMValueRef logexp = NULL;
LLVMValueRef logmant = NULL;
LLVMValueRef res = NULL;
if(p_exp || p_floor_log2 || p_log2) {
/* TODO: optimize the constant case */
if(LLVMIsConstant(x))
debug_printf("%s: inefficient/imprecise constant arithmetic\n",
__FUNCTION__);
assert(type.floating && type.width == 32);
i = LLVMBuildBitCast(bld->builder, x, int_type, "");
/* exp = (float) exponent(x) */
exp = LLVMBuildAnd(bld->builder, i, expmask, "");
}
if(p_floor_log2 || p_log2) {
LLVMValueRef c23 = LLVMConstInt(int_type, 23, 0);
LLVMValueRef c127 = LLVMConstInt(int_type, 127, 0);
logexp = LLVMBuildLShr(bld->builder, exp, c23, "");
logexp = LLVMBuildSub(bld->builder, logexp, c127, "");
logexp = LLVMBuildSIToFP(bld->builder, logexp, float_type, "");
}
if(p_log2) {
/* mant = (float) mantissa(x) */
mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
mant = LLVMBuildOr(bld->builder, mant, one, "");
mant = LLVMBuildBitCast(bld->builder, mant, float_type, "");
logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
Elements(lp_build_log2_polynomial));
/* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
}
if(p_exp)
*p_exp = exp;
if(p_floor_log2)
*p_floor_log2 = logexp;
if(p_log2)
*p_log2 = res;
}
LLVMValueRef LLVMValueRef
lp_build_log2(struct lp_build_context *bld, lp_build_log2(struct lp_build_context *bld,
LLVMValueRef x) LLVMValueRef x)
{ {
LLVMValueRef res; LLVMValueRef res;
lp_build_log2_approx(bld, x, NULL, NULL, &res); if (bld->type.length == 1) {
lp_build_float_log2_approx(bld, x, NULL, NULL, &res);
}
else {
lp_build_log2_approx(bld, x, NULL, NULL, &res);
}
return res; return res;
} }

View File

@ -264,10 +264,16 @@ lp_build_one(struct lp_type type)
for(i = 1; i < type.length; ++i) for(i = 1; i < type.length; ++i)
elems[i] = elems[0]; elems[i] = elems[0];
return LLVMConstVector(elems, type.length); if (type.length == 1)
return elems[0];
else
return LLVMConstVector(elems, type.length);
} }
/**
* Build constant-valued vector from a scalar value.
*/
LLVMValueRef LLVMValueRef
lp_build_const_scalar(struct lp_type type, lp_build_const_scalar(struct lp_type type,
double val) double val)

View File

@ -198,7 +198,7 @@ lp_build_compare(LLVMBuilderRef builder,
return res; return res;
} }
} } /* if (type.width * type.length == 128) */
#endif #endif
if(type.floating) { if(type.floating) {
@ -238,20 +238,25 @@ lp_build_compare(LLVMBuilderRef builder,
cond = LLVMBuildFCmp(builder, op, a, b, ""); cond = LLVMBuildFCmp(builder, op, a, b, "");
res = LLVMBuildSelect(builder, cond, ones, zeros, ""); res = LLVMBuildSelect(builder, cond, ones, zeros, "");
#else #else
debug_printf("%s: warning: using slow element-wise vector comparison\n",
__FUNCTION__);
res = LLVMGetUndef(int_vec_type); res = LLVMGetUndef(int_vec_type);
for(i = 0; i < type.length; ++i) { if (type.length == 1) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); res = LLVMBuildFCmp(builder, op, a, b, "");
cond = LLVMBuildFCmp(builder, op, }
LLVMBuildExtractElement(builder, a, index, ""), else {
LLVMBuildExtractElement(builder, b, index, ""), debug_printf("%s: warning: using slow element-wise float"
""); " vector comparison\n", __FUNCTION__);
cond = LLVMBuildSelect(builder, cond, for (i = 0; i < type.length; ++i) {
LLVMConstExtractElement(ones, index), LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMConstExtractElement(zeros, index), cond = LLVMBuildFCmp(builder, op,
""); LLVMBuildExtractElement(builder, a, index, ""),
res = LLVMBuildInsertElement(builder, res, cond, index, ""); LLVMBuildExtractElement(builder, b, index, ""),
"");
cond = LLVMBuildSelect(builder, cond,
LLVMConstExtractElement(ones, index),
LLVMConstExtractElement(zeros, index),
"");
res = LLVMBuildInsertElement(builder, res, cond, index, "");
}
} }
#endif #endif
} }
@ -286,20 +291,26 @@ lp_build_compare(LLVMBuilderRef builder,
cond = LLVMBuildICmp(builder, op, a, b, ""); cond = LLVMBuildICmp(builder, op, a, b, "");
res = LLVMBuildSelect(builder, cond, ones, zeros, ""); res = LLVMBuildSelect(builder, cond, ones, zeros, "");
#else #else
debug_printf("%s: warning: using slow element-wise int vector comparison\n",
__FUNCTION__);
res = LLVMGetUndef(int_vec_type); res = LLVMGetUndef(int_vec_type);
for(i = 0; i < type.length; ++i) { if (type.length == 1) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); res = LLVMBuildICmp(builder, op, a, b, "");
cond = LLVMBuildICmp(builder, op, }
LLVMBuildExtractElement(builder, a, index, ""), else {
LLVMBuildExtractElement(builder, b, index, ""), debug_printf("%s: warning: using slow element-wise int"
""); " vector comparison\n", __FUNCTION__);
cond = LLVMBuildSelect(builder, cond,
LLVMConstExtractElement(ones, index), for(i = 0; i < type.length; ++i) {
LLVMConstExtractElement(zeros, index), LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
""); cond = LLVMBuildICmp(builder, op,
res = LLVMBuildInsertElement(builder, res, cond, index, ""); LLVMBuildExtractElement(builder, a, index, ""),
LLVMBuildExtractElement(builder, b, index, ""),
"");
cond = LLVMBuildSelect(builder, cond,
LLVMConstExtractElement(ones, index),
LLVMConstExtractElement(zeros, index),
"");
res = LLVMBuildInsertElement(builder, res, cond, index, "");
}
} }
#endif #endif
} }
@ -339,26 +350,31 @@ lp_build_select(struct lp_build_context *bld,
if(a == b) if(a == b)
return a; return a;
if(type.floating) { if (type.length == 1) {
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); res = LLVMBuildSelect(bld->builder, mask, a, b, "");
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
} }
else {
if(type.floating) {
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
}
a = LLVMBuildAnd(bld->builder, a, mask, ""); a = LLVMBuildAnd(bld->builder, a, mask, "");
/* This often gets translated to PANDN, but sometimes the NOT is /* This often gets translated to PANDN, but sometimes the NOT is
* pre-computed and stored in another constant. The best strategy depends * pre-computed and stored in another constant. The best strategy depends
* on available registers, so it is not a big deal -- hopefully LLVM does * on available registers, so it is not a big deal -- hopefully LLVM does
* the right decision attending the rest of the program. * the right decision attending the rest of the program.
*/ */
b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), ""); b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
res = LLVMBuildOr(bld->builder, a, b, ""); res = LLVMBuildOr(bld->builder, a, b, "");
if(type.floating) { if(type.floating) {
LLVMTypeRef vec_type = lp_build_vec_type(type); LLVMTypeRef vec_type = lp_build_vec_type(type);
res = LLVMBuildBitCast(bld->builder, res, vec_type, ""); res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
}
} }
return res; return res;

View File

@ -65,6 +65,14 @@ struct lp_build_sample_context
const struct util_format_description *format_desc; const struct util_format_description *format_desc;
/** regular scalar float type */
struct lp_type float_type;
struct lp_build_context float_bld;
/** regular scalar float type */
struct lp_type int_type;
struct lp_build_context int_bld;
/** Incoming coordinates type and build context */ /** Incoming coordinates type and build context */
struct lp_type coord_type; struct lp_type coord_type;
struct lp_build_context coord_bld; struct lp_build_context coord_bld;
@ -108,6 +116,27 @@ wrap_mode_uses_border_color(unsigned mode)
} }
static LLVMValueRef
lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
LLVMValueRef data_array, LLVMValueRef level)
{
LLVMValueRef indexes[2], data_ptr;
indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
indexes[1] = level;
data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
return data_ptr;
}
static LLVMValueRef
lp_build_get_const_mipmap_level(struct lp_build_sample_context *bld,
LLVMValueRef data_array, int level)
{
LLVMValueRef lvl = LLVMConstInt(LLVMInt32Type(), level, 0);
return lp_build_get_mipmap_level(bld, data_array, lvl);
}
/** /**
* Gen code to fetch a texel from a texture at int coords (x, y). * Gen code to fetch a texel from a texture at int coords (x, y).
@ -124,14 +153,13 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
LLVMValueRef x, LLVMValueRef x,
LLVMValueRef y, LLVMValueRef y,
LLVMValueRef y_stride, LLVMValueRef y_stride,
LLVMValueRef data_array, LLVMValueRef data_ptr,
LLVMValueRef *texel) LLVMValueRef *texel)
{ {
struct lp_build_context *int_coord_bld = &bld->int_coord_bld; struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef offset; LLVMValueRef offset;
LLVMValueRef packed; LLVMValueRef packed;
LLVMValueRef use_border = NULL; LLVMValueRef use_border = NULL;
LLVMValueRef data_ptr;
/* use_border = x < 0 || x >= width || y < 0 || y >= height */ /* use_border = x < 0 || x >= width || y < 0 || y >= height */
if (wrap_mode_uses_border_color(bld->static_state->wrap_s)) { if (wrap_mode_uses_border_color(bld->static_state->wrap_s)) {
@ -154,16 +182,6 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
} }
} }
/* XXX always use mipmap level 0 for now */
{
const int level = 0;
LLVMValueRef indexes[2];
indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
indexes[1] = LLVMConstInt(LLVMInt32Type(), level, 0);
data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
}
/* /*
* Note: if we find an app which frequently samples the texture border * Note: if we find an app which frequently samples the texture border
* we might want to implement a true conditional here to avoid sampling * we might want to implement a true conditional here to avoid sampling
@ -233,17 +251,8 @@ lp_build_sample_packed(struct lp_build_sample_context *bld,
assert(bld->format_desc->block.height == 1); assert(bld->format_desc->block.height == 1);
assert(bld->format_desc->block.bits <= bld->texel_type.width); assert(bld->format_desc->block.bits <= bld->texel_type.width);
/* XXX always use mipmap level 0 for now */ /* get pointer to mipmap level 0 data */
{ data_ptr = lp_build_get_const_mipmap_level(bld, data_array, 0);
const int level = 0;
LLVMValueRef indexes[2];
/* get data_ptr[level] */
indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
indexes[1] = LLVMConstInt(LLVMInt32Type(), level, 0);
data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
/* load texture base address */
data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
}
return lp_build_gather(bld->builder, return lp_build_gather(bld->builder,
bld->texel_type.length, bld->texel_type.length,
@ -733,7 +742,210 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
/** /**
* Sample 2D texture with nearest filtering. * Codegen equivalent for u_minify().
* Return max(1, base_size >> level);
*/
static LLVMValueRef
lp_build_minify(struct lp_build_sample_context *bld,
LLVMValueRef base_size,
LLVMValueRef level)
{
LLVMValueRef size = LLVMBuildAShr(bld->builder, base_size, level, "minify");
size = lp_build_max(&bld->int_coord_bld, size, bld->int_coord_bld.one);
return size;
}
static int
texture_dims(enum pipe_texture_target tex)
{
switch (tex) {
case PIPE_TEXTURE_1D:
return 1;
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_CUBE:
return 2;
case PIPE_TEXTURE_3D:
return 3;
default:
assert(0 && "bad texture target in texture_dims()");
return 2;
}
}
/**
* Generate code to compute texture level of detail (lambda).
* \param s vector of texcoord s values
* \param t vector of texcoord t values
* \param r vector of texcoord r values
* \param width scalar int texture width
* \param height scalar int texture height
* \param depth scalar int texture depth
*/
static LLVMValueRef
lp_build_lod_selector(struct lp_build_sample_context *bld,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef depth)
{
const int dims = texture_dims(bld->static_state->target);
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *float_bld = &bld->float_bld;
LLVMValueRef lod_bias = LLVMConstReal(LLVMFloatType(), bld->static_state->lod_bias);
LLVMValueRef min_lod = LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod);
LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(), bld->static_state->max_lod);
LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
LLVMValueRef s0, s1, s2;
LLVMValueRef t0, t1, t2;
LLVMValueRef r0, r1, r2;
LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
LLVMValueRef rho, lod;
/*
* dsdx = abs(s[1] - s[0]);
* dsdy = abs(s[2] - s[0]);
* dtdx = abs(t[1] - t[0]);
* dtdy = abs(t[2] - t[0]);
* drdx = abs(r[1] - r[0]);
* drdy = abs(r[2] - r[0]);
* XXX we're assuming a four-element quad in 2x2 layout here.
*/
s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
dsdx = LLVMBuildSub(bld->builder, s1, s0, "");
dsdx = lp_build_abs(float_bld, dsdx);
dsdy = LLVMBuildSub(bld->builder, s2, s0, "");
dsdy = lp_build_abs(float_bld, dsdy);
if (dims > 1) {
t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
dtdx = LLVMBuildSub(bld->builder, t1, t0, "");
dtdx = lp_build_abs(float_bld, dtdx);
dtdy = LLVMBuildSub(bld->builder, t2, t0, "");
dtdy = lp_build_abs(float_bld, dtdy);
if (dims > 2) {
r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
drdx = LLVMBuildSub(bld->builder, r1, r0, "");
drdx = lp_build_abs(float_bld, drdx);
drdy = LLVMBuildSub(bld->builder, r2, r0, "");
drdy = lp_build_abs(float_bld, drdy);
}
}
/* Compute rho = max of all partial derivatives scaled by texture size.
* XXX this could be vectorized somewhat
*/
rho = LLVMBuildMul(bld->builder,
lp_build_max(float_bld, dsdx, dsdy),
lp_build_int_to_float(float_bld, width), "");
if (dims > 1) {
LLVMValueRef max;
max = LLVMBuildMul(bld->builder,
lp_build_max(float_bld, dtdx, dtdy),
lp_build_int_to_float(float_bld, height), "");
rho = lp_build_max(float_bld, rho, max);
if (dims > 2) {
max = LLVMBuildMul(bld->builder,
lp_build_max(float_bld, drdx, drdy),
lp_build_int_to_float(float_bld, depth), "");
rho = lp_build_max(float_bld, rho, max);
}
}
/* compute lod = log2(rho) */
lod = lp_build_log2(float_bld, rho);
/* add lod bias */
lod = LLVMBuildAdd(bld->builder, lod, lod_bias, "LOD bias");
/* clamp lod */
lod = lp_build_clamp(float_bld, lod, min_lod, max_lod);
return lod;
}
/**
* For PIPE_TEX_MIPFILTER_NEAREST, convert float LOD to integer
* mipmap level index.
* Note: this is all scalar code.
* \param lod scalar float texture level of detail
* \param level_out returns integer
*/
static void
lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
unsigned unit,
LLVMValueRef lod,
LLVMValueRef *level_out)
{
struct lp_build_context *float_bld = &bld->float_bld;
struct lp_build_context *int_bld = &bld->int_bld;
LLVMValueRef last_level, level;
LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, 0);
last_level = bld->dynamic_state->last_level(bld->dynamic_state,
bld->builder, unit);
/* convert float lod to integer */
level = lp_build_iround(float_bld, lod);
/* clamp level to legal range of levels */
*level_out = lp_build_clamp(int_bld, level, zero, last_level);
}
/**
* For PIPE_TEX_MIPFILTER_LINEAR, convert float LOD to integer to
* two (adjacent) mipmap level indexes. Later, we'll sample from those
* two mipmap levels and interpolate between them.
*/
static void
lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
unsigned unit,
LLVMValueRef lod,
LLVMValueRef *level0_out,
LLVMValueRef *level1_out,
LLVMValueRef *weight_out)
{
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef last_level, level;
last_level = bld->dynamic_state->last_level(bld->dynamic_state,
bld->builder, unit);
/* convert float lod to integer */
level = lp_build_ifloor(coord_bld, lod);
/* compute level 0 and clamp to legal range of levels */
*level0_out = lp_build_clamp(int_coord_bld, level,
int_coord_bld->zero,
last_level);
/* compute level 1 and clamp to legal range of levels */
*level1_out = lp_build_add(int_coord_bld, *level0_out, int_coord_bld->one);
*level1_out = lp_build_min(int_coord_bld, *level1_out, int_coord_bld->zero);
*weight_out = lp_build_fract(coord_bld, lod);
}
/**
* Sample 2D texture with nearest filtering, no mipmapping.
*/ */
static void static void
lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld, lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
@ -746,6 +958,7 @@ lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
LLVMValueRef *texel) LLVMValueRef *texel)
{ {
LLVMValueRef x, y; LLVMValueRef x, y;
LLVMValueRef data_ptr;
x = lp_build_sample_wrap_nearest(bld, s, width, x = lp_build_sample_wrap_nearest(bld, s, width,
bld->static_state->pot_width, bld->static_state->pot_width,
@ -757,7 +970,63 @@ lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
lp_build_name(x, "tex.x.wrapped"); lp_build_name(x, "tex.x.wrapped");
lp_build_name(y, "tex.y.wrapped"); lp_build_name(y, "tex.y.wrapped");
lp_build_sample_texel_soa(bld, width, height, x, y, stride, data_array, texel); /* get pointer to mipmap level 0 data */
data_ptr = lp_build_get_const_mipmap_level(bld, data_array, 0);
lp_build_sample_texel_soa(bld, width, height, x, y, stride, data_ptr, texel);
}
/**
* Sample 2D texture with nearest filtering, nearest mipmap.
*/
static void
lp_build_sample_2d_nearest_mip_nearest_soa(struct lp_build_sample_context *bld,
unsigned unit,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef width_vec,
LLVMValueRef height_vec,
LLVMValueRef stride,
LLVMValueRef data_array,
LLVMValueRef *texel)
{
LLVMValueRef x, y;
LLVMValueRef lod, ilevel, ilevel_vec;
LLVMValueRef data_ptr;
/* compute float LOD */
lod = lp_build_lod_selector(bld, s, t, NULL, width, height, NULL);
/* convert LOD to int */
lp_build_nearest_mip_level(bld, unit, lod, &ilevel);
ilevel_vec = lp_build_broadcast_scalar(&bld->int_coord_bld, ilevel);
/* compute width_vec, height at mipmap level 'ilevel' */
width_vec = lp_build_minify(bld, width_vec, ilevel_vec);
height_vec = lp_build_minify(bld, height_vec, ilevel_vec);
stride = lp_build_minify(bld, stride, ilevel_vec);
x = lp_build_sample_wrap_nearest(bld, s, width_vec,
bld->static_state->pot_width,
bld->static_state->wrap_s);
y = lp_build_sample_wrap_nearest(bld, t, height_vec,
bld->static_state->pot_height,
bld->static_state->wrap_t);
lp_build_name(x, "tex.x.wrapped");
lp_build_name(y, "tex.y.wrapped");
/* get pointer to mipmap level [ilevel] data */
if (0)
data_ptr = lp_build_get_mipmap_level(bld, data_array, ilevel);
else
data_ptr = lp_build_get_const_mipmap_level(bld, data_array, 0);
lp_build_sample_texel_soa(bld, width_vec, height_vec, x, y, stride, data_ptr, texel);
} }
@ -779,6 +1048,7 @@ lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
LLVMValueRef x0, x1; LLVMValueRef x0, x1;
LLVMValueRef y0, y1; LLVMValueRef y0, y1;
LLVMValueRef neighbors[2][2][4]; LLVMValueRef neighbors[2][2][4];
LLVMValueRef data_ptr;
unsigned chan; unsigned chan;
lp_build_sample_wrap_linear(bld, s, width, bld->static_state->pot_width, lp_build_sample_wrap_linear(bld, s, width, bld->static_state->pot_width,
@ -786,10 +1056,13 @@ lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
lp_build_sample_wrap_linear(bld, t, height, bld->static_state->pot_height, lp_build_sample_wrap_linear(bld, t, height, bld->static_state->pot_height,
bld->static_state->wrap_t, &y0, &y1, &t_fpart); bld->static_state->wrap_t, &y0, &y1, &t_fpart);
lp_build_sample_texel_soa(bld, width, height, x0, y0, stride, data_array, neighbors[0][0]); /* get pointer to mipmap level 0 data */
lp_build_sample_texel_soa(bld, width, height, x1, y0, stride, data_array, neighbors[0][1]); data_ptr = lp_build_get_const_mipmap_level(bld, data_array, 0);
lp_build_sample_texel_soa(bld, width, height, x0, y1, stride, data_array, neighbors[1][0]);
lp_build_sample_texel_soa(bld, width, height, x1, y1, stride, data_array, neighbors[1][1]); lp_build_sample_texel_soa(bld, width, height, x0, y0, stride, data_ptr, neighbors[0][0]);
lp_build_sample_texel_soa(bld, width, height, x1, y0, stride, data_ptr, neighbors[0][1]);
lp_build_sample_texel_soa(bld, width, height, x0, y1, stride, data_ptr, neighbors[1][0]);
lp_build_sample_texel_soa(bld, width, height, x1, y1, stride, data_ptr, neighbors[1][1]);
/* TODO: Don't interpolate missing channels */ /* TODO: Don't interpolate missing channels */
for(chan = 0; chan < 4; ++chan) { for(chan = 0; chan < 4; ++chan) {
@ -857,7 +1130,7 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
LLVMValueRef packed, packed_lo, packed_hi; LLVMValueRef packed, packed_lo, packed_hi;
LLVMValueRef unswizzled[4]; LLVMValueRef unswizzled[4];
lp_build_context_init(&i32, builder, lp_type_int(32)); lp_build_context_init(&i32, builder, lp_type_int_vec(32));
lp_build_context_init(&h16, builder, lp_type_ufixed(16)); lp_build_context_init(&h16, builder, lp_type_ufixed(16));
lp_build_context_init(&u8n, builder, lp_type_unorm(8)); lp_build_context_init(&u8n, builder, lp_type_unorm(8));
@ -1066,194 +1339,11 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
} }
static int
texture_dims(enum pipe_texture_target tex)
{
switch (tex) {
case PIPE_TEXTURE_1D:
return 1;
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_CUBE:
return 2;
case PIPE_TEXTURE_3D:
return 3;
default:
assert(0 && "bad texture target in texture_dims()");
return 2;
}
}
/**
* Generate code to compute texture level of detail (lambda).
* \param s vector of texcoord s values
* \param t vector of texcoord t values
* \param r vector of texcoord r values
* \param width scalar int texture width
* \param height scalar int texture height
* \param depth scalar int texture depth
*/
static LLVMValueRef
lp_build_lod_selector(struct lp_build_sample_context *bld,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef depth)
{
const int dims = texture_dims(bld->static_state->target);
struct lp_build_context *coord_bld = &bld->coord_bld;
LLVMValueRef lod_bias = lp_build_const_scalar(bld->coord_bld.type,
bld->static_state->lod_bias);
LLVMValueRef min_lod = lp_build_const_scalar(bld->coord_bld.type,
bld->static_state->min_lod);
LLVMValueRef max_lod = lp_build_const_scalar(bld->coord_bld.type,
bld->static_state->max_lod);
LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
LLVMValueRef s0, s1, s2;
LLVMValueRef t0, t1, t2;
LLVMValueRef r0, r1, r2;
LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
LLVMValueRef rho, lod;
/*
* dsdx = abs(s[1] - s[0]);
* dsdy = abs(s[2] - s[0]);
* dtdx = abs(t[1] - t[0]);
* dtdy = abs(t[2] - t[0]);
* drdx = abs(r[1] - r[0]);
* drdy = abs(r[2] - r[0]);
* XXX we're assuming a four-element quad in 2x2 layout here.
*/
s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
dsdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, s1, s0));
dsdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, s2, s0));
if (dims > 1) {
t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
dtdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, t1, t0));
dtdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, t2, t0));
if (dims > 2) {
r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
drdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, r1, r0));
drdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, r2, r0));
}
}
/* Compute rho = max of all partial derivatives scaled by texture size.
* XXX this can be vectorized somewhat
*/
rho = lp_build_mul(coord_bld,
lp_build_max(coord_bld, dsdx, dsdy),
lp_build_int_to_float(coord_bld, width));
if (dims > 1) {
LLVMValueRef max;
max = lp_build_mul(coord_bld,
lp_build_max(coord_bld, dtdx, dtdy),
lp_build_int_to_float(coord_bld, height));
rho = lp_build_max(coord_bld, rho, max);
if (dims > 2) {
max = lp_build_mul(coord_bld,
lp_build_max(coord_bld, drdx, drdy),
lp_build_int_to_float(coord_bld, depth));
rho = lp_build_max(coord_bld, rho, max);
}
}
/* compute lod = log2(rho) */
lod = lp_build_log2(coord_bld, rho);
/* add lod bias */
lod = lp_build_add(coord_bld, lod, lod_bias);
/* clamp lod */
lod = lp_build_clamp(coord_bld, lod, min_lod, max_lod);
return lod;
}
/**
* For PIPE_TEX_MIPFILTER_NEAREST, convert float LOD to integer
* mipmap level index.
* \param lod scalar float texture level of detail
* \param level_out returns integer
*/
static void
lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
unsigned unit,
LLVMValueRef lod,
LLVMValueRef *level_out)
{
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef last_level, level;
last_level = bld->dynamic_state->last_level(bld->dynamic_state,
bld->builder, unit);
/* convert float lod to integer */
level = lp_build_iround(coord_bld, lod);
/* clamp level to legal range of levels */
*level_out = lp_build_clamp(int_coord_bld, level,
int_coord_bld->zero,
last_level);
}
/**
* For PIPE_TEX_MIPFILTER_LINEAR, convert float LOD to integer to
* two (adjacent) mipmap level indexes. Later, we'll sample from those
* two mipmap levels and interpolate between them.
*/
static void
lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
unsigned unit,
LLVMValueRef lod,
LLVMValueRef *level0_out,
LLVMValueRef *level1_out,
LLVMValueRef *weight_out)
{
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef last_level, level;
last_level = bld->dynamic_state->last_level(bld->dynamic_state,
bld->builder, unit);
/* convert float lod to integer */
level = lp_build_ifloor(coord_bld, lod);
/* compute level 0 and clamp to legal range of levels */
*level0_out = lp_build_clamp(int_coord_bld, level,
int_coord_bld->zero,
last_level);
/* compute level 1 and clamp to legal range of levels */
*level1_out = lp_build_add(int_coord_bld, *level0_out, int_coord_bld->one);
*level1_out = lp_build_min(int_coord_bld, *level1_out, int_coord_bld->zero);
*weight_out = lp_build_fract(coord_bld, lod);
}
/** /**
* Build texture sampling code. * Build texture sampling code.
* 'texel' will return a vector of four LLVMValueRefs corresponding to * 'texel' will return a vector of four LLVMValueRefs corresponding to
* R, G, B, A. * R, G, B, A.
* \param type vector float type to use for coords, etc.
*/ */
void void
lp_build_sample_soa(LLVMBuilderRef builder, lp_build_sample_soa(LLVMBuilderRef builder,
@ -1267,17 +1357,19 @@ lp_build_sample_soa(LLVMBuilderRef builder,
LLVMValueRef *texel) LLVMValueRef *texel)
{ {
struct lp_build_sample_context bld; struct lp_build_sample_context bld;
LLVMValueRef width; LLVMValueRef width, width_vec;
LLVMValueRef height; LLVMValueRef height, height_vec;
LLVMValueRef stride; LLVMValueRef stride, stride_vec;
LLVMValueRef data_array; LLVMValueRef data_array;
LLVMValueRef s; LLVMValueRef s;
LLVMValueRef t; LLVMValueRef t;
LLVMValueRef r; LLVMValueRef r;
boolean done = FALSE;
(void) lp_build_lod_selector; /* temporary to silence warning */ (void) lp_build_lod_selector; /* temporary to silence warning */
(void) lp_build_nearest_mip_level; (void) lp_build_nearest_mip_level;
(void) lp_build_linear_mip_levels; (void) lp_build_linear_mip_levels;
(void) lp_build_minify;
/* Setup our build context */ /* Setup our build context */
memset(&bld, 0, sizeof bld); memset(&bld, 0, sizeof bld);
@ -1285,10 +1377,16 @@ lp_build_sample_soa(LLVMBuilderRef builder,
bld.static_state = static_state; bld.static_state = static_state;
bld.dynamic_state = dynamic_state; bld.dynamic_state = dynamic_state;
bld.format_desc = util_format_description(static_state->format); bld.format_desc = util_format_description(static_state->format);
bld.float_type = lp_type_float(32);
bld.int_type = lp_type_int(32);
bld.coord_type = type; bld.coord_type = type;
bld.uint_coord_type = lp_uint_type(type); bld.uint_coord_type = lp_uint_type(type);
bld.int_coord_type = lp_int_type(type); bld.int_coord_type = lp_int_type(type);
bld.texel_type = type; bld.texel_type = type;
lp_build_context_init(&bld.float_bld, builder, bld.float_type);
lp_build_context_init(&bld.int_bld, builder, bld.int_type);
lp_build_context_init(&bld.coord_bld, builder, bld.coord_type); lp_build_context_init(&bld.coord_bld, builder, bld.coord_type);
lp_build_context_init(&bld.uint_coord_bld, builder, bld.uint_coord_type); lp_build_context_init(&bld.uint_coord_bld, builder, bld.uint_coord_type);
lp_build_context_init(&bld.int_coord_bld, builder, bld.int_coord_type); lp_build_context_init(&bld.int_coord_bld, builder, bld.int_coord_type);
@ -1305,30 +1403,56 @@ lp_build_sample_soa(LLVMBuilderRef builder,
t = coords[1]; t = coords[1];
r = coords[2]; r = coords[2];
width = lp_build_broadcast_scalar(&bld.uint_coord_bld, width); width_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, width);
height = lp_build_broadcast_scalar(&bld.uint_coord_bld, height); height_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, height);
stride = lp_build_broadcast_scalar(&bld.uint_coord_bld, stride); stride_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, stride);
if(static_state->target == PIPE_TEXTURE_1D) if(static_state->target == PIPE_TEXTURE_1D)
t = bld.coord_bld.zero; t = bld.coord_bld.zero;
switch (static_state->min_img_filter) { switch (static_state->min_mip_filter) {
case PIPE_TEX_FILTER_NEAREST: case PIPE_TEX_MIPFILTER_NONE:
lp_build_sample_2d_nearest_soa(&bld, s, t, width, height,
stride, data_array, texel);
break; break;
case PIPE_TEX_FILTER_LINEAR: case PIPE_TEX_MIPFILTER_NEAREST:
if(lp_format_is_rgba8(bld.format_desc) &&
is_simple_wrap_mode(static_state->wrap_s) && switch (static_state->min_img_filter) {
is_simple_wrap_mode(static_state->wrap_t)) case PIPE_TEX_FILTER_NEAREST:
lp_build_sample_2d_linear_aos(&bld, s, t, width, height, lp_build_sample_2d_nearest_mip_nearest_soa(&bld, unit,
stride, data_array, texel); s, t,
else width, height,
lp_build_sample_2d_linear_soa(&bld, s, t, width, height, width_vec, height_vec,
stride, data_array, texel); stride_vec,
data_array, texel);
done = TRUE;
break;
}
break;
case PIPE_TEX_MIPFILTER_LINEAR:
break; break;
default: default:
assert(0); assert(0 && "invalid mip filter");
}
if (!done) {
switch (static_state->min_img_filter) {
case PIPE_TEX_FILTER_NEAREST:
lp_build_sample_2d_nearest_soa(&bld, s, t, width_vec, height_vec,
stride_vec, data_array, texel);
break;
case PIPE_TEX_FILTER_LINEAR:
if(lp_format_is_rgba8(bld.format_desc) &&
is_simple_wrap_mode(static_state->wrap_s) &&
is_simple_wrap_mode(static_state->wrap_t))
lp_build_sample_2d_linear_aos(&bld, s, t, width_vec, height_vec,
stride_vec, data_array, texel);
else
lp_build_sample_2d_linear_soa(&bld, s, t, width_vec, height_vec,
stride_vec, data_array, texel);
break;
default:
assert(0);
}
} }
/* FIXME: respect static_state->min_mip_filter */; /* FIXME: respect static_state->min_mip_filter */;

View File

@ -103,7 +103,7 @@ struct lp_type {
unsigned width:14; unsigned width:14;
/** /**
* Vector length. * Vector length. If length==1, this is a scalar (float/int) type.
* *
* width*length should be a power of two greater or equal to eight. * width*length should be a power of two greater or equal to eight.
* *
@ -139,11 +139,28 @@ struct lp_build_context
}; };
/** Create scalar float type */
static INLINE struct lp_type static INLINE struct lp_type
lp_type_float(unsigned width) lp_type_float(unsigned width)
{ {
struct lp_type res_type; struct lp_type res_type;
memset(&res_type, 0, sizeof res_type);
res_type.floating = TRUE;
res_type.sign = TRUE;
res_type.width = width;
res_type.length = 1;
return res_type;
}
/** Create vector of float type */
static INLINE struct lp_type
lp_type_float_vec(unsigned width)
{
struct lp_type res_type;
memset(&res_type, 0, sizeof res_type); memset(&res_type, 0, sizeof res_type);
res_type.floating = TRUE; res_type.floating = TRUE;
res_type.sign = TRUE; res_type.sign = TRUE;
@ -154,11 +171,27 @@ lp_type_float(unsigned width)
} }
/** Create scalar int type */
static INLINE struct lp_type static INLINE struct lp_type
lp_type_int(unsigned width) lp_type_int(unsigned width)
{ {
struct lp_type res_type; struct lp_type res_type;
memset(&res_type, 0, sizeof res_type);
res_type.sign = TRUE;
res_type.width = width;
res_type.length = 1;
return res_type;
}
/** Create vector int type */
static INLINE struct lp_type
lp_type_int_vec(unsigned width)
{
struct lp_type res_type;
memset(&res_type, 0, sizeof res_type); memset(&res_type, 0, sizeof res_type);
res_type.sign = TRUE; res_type.sign = TRUE;
res_type.width = width; res_type.width = width;
@ -168,11 +201,26 @@ lp_type_int(unsigned width)
} }
/** Create scalar uint type */
static INLINE struct lp_type static INLINE struct lp_type
lp_type_uint(unsigned width) lp_type_uint(unsigned width)
{ {
struct lp_type res_type; struct lp_type res_type;
memset(&res_type, 0, sizeof res_type);
res_type.width = width;
res_type.length = 1;
return res_type;
}
/** Create vector uint type */
static INLINE struct lp_type
lp_type_uint_vec(unsigned width)
{
struct lp_type res_type;
memset(&res_type, 0, sizeof res_type); memset(&res_type, 0, sizeof res_type);
res_type.width = width; res_type.width = width;
res_type.length = LP_NATIVE_VECTOR_WIDTH / width; res_type.length = LP_NATIVE_VECTOR_WIDTH / width;

View File

@ -63,6 +63,7 @@ struct blit_state
struct pipe_sampler_state sampler; struct pipe_sampler_state sampler;
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
struct pipe_clip_state clip; struct pipe_clip_state clip;
struct pipe_vertex_element velem[2];
void *vs; void *vs;
void *fs[TGSI_WRITEMASK_XYZW + 1]; void *fs[TGSI_WRITEMASK_XYZW + 1];
@ -114,6 +115,15 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
ctx->sampler.mag_img_filter = 0; /* set later */ ctx->sampler.mag_img_filter = 0; /* set later */
ctx->sampler.normalized_coords = 1; ctx->sampler.normalized_coords = 1;
/* vertex elements state */
memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2);
for (i = 0; i < 2; i++) {
ctx->velem[i].src_offset = i * 4 * sizeof(float);
ctx->velem[i].instance_divisor = 0;
ctx->velem[i].vertex_buffer_index = 0;
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
/* vertex shader - still required to provide the linkage between /* vertex shader - still required to provide the linkage between
* fragment shader input semantics and vertex_element/buffers. * fragment shader input semantics and vertex_element/buffers.
*/ */
@ -410,12 +420,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_save_fragment_shader(ctx->cso); cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso); cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso); cso_save_clip(ctx->cso);
cso_save_vertex_elements(ctx->cso);
/* set misc state we care about */ /* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend); cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip); cso_set_clip(ctx->cso, &ctx->clip);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
/* sampler */ /* sampler */
ctx->sampler.min_img_filter = filter; ctx->sampler.min_img_filter = filter;
@ -480,6 +492,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_fragment_shader(ctx->cso); cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso); cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
pipe_texture_reference(&tex, NULL); pipe_texture_reference(&tex, NULL);
} }
@ -564,12 +577,14 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_save_fragment_shader(ctx->cso); cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso); cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso); cso_save_clip(ctx->cso);
cso_save_vertex_elements(ctx->cso);
/* set misc state we care about */ /* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend); cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip); cso_set_clip(ctx->cso, &ctx->clip);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
/* sampler */ /* sampler */
ctx->sampler.min_img_filter = filter; ctx->sampler.min_img_filter = filter;
@ -628,4 +643,5 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_restore_fragment_shader(ctx->cso); cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso); cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
} }

View File

@ -88,6 +88,8 @@ struct blitter_context_priv
void *dsa_write_depth_keep_stencil; void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil; void *dsa_keep_depth_stencil;
void *velem_state;
/* Sampler state for clamping to a miplevel. */ /* Sampler state for clamping to a miplevel. */
void *sampler_state[PIPE_MAX_TEXTURE_LEVELS]; void *sampler_state[PIPE_MAX_TEXTURE_LEVELS];
@ -108,6 +110,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
struct pipe_depth_stencil_alpha_state dsa = { { 0 } }; struct pipe_depth_stencil_alpha_state dsa = { { 0 } };
struct pipe_rasterizer_state rs_state = { 0 }; struct pipe_rasterizer_state rs_state = { 0 };
struct pipe_sampler_state *sampler_state; struct pipe_sampler_state *sampler_state;
struct pipe_vertex_element velem[2];
unsigned i; unsigned i;
ctx = CALLOC_STRUCT(blitter_context_priv); ctx = CALLOC_STRUCT(blitter_context_priv);
@ -122,6 +125,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->blitter.saved_rs_state = INVALID_PTR; ctx->blitter.saved_rs_state = INVALID_PTR;
ctx->blitter.saved_fs = INVALID_PTR; ctx->blitter.saved_fs = INVALID_PTR;
ctx->blitter.saved_vs = INVALID_PTR; ctx->blitter.saved_vs = INVALID_PTR;
ctx->blitter.saved_velem_state = INVALID_PTR;
ctx->blitter.saved_fb_state.nr_cbufs = ~0; ctx->blitter.saved_fb_state.nr_cbufs = ~0;
ctx->blitter.saved_num_textures = ~0; ctx->blitter.saved_num_textures = ~0;
ctx->blitter.saved_num_sampler_states = ~0; ctx->blitter.saved_num_sampler_states = ~0;
@ -170,6 +174,16 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
rs_state.flatshade = 1; rs_state.flatshade = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
/* vertex elements state */
memset(&velem[0], 0, sizeof(velem[0]) * 2);
for (i = 0; i < 2; i++) {
velem[i].src_offset = i * 4 * sizeof(float);
velem[i].instance_divisor = 0;
velem[i].vertex_buffer_index = 0;
velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
/* fragment shaders are created on-demand */ /* fragment shaders are created on-demand */
/* vertex shaders */ /* vertex shaders */
@ -219,6 +233,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_rasterizer_state(pipe, ctx->rs_state); pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_vs_state(pipe, ctx->vs_col); pipe->delete_vs_state(pipe, ctx->vs_col);
pipe->delete_vs_state(pipe, ctx->vs_tex); pipe->delete_vs_state(pipe, ctx->vs_tex);
pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
if (ctx->fs_texfetch_col[i]) if (ctx->fs_texfetch_col[i])
@ -246,7 +261,8 @@ static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
ctx->blitter.saved_dsa_state != INVALID_PTR && ctx->blitter.saved_dsa_state != INVALID_PTR &&
ctx->blitter.saved_rs_state != INVALID_PTR && ctx->blitter.saved_rs_state != INVALID_PTR &&
ctx->blitter.saved_fs != INVALID_PTR && ctx->blitter.saved_fs != INVALID_PTR &&
ctx->blitter.saved_vs != INVALID_PTR); ctx->blitter.saved_vs != INVALID_PTR &&
ctx->blitter.saved_velem_state != INVALID_PTR);
} }
static void blitter_restore_CSOs(struct blitter_context_priv *ctx) static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
@ -259,12 +275,14 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
pipe->bind_rasterizer_state(pipe, ctx->blitter.saved_rs_state); pipe->bind_rasterizer_state(pipe, ctx->blitter.saved_rs_state);
pipe->bind_fs_state(pipe, ctx->blitter.saved_fs); pipe->bind_fs_state(pipe, ctx->blitter.saved_fs);
pipe->bind_vs_state(pipe, ctx->blitter.saved_vs); pipe->bind_vs_state(pipe, ctx->blitter.saved_vs);
pipe->bind_vertex_elements_state(pipe, ctx->blitter.saved_velem_state);
ctx->blitter.saved_blend_state = INVALID_PTR; ctx->blitter.saved_blend_state = INVALID_PTR;
ctx->blitter.saved_dsa_state = INVALID_PTR; ctx->blitter.saved_dsa_state = INVALID_PTR;
ctx->blitter.saved_rs_state = INVALID_PTR; ctx->blitter.saved_rs_state = INVALID_PTR;
ctx->blitter.saved_fs = INVALID_PTR; ctx->blitter.saved_fs = INVALID_PTR;
ctx->blitter.saved_vs = INVALID_PTR; ctx->blitter.saved_vs = INVALID_PTR;
ctx->blitter.saved_velem_state = INVALID_PTR;
pipe->set_stencil_ref(pipe, &ctx->blitter.saved_stencil_ref); pipe->set_stencil_ref(pipe, &ctx->blitter.saved_stencil_ref);
@ -569,6 +587,7 @@ void util_blitter_clear(struct blitter_context *blitter,
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state); pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs)); pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
pipe->bind_vs_state(pipe, ctx->vs_col); pipe->bind_vs_state(pipe, ctx->vs_col);
@ -634,6 +653,7 @@ static void util_blitter_do_copy(struct blitter_context *blitter,
pipe->bind_vs_state(pipe, ctx->vs_tex); pipe->bind_vs_state(pipe, ctx->vs_tex);
pipe->bind_fragment_sampler_states(pipe, 1, pipe->bind_fragment_sampler_states(pipe, 1,
blitter_get_sampler_state(ctx, src->level)); blitter_get_sampler_state(ctx, src->level));
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
pipe->set_fragment_sampler_textures(pipe, 1, &src->texture); pipe->set_fragment_sampler_textures(pipe, 1, &src->texture);
pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_framebuffer_state(pipe, &fb_state);
@ -807,6 +827,7 @@ void util_blitter_fill(struct blitter_context *blitter,
pipe->bind_rasterizer_state(pipe, ctx->rs_state); pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1)); pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1));
pipe->bind_vs_state(pipe, ctx->vs_col); pipe->bind_vs_state(pipe, ctx->vs_col);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
/* set a framebuffer state */ /* set a framebuffer state */
fb_state.width = dst->width; fb_state.width = dst->width;

View File

@ -43,6 +43,7 @@ struct blitter_context
/* Private members, really. */ /* Private members, really. */
void *saved_blend_state; /**< blend state */ void *saved_blend_state; /**< blend state */
void *saved_dsa_state; /**< depth stencil alpha state */ void *saved_dsa_state; /**< depth stencil alpha state */
void *saved_velem_state; /**< vertex elements state */
void *saved_rs_state; /**< rasterizer state */ void *saved_rs_state; /**< rasterizer state */
void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */ void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */
@ -172,6 +173,13 @@ void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
blitter->saved_dsa_state = state; blitter->saved_dsa_state = state;
} }
static INLINE
void util_blitter_save_vertex_elements(struct blitter_context *blitter,
void *state)
{
blitter->saved_velem_state = state;
}
static INLINE static INLINE
void util_blitter_save_stencil_ref(struct blitter_context *blitter, void util_blitter_save_stencil_ref(struct blitter_context *blitter,
const struct pipe_stencil_ref *state) const struct pipe_stencil_ref *state)

View File

@ -45,8 +45,6 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
uint num_attribs) uint num_attribs)
{ {
struct pipe_vertex_buffer vbuffer; struct pipe_vertex_buffer vbuffer;
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
uint i;
assert(num_attribs <= PIPE_MAX_ATTRIBS); assert(num_attribs <= PIPE_MAX_ATTRIBS);
@ -58,15 +56,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
vbuffer.max_index = num_verts - 1; vbuffer.max_index = num_verts - 1;
pipe->set_vertex_buffers(pipe, 1, &vbuffer); pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */ /* note: vertex elements already set by caller */
for (i = 0; i < num_attribs; i++) {
velements[i].src_offset = i * 4 * sizeof(float);
velements[i].instance_divisor = 0;
velements[i].vertex_buffer_index = 0;
velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
velements[i].nr_components = 4;
}
pipe->set_vertex_elements(pipe, num_attribs, velements);
/* draw */ /* draw */
pipe->draw_arrays(pipe, prim_type, 0, num_verts); pipe->draw_arrays(pipe, prim_type, 0, num_verts);

View File

@ -700,7 +700,6 @@ util_dump_vertex_element(struct os_stream *stream, const struct pipe_vertex_elem
util_dump_member(stream, uint, state, src_offset); util_dump_member(stream, uint, state, src_offset);
util_dump_member(stream, uint, state, vertex_buffer_index); util_dump_member(stream, uint, state, vertex_buffer_index);
util_dump_member(stream, uint, state, nr_components);
util_dump_member(stream, format, state, src_format); util_dump_member(stream, format, state, src_format);

View File

@ -415,6 +415,16 @@ util_format_has_alpha(enum pipe_format format)
} }
} }
/**
* Return the number of components stored.
* Formats with block size != 1x1 will always have 1 component (the block).
*/
static INLINE unsigned
util_format_get_nr_components(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
return desc->nr_channels;
}
/* /*
* Format access functions. * Format access functions.

View File

@ -418,31 +418,70 @@ def generate_format_pack(format, src_channel, src_native_type, src_suffix):
dst_native_type = native_type(format) dst_native_type = native_type(format)
print 'static INLINE void'
print 'util_format_%s_pack_%s(void *dst, %s r, %s g, %s b, %s a)' % (name, src_suffix, src_native_type, src_native_type, src_native_type, src_native_type)
print '{'
print ' union util_format_%s pixel;' % format.short_name()
assert format.layout == PLAIN assert format.layout == PLAIN
inv_swizzle = format.inv_swizzles() inv_swizzle = format.inv_swizzles()
for i in range(4): print 'static INLINE void'
dst_channel = format.channels[i] print 'util_format_%s_pack_%s(void *dst, %s r, %s g, %s b, %s a)' % (name, src_suffix, src_native_type, src_native_type, src_native_type, src_native_type)
width = dst_channel.size print '{'
if inv_swizzle[i] is None:
continue if format.is_bitmask():
value = 'rgba'[inv_swizzle[i]] depth = format.block_size()
value = conversion_expr(src_channel, dst_channel, dst_native_type, value) print ' uint%u_t value = 0;' % depth
if format.colorspace == ZS:
if i == 3: shift = 0
value = get_one(dst_channel) for i in range(4):
elif i >= 1: dst_channel = format.channels[i]
value = '0' if inv_swizzle[i] is not None:
print ' pixel.chan.%s = %s;' % (dst_channel.name, value) value = 'rgba'[inv_swizzle[i]]
value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
if format.colorspace == ZS:
if i == 3:
value = get_one(dst_channel)
elif i >= 1:
value = '0'
if dst_channel.type in (UNSIGNED, SIGNED):
if shift + dst_channel.size < depth:
value = '(%s) & 0x%x' % (value, (1 << dst_channel.size) - 1)
if shift:
value = '(%s) << %u' % (value, shift)
if dst_channel.type == SIGNED:
# Cast to unsigned
value = '(uint%u_t)(%s) ' % (depth, value)
else:
value = None
if value is not None:
print ' value |= %s;' % (value)
shift += dst_channel.size
print '#ifdef PIPE_ARCH_BIG_ENDIAN'
print ' value = util_bswap%u(value);' % depth
print '#endif'
print ' *(uint%u_t *)dst = value;' % depth
else:
print ' union util_format_%s pixel;' % format.short_name()
for i in range(4):
dst_channel = format.channels[i]
width = dst_channel.size
if inv_swizzle[i] is None:
continue
value = 'rgba'[inv_swizzle[i]]
value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
if format.colorspace == ZS:
if i == 3:
value = get_one(dst_channel)
elif i >= 1:
value = '0'
print ' pixel.chan.%s = %s;' % (dst_channel.name, value)
bswap_format(format)
print ' memcpy(dst, &pixel, sizeof pixel);'
bswap_format(format)
print ' memcpy(dst, &pixel, sizeof pixel);'
print '}' print '}'
print print

View File

@ -62,6 +62,7 @@ struct gen_mipmap_state
struct pipe_rasterizer_state rasterizer; struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler; struct pipe_sampler_state sampler;
struct pipe_clip_state clip; struct pipe_clip_state clip;
struct pipe_vertex_element velem[2];
void *vs; void *vs;
void *fs2d, *fsCube; void *fs2d, *fsCube;
@ -1307,6 +1308,15 @@ util_create_gen_mipmap(struct pipe_context *pipe,
ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
ctx->sampler.normalized_coords = 1; ctx->sampler.normalized_coords = 1;
/* vertex elements state */
memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2);
for (i = 0; i < 2; i++) {
ctx->velem[i].src_offset = i * 4 * sizeof(float);
ctx->velem[i].instance_divisor = 0;
ctx->velem[i].vertex_buffer_index = 0;
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
/* vertex shader - still needed to specify mapping from fragment /* vertex shader - still needed to specify mapping from fragment
* shader input semantics to vertex elements * shader input semantics to vertex elements
*/ */
@ -1501,12 +1511,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_save_vertex_shader(ctx->cso); cso_save_vertex_shader(ctx->cso);
cso_save_viewport(ctx->cso); cso_save_viewport(ctx->cso);
cso_save_clip(ctx->cso); cso_save_clip(ctx->cso);
cso_save_vertex_elements(ctx->cso);
/* bind our state */ /* bind our state */
cso_set_blend(ctx->cso, &ctx->blend); cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip); cso_set_clip(ctx->cso, &ctx->clip);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
cso_set_fragment_shader_handle(ctx->cso, fs); cso_set_fragment_shader_handle(ctx->cso, fs);
cso_set_vertex_shader_handle(ctx->cso, ctx->vs); cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
@ -1593,4 +1605,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_restore_vertex_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso);
cso_restore_viewport(ctx->cso); cso_restore_viewport(ctx->cso);
cso_restore_clip(ctx->cso); cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
} }

View File

@ -230,6 +230,7 @@ static bool
init_pipe_state(struct vl_compositor *c) init_pipe_state(struct vl_compositor *c)
{ {
struct pipe_sampler_state sampler; struct pipe_sampler_state sampler;
struct pipe_vertex_element vertex_elems[2];
assert(c); assert(c);
@ -252,6 +253,17 @@ init_pipe_state(struct vl_compositor *c)
/*sampler.max_anisotropy = ;*/ /*sampler.max_anisotropy = ;*/
c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler); c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler);
vertex_elems[0].src_offset = 0;
vertex_elems[0].instance_divisor = 0;
vertex_elems[0].vertex_buffer_index = 0;
vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
vertex_elems[1].src_offset = 0;
vertex_elems[1].instance_divisor = 0;
vertex_elems[1].vertex_buffer_index = 1;
vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
c->vertex_elems = c->pipe->create_vertex_elements_state(c->pipe, 2, vertex_elems);
return true; return true;
} }
@ -260,6 +272,7 @@ static void cleanup_pipe_state(struct vl_compositor *c)
assert(c); assert(c);
c->pipe->delete_sampler_state(c->pipe, c->sampler); c->pipe->delete_sampler_state(c->pipe, c->sampler);
c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems);
} }
static bool static bool
@ -314,12 +327,6 @@ init_buffers(struct vl_compositor *c)
pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[0].buffer); pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[0].buffer);
c->vertex_elems[0].src_offset = 0;
c->vertex_elems[0].instance_divisor = 0;
c->vertex_elems[0].vertex_buffer_index = 0;
c->vertex_elems[0].nr_components = 2;
c->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* /*
* Create our texcoord buffer and texcoord buffer element * Create our texcoord buffer and texcoord buffer element
* Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices * Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices
@ -344,12 +351,6 @@ init_buffers(struct vl_compositor *c)
pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[1].buffer); pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[1].buffer);
c->vertex_elems[1].src_offset = 0;
c->vertex_elems[1].instance_divisor = 0;
c->vertex_elems[1].vertex_buffer_index = 1;
c->vertex_elems[1].nr_components = 2;
c->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* /*
* Create our vertex shader's constant buffer * Create our vertex shader's constant buffer
* Const buffer contains scaling and translation vectors * Const buffer contains scaling and translation vectors
@ -483,7 +484,7 @@ void vl_compositor_render(struct vl_compositor *compositor,
compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader); compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader); compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader);
compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs); compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs);
compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems); compositor->pipe->bind_vertex_elements_state(compositor->pipe, compositor->vertex_elems);
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, compositor->vs_const_buf); compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, compositor->vs_const_buf);
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf); compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf);

View File

@ -43,10 +43,10 @@ struct vl_compositor
void *sampler; void *sampler;
void *vertex_shader; void *vertex_shader;
void *fragment_shader; void *fragment_shader;
void *vertex_elems;
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
struct pipe_scissor_state scissor; struct pipe_scissor_state scissor;
struct pipe_vertex_buffer vertex_bufs[2]; struct pipe_vertex_buffer vertex_bufs[2];
struct pipe_vertex_element vertex_elems[2];
struct pipe_buffer *vs_const_buf, *fs_const_buf; struct pipe_buffer *vs_const_buf, *fs_const_buf;
}; };

View File

@ -708,6 +708,7 @@ static bool
init_pipe_state(struct vl_mpeg12_mc_renderer *r) init_pipe_state(struct vl_mpeg12_mc_renderer *r)
{ {
struct pipe_sampler_state sampler; struct pipe_sampler_state sampler;
struct pipe_vertex_element vertex_elems[8];
unsigned filters[5]; unsigned filters[5];
unsigned i; unsigned i;
@ -771,6 +772,59 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r)
r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler); r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler);
} }
/* Position element */
vertex_elems[0].src_offset = 0;
vertex_elems[0].instance_divisor = 0;
vertex_elems[0].vertex_buffer_index = 0;
vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Luma, texcoord element */
vertex_elems[1].src_offset = sizeof(struct vertex2f);
vertex_elems[1].instance_divisor = 0;
vertex_elems[1].vertex_buffer_index = 0;
vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Chroma Cr texcoord element */
vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
vertex_elems[2].instance_divisor = 0;
vertex_elems[2].vertex_buffer_index = 0;
vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Chroma Cb texcoord element */
vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
vertex_elems[3].instance_divisor = 0;
vertex_elems[3].vertex_buffer_index = 0;
vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* First ref surface top field texcoord element */
vertex_elems[4].src_offset = 0;
vertex_elems[4].instance_divisor = 0;
vertex_elems[4].vertex_buffer_index = 1;
vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* First ref surface bottom field texcoord element */
vertex_elems[5].src_offset = sizeof(struct vertex2f);
vertex_elems[5].instance_divisor = 0;
vertex_elems[5].vertex_buffer_index = 1;
vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Second ref surface top field texcoord element */
vertex_elems[6].src_offset = 0;
vertex_elems[6].instance_divisor = 0;
vertex_elems[6].vertex_buffer_index = 2;
vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Second ref surface bottom field texcoord element */
vertex_elems[7].src_offset = sizeof(struct vertex2f);
vertex_elems[7].instance_divisor = 0;
vertex_elems[7].vertex_buffer_index = 2;
vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* need versions with 4,6 and 8 vertex elems */
r->vertex_elems[0] = r->pipe->create_vertex_elements_state(r->pipe, 4, vertex_elems);
r->vertex_elems[1] = r->pipe->create_vertex_elements_state(r->pipe, 6, vertex_elems);
r->vertex_elems[2] = r->pipe->create_vertex_elements_state(r->pipe, 8, vertex_elems);
return true; return true;
} }
@ -783,6 +837,8 @@ cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r)
for (i = 0; i < 5; ++i) for (i = 0; i < 5; ++i)
r->pipe->delete_sampler_state(r->pipe, r->samplers.all[i]); r->pipe->delete_sampler_state(r->pipe, r->samplers.all[i]);
for (i = 0; i < 3; i++)
r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems[i]);
} }
static bool static bool
@ -888,62 +944,6 @@ init_buffers(struct vl_mpeg12_mc_renderer *r)
); );
} }
/* Position element */
r->vertex_elems[0].src_offset = 0;
r->vertex_elems[0].instance_divisor = 0;
r->vertex_elems[0].vertex_buffer_index = 0;
r->vertex_elems[0].nr_components = 2;
r->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Luma, texcoord element */
r->vertex_elems[1].src_offset = sizeof(struct vertex2f);
r->vertex_elems[1].instance_divisor = 0;
r->vertex_elems[1].vertex_buffer_index = 0;
r->vertex_elems[1].nr_components = 2;
r->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Chroma Cr texcoord element */
r->vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
r->vertex_elems[2].instance_divisor = 0;
r->vertex_elems[2].vertex_buffer_index = 0;
r->vertex_elems[2].nr_components = 2;
r->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Chroma Cb texcoord element */
r->vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
r->vertex_elems[3].instance_divisor = 0;
r->vertex_elems[3].vertex_buffer_index = 0;
r->vertex_elems[3].nr_components = 2;
r->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* First ref surface top field texcoord element */
r->vertex_elems[4].src_offset = 0;
r->vertex_elems[4].instance_divisor = 0;
r->vertex_elems[4].vertex_buffer_index = 1;
r->vertex_elems[4].nr_components = 2;
r->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* First ref surface bottom field texcoord element */
r->vertex_elems[5].src_offset = sizeof(struct vertex2f);
r->vertex_elems[5].instance_divisor = 0;
r->vertex_elems[5].vertex_buffer_index = 1;
r->vertex_elems[5].nr_components = 2;
r->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Second ref surface top field texcoord element */
r->vertex_elems[6].src_offset = 0;
r->vertex_elems[6].instance_divisor = 0;
r->vertex_elems[6].vertex_buffer_index = 2;
r->vertex_elems[6].nr_components = 2;
r->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
/* Second ref surface bottom field texcoord element */
r->vertex_elems[7].src_offset = sizeof(struct vertex2f);
r->vertex_elems[7].instance_divisor = 0;
r->vertex_elems[7].vertex_buffer_index = 2;
r->vertex_elems[7].nr_components = 2;
r->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
r->vs_const_buf = pipe_buffer_create r->vs_const_buf = pipe_buffer_create
( (
r->pipe->screen, r->pipe->screen,
@ -1307,7 +1307,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) { if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all); r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all);
r->pipe->set_vertex_elements(r->pipe, 4, r->vertex_elems); r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[0]);
r->pipe->set_fragment_sampler_textures(r->pipe, 3, r->textures.all); r->pipe->set_fragment_sampler_textures(r->pipe, 3, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 3, r->samplers.all); r->pipe->bind_fragment_sampler_states(r->pipe, 3, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->i_vs); r->pipe->bind_vs_state(r->pipe, r->i_vs);
@ -1320,7 +1320,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) { if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->past; r->textures.individual.ref[0] = r->past;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all); r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all); r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@ -1334,7 +1334,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) { if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->past; r->textures.individual.ref[0] = r->past;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all); r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all); r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@ -1348,7 +1348,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) { if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->future; r->textures.individual.ref[0] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all); r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all); r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@ -1362,7 +1362,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0 */ ) { if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->future; r->textures.individual.ref[0] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all); r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all); r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@ -1376,7 +1376,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) { if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all); r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems); r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[2]);
r->textures.individual.ref[0] = r->past; r->textures.individual.ref[0] = r->past;
r->textures.individual.ref[1] = r->future; r->textures.individual.ref[1] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all); r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
@ -1391,7 +1391,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) { if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all); r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems); r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[2]);
r->textures.individual.ref[0] = r->past; r->textures.individual.ref[0] = r->past;
r->textures.individual.ref[1] = r->future; r->textures.individual.ref[1] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all); r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);

View File

@ -66,7 +66,7 @@ struct vl_mpeg12_mc_renderer
struct pipe_buffer *vs_const_buf; struct pipe_buffer *vs_const_buf;
struct pipe_buffer *fs_const_buf; struct pipe_buffer *fs_const_buf;
struct pipe_framebuffer_state fb_state; struct pipe_framebuffer_state fb_state;
struct pipe_vertex_element vertex_elems[8]; void *vertex_elems[3];
union union
{ {

View File

@ -24,6 +24,7 @@ CSO objects handled by the context object:
* :ref:`Depth, Stencil, & Alpha`: ``*_depth_stencil_alpha_state`` * :ref:`Depth, Stencil, & Alpha`: ``*_depth_stencil_alpha_state``
* :ref:`Shader`: These have two sets of methods. ``*_fs_state`` is for * :ref:`Shader`: These have two sets of methods. ``*_fs_state`` is for
fragment shaders, and ``*_vs_state`` is for vertex shaders. fragment shaders, and ``*_vs_state`` is for vertex shaders.
* :ref:`Vertex Elements`: ``*_vertex_elements_state``
Resource Binding State Resource Binding State
@ -60,7 +61,6 @@ objects. They all follow simple, one-method binding calls, e.g.
not have the scissor test enabled, then the scissor bounds never need to not have the scissor test enabled, then the scissor bounds never need to
be set since they will not be used. be set since they will not be used.
* ``set_viewport_state`` * ``set_viewport_state``
* ``set_vertex_elements``
Clearing Clearing

View File

@ -0,0 +1,24 @@
.. _vertex,elements
Vertex Elements
===============
This state controls format etc. of the input attributes contained
in the pipe_vertex_buffer(s). There's one pipe_vertex_element array member
for each input attribute.
Members
-------
src_offset
The byte offset of the attribute in the buffer given by
vertex_buffer_index for the first vertex.
instance_divisor
The instance data rate divisor, used for instancing.
0 means this is per-vertex data, n means per-instance data used for
n consecutive instances (n > 0).
vertex_buffer_index
The vertex buffer this attribute lives in. Several attributes may
live in the same vertex buffer.
src_format
The format of the attribute data. One of the PIPE_FORMAT tokens.

View File

@ -93,6 +93,11 @@ struct cell_buffer_list
struct cell_buffer_node *head; struct cell_buffer_node *head;
}; };
struct cell_velems_state
{
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
}
/** /**
* Per-context state, subclass of pipe_context. * Per-context state, subclass of pipe_context.
@ -110,6 +115,7 @@ struct cell_context
const struct pipe_rasterizer_state *rasterizer; const struct pipe_rasterizer_state *rasterizer;
const struct cell_vertex_shader_state *vs; const struct cell_vertex_shader_state *vs;
const struct cell_fragment_shader_state *fs; const struct cell_fragment_shader_state *fs;
const struct cell_velems_state *velems;
struct spe_function logic_op; struct spe_function logic_op;
@ -125,8 +131,6 @@ struct cell_context
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers; uint num_vertex_buffers;
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
uint num_vertex_elements;
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS]; ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map; ubyte *zsbuf_map;

View File

@ -32,24 +32,43 @@
#include "cell_context.h" #include "cell_context.h"
#include "cell_state.h" #include "cell_state.h"
#include "util/u_memory.h"
#include "draw/draw_context.h" #include "draw/draw_context.h"
static void void *
cell_set_vertex_elements(struct pipe_context *pipe, cell_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count, unsigned count,
const struct pipe_vertex_element *elements) const struct pipe_vertex_element *attribs)
{
struct cell_velems_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
velems = (struct cell_velems_state *) MALLOC(sizeof(struct cell_velems_state));
if (velems) {
velems->count = count;
memcpy(velems->velem, attribs, sizeof(*attribs) * count);
}
return velems;
}
void
cell_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{ {
struct cell_context *cell = cell_context(pipe); struct cell_context *cell = cell_context(pipe);
struct cell_velems_state *cell_velems = (struct cell_velems_state *) velems;
assert(count <= PIPE_MAX_ATTRIBS); cell->velems = cell_velems;
memcpy(cell->vertex_element, elements, count * sizeof(elements[0]));
cell->num_vertex_elements = count;
cell->dirty |= CELL_NEW_VERTEX; cell->dirty |= CELL_NEW_VERTEX;
draw_set_vertex_elements(cell->draw, count, elements); draw_set_vertex_elements(cell->draw, cell_velems->count, cell_velems->velem);
}
void
cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
} }
@ -75,5 +94,7 @@ void
cell_init_vertex_functions(struct cell_context *cell) cell_init_vertex_functions(struct cell_context *cell)
{ {
cell->pipe.set_vertex_buffers = cell_set_vertex_buffers; cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
cell->pipe.set_vertex_elements = cell_set_vertex_elements; cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state;
cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state;
cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state;
} }

View File

@ -78,6 +78,7 @@ struct failover_context {
const struct fo_state *rasterizer; const struct fo_state *rasterizer;
const struct fo_state *fragment_shader; const struct fo_state *fragment_shader;
const struct fo_state *vertex_shader; const struct fo_state *vertex_shader;
const struct fo_state *vertex_elements;
struct pipe_blend_color blend_color; struct pipe_blend_color blend_color;
struct pipe_stencil_ref stencil_ref; struct pipe_stencil_ref stencil_ref;
@ -89,10 +90,8 @@ struct failover_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers; uint num_vertex_buffers;
uint num_vertex_elements;
void *sw_sampler_state[PIPE_MAX_SAMPLERS]; void *sw_sampler_state[PIPE_MAX_SAMPLERS];
void *hw_sampler_state[PIPE_MAX_SAMPLERS]; void *hw_sampler_state[PIPE_MAX_SAMPLERS];

View File

@ -255,9 +255,52 @@ failover_delete_vs_state(struct pipe_context *pipe,
free(state); free(state);
} }
static void *
failover_create_vertex_elements_state( struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *velems )
{
struct fo_state *state = malloc(sizeof(struct fo_state));
struct failover_context *failover = failover_context(pipe);
state->sw_state = failover->sw->create_vertex_elements_state(failover->sw, count, velems);
state->hw_state = failover->hw->create_vertex_elements_state(failover->hw, count, velems);
return state;
}
static void
failover_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems )
{
struct failover_context *failover = failover_context(pipe);
struct fo_state *state = (struct fo_state*)velems;
failover->vertex_elements = state;
failover->dirty |= FO_NEW_VERTEX_ELEMENT;
failover->sw->bind_vertex_elements_state( failover->sw, velems );
failover->hw->bind_vertex_elements_state( failover->hw, velems );
}
static void
failover_delete_vertex_elements_state( struct pipe_context *pipe,
void *velems )
{
struct fo_state *state = (struct fo_state*)velems;
struct failover_context *failover = failover_context(pipe);
failover->sw->delete_vertex_elements_state(failover->sw, state->sw_state);
failover->hw->delete_vertex_elements_state(failover->hw, state->hw_state);
state->sw_state = 0;
state->hw_state = 0;
free(state);
}
static void static void
failover_set_polygon_stipple( struct pipe_context *pipe, failover_set_polygon_stipple( struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple ) const struct pipe_poly_stipple *stipple )
{ {
struct failover_context *failover = failover_context(pipe); struct failover_context *failover = failover_context(pipe);
@ -490,22 +533,6 @@ failover_set_vertex_buffers(struct pipe_context *pipe,
} }
static void
failover_set_vertex_elements(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *vertex_elements)
{
struct failover_context *failover = failover_context(pipe);
memcpy(failover->vertex_elements, vertex_elements,
count * sizeof(vertex_elements[0]));
failover->dirty |= FO_NEW_VERTEX_ELEMENT;
failover->num_vertex_elements = count;
failover->sw->set_vertex_elements( failover->sw, count, vertex_elements );
failover->hw->set_vertex_elements( failover->hw, count, vertex_elements );
}
void void
failover_set_constant_buffer(struct pipe_context *pipe, failover_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index, uint shader, uint index,
@ -543,6 +570,9 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.create_vs_state = failover_create_vs_state; failover->pipe.create_vs_state = failover_create_vs_state;
failover->pipe.bind_vs_state = failover_bind_vs_state; failover->pipe.bind_vs_state = failover_bind_vs_state;
failover->pipe.delete_vs_state = failover_delete_vs_state; failover->pipe.delete_vs_state = failover_delete_vs_state;
failover->pipe.create_vertex_elements_state = failover_create_vertex_elements_state;
failover->pipe.bind_vertex_elements_state = failover_bind_vertex_elements_state;
failover->pipe.delete_vertex_elements_state = failover_delete_vertex_elements_state;
failover->pipe.set_blend_color = failover_set_blend_color; failover->pipe.set_blend_color = failover_set_blend_color;
failover->pipe.set_stencil_ref = failover_set_stencil_ref; failover->pipe.set_stencil_ref = failover_set_stencil_ref;
@ -554,6 +584,5 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures; failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures;
failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffers = failover_set_vertex_buffers; failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
failover->pipe.set_vertex_elements = failover_set_vertex_elements;
failover->pipe.set_constant_buffer = failover_set_constant_buffer; failover->pipe.set_constant_buffer = failover_set_constant_buffer;
} }

View File

@ -81,6 +81,10 @@ failover_state_emit( struct failover_context *failover )
failover->sw->bind_vs_state( failover->sw, failover->sw->bind_vs_state( failover->sw,
failover->vertex_shader->sw_state ); failover->vertex_shader->sw_state );
if (failover->dirty & FO_NEW_VERTEX_ELEMENT)
failover->sw->bind_vertex_elements_state( failover->sw,
failover->vertex_elements->sw_state );
if (failover->dirty & FO_NEW_STIPPLE) if (failover->dirty & FO_NEW_STIPPLE)
failover->sw->set_polygon_stipple( failover->sw, &failover->poly_stipple ); failover->sw->set_polygon_stipple( failover->sw, &failover->poly_stipple );
@ -116,11 +120,5 @@ failover_state_emit( struct failover_context *failover )
failover->vertex_buffers ); failover->vertex_buffers );
} }
if (failover->dirty & FO_NEW_VERTEX_ELEMENT) {
failover->sw->set_vertex_elements( failover->sw,
failover->num_vertex_elements,
failover->vertex_elements );
}
failover->dirty = 0; failover->dirty = 0;
} }

View File

@ -187,6 +187,11 @@ struct i915_sampler_state {
unsigned maxlod; unsigned maxlod;
}; };
struct i915_velems_state {
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
};
#define I915_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */ #define I915_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */
#define I915_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */ #define I915_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */
@ -250,7 +255,6 @@ struct i915_context
unsigned num_samplers; unsigned num_samplers;
unsigned num_textures; unsigned num_textures;
unsigned num_vertex_elements;
unsigned num_vertex_buffers; unsigned num_vertex_buffers;
struct intel_batchbuffer *batch; struct intel_batchbuffer *batch;

View File

@ -742,21 +742,42 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
draw_set_vertex_buffers(i915->draw, count, buffers); draw_set_vertex_buffers(i915->draw, count, buffers);
} }
static void i915_set_vertex_elements(struct pipe_context *pipe, static void *
unsigned count, i915_create_vertex_elements_state(struct pipe_context *pipe,
const struct pipe_vertex_element *elements) unsigned count,
const struct pipe_vertex_element *attribs)
{
struct i915_velems_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
velems = (struct i915_velems_state *) MALLOC(sizeof(struct i915_velems_state));
if (velems) {
velems->count = count;
memcpy(velems->velem, attribs, sizeof(*attribs) * count);
}
return velems;
}
static void
i915_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{ {
struct i915_context *i915 = i915_context(pipe); struct i915_context *i915 = i915_context(pipe);
struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems;
/* Because we change state before the draw_set_vertex_buffers call /* Because we change state before the draw_set_vertex_buffers call
* we need a flush here, just to be sure. * we need a flush here, just to be sure.
*/ */
draw_flush(i915->draw); draw_flush(i915->draw);
i915->num_vertex_elements = count;
/* pass-through to draw module */ /* pass-through to draw module */
draw_set_vertex_elements(i915->draw, count, elements); draw_set_vertex_elements(i915->draw, i915_velems->count, i915_velems->velem);
} }
static void
i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
}
void void
i915_init_state_functions( struct i915_context *i915 ) i915_init_state_functions( struct i915_context *i915 )
@ -782,6 +803,9 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.create_vs_state = i915_create_vs_state; i915->base.create_vs_state = i915_create_vs_state;
i915->base.bind_vs_state = i915_bind_vs_state; i915->base.bind_vs_state = i915_bind_vs_state;
i915->base.delete_vs_state = i915_delete_vs_state; i915->base.delete_vs_state = i915_delete_vs_state;
i915->base.create_vertex_elements_state = i915_create_vertex_elements_state;
i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state;
i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state;
i915->base.set_blend_color = i915_set_blend_color; i915->base.set_blend_color = i915_set_blend_color;
i915->base.set_stencil_ref = i915_set_stencil_ref; i915->base.set_stencil_ref = i915_set_stencil_ref;
@ -794,5 +818,4 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.set_fragment_sampler_textures = i915_set_sampler_textures; i915->base.set_fragment_sampler_textures = i915_set_sampler_textures;
i915->base.set_viewport_state = i915_set_viewport_state; i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers; i915->base.set_vertex_buffers = i915_set_vertex_buffers;
i915->base.set_vertex_elements = i915_set_vertex_elements;
} }

View File

@ -351,7 +351,7 @@ struct brw_vs_prog_data {
/* Size == 0 if output either not written, or always [0,0,0,1] /* Size == 0 if output either not written, or always [0,0,0,1]
*/ */
struct brw_vs_ouput_sizes { struct brw_vs_output_sizes {
GLubyte output_size[PIPE_MAX_SHADER_OUTPUTS]; GLubyte output_size[PIPE_MAX_SHADER_OUTPUTS];
}; };
@ -546,14 +546,13 @@ struct brw_context
const struct brw_blend_state *blend; const struct brw_blend_state *blend;
const struct brw_rasterizer_state *rast; const struct brw_rasterizer_state *rast;
const struct brw_depth_stencil_state *zstencil; const struct brw_depth_stencil_state *zstencil;
const struct brw_vertex_element_packet *velems;
const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS]; const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];
unsigned num_samplers; unsigned num_samplers;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_vertex_elements;
unsigned num_textures; unsigned num_textures;
unsigned num_vertex_buffers; unsigned num_vertex_buffers;

View File

@ -42,141 +42,6 @@
static unsigned brw_translate_surface_format( unsigned id )
{
switch (id) {
case PIPE_FORMAT_R64_FLOAT:
return BRW_SURFACEFORMAT_R64_FLOAT;
case PIPE_FORMAT_R64G64_FLOAT:
return BRW_SURFACEFORMAT_R64G64_FLOAT;
case PIPE_FORMAT_R64G64B64_FLOAT:
return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
case PIPE_FORMAT_R64G64B64A64_FLOAT:
return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
case PIPE_FORMAT_R32_FLOAT:
return BRW_SURFACEFORMAT_R32_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
return BRW_SURFACEFORMAT_R32G32_FLOAT;
case PIPE_FORMAT_R32G32B32_FLOAT:
return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
case PIPE_FORMAT_R32_UNORM:
return BRW_SURFACEFORMAT_R32_UNORM;
case PIPE_FORMAT_R32G32_UNORM:
return BRW_SURFACEFORMAT_R32G32_UNORM;
case PIPE_FORMAT_R32G32B32_UNORM:
return BRW_SURFACEFORMAT_R32G32B32_UNORM;
case PIPE_FORMAT_R32G32B32A32_UNORM:
return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
case PIPE_FORMAT_R32_USCALED:
return BRW_SURFACEFORMAT_R32_USCALED;
case PIPE_FORMAT_R32G32_USCALED:
return BRW_SURFACEFORMAT_R32G32_USCALED;
case PIPE_FORMAT_R32G32B32_USCALED:
return BRW_SURFACEFORMAT_R32G32B32_USCALED;
case PIPE_FORMAT_R32G32B32A32_USCALED:
return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
case PIPE_FORMAT_R32_SNORM:
return BRW_SURFACEFORMAT_R32_SNORM;
case PIPE_FORMAT_R32G32_SNORM:
return BRW_SURFACEFORMAT_R32G32_SNORM;
case PIPE_FORMAT_R32G32B32_SNORM:
return BRW_SURFACEFORMAT_R32G32B32_SNORM;
case PIPE_FORMAT_R32G32B32A32_SNORM:
return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
case PIPE_FORMAT_R32_SSCALED:
return BRW_SURFACEFORMAT_R32_SSCALED;
case PIPE_FORMAT_R32G32_SSCALED:
return BRW_SURFACEFORMAT_R32G32_SSCALED;
case PIPE_FORMAT_R32G32B32_SSCALED:
return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
case PIPE_FORMAT_R32G32B32A32_SSCALED:
return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
case PIPE_FORMAT_R16_UNORM:
return BRW_SURFACEFORMAT_R16_UNORM;
case PIPE_FORMAT_R16G16_UNORM:
return BRW_SURFACEFORMAT_R16G16_UNORM;
case PIPE_FORMAT_R16G16B16_UNORM:
return BRW_SURFACEFORMAT_R16G16B16_UNORM;
case PIPE_FORMAT_R16G16B16A16_UNORM:
return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
case PIPE_FORMAT_R16_USCALED:
return BRW_SURFACEFORMAT_R16_USCALED;
case PIPE_FORMAT_R16G16_USCALED:
return BRW_SURFACEFORMAT_R16G16_USCALED;
case PIPE_FORMAT_R16G16B16_USCALED:
return BRW_SURFACEFORMAT_R16G16B16_USCALED;
case PIPE_FORMAT_R16G16B16A16_USCALED:
return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
case PIPE_FORMAT_R16_SNORM:
return BRW_SURFACEFORMAT_R16_SNORM;
case PIPE_FORMAT_R16G16_SNORM:
return BRW_SURFACEFORMAT_R16G16_SNORM;
case PIPE_FORMAT_R16G16B16_SNORM:
return BRW_SURFACEFORMAT_R16G16B16_SNORM;
case PIPE_FORMAT_R16G16B16A16_SNORM:
return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
case PIPE_FORMAT_R16_SSCALED:
return BRW_SURFACEFORMAT_R16_SSCALED;
case PIPE_FORMAT_R16G16_SSCALED:
return BRW_SURFACEFORMAT_R16G16_SSCALED;
case PIPE_FORMAT_R16G16B16_SSCALED:
return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
case PIPE_FORMAT_R16G16B16A16_SSCALED:
return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
case PIPE_FORMAT_R8_UNORM:
return BRW_SURFACEFORMAT_R8_UNORM;
case PIPE_FORMAT_R8G8_UNORM:
return BRW_SURFACEFORMAT_R8G8_UNORM;
case PIPE_FORMAT_R8G8B8_UNORM:
return BRW_SURFACEFORMAT_R8G8B8_UNORM;
case PIPE_FORMAT_R8G8B8A8_UNORM:
return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
case PIPE_FORMAT_R8_USCALED:
return BRW_SURFACEFORMAT_R8_USCALED;
case PIPE_FORMAT_R8G8_USCALED:
return BRW_SURFACEFORMAT_R8G8_USCALED;
case PIPE_FORMAT_R8G8B8_USCALED:
return BRW_SURFACEFORMAT_R8G8B8_USCALED;
case PIPE_FORMAT_R8G8B8A8_USCALED:
return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
case PIPE_FORMAT_R8_SNORM:
return BRW_SURFACEFORMAT_R8_SNORM;
case PIPE_FORMAT_R8G8_SNORM:
return BRW_SURFACEFORMAT_R8G8_SNORM;
case PIPE_FORMAT_R8G8B8_SNORM:
return BRW_SURFACEFORMAT_R8G8B8_SNORM;
case PIPE_FORMAT_R8G8B8A8_SNORM:
return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
case PIPE_FORMAT_R8_SSCALED:
return BRW_SURFACEFORMAT_R8_SSCALED;
case PIPE_FORMAT_R8G8_SSCALED:
return BRW_SURFACEFORMAT_R8G8_SSCALED;
case PIPE_FORMAT_R8G8B8_SSCALED:
return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
case PIPE_FORMAT_R8G8B8A8_SSCALED:
return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
default:
assert(0);
return 0;
}
}
static unsigned get_index_type(int type) static unsigned get_index_type(int type)
{ {
switch (type) { switch (type) {
@ -315,75 +180,16 @@ static int brw_emit_vertex_buffers( struct brw_context *brw )
static int brw_emit_vertex_elements(struct brw_context *brw) static int brw_emit_vertex_elements(struct brw_context *brw)
{ {
GLuint nr = brw->curr.num_vertex_elements; const struct brw_vertex_element_packet *brw_velems = brw->curr.velems;
GLuint i; unsigned size = brw_velems->header.length + 2;
/* why is this here */
brw_emit_query_begin(brw); brw_emit_query_begin(brw);
/* If the VS doesn't read any inputs (calculating vertex position from brw_batchbuffer_data(brw->batch, brw_velems, size * 4, IGNORE_CLIPRECTS);
* a state variable for some reason, for example), emit a single pad
* VERTEX_ELEMENT struct and bail.
*
* The stale VB state stays in place, but they don't do anything unless
* a VE loads from them.
*/
if (nr == 0) {
BEGIN_BATCH(3, IGNORE_CLIPRECTS);
OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
BRW_VE0_VALID |
(BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
(0 << BRW_VE0_SRC_OFFSET_SHIFT));
OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
(BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
ADVANCE_BATCH();
return 0;
}
/* Now emit vertex element (VEP) state packets.
*
*/
BEGIN_BATCH(1 + nr * 2, IGNORE_CLIPRECTS);
OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + nr * 2) - 2));
for (i = 0; i < nr; i++) {
const struct pipe_vertex_element *input = &brw->curr.vertex_element[i];
uint32_t format = brw_translate_surface_format( input->src_format );
uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
switch (input->nr_components) {
case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
break;
}
OUT_BATCH((input->vertex_buffer_index << BRW_VE0_INDEX_SHIFT) |
BRW_VE0_VALID |
(format << BRW_VE0_FORMAT_SHIFT) |
(input->src_offset << BRW_VE0_SRC_OFFSET_SHIFT));
if (BRW_IS_IGDNG(brw))
OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
(comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
(comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
(comp3 << BRW_VE1_COMPONENT_3_SHIFT));
else
OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
(comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
(comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
(comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
}
ADVANCE_BATCH();
return 0; return 0;
} }
@ -396,6 +202,7 @@ static int brw_emit_vertices( struct brw_context *brw )
if (ret) if (ret)
return ret; return ret;
/* XXX should separate this? */
ret = brw_emit_vertex_elements( brw ); ret = brw_emit_vertex_elements( brw );
if (ret) if (ret)
return ret; return ret;
@ -407,7 +214,8 @@ static int brw_emit_vertices( struct brw_context *brw )
const struct brw_tracked_state brw_vertices = { const struct brw_tracked_state brw_vertices = {
.dirty = { .dirty = {
.mesa = (PIPE_NEW_INDEX_RANGE | .mesa = (PIPE_NEW_INDEX_RANGE |
PIPE_NEW_VERTEX_BUFFER), PIPE_NEW_VERTEX_BUFFER |
PIPE_NEW_VERTEX_ELEMENT),
.brw = BRW_NEW_BATCH, .brw = BRW_NEW_BATCH,
.cache = 0, .cache = 0,
}, },

View File

@ -1,22 +1,251 @@
#include "brw_context.h" #include "brw_context.h"
#include "brw_defines.h"
#include "brw_structs.h"
#include "util/u_memory.h"
#include "util/u_format.h"
static void brw_set_vertex_elements( struct pipe_context *pipe, static unsigned brw_translate_surface_format( unsigned id )
unsigned count, {
const struct pipe_vertex_element *elements ) switch (id) {
case PIPE_FORMAT_R64_FLOAT:
return BRW_SURFACEFORMAT_R64_FLOAT;
case PIPE_FORMAT_R64G64_FLOAT:
return BRW_SURFACEFORMAT_R64G64_FLOAT;
case PIPE_FORMAT_R64G64B64_FLOAT:
return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
case PIPE_FORMAT_R64G64B64A64_FLOAT:
return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
case PIPE_FORMAT_R32_FLOAT:
return BRW_SURFACEFORMAT_R32_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
return BRW_SURFACEFORMAT_R32G32_FLOAT;
case PIPE_FORMAT_R32G32B32_FLOAT:
return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
case PIPE_FORMAT_R32_UNORM:
return BRW_SURFACEFORMAT_R32_UNORM;
case PIPE_FORMAT_R32G32_UNORM:
return BRW_SURFACEFORMAT_R32G32_UNORM;
case PIPE_FORMAT_R32G32B32_UNORM:
return BRW_SURFACEFORMAT_R32G32B32_UNORM;
case PIPE_FORMAT_R32G32B32A32_UNORM:
return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
case PIPE_FORMAT_R32_USCALED:
return BRW_SURFACEFORMAT_R32_USCALED;
case PIPE_FORMAT_R32G32_USCALED:
return BRW_SURFACEFORMAT_R32G32_USCALED;
case PIPE_FORMAT_R32G32B32_USCALED:
return BRW_SURFACEFORMAT_R32G32B32_USCALED;
case PIPE_FORMAT_R32G32B32A32_USCALED:
return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
case PIPE_FORMAT_R32_SNORM:
return BRW_SURFACEFORMAT_R32_SNORM;
case PIPE_FORMAT_R32G32_SNORM:
return BRW_SURFACEFORMAT_R32G32_SNORM;
case PIPE_FORMAT_R32G32B32_SNORM:
return BRW_SURFACEFORMAT_R32G32B32_SNORM;
case PIPE_FORMAT_R32G32B32A32_SNORM:
return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
case PIPE_FORMAT_R32_SSCALED:
return BRW_SURFACEFORMAT_R32_SSCALED;
case PIPE_FORMAT_R32G32_SSCALED:
return BRW_SURFACEFORMAT_R32G32_SSCALED;
case PIPE_FORMAT_R32G32B32_SSCALED:
return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
case PIPE_FORMAT_R32G32B32A32_SSCALED:
return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
case PIPE_FORMAT_R16_UNORM:
return BRW_SURFACEFORMAT_R16_UNORM;
case PIPE_FORMAT_R16G16_UNORM:
return BRW_SURFACEFORMAT_R16G16_UNORM;
case PIPE_FORMAT_R16G16B16_UNORM:
return BRW_SURFACEFORMAT_R16G16B16_UNORM;
case PIPE_FORMAT_R16G16B16A16_UNORM:
return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
case PIPE_FORMAT_R16_USCALED:
return BRW_SURFACEFORMAT_R16_USCALED;
case PIPE_FORMAT_R16G16_USCALED:
return BRW_SURFACEFORMAT_R16G16_USCALED;
case PIPE_FORMAT_R16G16B16_USCALED:
return BRW_SURFACEFORMAT_R16G16B16_USCALED;
case PIPE_FORMAT_R16G16B16A16_USCALED:
return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
case PIPE_FORMAT_R16_SNORM:
return BRW_SURFACEFORMAT_R16_SNORM;
case PIPE_FORMAT_R16G16_SNORM:
return BRW_SURFACEFORMAT_R16G16_SNORM;
case PIPE_FORMAT_R16G16B16_SNORM:
return BRW_SURFACEFORMAT_R16G16B16_SNORM;
case PIPE_FORMAT_R16G16B16A16_SNORM:
return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
case PIPE_FORMAT_R16_SSCALED:
return BRW_SURFACEFORMAT_R16_SSCALED;
case PIPE_FORMAT_R16G16_SSCALED:
return BRW_SURFACEFORMAT_R16G16_SSCALED;
case PIPE_FORMAT_R16G16B16_SSCALED:
return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
case PIPE_FORMAT_R16G16B16A16_SSCALED:
return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
case PIPE_FORMAT_R8_UNORM:
return BRW_SURFACEFORMAT_R8_UNORM;
case PIPE_FORMAT_R8G8_UNORM:
return BRW_SURFACEFORMAT_R8G8_UNORM;
case PIPE_FORMAT_R8G8B8_UNORM:
return BRW_SURFACEFORMAT_R8G8B8_UNORM;
case PIPE_FORMAT_R8G8B8A8_UNORM:
return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
case PIPE_FORMAT_R8_USCALED:
return BRW_SURFACEFORMAT_R8_USCALED;
case PIPE_FORMAT_R8G8_USCALED:
return BRW_SURFACEFORMAT_R8G8_USCALED;
case PIPE_FORMAT_R8G8B8_USCALED:
return BRW_SURFACEFORMAT_R8G8B8_USCALED;
case PIPE_FORMAT_R8G8B8A8_USCALED:
return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
case PIPE_FORMAT_R8_SNORM:
return BRW_SURFACEFORMAT_R8_SNORM;
case PIPE_FORMAT_R8G8_SNORM:
return BRW_SURFACEFORMAT_R8G8_SNORM;
case PIPE_FORMAT_R8G8B8_SNORM:
return BRW_SURFACEFORMAT_R8G8B8_SNORM;
case PIPE_FORMAT_R8G8B8A8_SNORM:
return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
case PIPE_FORMAT_R8_SSCALED:
return BRW_SURFACEFORMAT_R8_SSCALED;
case PIPE_FORMAT_R8G8_SSCALED:
return BRW_SURFACEFORMAT_R8G8_SSCALED;
case PIPE_FORMAT_R8G8B8_SSCALED:
return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
case PIPE_FORMAT_R8G8B8A8_SSCALED:
return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
default:
assert(0);
return 0;
}
}
static void brw_translate_vertex_elements(struct brw_context *brw,
struct brw_vertex_element_packet *brw_velems,
const struct pipe_vertex_element *attribs,
unsigned count)
{
unsigned i;
/* If the VS doesn't read any inputs (calculating vertex position from
* a state variable for some reason, for example), emit a single pad
* VERTEX_ELEMENT struct and bail.
*
* The stale VB state stays in place, but they don't do anything unless
* a VE loads from them.
*/
brw_velems->header.opcode = CMD_VERTEX_ELEMENT;
if (count == 0) {
brw_velems->header.length = 1;
brw_velems->ve[0].ve0.src_offset = 0;
brw_velems->ve[0].ve0.src_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
brw_velems->ve[0].ve0.valid = 1;
brw_velems->ve[0].ve0.vertex_buffer_index = 0;
brw_velems->ve[0].ve1.dst_offset = 0;
brw_velems->ve[0].ve1.vfcomponent0 = BRW_VE1_COMPONENT_STORE_0;
brw_velems->ve[0].ve1.vfcomponent1 = BRW_VE1_COMPONENT_STORE_0;
brw_velems->ve[0].ve1.vfcomponent2 = BRW_VE1_COMPONENT_STORE_0;
brw_velems->ve[0].ve1.vfcomponent3 = BRW_VE1_COMPONENT_STORE_1_FLT;
return;
}
/* Now emit vertex element (VEP) state packets.
*
*/
brw_velems->header.length = (1 + count * 2) - 2;
for (i = 0; i < count; i++) {
const struct pipe_vertex_element *input = &attribs[i];
unsigned nr_components = util_format_get_nr_components(input->src_format);
uint32_t format = brw_translate_surface_format( input->src_format );
uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
switch (nr_components) {
case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
break;
}
brw_velems->ve[i].ve0.src_offset = input->src_offset;
brw_velems->ve[i].ve0.src_format = format;
brw_velems->ve[i].ve0.valid = 1;
brw_velems->ve[i].ve0.vertex_buffer_index = input->vertex_buffer_index;
brw_velems->ve[i].ve1.vfcomponent0 = comp0;
brw_velems->ve[i].ve1.vfcomponent1 = comp1;
brw_velems->ve[i].ve1.vfcomponent2 = comp2;
brw_velems->ve[i].ve1.vfcomponent3 = comp3;
if (BRW_IS_IGDNG(brw))
brw_velems->ve[i].ve1.dst_offset = 0;
else
brw_velems->ve[i].ve1.dst_offset = i * 4;
}
}
static void* brw_create_vertex_elements_state( struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *attribs )
{
/* note: for the brw_swtnl.c code (if ever we need draw fallback) we'd also need
to store the original data */
struct brw_context *brw = brw_context(pipe);
struct brw_vertex_element_packet *velems;
assert(count <= BRW_VEP_MAX);
velems = (struct brw_vertex_element_packet *) MALLOC(sizeof(struct brw_vertex_element_packet));
if (velems) {
brw_translate_vertex_elements(brw, velems, attribs, count);
}
return velems;
}
static void brw_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{ {
struct brw_context *brw = brw_context(pipe); struct brw_context *brw = brw_context(pipe);
struct brw_vertex_element_packet *brw_velems = (struct brw_vertex_element_packet *) velems;
memcpy(brw->curr.vertex_element, elements, count * sizeof(elements[0])); brw->curr.velems = brw_velems;
brw->curr.num_vertex_elements = count;
brw->state.dirty.mesa |= PIPE_NEW_VERTEX_ELEMENT; brw->state.dirty.mesa |= PIPE_NEW_VERTEX_ELEMENT;
} }
static void brw_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
}
static void brw_set_vertex_buffers(struct pipe_context *pipe, static void brw_set_vertex_buffers(struct pipe_context *pipe,
unsigned count, unsigned count,
const struct pipe_vertex_buffer *buffers) const struct pipe_vertex_buffer *buffers)
{ {
struct brw_context *brw = brw_context(pipe); struct brw_context *brw = brw_context(pipe);
unsigned i; unsigned i;
@ -49,7 +278,9 @@ void
brw_pipe_vertex_init( struct brw_context *brw ) brw_pipe_vertex_init( struct brw_context *brw )
{ {
brw->base.set_vertex_buffers = brw_set_vertex_buffers; brw->base.set_vertex_buffers = brw_set_vertex_buffers;
brw->base.set_vertex_elements = brw_set_vertex_elements; brw->base.create_vertex_elements_state = brw_create_vertex_elements_state;
brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state;
brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state;
} }

View File

@ -377,6 +377,42 @@ identity_delete_vs_state(struct pipe_context *_pipe,
vs); vs);
} }
static void *
identity_create_vertex_elements_state(struct pipe_context *_pipe,
unsigned num_elements,
const struct pipe_vertex_element *vertex_elements)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
return pipe->create_vertex_elements_state(pipe,
num_elements,
vertex_elements);
}
static void
identity_bind_vertex_elements_state(struct pipe_context *_pipe,
void *velems)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
pipe->bind_vertex_elements_state(pipe,
velems);
}
static void
identity_delete_vertex_elements_state(struct pipe_context *_pipe,
void *velems)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
pipe->delete_vertex_elements_state(pipe,
velems);
}
static void static void
identity_set_blend_color(struct pipe_context *_pipe, identity_set_blend_color(struct pipe_context *_pipe,
const struct pipe_blend_color *blend_color) const struct pipe_blend_color *blend_color)
@ -563,20 +599,6 @@ identity_set_vertex_buffers(struct pipe_context *_pipe,
num_buffers, num_buffers,
buffers); buffers);
} }
static void
identity_set_vertex_elements(struct pipe_context *_pipe,
unsigned num_elements,
const struct pipe_vertex_element *vertex_elements)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
pipe->set_vertex_elements(pipe,
num_elements,
vertex_elements);
}
static void static void
identity_surface_copy(struct pipe_context *_pipe, identity_surface_copy(struct pipe_context *_pipe,
struct pipe_surface *_dst, struct pipe_surface *_dst,
@ -733,6 +755,9 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.create_vs_state = identity_create_vs_state; id_pipe->base.create_vs_state = identity_create_vs_state;
id_pipe->base.bind_vs_state = identity_bind_vs_state; id_pipe->base.bind_vs_state = identity_bind_vs_state;
id_pipe->base.delete_vs_state = identity_delete_vs_state; id_pipe->base.delete_vs_state = identity_delete_vs_state;
id_pipe->base.create_vertex_elements_state = identity_create_vertex_elements_state;
id_pipe->base.bind_vertex_elements_state = identity_bind_vertex_elements_state;
id_pipe->base.delete_vertex_elements_state = identity_delete_vertex_elements_state;
id_pipe->base.set_blend_color = identity_set_blend_color; id_pipe->base.set_blend_color = identity_set_blend_color;
id_pipe->base.set_stencil_ref = identity_set_stencil_ref; id_pipe->base.set_stencil_ref = identity_set_stencil_ref;
id_pipe->base.set_clip_state = identity_set_clip_state; id_pipe->base.set_clip_state = identity_set_clip_state;
@ -744,7 +769,6 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures; id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures;
id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures; id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
id_pipe->base.set_vertex_elements = identity_set_vertex_elements;
id_pipe->base.surface_copy = identity_surface_copy; id_pipe->base.surface_copy = identity_surface_copy;
id_pipe->base.surface_fill = identity_surface_fill; id_pipe->base.surface_fill = identity_surface_fill;
id_pipe->base.clear = identity_clear; id_pipe->base.clear = identity_clear;

View File

@ -145,6 +145,10 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state; llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state; llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
llvmpipe->pipe.create_vertex_elements_state = llvmpipe_create_vertex_elements_state;
llvmpipe->pipe.bind_vertex_elements_state = llvmpipe_bind_vertex_elements_state;
llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color; llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref; llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state; llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
@ -157,7 +161,6 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state; llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers; llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
llvmpipe->pipe.set_vertex_elements = llvmpipe_set_vertex_elements;
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays; llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
llvmpipe->pipe.draw_elements = llvmpipe_draw_elements; llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;

View File

@ -46,6 +46,7 @@ struct lp_fragment_shader;
struct lp_vertex_shader; struct lp_vertex_shader;
struct lp_blend_state; struct lp_blend_state;
struct setup_context; struct setup_context;
struct lp_velems_state;
struct llvmpipe_context { struct llvmpipe_context {
struct pipe_context pipe; /**< base class */ struct pipe_context pipe; /**< base class */
@ -58,6 +59,7 @@ struct llvmpipe_context {
const struct pipe_rasterizer_state *rasterizer; const struct pipe_rasterizer_state *rasterizer;
struct lp_fragment_shader *fs; struct lp_fragment_shader *fs;
const struct lp_vertex_shader *vs; const struct lp_vertex_shader *vs;
const struct lp_velems_state *velems;
/** Other rendering state */ /** Other rendering state */
struct pipe_blend_color blend_color; struct pipe_blend_color blend_color;
@ -71,13 +73,11 @@ struct llvmpipe_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers; unsigned num_samplers;
unsigned num_textures; unsigned num_textures;
unsigned num_vertex_samplers; unsigned num_vertex_samplers;
unsigned num_vertex_textures; unsigned num_vertex_textures;
unsigned num_vertex_elements;
unsigned num_vertex_buffers; unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of LP_NEW_x flags */ unsigned dirty; /**< Mask of LP_NEW_x flags */

View File

@ -119,6 +119,10 @@ struct lp_vertex_shader {
struct draw_vertex_shader *draw_data; struct draw_vertex_shader *draw_data;
}; };
struct lp_velems_state {
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
};
void * void *
@ -176,8 +180,14 @@ void *llvmpipe_create_vs_state(struct pipe_context *,
void llvmpipe_bind_vs_state(struct pipe_context *, void *); void llvmpipe_bind_vs_state(struct pipe_context *, void *);
void llvmpipe_delete_vs_state(struct pipe_context *, void *); void llvmpipe_delete_vs_state(struct pipe_context *, void *);
void *llvmpipe_create_vertex_elements_state(struct pipe_context *,
unsigned count,
const struct pipe_vertex_element *);
void llvmpipe_bind_vertex_elements_state(struct pipe_context *, void *);
void llvmpipe_delete_vertex_elements_state(struct pipe_context *, void *);
void llvmpipe_set_polygon_stipple( struct pipe_context *, void llvmpipe_set_polygon_stipple( struct pipe_context *,
const struct pipe_poly_stipple * ); const struct pipe_poly_stipple * );
void llvmpipe_set_scissor_state( struct pipe_context *, void llvmpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * ); const struct pipe_scissor_state * );
@ -194,10 +204,6 @@ llvmpipe_set_vertex_sampler_textures(struct pipe_context *,
void llvmpipe_set_viewport_state( struct pipe_context *, void llvmpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * ); const struct pipe_viewport_state * );
void llvmpipe_set_vertex_elements(struct pipe_context *,
unsigned count,
const struct pipe_vertex_element *);
void llvmpipe_set_vertex_buffers(struct pipe_context *, void llvmpipe_set_vertex_buffers(struct pipe_context *,
unsigned count, unsigned count,
const struct pipe_vertex_buffer *); const struct pipe_vertex_buffer *);

View File

@ -35,24 +35,41 @@
#include "draw/draw_context.h" #include "draw/draw_context.h"
void *
llvmpipe_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *attribs)
{
struct lp_velems_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
velems = (struct lp_velems_state *) MALLOC(sizeof(struct lp_velems_state));
if (velems) {
velems->count = count;
memcpy(velems->velem, attribs, sizeof(*attribs) * count);
}
return velems;
}
void void
llvmpipe_set_vertex_elements(struct pipe_context *pipe, llvmpipe_bind_vertex_elements_state(struct pipe_context *pipe,
unsigned count, void *velems)
const struct pipe_vertex_element *attribs)
{ {
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct lp_velems_state *lp_velems = (struct lp_velems_state *) velems;
assert(count <= PIPE_MAX_ATTRIBS); llvmpipe->velems = lp_velems;
memcpy(llvmpipe->vertex_element, attribs,
count * sizeof(struct pipe_vertex_element));
llvmpipe->num_vertex_elements = count;
llvmpipe->dirty |= LP_NEW_VERTEX; llvmpipe->dirty |= LP_NEW_VERTEX;
draw_set_vertex_elements(llvmpipe->draw, count, attribs); if (velems)
draw_set_vertex_elements(llvmpipe->draw, lp_velems->count, lp_velems->velem);
} }
void
llvmpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
}
void void
llvmpipe_set_vertex_buffers(struct pipe_context *pipe, llvmpipe_set_vertex_buffers(struct pipe_context *pipe,

View File

@ -124,7 +124,7 @@ nouveau_screen_map_flags(unsigned pipe)
if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK) if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK)
flags |= NOUVEAU_BO_NOWAIT; flags |= NOUVEAU_BO_NOWAIT;
else else
if (pipe & 0 /*PIPE_BUFFER_USAGE_UNSYNCHRONIZED*/) if (pipe & PIPE_BUFFER_USAGE_UNSYNCHRONIZED)
flags |= NOUVEAU_BO_NOSYNC; flags |= NOUVEAU_BO_NOSYNC;
return flags; return flags;

View File

@ -88,4 +88,104 @@ static INLINE unsigned log2i(unsigned i)
return r; return r;
} }
struct u_split_prim {
void *priv;
void (*emit)(void *priv, unsigned start, unsigned count);
void (*edge)(void *priv, boolean enabled);
unsigned mode;
unsigned start;
unsigned p_start;
unsigned p_end;
int repeat_first:1;
int close_first:1;
int edgeflag_off:1;
};
static inline void
u_split_prim_init(struct u_split_prim *s,
unsigned mode, unsigned start, unsigned count)
{
if (mode == PIPE_PRIM_LINE_LOOP) {
s->mode = PIPE_PRIM_LINE_STRIP;
s->close_first = 1;
} else {
s->mode = mode;
s->close_first = 0;
}
s->start = start;
s->p_start = start;
s->p_end = start + count;
s->edgeflag_off = 0;
s->repeat_first = 0;
}
static INLINE boolean
u_split_prim_next(struct u_split_prim *s, unsigned max_verts)
{
int repeat = 0;
if (s->repeat_first) {
s->emit(s->priv, s->start, 1);
max_verts--;
if (s->edgeflag_off) {
s->edge(s->priv, TRUE);
s->edgeflag_off = FALSE;
}
}
if (s->p_start + s->close_first + max_verts >= s->p_end) {
s->emit(s->priv, s->p_start, s->p_end - s->p_start);
if (s->close_first)
s->emit(s->priv, s->start, 1);
return TRUE;
}
switch (s->mode) {
case PIPE_PRIM_LINES:
max_verts &= ~1;
break;
case PIPE_PRIM_LINE_STRIP:
repeat = 1;
break;
case PIPE_PRIM_POLYGON:
max_verts--;
s->emit(s->priv, s->p_start, max_verts);
s->edge(s->priv, FALSE);
s->emit(s->priv, s->p_start + max_verts, 1);
s->p_start += max_verts;
s->repeat_first = TRUE;
s->edgeflag_off = TRUE;
return FALSE;
case PIPE_PRIM_TRIANGLES:
max_verts = max_verts - (max_verts % 3);
break;
case PIPE_PRIM_TRIANGLE_STRIP:
/* to ensure winding stays correct, always split
* on an even number of generated triangles
*/
max_verts = max_verts & ~1;
repeat = 2;
break;
case PIPE_PRIM_TRIANGLE_FAN:
s->repeat_first = TRUE;
repeat = 1;
break;
case PIPE_PRIM_QUADS:
max_verts &= ~3;
break;
case PIPE_PRIM_QUAD_STRIP:
max_verts &= ~1;
repeat = 2;
break;
default:
break;
}
s->emit (s->priv, s->p_start, max_verts);
s->p_start += (max_verts - repeat);
return FALSE;
}
#endif #endif

View File

@ -107,6 +107,11 @@ struct nv30_state {
struct nouveau_stateobj *hw[NV30_STATE_MAX]; struct nouveau_stateobj *hw[NV30_STATE_MAX];
}; };
struct nv30_vtxelt_state {
struct pipe_vertex_element pipe[16];
unsigned num_elements;
};
struct nv30_context { struct nv30_context {
struct pipe_context pipe; struct pipe_context pipe;
@ -142,8 +147,7 @@ struct nv30_context {
unsigned dirty_samplers; unsigned dirty_samplers;
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr; unsigned vtxbuf_nr;
struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; struct nv30_vtxelt_state *vtxelt;
unsigned vtxelt_nr;
}; };
static INLINE struct nv30_context * static INLINE struct nv30_context *

View File

@ -236,5 +236,5 @@ nv30_screen_init_miptree_functions(struct pipe_screen *pscreen)
pscreen->get_tex_surface = nv30_miptree_surface_new; pscreen->get_tex_surface = nv30_miptree_surface_new;
pscreen->tex_surface_destroy = nv30_miptree_surface_del; pscreen->tex_surface_destroy = nv30_miptree_surface_del;
nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket; nouveau_screen(pscreen)->texture_blanket = nv30_miptree_blanket;
} }

View File

@ -669,15 +669,34 @@ nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
/*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/ /*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
} }
static void *
nv30_vtxelts_state_create(struct pipe_context *pipe,
unsigned num_elements,
const struct pipe_vertex_element *elements)
{
struct nv30_vtxelt_state *cso = CALLOC_STRUCT(nv30_vtxelt_state);
assert(num_elements < 16); /* not doing fallbacks yet */
cso->num_elements = num_elements;
memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
/* nv30_vtxelt_construct(cso);*/
return (void *)cso;
}
static void static void
nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count, nv30_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
const struct pipe_vertex_element *ve) {
FREE(hwcso);
}
static void
nv30_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
{ {
struct nv30_context *nv30 = nv30_context(pipe); struct nv30_context *nv30 = nv30_context(pipe);
memcpy(nv30->vtxelt, ve, sizeof(*ve) * count); nv30->vtxelt = hwcso;
nv30->vtxelt_nr = count;
nv30->dirty |= NV30_NEW_ARRAYS; nv30->dirty |= NV30_NEW_ARRAYS;
/*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/ /*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
} }
@ -722,7 +741,10 @@ nv30_init_state_functions(struct nv30_context *nv30)
nv30->pipe.set_scissor_state = nv30_set_scissor_state; nv30->pipe.set_scissor_state = nv30_set_scissor_state;
nv30->pipe.set_viewport_state = nv30_set_viewport_state; nv30->pipe.set_viewport_state = nv30_set_viewport_state;
nv30->pipe.create_vertex_elements_state = nv30_vtxelts_state_create;
nv30->pipe.delete_vertex_elements_state = nv30_vtxelts_state_delete;
nv30->pipe.bind_vertex_elements_state = nv30_vtxelts_state_bind;
nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers; nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers;
nv30->pipe.set_vertex_elements = nv30_set_vertex_elements;
} }

View File

@ -492,16 +492,16 @@ nv30_vbo_validate(struct nv30_context *nv30)
int hw; int hw;
vtxbuf = so_new(3, 17, 18); vtxbuf = so_new(3, 17, 18);
so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt_nr); so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt->num_elements);
vtxfmt = so_new(1, 16, 0); vtxfmt = so_new(1, 16, 0);
so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt_nr); so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt->num_elements);
for (hw = 0; hw < nv30->vtxelt_nr; hw++) { for (hw = 0; hw < nv30->vtxelt->num_elements; hw++) {
struct pipe_vertex_element *ve; struct pipe_vertex_element *ve;
struct pipe_vertex_buffer *vb; struct pipe_vertex_buffer *vb;
unsigned type, ncomp; unsigned type, ncomp;
ve = &nv30->vtxelt[hw]; ve = &nv30->vtxelt->pipe[hw];
vb = &nv30->vtxbuf[ve->vertex_buffer_index]; vb = &nv30->vtxbuf[ve->vertex_buffer_index];
if (!vb->stride) { if (!vb->stride) {

View File

@ -107,6 +107,12 @@ struct nv40_state {
struct nouveau_stateobj *hw[NV40_STATE_MAX]; struct nouveau_stateobj *hw[NV40_STATE_MAX];
}; };
struct nv40_vtxelt_state {
struct pipe_vertex_element pipe[16];
unsigned num_elements;
};
struct nv40_context { struct nv40_context {
struct pipe_context pipe; struct pipe_context pipe;
@ -157,8 +163,7 @@ struct nv40_context {
unsigned dirty_samplers; unsigned dirty_samplers;
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr; unsigned vtxbuf_nr;
struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; struct nv40_vtxelt_state *vtxelt;
unsigned vtxelt_nr;
}; };
static INLINE struct nv40_context * static INLINE struct nv40_context *

View File

@ -684,15 +684,34 @@ nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
nv40->draw_dirty |= NV40_NEW_ARRAYS; nv40->draw_dirty |= NV40_NEW_ARRAYS;
} }
static void *
nv40_vtxelts_state_create(struct pipe_context *pipe,
unsigned num_elements,
const struct pipe_vertex_element *elements)
{
struct nv40_vtxelt_state *cso = CALLOC_STRUCT(nv40_vtxelt_state);
assert(num_elements < 16); /* not doing fallbacks yet */
cso->num_elements = num_elements;
memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
/* nv40_vtxelt_construct(cso);*/
return (void *)cso;
}
static void static void
nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count, nv40_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
const struct pipe_vertex_element *ve) {
FREE(hwcso);
}
static void
nv40_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
{ {
struct nv40_context *nv40 = nv40_context(pipe); struct nv40_context *nv40 = nv40_context(pipe);
memcpy(nv40->vtxelt, ve, sizeof(*ve) * count); nv40->vtxelt = hwcso;
nv40->vtxelt_nr = count;
nv40->dirty |= NV40_NEW_ARRAYS; nv40->dirty |= NV40_NEW_ARRAYS;
nv40->draw_dirty |= NV40_NEW_ARRAYS; nv40->draw_dirty |= NV40_NEW_ARRAYS;
} }
@ -737,7 +756,10 @@ nv40_init_state_functions(struct nv40_context *nv40)
nv40->pipe.set_scissor_state = nv40_set_scissor_state; nv40->pipe.set_scissor_state = nv40_set_scissor_state;
nv40->pipe.set_viewport_state = nv40_set_viewport_state; nv40->pipe.set_viewport_state = nv40_set_viewport_state;
nv40->pipe.create_vertex_elements_state = nv40_vtxelts_state_create;
nv40->pipe.delete_vertex_elements_state = nv40_vtxelts_state_delete;
nv40->pipe.bind_vertex_elements_state = nv40_vtxelts_state_bind;
nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers; nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers;
nv40->pipe.set_vertex_elements = nv40_set_vertex_elements;
} }

View File

@ -174,7 +174,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40)
if (nv40->draw_dirty & NV40_NEW_ARRAYS) { if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf); draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt); draw_set_vertex_elements(draw, nv40->vtxelt->num_elements, nv40->vtxelt->pipe);
} }
nv40_state_do_validate(nv40, swtnl_states); nv40_state_do_validate(nv40, swtnl_states);

View File

@ -493,16 +493,16 @@ nv40_vbo_validate(struct nv40_context *nv40)
int hw; int hw;
vtxbuf = so_new(3, 17, 18); vtxbuf = so_new(3, 17, 18);
so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr); so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt->num_elements);
vtxfmt = so_new(1, 16, 0); vtxfmt = so_new(1, 16, 0);
so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt_nr); so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt->num_elements);
for (hw = 0; hw < nv40->vtxelt_nr; hw++) { for (hw = 0; hw < nv40->vtxelt->num_elements; hw++) {
struct pipe_vertex_element *ve; struct pipe_vertex_element *ve;
struct pipe_vertex_buffer *vb; struct pipe_vertex_buffer *vb;
unsigned type, ncomp; unsigned type, ncomp;
ve = &nv40->vtxelt[hw]; ve = &nv40->vtxelt->pipe[hw];
vb = &nv40->vtxbuf[ve->vertex_buffer_index]; vb = &nv40->vtxbuf[ve->vertex_buffer_index];
if (!vb->stride) { if (!vb->stride) {

View File

@ -16,6 +16,7 @@ C_SOURCES = \
nv50_surface.c \ nv50_surface.c \
nv50_tex.c \ nv50_tex.c \
nv50_transfer.c \ nv50_transfer.c \
nv50_vbo.c nv50_vbo.c \
nv50_push.c
include ../../Makefile.template include ../../Makefile.template

View File

@ -36,7 +36,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
struct pipe_framebuffer_state *fb = &nv50->framebuffer; struct pipe_framebuffer_state *fb = &nv50->framebuffer;
unsigned mode = 0, i; unsigned mode = 0, i;
if (!nv50_state_validate(nv50)) if (!nv50_state_validate(nv50, 64))
return; return;
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {

View File

@ -46,43 +46,13 @@ static void
nv50_destroy(struct pipe_context *pipe) nv50_destroy(struct pipe_context *pipe)
{ {
struct nv50_context *nv50 = nv50_context(pipe); struct nv50_context *nv50 = nv50_context(pipe);
int i;
if (nv50->state.fb) for (i = 0; i < 64; i++) {
so_ref(NULL, &nv50->state.fb); if (!nv50->state.hw[i])
if (nv50->state.blend) continue;
so_ref(NULL, &nv50->state.blend); so_ref(NULL, &nv50->state.hw[i]);
if (nv50->state.blend_colour) }
so_ref(NULL, &nv50->state.blend_colour);
if (nv50->state.zsa)
so_ref(NULL, &nv50->state.zsa);
if (nv50->state.rast)
so_ref(NULL, &nv50->state.rast);
if (nv50->state.stipple)
so_ref(NULL, &nv50->state.stipple);
if (nv50->state.scissor)
so_ref(NULL, &nv50->state.scissor);
if (nv50->state.viewport)
so_ref(NULL, &nv50->state.viewport);
if (nv50->state.tsc_upload)
so_ref(NULL, &nv50->state.tsc_upload);
if (nv50->state.tic_upload)
so_ref(NULL, &nv50->state.tic_upload);
if (nv50->state.vertprog)
so_ref(NULL, &nv50->state.vertprog);
if (nv50->state.fragprog)
so_ref(NULL, &nv50->state.fragprog);
if (nv50->state.geomprog)
so_ref(NULL, &nv50->state.geomprog);
if (nv50->state.fp_linkage)
so_ref(NULL, &nv50->state.fp_linkage);
if (nv50->state.gp_linkage)
so_ref(NULL, &nv50->state.gp_linkage);
if (nv50->state.vtxfmt)
so_ref(NULL, &nv50->state.vtxfmt);
if (nv50->state.vtxbuf)
so_ref(NULL, &nv50->state.vtxbuf);
if (nv50->state.vtxattr)
so_ref(NULL, &nv50->state.vtxattr);
draw_destroy(nv50->draw); draw_destroy(nv50->draw);
@ -123,7 +93,6 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
nv50->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; nv50->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
screen->base.channel->user_private = nv50; screen->base.channel->user_private = nv50;
screen->base.channel->flush_notify = nv50_state_flush_notify;
nv50_init_surface_functions(nv50); nv50_init_surface_functions(nv50);
nv50_init_state_functions(nv50); nv50_init_state_functions(nv50);

View File

@ -72,6 +72,12 @@ struct nv50_sampler_stateobj {
unsigned tsc[8]; unsigned tsc[8];
}; };
struct nv50_vtxelt_stateobj {
struct pipe_vertex_element pipe[16];
unsigned num_elements;
uint32_t hw[16];
};
static INLINE unsigned static INLINE unsigned
get_tile_height(uint32_t tile_mode) get_tile_height(uint32_t tile_mode)
{ {
@ -117,30 +123,12 @@ nv50_surface(struct pipe_surface *pt)
} }
struct nv50_state { struct nv50_state {
unsigned dirty; struct nouveau_stateobj *hw[64];
uint64_t hw_dirty;
struct nouveau_stateobj *fb;
struct nouveau_stateobj *blend;
struct nouveau_stateobj *blend_colour;
struct nouveau_stateobj *zsa;
struct nouveau_stateobj *stencil_ref;
struct nouveau_stateobj *rast;
struct nouveau_stateobj *stipple;
struct nouveau_stateobj *scissor;
unsigned scissor_enabled;
struct nouveau_stateobj *viewport;
struct nouveau_stateobj *tsc_upload;
struct nouveau_stateobj *tic_upload;
unsigned miptree_nr[PIPE_SHADER_TYPES]; unsigned miptree_nr[PIPE_SHADER_TYPES];
struct nouveau_stateobj *vertprog;
struct nouveau_stateobj *fragprog;
struct nouveau_stateobj *geomprog;
struct nouveau_stateobj *fp_linkage;
struct nouveau_stateobj *gp_linkage;
struct nouveau_stateobj *vtxfmt;
struct nouveau_stateobj *vtxbuf; struct nouveau_stateobj *vtxbuf;
struct nouveau_stateobj *vtxattr; struct nouveau_stateobj *vtxattr;
struct nouveau_stateobj *instbuf;
unsigned vtxelt_nr; unsigned vtxelt_nr;
}; };
@ -169,14 +157,13 @@ struct nv50_context {
struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr; unsigned vtxbuf_nr;
struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; struct nv50_vtxelt_stateobj *vtxelt;
unsigned vtxelt_nr;
struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
unsigned sampler_nr[PIPE_SHADER_TYPES]; unsigned sampler_nr[PIPE_SHADER_TYPES];
struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
unsigned miptree_nr[PIPE_SHADER_TYPES]; unsigned miptree_nr[PIPE_SHADER_TYPES];
uint16_t vbo_fifo; unsigned vbo_fifo;
}; };
static INLINE struct nv50_context * static INLINE struct nv50_context *
@ -218,24 +205,36 @@ extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
unsigned count, unsigned count,
unsigned startInstance, unsigned startInstance,
unsigned instanceCount); unsigned instanceCount);
extern void nv50_vbo_validate(struct nv50_context *nv50); extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
/* nv50_push.c */
extern void
nv50_push_elements_instanced(struct pipe_context *, struct pipe_buffer *,
unsigned idxsize, unsigned mode, unsigned start,
unsigned count, unsigned i_start,
unsigned i_count);
/* nv50_clear.c */ /* nv50_clear.c */
extern void nv50_clear(struct pipe_context *pipe, unsigned buffers, extern void nv50_clear(struct pipe_context *pipe, unsigned buffers,
const float *rgba, double depth, unsigned stencil); const float *rgba, double depth, unsigned stencil);
/* nv50_program.c */ /* nv50_program.c */
extern void nv50_vertprog_validate(struct nv50_context *nv50); extern struct nouveau_stateobj *
extern void nv50_fragprog_validate(struct nv50_context *nv50); nv50_vertprog_validate(struct nv50_context *nv50);
extern void nv50_geomprog_validate(struct nv50_context *nv50); extern struct nouveau_stateobj *
extern void nv50_fp_linkage_validate(struct nv50_context *nv50); nv50_fragprog_validate(struct nv50_context *nv50);
extern void nv50_gp_linkage_validate(struct nv50_context *nv50); extern struct nouveau_stateobj *
nv50_geomprog_validate(struct nv50_context *nv50);
extern struct nouveau_stateobj *
nv50_fp_linkage_validate(struct nv50_context *nv50);
extern struct nouveau_stateobj *
nv50_gp_linkage_validate(struct nv50_context *nv50);
extern void nv50_program_destroy(struct nv50_context *nv50, extern void nv50_program_destroy(struct nv50_context *nv50,
struct nv50_program *p); struct nv50_program *p);
/* nv50_state_validate.c */ /* nv50_state_validate.c */
extern boolean nv50_state_validate(struct nv50_context *nv50); extern boolean nv50_state_validate(struct nv50_context *nv50, unsigned dwords);
extern void nv50_state_flush_notify(struct nouveau_channel *chan);
extern void nv50_so_init_sifc(struct nv50_context *nv50, extern void nv50_so_init_sifc(struct nv50_context *nv50,
struct nouveau_stateobj *so, struct nouveau_stateobj *so,
@ -243,7 +242,8 @@ extern void nv50_so_init_sifc(struct nv50_context *nv50,
unsigned offset, unsigned size); unsigned offset, unsigned size);
/* nv50_tex.c */ /* nv50_tex.c */
extern void nv50_tex_validate(struct nv50_context *); extern void nv50_tex_relocs(struct nv50_context *);
extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *);
/* nv50_transfer.c */ /* nv50_transfer.c */
extern void extern void
@ -257,4 +257,35 @@ nv50_upload_sifc(struct nv50_context *nv50,
struct pipe_context * struct pipe_context *
nv50_create(struct pipe_screen *pscreen, void *priv); nv50_create(struct pipe_screen *pscreen, void *priv);
static INLINE unsigned
nv50_prim(unsigned mode)
{
switch (mode) {
case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS;
case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES;
case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP;
case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP;
case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES;
case PIPE_PRIM_TRIANGLE_STRIP:
return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP;
case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN;
case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
case PIPE_PRIM_LINES_ADJACENCY:
return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
case PIPE_PRIM_TRIANGLES_ADJACENCY:
return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
default:
break;
}
NOUVEAU_ERR("invalid primitive type %d\n", mode);
return NV50TCL_VERTEX_BEGIN_POINTS;
}
#endif #endif

View File

@ -4270,7 +4270,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
FREE(up); FREE(up);
} }
void struct nouveau_stateobj *
nv50_vertprog_validate(struct nv50_context *nv50) nv50_vertprog_validate(struct nv50_context *nv50)
{ {
struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_grobj *tesla = nv50->screen->tesla;
@ -4286,6 +4286,9 @@ nv50_vertprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p); nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p); nv50_program_validate_code(nv50, p);
if (!(nv50->dirty & NV50_NEW_VERTPROG))
return NULL;
so = so_new(5, 7, 2); so = so_new(5, 7, 2);
so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2); so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@ -4301,11 +4304,10 @@ nv50_vertprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.high_temp); so_data (so, p->cfg.high_temp);
so_method(so, tesla, NV50TCL_VP_START_ID, 1); so_method(so, tesla, NV50TCL_VP_START_ID, 1);
so_data (so, 0); /* program start offset */ so_data (so, 0); /* program start offset */
so_ref(so, &nv50->state.vertprog); return so;
so_ref(NULL, &so);
} }
void struct nouveau_stateobj *
nv50_fragprog_validate(struct nv50_context *nv50) nv50_fragprog_validate(struct nv50_context *nv50)
{ {
struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_grobj *tesla = nv50->screen->tesla;
@ -4321,6 +4323,9 @@ nv50_fragprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p); nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p); nv50_program_validate_code(nv50, p);
if (!(nv50->dirty & NV50_NEW_FRAGPROG))
return NULL;
so = so_new(6, 7, 2); so = so_new(6, 7, 2);
so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@ -4337,11 +4342,10 @@ nv50_fragprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.regs[3]); so_data (so, p->cfg.regs[3]);
so_method(so, tesla, NV50TCL_FP_START_ID, 1); so_method(so, tesla, NV50TCL_FP_START_ID, 1);
so_data (so, 0); /* program start offset */ so_data (so, 0); /* program start offset */
so_ref(so, &nv50->state.fragprog); return so;
so_ref(NULL, &so);
} }
void struct nouveau_stateobj *
nv50_geomprog_validate(struct nv50_context *nv50) nv50_geomprog_validate(struct nv50_context *nv50)
{ {
struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_grobj *tesla = nv50->screen->tesla;
@ -4357,6 +4361,9 @@ nv50_geomprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p); nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p); nv50_program_validate_code(nv50, p);
if (!(nv50->dirty & NV50_NEW_GEOMPROG))
return NULL;
so = so_new(6, 7, 2); so = so_new(6, 7, 2);
so_method(so, tesla, NV50TCL_GP_ADDRESS_HIGH, 2); so_method(so, tesla, NV50TCL_GP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@ -4373,8 +4380,7 @@ nv50_geomprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.vert_count); so_data (so, p->cfg.vert_count);
so_method(so, tesla, NV50TCL_GP_START_ID, 1); so_method(so, tesla, NV50TCL_GP_START_ID, 1);
so_data (so, 0); so_data (so, 0);
so_ref(so, &nv50->state.geomprog); return so;
so_ref(NULL, &so);
} }
static uint32_t static uint32_t
@ -4454,7 +4460,7 @@ nv50_vec4_map(uint32_t *map32, int mid, uint8_t zval, uint32_t lin[4],
return mid; return mid;
} }
void struct nouveau_stateobj *
nv50_fp_linkage_validate(struct nv50_context *nv50) nv50_fp_linkage_validate(struct nv50_context *nv50)
{ {
struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_grobj *tesla = nv50->screen->tesla;
@ -4580,8 +4586,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_GP_ENABLE, 1); so_method(so, tesla, NV50TCL_GP_ENABLE, 1);
so_data (so, (vp->type == PIPE_SHADER_GEOMETRY) ? 1 : 0); so_data (so, (vp->type == PIPE_SHADER_GEOMETRY) ? 1 : 0);
so_ref(so, &nv50->state.fp_linkage); return so;
so_ref(NULL, &so);
} }
static int static int
@ -4615,7 +4620,7 @@ construct_vp_gp_mapping(uint32_t *map32, int m,
return m; return m;
} }
void struct nouveau_stateobj *
nv50_gp_linkage_validate(struct nv50_context *nv50) nv50_gp_linkage_validate(struct nv50_context *nv50)
{ {
struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_grobj *tesla = nv50->screen->tesla;
@ -4625,10 +4630,8 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
uint32_t map[16]; uint32_t map[16];
int m = 0; int m = 0;
if (!gp) { if (!gp)
so_ref(NULL, &nv50->state.gp_linkage); return NULL;
return;
}
memset(map, 0, sizeof(map)); memset(map, 0, sizeof(map));
m = construct_vp_gp_mapping(map, m, vp, gp); m = construct_vp_gp_mapping(map, m, vp, gp);
@ -4646,8 +4649,7 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m); so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m);
so_datap (so, map, m); so_datap (so, map, m);
so_ref(so, &nv50->state.gp_linkage); return so;
so_ref(NULL, &so);
} }
void void

View File

@ -0,0 +1,326 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
#include "nouveau/nouveau_util.h"
#include "nv50_context.h"
struct push_context {
struct nv50_context *nv50;
unsigned vtx_size;
void *idxbuf;
unsigned idxsize;
float edgeflag;
int edgeflag_attr;
struct {
void *map;
unsigned stride;
unsigned divisor;
unsigned step;
void (*push)(struct nouveau_channel *, void *);
} attr[16];
unsigned attr_nr;
};
static void
emit_b32_1(struct nouveau_channel *chan, void *data)
{
uint32_t *v = data;
OUT_RING(chan, v[0]);
}
static void
emit_b32_2(struct nouveau_channel *chan, void *data)
{
uint32_t *v = data;
OUT_RING(chan, v[0]);
OUT_RING(chan, v[1]);
}
static void
emit_b32_3(struct nouveau_channel *chan, void *data)
{
uint32_t *v = data;
OUT_RING(chan, v[0]);
OUT_RING(chan, v[1]);
OUT_RING(chan, v[2]);
}
static void
emit_b32_4(struct nouveau_channel *chan, void *data)
{
uint32_t *v = data;
OUT_RING(chan, v[0]);
OUT_RING(chan, v[1]);
OUT_RING(chan, v[2]);
OUT_RING(chan, v[3]);
}
static void
emit_b16_1(struct nouveau_channel *chan, void *data)
{
uint16_t *v = data;
OUT_RING(chan, v[0]);
}
static void
emit_b16_3(struct nouveau_channel *chan, void *data)
{
uint16_t *v = data;
OUT_RING(chan, (v[1] << 16) | v[0]);
OUT_RING(chan, v[2]);
}
static void
emit_b08_1(struct nouveau_channel *chan, void *data)
{
uint8_t *v = data;
OUT_RING(chan, v[0]);
}
static void
emit_b08_3(struct nouveau_channel *chan, void *data)
{
uint8_t *v = data;
OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]);
}
static INLINE void
emit_vertex(struct push_context *ctx, unsigned n)
{
struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
struct nouveau_channel *chan = tesla->channel;
int i;
if (ctx->edgeflag_attr < 16) {
float *edgeflag = ctx->attr[ctx->edgeflag_attr].map +
ctx->attr[ctx->edgeflag_attr].stride * n;
if (*edgeflag != ctx->edgeflag) {
BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
OUT_RING (chan, *edgeflag ? 1 : 0);
ctx->edgeflag = *edgeflag;
}
}
BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, ctx->vtx_size);
for (i = 0; i < ctx->attr_nr; i++)
ctx->attr[i].push(chan, ctx->attr[i].map + ctx->attr[i].stride * n);
}
static void
emit_edgeflag(void *priv, boolean enabled)
{
struct push_context *ctx = priv;
struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
struct nouveau_channel *chan = tesla->channel;
BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
OUT_RING (chan, enabled ? 1 : 0);
}
static void
emit_elt08(void *priv, unsigned start, unsigned count)
{
struct push_context *ctx = priv;
uint8_t *idxbuf = ctx->idxbuf;
while (count--)
emit_vertex(ctx, idxbuf[start++]);
}
static void
emit_elt16(void *priv, unsigned start, unsigned count)
{
struct push_context *ctx = priv;
uint16_t *idxbuf = ctx->idxbuf;
while (count--)
emit_vertex(ctx, idxbuf[start++]);
}
static void
emit_elt32(void *priv, unsigned start, unsigned count)
{
struct push_context *ctx = priv;
uint32_t *idxbuf = ctx->idxbuf;
while (count--)
emit_vertex(ctx, idxbuf[start++]);
}
static void
emit_verts(void *priv, unsigned start, unsigned count)
{
while (count--)
emit_vertex(priv, start++);
}
void
nv50_push_elements_instanced(struct pipe_context *pipe,
struct pipe_buffer *idxbuf, unsigned idxsize,
unsigned mode, unsigned start, unsigned count,
unsigned i_start, unsigned i_count)
{
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_channel *chan = tesla->channel;
struct push_context ctx;
const unsigned p_overhead = 4 + /* begin/end */
4; /* potential edgeflag enable/disable */
const unsigned v_overhead = 1 + /* VERTEX_DATA packet header */
2; /* potential edgeflag modification */
struct u_split_prim s;
unsigned vtx_size;
boolean nzi = FALSE;
int i;
ctx.nv50 = nv50;
ctx.attr_nr = 0;
ctx.idxbuf = NULL;
ctx.vtx_size = 0;
ctx.edgeflag = 0.5f;
ctx.edgeflag_attr = nv50->vertprog->cfg.edgeflag_in;
/* map vertex buffers, determine vertex size */
for (i = 0; i < nv50->vtxelt->num_elements; i++) {
struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index];
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
unsigned size, nr_components, n;
if (!(nv50->vbo_fifo & (1 << i)))
continue;
n = ctx.attr_nr++;
if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
assert(bo->map);
return;
}
ctx.attr[n].map = bo->map + vb->buffer_offset + ve->src_offset;
nouveau_bo_unmap(bo);
ctx.attr[n].stride = vb->stride;
ctx.attr[n].divisor = ve->instance_divisor;
if (ctx.attr[n].divisor) {
ctx.attr[n].step = i_start % ve->instance_divisor;
ctx.attr[n].map += i_start * vb->stride;
}
size = util_format_get_component_bits(ve->src_format,
UTIL_FORMAT_COLORSPACE_RGB, 0);
nr_components = util_format_get_nr_components(ve->src_format);
switch (size) {
case 8:
switch (nr_components) {
case 1: ctx.attr[n].push = emit_b08_1; break;
case 2: ctx.attr[n].push = emit_b16_1; break;
case 3: ctx.attr[n].push = emit_b08_3; break;
case 4: ctx.attr[n].push = emit_b32_1; break;
}
ctx.vtx_size++;
break;
case 16:
switch (nr_components) {
case 1: ctx.attr[n].push = emit_b16_1; break;
case 2: ctx.attr[n].push = emit_b32_1; break;
case 3: ctx.attr[n].push = emit_b16_3; break;
case 4: ctx.attr[n].push = emit_b32_2; break;
}
ctx.vtx_size += (nr_components + 1) >> 1;
break;
case 32:
switch (nr_components) {
case 1: ctx.attr[n].push = emit_b32_1; break;
case 2: ctx.attr[n].push = emit_b32_2; break;
case 3: ctx.attr[n].push = emit_b32_3; break;
case 4: ctx.attr[n].push = emit_b32_4; break;
}
ctx.vtx_size += nr_components;
break;
default:
assert(0);
return;
}
}
vtx_size = ctx.vtx_size + v_overhead;
/* map index buffer, if present */
if (idxbuf) {
struct nouveau_bo *bo = nouveau_bo(idxbuf);
if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
assert(bo->map);
return;
}
ctx.idxbuf = bo->map;
ctx.idxsize = idxsize;
nouveau_bo_unmap(bo);
}
s.priv = &ctx;
s.edge = emit_edgeflag;
if (idxbuf) {
if (idxsize == 1)
s.emit = emit_elt08;
else
if (idxsize == 2)
s.emit = emit_elt16;
else
s.emit = emit_elt32;
} else
s.emit = emit_verts;
/* per-instance loop */
BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
OUT_RING (chan, NV50_CB_AUX | (24 << 8));
OUT_RING (chan, i_start);
while (i_count--) {
unsigned max_verts;
boolean done;
for (i = 0; i < ctx.attr_nr; i++) {
if (!ctx.attr[i].divisor ||
ctx.attr[i].divisor != ++ctx.attr[i].step)
continue;
ctx.attr[i].step = 0;
ctx.attr[i].map += ctx.attr[i].stride;
}
u_split_prim_init(&s, mode, start, count);
do {
if (AVAIL_RING(chan) < p_overhead + (6 * vtx_size)) {
FIRE_RING(chan);
if (!nv50_state_validate(nv50, p_overhead + (6 * vtx_size))) {
assert(0);
return;
}
}
max_verts = AVAIL_RING(chan);
max_verts -= p_overhead;
max_verts /= vtx_size;
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1 << 28) : 0));
done = u_split_prim_next(&s, max_verts);
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
} while (!done);
nzi = TRUE;
}
}

View File

@ -95,6 +95,8 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
static int static int
nv50_screen_get_param(struct pipe_screen *pscreen, int param) nv50_screen_get_param(struct pipe_screen *pscreen, int param)
{ {
struct nv50_screen *screen = nv50_screen(pscreen);
switch (param) { switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return 32; return 32;
@ -132,9 +134,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1; return 1;
case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_VTXBUF:
return 1; return screen->force_push ? 0 : 1;
case NOUVEAU_CAP_HW_IDXBUF: case NOUVEAU_CAP_HW_IDXBUF:
return 1; return screen->force_push ? 0 : 1;
case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_INDEP_BLEND_ENABLE:
return 1; return 1;
case PIPE_CAP_INDEP_BLEND_FUNC: case PIPE_CAP_INDEP_BLEND_FUNC:
@ -202,28 +204,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
FREE(screen); FREE(screen);
} }
static int
nv50_pre_pipebuffer_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
unsigned usage)
{
struct nv50_screen *screen = nv50_screen(pscreen);
struct nv50_context *ctx = screen->cur_ctx;
if (!(pb->usage & PIPE_BUFFER_USAGE_VERTEX))
return 0;
/* Our vtxbuf got mapped, it can no longer be considered part of current
* state, remove it to avoid emitting reloc markers.
*/
if (ctx && ctx->state.vtxbuf && so_bo_is_reloc(ctx->state.vtxbuf,
nouveau_bo(pb))) {
so_ref(NULL, &ctx->state.vtxbuf);
ctx->dirty |= NV50_NEW_ARRAYS;
}
return 0;
}
struct pipe_screen * struct pipe_screen *
nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{ {
@ -252,7 +232,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
pscreen->get_paramf = nv50_screen_get_paramf; pscreen->get_paramf = nv50_screen_get_paramf;
pscreen->is_format_supported = nv50_screen_is_format_supported; pscreen->is_format_supported = nv50_screen_is_format_supported;
pscreen->context_create = nv50_create; pscreen->context_create = nv50_create;
screen->base.pre_pipebuffer_map_callback = nv50_pre_pipebuffer_map;
nv50_screen_init_miptree_functions(pscreen); nv50_screen_init_miptree_functions(pscreen);
nv50_transfer_init_screen_functions(pscreen); nv50_transfer_init_screen_functions(pscreen);
@ -508,10 +487,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_method(so, screen->tesla, NV50TCL_LINKED_TSC, 1); so_method(so, screen->tesla, NV50TCL_LINKED_TSC, 1);
so_data (so, 1); so_data (so, 1);
/* activate first scissor rectangle */
so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
so_data (so, 1);
so_method(so, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1); so_method(so, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
so_data (so, 1); /* default edgeflag to TRUE */ so_data (so, 1); /* default edgeflag to TRUE */
@ -520,6 +495,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_ref (NULL, &so); so_ref (NULL, &so);
nouveau_pushbuf_flush(chan, 0); nouveau_pushbuf_flush(chan, 0);
screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
return pscreen; return pscreen;
} }

View File

@ -28,6 +28,8 @@ struct nv50_screen {
struct nouveau_bo *tsc; struct nouveau_bo *tsc;
struct nouveau_stateobj *static_init; struct nouveau_stateobj *static_init;
boolean force_push;
}; };
static INLINE struct nv50_screen * static INLINE struct nv50_screen *

View File

@ -302,7 +302,7 @@ static void *
nv50_rasterizer_state_create(struct pipe_context *pipe, nv50_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso) const struct pipe_rasterizer_state *cso)
{ {
struct nouveau_stateobj *so = so_new(15, 21, 0); struct nouveau_stateobj *so = so_new(16, 22, 0);
struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
struct nv50_rasterizer_stateobj *rso = struct nv50_rasterizer_stateobj *rso =
CALLOC_STRUCT(nv50_rasterizer_stateobj); CALLOC_STRUCT(nv50_rasterizer_stateobj);
@ -314,6 +314,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
* - point_sprite / sprite_coord_mode * - point_sprite / sprite_coord_mode
*/ */
so_method(so, tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
so_data (so, cso->scissor);
so_method(so, tesla, NV50TCL_SHADE_MODEL, 1); so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT : so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
NV50TCL_SHADE_MODEL_SMOOTH); NV50TCL_SHADE_MODEL_SMOOTH);
@ -720,15 +723,34 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
nv50->dirty |= NV50_NEW_ARRAYS; nv50->dirty |= NV50_NEW_ARRAYS;
} }
static void *
nv50_vtxelts_state_create(struct pipe_context *pipe,
unsigned num_elements,
const struct pipe_vertex_element *elements)
{
struct nv50_vtxelt_stateobj *cso = CALLOC_STRUCT(nv50_vtxelt_stateobj);
assert(num_elements < 16); /* not doing fallbacks yet */
cso->num_elements = num_elements;
memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
nv50_vtxelt_construct(cso);
return (void *)cso;
}
static void static void
nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count, nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
const struct pipe_vertex_element *ve) {
FREE(hwcso);
}
static void
nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
{ {
struct nv50_context *nv50 = nv50_context(pipe); struct nv50_context *nv50 = nv50_context(pipe);
memcpy(nv50->vtxelt, ve, sizeof(*ve) * count); nv50->vtxelt = hwcso;
nv50->vtxelt_nr = count;
nv50->dirty |= NV50_NEW_ARRAYS; nv50->dirty |= NV50_NEW_ARRAYS;
} }
@ -778,7 +800,10 @@ nv50_init_state_functions(struct nv50_context *nv50)
nv50->pipe.set_scissor_state = nv50_set_scissor_state; nv50->pipe.set_scissor_state = nv50_set_scissor_state;
nv50->pipe.set_viewport_state = nv50_set_viewport_state; nv50->pipe.set_viewport_state = nv50_set_viewport_state;
nv50->pipe.create_vertex_elements_state = nv50_vtxelts_state_create;
nv50->pipe.delete_vertex_elements_state = nv50_vtxelts_state_delete;
nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers; nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
nv50->pipe.set_vertex_elements = nv50_set_vertex_elements;
} }

View File

@ -25,8 +25,8 @@
#include "nv50_context.h" #include "nv50_context.h"
#include "nouveau/nouveau_stateobj.h" #include "nouveau/nouveau_stateobj.h"
static void static struct nouveau_stateobj *
nv50_state_validate_fb(struct nv50_context *nv50) validate_fb(struct nv50_context *nv50)
{ {
struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so = so_new(32, 79, 18); struct nouveau_stateobj *so = so_new(32, 79, 18);
@ -167,12 +167,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_data (so, w << 16); so_data (so, w << 16);
so_data (so, h << 16); so_data (so, h << 16);
/* we set scissors to framebuffer size when they're 'turned off' */ return so;
nv50->dirty |= NV50_NEW_SCISSOR;
so_ref(NULL, &nv50->state.scissor);
so_ref(so, &nv50->state.fb);
so_ref(NULL, &so);
} }
static void static void
@ -199,263 +194,256 @@ nv50_validate_samplers(struct nv50_context *nv50, struct nouveau_stateobj *so,
} }
} }
static void static struct nouveau_stateobj *
nv50_state_emit(struct nv50_context *nv50) validate_blend(struct nv50_context *nv50)
{ {
struct nv50_screen *screen = nv50->screen; struct nouveau_stateobj *so = NULL;
struct nouveau_channel *chan = screen->base.channel; so_ref(nv50->blend->so, &so);
return so;
}
/* XXX: this is racy for multiple contexts active on separate static struct nouveau_stateobj *
* threads. validate_zsa(struct nv50_context *nv50)
{
struct nouveau_stateobj *so = NULL;
so_ref(nv50->zsa->so, &so);
return so;
}
static struct nouveau_stateobj *
validate_rast(struct nv50_context *nv50)
{
struct nouveau_stateobj *so = NULL;
so_ref(nv50->rasterizer->so, &so);
return so;
}
static struct nouveau_stateobj *
validate_blend_colour(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so = so_new(1, 4, 0);
so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
so_data (so, fui(nv50->blend_colour.color[0]));
so_data (so, fui(nv50->blend_colour.color[1]));
so_data (so, fui(nv50->blend_colour.color[2]));
so_data (so, fui(nv50->blend_colour.color[3]));
return so;
}
static struct nouveau_stateobj *
validate_stencil_ref(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so = so = so_new(2, 2, 0);
so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
so_data (so, nv50->stencil_ref.ref_value[0]);
so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
so_data (so, nv50->stencil_ref.ref_value[1]);
return so;
}
static struct nouveau_stateobj *
validate_stipple(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so = so_new(1, 32, 0);
int i;
so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
for (i = 0; i < 32; i++)
so_data(so, util_bswap32(nv50->stipple.stipple[i]));
return so;
}
static struct nouveau_stateobj *
validate_scissor(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct pipe_scissor_state *s = &nv50->scissor;
struct nouveau_stateobj *so;
so = so_new(1, 2, 0);
so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
so_data (so, (s->maxx << 16) | s->minx);
so_data (so, (s->maxy << 16) | s->miny);
return so;
}
static struct nouveau_stateobj *
validate_viewport(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so = so_new(5, 9, 0);
so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
so_data (so, fui(nv50->viewport.translate[0]));
so_data (so, fui(nv50->viewport.translate[1]));
so_data (so, fui(nv50->viewport.translate[2]));
so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
so_data (so, fui(nv50->viewport.scale[0]));
so_data (so, fui(nv50->viewport.scale[1]));
so_data (so, fui(nv50->viewport.scale[2]));
so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
so_data (so, 1);
/* 0x0000 = remove whole primitive only (xyz)
* 0x1018 = remove whole primitive only (xy), clamp z
* 0x1080 = clip primitive (xyz)
* 0x1098 = clip primitive (xy), clamp z
*/ */
if (screen->cur_ctx != nv50) { so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
if (nv50->state.fb) so_data (so, 0x1080);
nv50->state.dirty |= NV50_NEW_FRAMEBUFFER; /* no idea what 0f90 does */
if (nv50->state.blend) so_method(so, tesla, 0x0f90, 1);
nv50->state.dirty |= NV50_NEW_BLEND; so_data (so, 0);
if (nv50->state.zsa)
nv50->state.dirty |= NV50_NEW_ZSA;
if (nv50->state.vertprog)
nv50->state.dirty |= NV50_NEW_VERTPROG;
if (nv50->state.fragprog)
nv50->state.dirty |= NV50_NEW_FRAGPROG;
if (nv50->state.geomprog)
nv50->state.dirty |= NV50_NEW_GEOMPROG;
if (nv50->state.rast)
nv50->state.dirty |= NV50_NEW_RASTERIZER;
if (nv50->state.blend_colour)
nv50->state.dirty |= NV50_NEW_BLEND_COLOUR;
if (nv50->state.stencil_ref)
nv50->state.dirty |= NV50_NEW_STENCIL_REF;
if (nv50->state.stipple)
nv50->state.dirty |= NV50_NEW_STIPPLE;
if (nv50->state.scissor)
nv50->state.dirty |= NV50_NEW_SCISSOR;
if (nv50->state.viewport)
nv50->state.dirty |= NV50_NEW_VIEWPORT;
if (nv50->state.tsc_upload)
nv50->state.dirty |= NV50_NEW_SAMPLER;
if (nv50->state.tic_upload)
nv50->state.dirty |= NV50_NEW_TEXTURE;
if (nv50->state.vtxfmt && nv50->state.vtxbuf)
nv50->state.dirty |= NV50_NEW_ARRAYS;
screen->cur_ctx = nv50;
}
if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER) return so;
so_emit(chan, nv50->state.fb);
if (nv50->state.dirty & NV50_NEW_BLEND)
so_emit(chan, nv50->state.blend);
if (nv50->state.dirty & NV50_NEW_ZSA)
so_emit(chan, nv50->state.zsa);
if (nv50->state.dirty & NV50_NEW_VERTPROG)
so_emit(chan, nv50->state.vertprog);
if (nv50->state.dirty & NV50_NEW_FRAGPROG)
so_emit(chan, nv50->state.fragprog);
if (nv50->state.dirty & NV50_NEW_GEOMPROG && nv50->state.geomprog)
so_emit(chan, nv50->state.geomprog);
if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
so_emit(chan, nv50->state.fp_linkage);
if ((nv50->state.dirty & (NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG))
&& nv50->state.gp_linkage)
so_emit(chan, nv50->state.gp_linkage);
if (nv50->state.dirty & NV50_NEW_RASTERIZER)
so_emit(chan, nv50->state.rast);
if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
so_emit(chan, nv50->state.blend_colour);
if (nv50->state.dirty & NV50_NEW_STENCIL_REF)
so_emit(chan, nv50->state.stencil_ref);
if (nv50->state.dirty & NV50_NEW_STIPPLE)
so_emit(chan, nv50->state.stipple);
if (nv50->state.dirty & NV50_NEW_SCISSOR)
so_emit(chan, nv50->state.scissor);
if (nv50->state.dirty & NV50_NEW_VIEWPORT)
so_emit(chan, nv50->state.viewport);
if (nv50->state.dirty & NV50_NEW_SAMPLER)
so_emit(chan, nv50->state.tsc_upload);
if (nv50->state.dirty & NV50_NEW_TEXTURE)
so_emit(chan, nv50->state.tic_upload);
if (nv50->state.dirty & NV50_NEW_ARRAYS) {
so_emit(chan, nv50->state.vtxfmt);
so_emit(chan, nv50->state.vtxbuf);
if (nv50->state.vtxattr)
so_emit(chan, nv50->state.vtxattr);
}
nv50->state.dirty = 0;
} }
void static struct nouveau_stateobj *
nv50_state_flush_notify(struct nouveau_channel *chan) validate_sampler(struct nv50_context *nv50)
{
struct nv50_context *nv50 = chan->user_private;
if (nv50->state.tic_upload && !(nv50->dirty & NV50_NEW_TEXTURE))
so_emit(chan, nv50->state.tic_upload);
so_emit_reloc_markers(chan, nv50->state.fb);
so_emit_reloc_markers(chan, nv50->state.vertprog);
so_emit_reloc_markers(chan, nv50->state.fragprog);
so_emit_reloc_markers(chan, nv50->state.vtxbuf);
so_emit_reloc_markers(chan, nv50->screen->static_init);
if (nv50->state.instbuf)
so_emit_reloc_markers(chan, nv50->state.instbuf);
}
boolean
nv50_state_validate(struct nv50_context *nv50)
{ {
struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so; struct nouveau_stateobj *so;
unsigned i; unsigned nr = 0, i;
if (nv50->dirty & NV50_NEW_FRAMEBUFFER) for (i = 0; i < PIPE_SHADER_TYPES; ++i)
nv50_state_validate_fb(nv50); nr += nv50->sampler_nr[i];
if (nv50->dirty & NV50_NEW_BLEND) so = so_new(1 + 5 * PIPE_SHADER_TYPES,
so_ref(nv50->blend->so, &nv50->state.blend); 1 + 19 * PIPE_SHADER_TYPES + nr * 8,
PIPE_SHADER_TYPES * 2);
if (nv50->dirty & NV50_NEW_ZSA) nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
so_ref(nv50->zsa->so, &nv50->state.zsa); nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB)) so_method(so, tesla, 0x1334, 1); /* flush TSC */
nv50_vertprog_validate(nv50); so_data (so, 0);
if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB)) return so;
nv50_fragprog_validate(nv50); }
if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB)) static struct nouveau_stateobj *
nv50_geomprog_validate(nv50); validate_vtxbuf(struct nv50_context *nv50)
{
struct nouveau_stateobj *so = NULL;
so_ref(nv50->state.vtxbuf, &so);
return so;
}
if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG | static struct nouveau_stateobj *
NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER)) validate_vtxattr(struct nv50_context *nv50)
nv50_fp_linkage_validate(nv50); {
struct nouveau_stateobj *so = NULL;
so_ref(nv50->state.vtxattr, &so);
return so;
}
if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_VERTPROG)) struct state_validate {
nv50_gp_linkage_validate(nv50); struct nouveau_stateobj *(*func)(struct nv50_context *nv50);
unsigned states;
} validate_list[] = {
{ validate_fb , NV50_NEW_FRAMEBUFFER },
{ validate_blend , NV50_NEW_BLEND },
{ validate_zsa , NV50_NEW_ZSA },
{ nv50_vertprog_validate , NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB },
{ nv50_fragprog_validate , NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB },
{ nv50_geomprog_validate , NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB },
{ nv50_fp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG |
NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER },
{ nv50_gp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG },
{ validate_rast , NV50_NEW_RASTERIZER },
{ validate_blend_colour , NV50_NEW_BLEND_COLOUR },
{ validate_stencil_ref , NV50_NEW_STENCIL_REF },
{ validate_stipple , NV50_NEW_STIPPLE },
{ validate_scissor , NV50_NEW_SCISSOR },
{ validate_viewport , NV50_NEW_VIEWPORT },
{ validate_sampler , NV50_NEW_SAMPLER },
{ nv50_tex_validate , NV50_NEW_TEXTURE | NV50_NEW_SAMPLER },
{ nv50_vbo_validate , NV50_NEW_ARRAYS },
{ validate_vtxbuf , NV50_NEW_ARRAYS },
{ validate_vtxattr , NV50_NEW_ARRAYS },
{}
};
#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
if (nv50->dirty & NV50_NEW_RASTERIZER) boolean
so_ref(nv50->rasterizer->so, &nv50->state.rast); nv50_state_validate(struct nv50_context *nv50, unsigned wait_dwords)
{
struct nouveau_channel *chan = nv50->screen->base.channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
unsigned nr_relocs = 128, nr_dwords = wait_dwords + 128 + 4;
int ret, i;
if (nv50->dirty & NV50_NEW_BLEND_COLOUR) { for (i = 0; i < validate_list_len; i++) {
so = so_new(1, 4, 0); struct state_validate *validate = &validate_list[i];
so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4); struct nouveau_stateobj *so;
so_data (so, fui(nv50->blend_colour.color[0]));
so_data (so, fui(nv50->blend_colour.color[1])); if (!(nv50->dirty & validate->states))
so_data (so, fui(nv50->blend_colour.color[2])); continue;
so_data (so, fui(nv50->blend_colour.color[3]));
so_ref(so, &nv50->state.blend_colour); so = validate->func(nv50);
if (!so)
continue;
nr_dwords += (so->total + so->cur);
nr_relocs += so->cur_reloc;
so_ref(so, &nv50->state.hw[i]);
so_ref(NULL, &so); so_ref(NULL, &so);
nv50->state.hw_dirty |= (1 << i);
} }
if (nv50->dirty & NV50_NEW_STENCIL_REF) {
so = so_new(2, 2, 0);
so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
so_data (so, nv50->stencil_ref.ref_value[0]);
so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
so_data (so, nv50->stencil_ref.ref_value[1]);
so_ref(so, &nv50->state.stencil_ref);
so_ref(NULL, &so);
}
if (nv50->dirty & NV50_NEW_STIPPLE) {
so = so_new(1, 32, 0);
so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
for (i = 0; i < 32; i++)
so_data(so, util_bswap32(nv50->stipple.stipple[i]));
so_ref(so, &nv50->state.stipple);
so_ref(NULL, &so);
}
if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) {
struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe;
struct pipe_scissor_state *s = &nv50->scissor;
if (nv50->state.scissor &&
(rast->scissor == 0 && nv50->state.scissor_enabled == 0))
goto scissor_uptodate;
nv50->state.scissor_enabled = rast->scissor;
so = so_new(1, 2, 0);
so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
if (nv50->state.scissor_enabled) {
so_data(so, (s->maxx << 16) | s->minx);
so_data(so, (s->maxy << 16) | s->miny);
} else {
so_data(so, (nv50->framebuffer.width << 16));
so_data(so, (nv50->framebuffer.height << 16));
}
so_ref(so, &nv50->state.scissor);
so_ref(NULL, &so);
nv50->state.dirty |= NV50_NEW_SCISSOR;
}
scissor_uptodate:
if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) {
if (nv50->state.viewport &&
!(nv50->dirty & NV50_NEW_VIEWPORT))
goto viewport_uptodate;
so = so_new(5, 9, 0);
so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
so_data (so, fui(nv50->viewport.translate[0]));
so_data (so, fui(nv50->viewport.translate[1]));
so_data (so, fui(nv50->viewport.translate[2]));
so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
so_data (so, fui(nv50->viewport.scale[0]));
so_data (so, fui(nv50->viewport.scale[1]));
so_data (so, fui(nv50->viewport.scale[2]));
so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
so_data (so, 1);
/* 0x0000 = remove whole primitive only (xyz)
* 0x1018 = remove whole primitive only (xy), clamp z
* 0x1080 = clip primitive (xyz)
* 0x1098 = clip primitive (xy), clamp z
*/
so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
so_data (so, 0x1080);
/* no idea what 0f90 does */
so_method(so, tesla, 0x0f90, 1);
so_data (so, 0);
so_ref(so, &nv50->state.viewport);
so_ref(NULL, &so);
nv50->state.dirty |= NV50_NEW_VIEWPORT;
}
viewport_uptodate:
if (nv50->dirty & NV50_NEW_SAMPLER) {
unsigned nr = 0;
for (i = 0; i < PIPE_SHADER_TYPES; ++i)
nr += nv50->sampler_nr[i];
so = so_new(1 + 5 * PIPE_SHADER_TYPES,
1 + 19 * PIPE_SHADER_TYPES + nr * 8,
PIPE_SHADER_TYPES * 2);
nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
so_method(so, tesla, 0x1334, 1); /* flush TSC */
so_data (so, 0);
so_ref(so, &nv50->state.tsc_upload);
so_ref(NULL, &so);
}
if (nv50->dirty & (NV50_NEW_TEXTURE | NV50_NEW_SAMPLER))
nv50_tex_validate(nv50);
if (nv50->dirty & NV50_NEW_ARRAYS)
nv50_vbo_validate(nv50);
nv50->state.dirty |= nv50->dirty;
nv50->dirty = 0; nv50->dirty = 0;
nv50_state_emit(nv50);
if (nv50->screen->cur_ctx != nv50) {
for (i = 0; i < validate_list_len; i++) {
if (!nv50->state.hw[i] ||
(nv50->state.hw_dirty & (1 << i)))
continue;
nr_dwords += (nv50->state.hw[i]->total +
nv50->state.hw[i]->cur);
nr_relocs += nv50->state.hw[i]->cur_reloc;
nv50->state.hw_dirty |= (1 << i);
}
nv50->screen->cur_ctx = nv50;
}
ret = MARK_RING(chan, nr_dwords, nr_relocs);
if (ret) {
debug_printf("MARK_RING(%d, %d) failed: %d\n",
nr_dwords, nr_relocs, ret);
return FALSE;
}
while (nv50->state.hw_dirty) {
i = ffs(nv50->state.hw_dirty) - 1;
nv50->state.hw_dirty &= ~(1 << i);
so_emit(chan, nv50->state.hw[i]);
}
/* Yes, really, we need to do this. If a buffer that is referenced
* on the hardware isn't part of changed state above, without doing
* this the kernel is given no clue that the buffer is being used
* still. This can cause all sorts of fun issues.
*/
nv50_tex_relocs(nv50);
so_emit_reloc_markers(chan, nv50->state.hw[0]); /* fb */
so_emit_reloc_markers(chan, nv50->state.hw[3]); /* vp */
so_emit_reloc_markers(chan, nv50->state.hw[4]); /* fp */
so_emit_reloc_markers(chan, nv50->state.hw[17]); /* vb */
so_emit_reloc_markers(chan, nv50->screen->static_init);
/* No idea.. */
BEGIN_RING(chan, tesla, 0x142c, 1);
OUT_RING (chan, 0);
BEGIN_RING(chan, tesla, 0x142c, 1);
OUT_RING (chan, 0);
return TRUE; return TRUE;
} }

View File

@ -24,6 +24,7 @@
#include "nv50_texture.h" #include "nv50_texture.h"
#include "nouveau/nouveau_stateobj.h" #include "nouveau/nouveau_stateobj.h"
#include "nouveau/nouveau_reloc.h"
#include "util/u_format.h" #include "util/u_format.h"
@ -195,6 +196,35 @@ nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,
} }
void void
nv50_tex_relocs(struct nv50_context *nv50)
{
struct nouveau_channel *chan = nv50->screen->tesla->channel;
int p, unit;
p = PIPE_SHADER_FRAGMENT;
for (unit = 0; unit < nv50->miptree_nr[p]; unit++) {
if (!nv50->miptree[p][unit])
continue;
nouveau_reloc_emit(chan, nv50->screen->tic,
((p * 32) + unit) * 32, NULL,
nv50->miptree[p][unit]->base.bo, 0, 0,
NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
NOUVEAU_BO_RD, 0, 0);
}
p = PIPE_SHADER_VERTEX;
for (unit = 0; unit < nv50->miptree_nr[p]; unit++) {
if (!nv50->miptree[p][unit])
continue;
nouveau_reloc_emit(chan, nv50->screen->tic,
((p * 32) + unit) * 32, NULL,
nv50->miptree[p][unit]->base.bo, 0, 0,
NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
NOUVEAU_BO_RD, 0, 0);
}
}
struct nouveau_stateobj *
nv50_tex_validate(struct nv50_context *nv50) nv50_tex_validate(struct nv50_context *nv50)
{ {
struct nouveau_stateobj *so; struct nouveau_stateobj *so;
@ -217,12 +247,11 @@ nv50_tex_validate(struct nv50_context *nv50)
so_ref(NULL, &so); so_ref(NULL, &so);
NOUVEAU_ERR("failed tex validate\n"); NOUVEAU_ERR("failed tex validate\n");
return; return NULL;
} }
so_method(so, tesla, 0x1330, 1); /* flush TIC */ so_method(so, tesla, 0x1330, 1); /* flush TIC */
so_data (so, 0); so_data (so, 0);
so_ref(so, &nv50->state.tic_upload); return so;
so_ref(NULL, &so);
} }

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,7 @@ static void r300_blitter_save_states(struct r300_context* r300)
util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state); util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
util_blitter_save_viewport(r300->blitter, &r300->viewport); util_blitter_save_viewport(r300->blitter, &r300->viewport);
util_blitter_save_clip(r300->blitter, &r300->clip); util_blitter_save_clip(r300->blitter, &r300->clip);
util_blitter_save_vertex_elements(r300->blitter, r300->velems);
} }
/* Clear currently bound buffers. */ /* Clear currently bound buffers. */

View File

@ -60,7 +60,6 @@ static void r300_destroy_context(struct pipe_context* context)
FREE(r300->rs_block_state.state); FREE(r300->rs_block_state.state);
FREE(r300->scissor_state.state); FREE(r300->scissor_state.state);
FREE(r300->textures_state.state); FREE(r300->textures_state.state);
FREE(r300->vertex_stream_state.state);
FREE(r300->vap_output_state.state); FREE(r300->vap_output_state.state);
FREE(r300->viewport_state.state); FREE(r300->viewport_state.state);
FREE(r300->ztop_state.state); FREE(r300->ztop_state.state);
@ -147,7 +146,6 @@ static void r300_setup_atoms(struct r300_context* r300)
r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
r300->textures_state.state = CALLOC_STRUCT(r300_textures_state); r300->textures_state.state = CALLOC_STRUCT(r300_textures_state);
r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state); r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);

View File

@ -278,6 +278,23 @@ struct r300_texture {
enum r300_buffer_tiling microtile, macrotile; enum r300_buffer_tiling microtile, macrotile;
}; };
struct r300_vertex_info {
/* Parent class */
struct vertex_info vinfo;
/* R300_VAP_PROG_STREAK_CNTL_[0-7] */
uint32_t vap_prog_stream_cntl[8];
/* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
uint32_t vap_prog_stream_cntl_ext[8];
};
struct r300_vertex_element_state {
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
struct r300_vertex_stream_state vertex_stream;
};
extern struct pipe_viewport_state r300_viewport_identity; extern struct pipe_viewport_state r300_viewport_identity;
struct r300_context { struct r300_context {
@ -350,8 +367,7 @@ struct r300_context {
int vertex_buffer_count; int vertex_buffer_count;
int vertex_buffer_max_index; int vertex_buffer_max_index;
/* Vertex elements for Gallium. */ /* Vertex elements for Gallium. */
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; struct r300_vertex_element_state *velems;
int vertex_element_count;
/* Vertex info for Draw. */ /* Vertex info for Draw. */
struct vertex_info vertex_info; struct vertex_info vertex_info;

View File

@ -757,9 +757,9 @@ void r300_emit_textures_state(struct r300_context *r300,
void r300_emit_aos(struct r300_context* r300, unsigned offset) void r300_emit_aos(struct r300_context* r300, unsigned offset)
{ {
struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer; struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->vertex_element; struct pipe_vertex_element *velem = r300->velems->velem;
int i; int i;
unsigned size1, size2, aos_count = r300->vertex_element_count; unsigned size1, size2, aos_count = r300->velems->count;
unsigned packet_size = (aos_count * 3 + 1) / 2; unsigned packet_size = (aos_count * 3 + 1) / 2;
CS_LOCALS(r300); CS_LOCALS(r300);
@ -1004,7 +1004,7 @@ void r300_emit_buffer_validate(struct r300_context *r300,
(struct r300_textures_state*)r300->textures_state.state; (struct r300_textures_state*)r300->textures_state.state;
struct r300_texture* tex; struct r300_texture* tex;
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->vertex_element; struct pipe_vertex_element *velem = r300->velems->velem;
struct pipe_buffer *pbuf; struct pipe_buffer *pbuf;
unsigned i; unsigned i;
boolean invalid = FALSE; boolean invalid = FALSE;
@ -1062,7 +1062,7 @@ validate:
} }
/* ...vertex buffers for HWTCL path... */ /* ...vertex buffers for HWTCL path... */
if (do_validate_vertex_buffers) { if (do_validate_vertex_buffers) {
for (i = 0; i < r300->vertex_element_count; i++) { for (i = 0; i < r300->velems->count; i++) {
pbuf = vbuf[velem[i].vertex_buffer_index].buffer; pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
if (!r300->winsys->add_buffer(r300->winsys, pbuf, if (!r300->winsys->add_buffer(r300->winsys, pbuf,

View File

@ -143,7 +143,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
{ {
struct pipe_vertex_element* velem; struct pipe_vertex_element* velem;
struct pipe_vertex_buffer* vbuf; struct pipe_vertex_buffer* vbuf;
unsigned vertex_element_count = r300->vertex_element_count; unsigned vertex_element_count = r300->velems->count;
unsigned i, v, vbi, dw, elem_offset, dwords; unsigned i, v, vbi, dw, elem_offset, dwords;
/* Size of the vertex, in dwords. */ /* Size of the vertex, in dwords. */
@ -166,7 +166,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */ /* Calculate the vertex size, offsets, strides etc. and map the buffers. */
for (i = 0; i < vertex_element_count; i++) { for (i = 0; i < vertex_element_count; i++) {
velem = &r300->vertex_element[i]; velem = &r300->velems->velem[i];
offset[i] = velem->src_offset / 4; offset[i] = velem->src_offset / 4;
size[i] = util_format_get_blocksize(velem->src_format) / 4; size[i] = util_format_get_blocksize(velem->src_format) / 4;
vertex_size += size[i]; vertex_size += size[i];
@ -183,7 +183,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
} }
} }
dwords = 10 + count * vertex_size; dwords = 9 + count * vertex_size;
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
r300_emit_buffer_validate(r300, FALSE, NULL); r300_emit_buffer_validate(r300, FALSE, NULL);
@ -193,8 +193,9 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
OUT_CS_REG(R300_GA_COLOR_CONTROL, OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode)); r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); OUT_CS(count - 1);
OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) | OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
r300_translate_primitive(mode)); r300_translate_primitive(mode));
@ -202,7 +203,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Emit vertices. */ /* Emit vertices. */
for (v = 0; v < count; v++) { for (v = 0; v < count; v++) {
for (i = 0; i < vertex_element_count; i++) { for (i = 0; i < vertex_element_count; i++) {
velem = &r300->vertex_element[i]; velem = &r300->velems->velem[i];
vbi = velem->vertex_buffer_index; vbi = velem->vertex_buffer_index;
elem_offset = offset[i] + stride[vbi] * (v + start); elem_offset = offset[i] + stride[vbi] * (v + start);
@ -215,7 +216,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Unmap buffers. */ /* Unmap buffers. */
for (i = 0; i < vertex_element_count; i++) { for (i = 0; i < vertex_element_count; i++) {
vbi = r300->vertex_element[i].vertex_buffer_index; vbi = r300->velems->velem[i].vertex_buffer_index;
if (map[vbi]) { if (map[vbi]) {
vbuf = &r300->vertex_buffer[vbi]; vbuf = &r300->vertex_buffer[vbi];
@ -238,15 +239,16 @@ static void r300_emit_draw_arrays(struct r300_context *r300,
if (alt_num_verts) { if (alt_num_verts) {
assert(count < (1 << 24)); assert(count < (1 << 24));
BEGIN_CS(10); BEGIN_CS(9);
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
} else { } else {
BEGIN_CS(8); BEGIN_CS(7);
} }
OUT_CS_REG(R300_GA_COLOR_CONTROL, OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode)); r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); OUT_CS(count - 1);
OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
r300_translate_primitive(mode) | r300_translate_primitive(mode) |
@ -281,15 +283,16 @@ static void r300_emit_draw_elements(struct r300_context *r300,
maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index); maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index);
if (alt_num_verts) { if (alt_num_verts) {
BEGIN_CS(16); BEGIN_CS(15);
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
} else { } else {
BEGIN_CS(14); BEGIN_CS(13);
} }
OUT_CS_REG(R300_GA_COLOR_CONTROL, OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode)); r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex); OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex); OUT_CS(maxIndex);
OUT_CS(minIndex);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
if (indexSize == 4) { if (indexSize == 4) {
count_dwords = count; count_dwords = count;

View File

@ -1046,19 +1046,17 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
if (r300->draw) { if (r300->draw) {
draw_flush(r300->draw); draw_flush(r300->draw);
draw_set_vertex_buffers(r300->draw, count, buffers); draw_set_vertex_buffers(r300->draw, count, buffers);
} else {
r300->vertex_stream_state.dirty = TRUE;
} }
} }
static boolean r300_validate_aos(struct r300_context *r300) static boolean r300_validate_aos(struct r300_context *r300)
{ {
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->vertex_element; struct pipe_vertex_element *velem = r300->velems->velem;
int i; int i;
/* Check if formats and strides are aligned to the size of DWORD. */ /* Check if formats and strides are aligned to the size of DWORD. */
for (i = 0; i < r300->vertex_element_count; i++) { for (i = 0; i < r300->velems->count; i++) {
if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 || if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
util_format_get_blocksize(velem[i].src_format) % 4 != 0) { util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
return FALSE; return FALSE;
@ -1067,20 +1065,209 @@ static boolean r300_validate_aos(struct r300_context *r300)
return TRUE; return TRUE;
} }
static void r300_set_vertex_elements(struct pipe_context* pipe, static void r300_draw_emit_attrib(struct r300_context* r300,
unsigned count, enum attrib_emit emit,
const struct pipe_vertex_element* elements) enum interp_mode interp,
int index)
{ {
struct r300_context* r300 = r300_context(pipe); struct r300_vertex_shader* vs = r300->vs_state.state;
struct tgsi_shader_info* info = &vs->info;
int output;
memcpy(r300->vertex_element, output = draw_find_shader_output(r300->draw,
elements, info->output_semantic_name[index],
sizeof(struct pipe_vertex_element) * count); info->output_semantic_index[index]);
r300->vertex_element_count = count; draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output);
}
static void r300_draw_emit_all_attribs(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
struct r300_shader_semantics* vs_outputs = &vs->outputs;
int i, gen_count;
/* Position. */
if (vs_outputs->pos != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
vs_outputs->pos);
} else {
assert(0);
}
/* Point size. */
if (vs_outputs->psize != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
vs_outputs->psize);
}
/* Colors. */
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (vs_outputs->color[i] != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
vs_outputs->color[i]);
}
}
/* XXX Back-face colors. */
/* Texture coordinates. */
gen_count = 0;
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
if (vs_outputs->generic[i] != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
vs_outputs->generic[i]);
gen_count++;
}
}
/* Fog coordinates. */
if (vs_outputs->fog != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
vs_outputs->fog);
gen_count++;
}
/* XXX magic */
assert(gen_count <= 8);
}
/* Update the PSC tables. */
static void r300_vertex_psc(struct r300_vertex_element_state *velems)
{
struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i;
assert(velems->count <= 16);
/* Vertex shaders have no semantics on their inputs,
* so PSC should just route stuff based on the vertex elements,
* and not on attrib information. */
for (i = 0; i < velems->count; i++) {
format = velems->velem[i].src_format;
type = r300_translate_vertex_data_type(format) |
(i << R300_DST_VEC_LOC_SHIFT);
swizzle = r300_translate_vertex_data_swizzle(format);
if (i & 1) {
vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
} else {
vstream->vap_prog_stream_cntl[i >> 1] |= type;
vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
}
}
/* Set the last vector in the PSC. */
if (i) {
i -= 1;
}
vstream->vap_prog_stream_cntl[i >> 1] |=
(R300_LAST_VEC << (i & 1 ? 16 : 0));
vstream->count = (i >> 1) + 1;
}
/* Update the PSC tables for SW TCL, using Draw. */
static void r300_swtcl_vertex_psc(struct r300_context *r300,
struct r300_vertex_element_state *velems)
{
struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
struct r300_vertex_shader* vs = r300->vs_state.state;
struct vertex_info* vinfo = &r300->vertex_info;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i, attrib_count;
int* vs_output_tab = vs->stream_loc_notcl;
/* For each Draw attribute, route it to the fragment shader according
* to the vs_output_tab. */
attrib_count = vinfo->num_attribs;
DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
for (i = 0; i < attrib_count; i++) {
DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
" vs_output_tab %d\n", vinfo->attrib[i].src_index,
vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
vs_output_tab[i]);
}
for (i = 0; i < attrib_count; i++) {
/* Make sure we have a proper destination for our attribute. */
assert(vs_output_tab[i] != -1);
format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
/* Obtain the type of data in this attribute. */
type = r300_translate_vertex_data_type(format) |
vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
/* Obtain the swizzle for this attribute. Note that the default
* swizzle in the hardware is not XYZW! */
swizzle = r300_translate_vertex_data_swizzle(format);
/* Add the attribute to the PSC table. */
if (i & 1) {
vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
} else {
vstream->vap_prog_stream_cntl[i >> 1] |= type;
vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
}
}
/* Set the last vector in the PSC. */
if (i) {
i -= 1;
}
vstream->vap_prog_stream_cntl[i >> 1] |=
(R300_LAST_VEC << (i & 1 ? 16 : 0));
vstream->count = (i >> 1) + 1;
}
static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
unsigned count,
const struct pipe_vertex_element* attribs)
{
struct r300_context *r300 = r300_context(pipe);
struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_vertex_element_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
velems = CALLOC_STRUCT(r300_vertex_element_state);
if (velems != NULL) {
velems->count = count;
memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
if (r300screen->caps->has_tcl) {
r300_vertex_psc(velems);
} else {
memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
r300_draw_emit_all_attribs(r300);
draw_compute_vertex_size(&r300->vertex_info);
r300_swtcl_vertex_psc(r300, velems);
}
}
return velems;
}
static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
void *state)
{
struct r300_context *r300 = r300_context(pipe);
struct r300_vertex_element_state *velems = state;
if (velems == NULL) {
return;
}
r300->velems = velems;
if (r300->draw) { if (r300->draw) {
draw_flush(r300->draw); draw_flush(r300->draw);
draw_set_vertex_elements(r300->draw, count, elements); draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
} }
if (!r300_validate_aos(r300)) { if (!r300_validate_aos(r300)) {
@ -1088,6 +1275,14 @@ static void r300_set_vertex_elements(struct pipe_context* pipe,
assert(0); assert(0);
abort(); abort();
} }
UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2;
}
static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
{
FREE(state);
} }
static void* r300_create_vs_state(struct pipe_context* pipe, static void* r300_create_vs_state(struct pipe_context* pipe,
@ -1262,7 +1457,10 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.set_viewport_state = r300_set_viewport_state; r300->context.set_viewport_state = r300_set_viewport_state;
r300->context.set_vertex_buffers = r300_set_vertex_buffers; r300->context.set_vertex_buffers = r300_set_vertex_buffers;
r300->context.set_vertex_elements = r300_set_vertex_elements;
r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
r300->context.delete_vertex_elements_state = r300_delete_vertex_elements_state;
r300->context.create_vs_state = r300_create_vs_state; r300->context.create_vs_state = r300_create_vs_state;
r300->context.bind_vs_state = r300_bind_vs_state; r300->context.bind_vs_state = r300_bind_vs_state;

View File

@ -37,187 +37,6 @@
/* r300_state_derived: Various bits of state which are dependent upon /* r300_state_derived: Various bits of state which are dependent upon
* currently bound CSO data. */ * currently bound CSO data. */
static void r300_draw_emit_attrib(struct r300_context* r300,
enum attrib_emit emit,
enum interp_mode interp,
int index)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
struct tgsi_shader_info* info = &vs->info;
int output;
output = draw_find_shader_output(r300->draw,
info->output_semantic_name[index],
info->output_semantic_index[index]);
draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output);
}
static void r300_draw_emit_all_attribs(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
struct r300_shader_semantics* vs_outputs = &vs->outputs;
int i, gen_count;
/* Position. */
if (vs_outputs->pos != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
vs_outputs->pos);
} else {
assert(0);
}
/* Point size. */
if (vs_outputs->psize != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
vs_outputs->psize);
}
/* Colors. */
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (vs_outputs->color[i] != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
vs_outputs->color[i]);
}
}
/* XXX Back-face colors. */
/* Texture coordinates. */
gen_count = 0;
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
if (vs_outputs->generic[i] != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
vs_outputs->generic[i]);
gen_count++;
}
}
/* Fog coordinates. */
if (vs_outputs->fog != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
vs_outputs->fog);
gen_count++;
}
/* XXX magic */
assert(gen_count <= 8);
}
/* Update the PSC tables. */
/* XXX move this function into r300_state.c after TCL-bypass gets removed
* XXX because this one is dependent only on vertex elements. */
static void r300_vertex_psc(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
struct r300_vertex_stream_state *vformat =
(struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i;
int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int* stream_tab;
memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
stream_tab = identity;
/* Vertex shaders have no semantics on their inputs,
* so PSC should just route stuff based on the vertex elements,
* and not on attrib information. */
DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements"
" in psc\n",
vs->info.num_inputs,
r300->vertex_element_count);
for (i = 0; i < r300->vertex_element_count; i++) {
format = r300->vertex_element[i].src_format;
type = r300_translate_vertex_data_type(format) |
(stream_tab[i] << R300_DST_VEC_LOC_SHIFT);
swizzle = r300_translate_vertex_data_swizzle(format);
if (i & 1) {
vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
} else {
vformat->vap_prog_stream_cntl[i >> 1] |= type;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
}
}
assert(i <= 15);
/* Set the last vector in the PSC. */
if (i) {
i -= 1;
}
vformat->vap_prog_stream_cntl[i >> 1] |=
(R300_LAST_VEC << (i & 1 ? 16 : 0));
vformat->count = (i >> 1) + 1;
r300->vertex_stream_state.size = (1 + vformat->count) * 2;
}
/* Update the PSC tables for SW TCL, using Draw. */
static void r300_swtcl_vertex_psc(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
struct r300_vertex_stream_state *vformat =
(struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
struct vertex_info* vinfo = &r300->vertex_info;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i, attrib_count;
int* vs_output_tab = vs->stream_loc_notcl;
memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
/* For each Draw attribute, route it to the fragment shader according
* to the vs_output_tab. */
attrib_count = vinfo->num_attribs;
DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
for (i = 0; i < attrib_count; i++) {
DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
" vs_output_tab %d\n", vinfo->attrib[i].src_index,
vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
vs_output_tab[i]);
}
for (i = 0; i < attrib_count; i++) {
/* Make sure we have a proper destination for our attribute. */
assert(vs_output_tab[i] != -1);
format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
/* Obtain the type of data in this attribute. */
type = r300_translate_vertex_data_type(format) |
vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
/* Obtain the swizzle for this attribute. Note that the default
* swizzle in the hardware is not XYZW! */
swizzle = r300_translate_vertex_data_swizzle(format);
/* Add the attribute to the PSC table. */
if (i & 1) {
vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
} else {
vformat->vap_prog_stream_cntl[i >> 1] |= type;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
}
}
/* Set the last vector in the PSC. */
if (i) {
i -= 1;
}
vformat->vap_prog_stream_cntl[i >> 1] |=
(R300_LAST_VEC << (i & 1 ? 16 : 0));
vformat->count = (i >> 1) + 1;
r300->vertex_stream_state.size = (1 + vformat->count) * 2;
}
static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
boolean swizzle_0001) boolean swizzle_0001)
{ {
@ -432,18 +251,8 @@ static void r300_update_rs_block(struct r300_context* r300,
static void r300_update_derived_shader_state(struct r300_context* r300) static void r300_update_derived_shader_state(struct r300_context* r300)
{ {
struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_vertex_shader* vs = r300->vs_state.state;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs);
if (r300screen->caps->has_tcl) {
r300_vertex_psc(r300);
} else {
memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
r300_draw_emit_all_attribs(r300);
draw_compute_vertex_size(&r300->vertex_info);
r300_swtcl_vertex_psc(r300);
}
} }
static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa) static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
@ -576,8 +385,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
void r300_update_derived_state(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300)
{ {
if (r300->rs_block_state.dirty || if (r300->rs_block_state.dirty) {
r300->vertex_stream_state.dirty) { /* XXX put updating PSC out of this file */
r300_update_derived_shader_state(r300); r300_update_derived_shader_state(r300);
} }

View File

@ -348,39 +348,12 @@ static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
return 0; return 0;
} }
/* Utility function to count the number of components in RGBAZS formats.
* XXX should go to util or p_format.h */
static INLINE unsigned pf_component_count(enum pipe_format format) {
unsigned count = 0;
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
count++;
}
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)) {
count++;
}
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)) {
count++;
}
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)) {
count++;
}
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) {
count++;
}
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
count++;
}
return count;
}
/* Translate pipe_formats into PSC vertex types. */ /* Translate pipe_formats into PSC vertex types. */
static INLINE uint16_t static INLINE uint16_t
r300_translate_vertex_data_type(enum pipe_format format) { r300_translate_vertex_data_type(enum pipe_format format) {
uint32_t result = 0; uint32_t result = 0;
const struct util_format_description *desc; const struct util_format_description *desc;
unsigned components = pf_component_count(format); unsigned components = util_format_get_nr_components(format);
desc = util_format_description(format); desc = util_format_description(format);

View File

@ -245,6 +245,10 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.bind_gs_state = softpipe_bind_gs_state; softpipe->pipe.bind_gs_state = softpipe_bind_gs_state;
softpipe->pipe.delete_gs_state = softpipe_delete_gs_state; softpipe->pipe.delete_gs_state = softpipe_delete_gs_state;
softpipe->pipe.create_vertex_elements_state = softpipe_create_vertex_elements_state;
softpipe->pipe.bind_vertex_elements_state = softpipe_bind_vertex_elements_state;
softpipe->pipe.delete_vertex_elements_state = softpipe_delete_vertex_elements_state;
softpipe->pipe.set_blend_color = softpipe_set_blend_color; softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref; softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref;
softpipe->pipe.set_clip_state = softpipe_set_clip_state; softpipe->pipe.set_clip_state = softpipe_set_clip_state;
@ -257,7 +261,6 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers; softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
softpipe->pipe.set_vertex_elements = softpipe_set_vertex_elements;
softpipe->pipe.draw_arrays = softpipe_draw_arrays; softpipe->pipe.draw_arrays = softpipe_draw_arrays;
softpipe->pipe.draw_elements = softpipe_draw_elements; softpipe->pipe.draw_elements = softpipe_draw_elements;

View File

@ -45,6 +45,7 @@ struct softpipe_tile_cache;
struct softpipe_tex_tile_cache; struct softpipe_tex_tile_cache;
struct sp_fragment_shader; struct sp_fragment_shader;
struct sp_vertex_shader; struct sp_vertex_shader;
struct sp_velems_state;
struct softpipe_context { struct softpipe_context {
@ -59,6 +60,7 @@ struct softpipe_context {
struct sp_fragment_shader *fs; struct sp_fragment_shader *fs;
struct sp_vertex_shader *vs; struct sp_vertex_shader *vs;
struct sp_geometry_shader *gs; struct sp_geometry_shader *gs;
struct sp_velems_state *velems;
/** Other rendering state */ /** Other rendering state */
struct pipe_blend_color blend_color; struct pipe_blend_color blend_color;
@ -72,13 +74,11 @@ struct softpipe_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers; unsigned num_samplers;
unsigned num_textures; unsigned num_textures;
unsigned num_vertex_samplers; unsigned num_vertex_samplers;
unsigned num_vertex_textures; unsigned num_vertex_textures;
unsigned num_vertex_elements;
unsigned num_vertex_buffers; unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of SP_NEW_x flags */ unsigned dirty; /**< Mask of SP_NEW_x flags */

View File

@ -100,6 +100,11 @@ struct sp_geometry_shader {
struct draw_geometry_shader *draw_data; struct draw_geometry_shader *draw_data;
}; };
struct sp_velems_state {
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
};
void * void *
softpipe_create_blend_state(struct pipe_context *, softpipe_create_blend_state(struct pipe_context *,
@ -160,8 +165,14 @@ void *softpipe_create_gs_state(struct pipe_context *,
void softpipe_bind_gs_state(struct pipe_context *, void *); void softpipe_bind_gs_state(struct pipe_context *, void *);
void softpipe_delete_gs_state(struct pipe_context *, void *); void softpipe_delete_gs_state(struct pipe_context *, void *);
void *softpipe_create_vertex_elements_state(struct pipe_context *,
unsigned count,
const struct pipe_vertex_element *);
void softpipe_bind_vertex_elements_state(struct pipe_context *, void *);
void softpipe_delete_vertex_elements_state(struct pipe_context *, void *);
void softpipe_set_polygon_stipple( struct pipe_context *, void softpipe_set_polygon_stipple( struct pipe_context *,
const struct pipe_poly_stipple * ); const struct pipe_poly_stipple * );
void softpipe_set_scissor_state( struct pipe_context *, void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * ); const struct pipe_scissor_state * );
@ -178,10 +189,6 @@ softpipe_set_vertex_sampler_textures(struct pipe_context *,
void softpipe_set_viewport_state( struct pipe_context *, void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * ); const struct pipe_viewport_state * );
void softpipe_set_vertex_elements(struct pipe_context *,
unsigned count,
const struct pipe_vertex_element *);
void softpipe_set_vertex_buffers(struct pipe_context *, void softpipe_set_vertex_buffers(struct pipe_context *,
unsigned count, unsigned count,
const struct pipe_vertex_buffer *); const struct pipe_vertex_buffer *);

View File

@ -32,27 +32,44 @@
#include "sp_context.h" #include "sp_context.h"
#include "sp_state.h" #include "sp_state.h"
#include "util/u_memory.h"
#include "draw/draw_context.h" #include "draw/draw_context.h"
void *
softpipe_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *attribs)
{
struct sp_velems_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
velems = (struct sp_velems_state *) MALLOC(sizeof(struct sp_velems_state));
if (velems) {
velems->count = count;
memcpy(velems->velem, attribs, sizeof(*attribs) * count);
}
return velems;
}
void void
softpipe_set_vertex_elements(struct pipe_context *pipe, softpipe_bind_vertex_elements_state(struct pipe_context *pipe,
unsigned count, void *velems)
const struct pipe_vertex_element *attribs)
{ {
struct softpipe_context *softpipe = softpipe_context(pipe); struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_velems_state *sp_velems = (struct sp_velems_state *) velems;
assert(count <= PIPE_MAX_ATTRIBS); softpipe->velems = sp_velems;
memcpy(softpipe->vertex_element, attribs,
count * sizeof(struct pipe_vertex_element));
softpipe->num_vertex_elements = count;
softpipe->dirty |= SP_NEW_VERTEX; softpipe->dirty |= SP_NEW_VERTEX;
draw_set_vertex_elements(softpipe->draw, count, attribs); draw_set_vertex_elements(softpipe->draw, sp_velems->count, sp_velems->velem);
} }
void
softpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
}
void void
softpipe_set_vertex_buffers(struct pipe_context *pipe, softpipe_set_vertex_buffers(struct pipe_context *pipe,

View File

@ -169,6 +169,11 @@ struct svga_sampler_state {
unsigned view_max_lod; unsigned view_max_lod;
}; };
struct svga_velems_state {
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
};
/* Use to calculate differences between state emitted to hardware and /* Use to calculate differences between state emitted to hardware and
* current driver-calculated state. * current driver-calculated state.
*/ */
@ -178,13 +183,13 @@ struct svga_state
const struct svga_depth_stencil_state *depth; const struct svga_depth_stencil_state *depth;
const struct svga_rasterizer_state *rast; const struct svga_rasterizer_state *rast;
const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct svga_velems_state *velems;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */ struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */
struct svga_fragment_shader *fs; struct svga_fragment_shader *fs;
struct svga_vertex_shader *vs; struct svga_vertex_shader *vs;
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
struct pipe_buffer *cb[PIPE_SHADER_TYPES]; struct pipe_buffer *cb[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer; struct pipe_framebuffer_state framebuffer;
@ -204,7 +209,6 @@ struct svga_state
unsigned num_samplers; unsigned num_samplers;
unsigned num_textures; unsigned num_textures;
unsigned num_vertex_elements;
unsigned num_vertex_buffers; unsigned num_vertex_buffers;
unsigned reduced_prim; unsigned reduced_prim;

View File

@ -26,6 +26,7 @@
#include "util/u_inlines.h" #include "util/u_inlines.h"
#include "pipe/p_defines.h" #include "pipe/p_defines.h"
#include "util/u_math.h" #include "util/u_math.h"
#include "util/u_memory.h"
#include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_parse.h"
#include "svga_screen.h" #include "svga_screen.h"
@ -64,20 +65,37 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
svga->dirty |= SVGA_NEW_VBUFFER; svga->dirty |= SVGA_NEW_VBUFFER;
} }
static void svga_set_vertex_elements(struct pipe_context *pipe,
unsigned count, static void *
const struct pipe_vertex_element *elements) svga_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *attribs)
{
struct svga_velems_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
velems = (struct svga_velems_state *) MALLOC(sizeof(struct svga_velems_state));
if (velems) {
velems->count = count;
memcpy(velems->velem, attribs, sizeof(*attribs) * count);
}
return velems;
}
static void svga_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{ {
struct svga_context *svga = svga_context(pipe); struct svga_context *svga = svga_context(pipe);
unsigned i; struct svga_velems_state *svga_velems = (struct svga_velems_state *) velems;
for (i = 0; i < count; i++) svga->curr.velems = svga_velems;
svga->curr.ve[i] = elements[i];
svga->curr.num_vertex_elements = count;
svga->dirty |= SVGA_NEW_VELEMENT; svga->dirty |= SVGA_NEW_VELEMENT;
} }
static void svga_delete_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{
FREE(velems);
}
void svga_cleanup_vertex_state( struct svga_context *svga ) void svga_cleanup_vertex_state( struct svga_context *svga )
{ {
@ -91,7 +109,9 @@ void svga_cleanup_vertex_state( struct svga_context *svga )
void svga_init_vertex_functions( struct svga_context *svga ) void svga_init_vertex_functions( struct svga_context *svga )
{ {
svga->pipe.set_vertex_buffers = svga_set_vertex_buffers; svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
svga->pipe.set_vertex_elements = svga_set_vertex_elements; svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state;
svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state;
svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state;
} }

View File

@ -76,8 +76,8 @@ static int update_need_swvfetch( struct svga_context *svga,
unsigned i; unsigned i;
boolean need_swvfetch = FALSE; boolean need_swvfetch = FALSE;
for (i = 0; i < svga->curr.num_vertex_elements; i++) { for (i = 0; i < svga->curr.velems->count; i++) {
svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.ve[i].src_format); svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.velems->velem[i].src_format);
if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) { if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) {
need_swvfetch = TRUE; need_swvfetch = TRUE;
break; break;

View File

@ -191,15 +191,24 @@ static int emit_rss( struct svga_context *svga,
EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail ); EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail );
} }
if (dirty & SVGA_NEW_RAST) if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
{ {
const struct svga_rasterizer_state *curr = svga->curr.rast; const struct svga_rasterizer_state *curr = svga->curr.rast;
unsigned cullmode = curr->cullmode;
/* Shademode: still need to rearrange index list to move /* Shademode: still need to rearrange index list to move
* flat-shading PV first vertex. * flat-shading PV first vertex.
*/ */
EMIT_RS( svga, curr->shademode, SHADEMODE, fail ); EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
/* Don't do culling while the software pipeline is active. It
* does it for us, and additionally introduces potentially
* back-facing triangles.
*/
if (svga->state.sw.need_pipeline)
cullmode = SVGA3D_FACE_NONE;
EMIT_RS( svga, cullmode, CULLMODE, fail );
EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail ); EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail ); EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail ); EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );

View File

@ -95,17 +95,17 @@ upload_user_buffers( struct svga_context *svga )
static int emit_hw_vs_vdecl( struct svga_context *svga, static int emit_hw_vs_vdecl( struct svga_context *svga,
unsigned dirty ) unsigned dirty )
{ {
const struct pipe_vertex_element *ve = svga->curr.ve; const struct pipe_vertex_element *ve = svga->curr.velems->velem;
SVGA3dVertexDecl decl; SVGA3dVertexDecl decl;
unsigned i; unsigned i;
assert(svga->curr.num_vertex_elements >= assert(svga->curr.velems->count >=
svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]); svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
svga_hwtnl_reset_vdecl( svga->hwtnl, svga_hwtnl_reset_vdecl( svga->hwtnl,
svga->curr.num_vertex_elements ); svga->curr.velems->count );
for (i = 0; i < svga->curr.num_vertex_elements; i++) { for (i = 0; i < svga->curr.velems->count; i++) {
const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
unsigned usage, index; unsigned usage, index;

View File

@ -186,8 +186,8 @@ static int update_zero_stride( struct svga_context *svga,
svga->curr.zero_stride_vertex_elements = 0; svga->curr.zero_stride_vertex_elements = 0;
svga->curr.num_zero_stride_vertex_elements = 0; svga->curr.num_zero_stride_vertex_elements = 0;
for (i = 0; i < svga->curr.num_vertex_elements; i++) { for (i = 0; i < svga->curr.velems->count; i++) {
const struct pipe_vertex_element *vel = &svga->curr.ve[i]; const struct pipe_vertex_element *vel = &svga->curr.velems->velem[i];
const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[ const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[
vel->vertex_buffer_index]; vel->vertex_buffer_index];
if (vbuffer->stride == 0) { if (vbuffer->stride == 0) {

View File

@ -99,8 +99,8 @@ static int update_swtnl_draw( struct svga_context *svga,
if (dirty & SVGA_NEW_VELEMENT) if (dirty & SVGA_NEW_VELEMENT)
draw_set_vertex_elements(svga->swtnl.draw, draw_set_vertex_elements(svga->swtnl.draw,
svga->curr.num_vertex_elements, svga->curr.velems->count,
svga->curr.ve ); svga->curr.velems->velem );
if (dirty & SVGA_NEW_CLIP) if (dirty & SVGA_NEW_CLIP)
draw_set_clip_state(svga->swtnl.draw, draw_set_clip_state(svga->swtnl.draw,

View File

@ -773,6 +773,70 @@ trace_context_delete_vs_state(struct pipe_context *_pipe,
} }
static INLINE void *
trace_context_create_vertex_elements_state(struct pipe_context *_pipe,
unsigned num_elements,
const struct pipe_vertex_element *elements)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
void * result;
trace_dump_call_begin("pipe_context", "create_vertex_elements_state");
trace_dump_arg(ptr, pipe);
trace_dump_arg(uint, num_elements);
trace_dump_arg_begin("elements");
trace_dump_struct_array(vertex_element, elements, num_elements);
trace_dump_arg_end();
result = pipe->create_vertex_elements_state(pipe, num_elements, elements);
trace_dump_ret(ptr, result);
trace_dump_call_end();
return result;
}
static INLINE void
trace_context_bind_vertex_elements_state(struct pipe_context *_pipe,
void *state)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
trace_dump_call_begin("pipe_context", "bind_vertex_elements_state");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, state);
pipe->bind_vertex_elements_state(pipe, state);
trace_dump_call_end();
}
static INLINE void
trace_context_delete_vertex_elements_state(struct pipe_context *_pipe,
void *state)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
trace_dump_call_begin("pipe_context", "delete_verte_elements_state");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, state);
pipe->delete_vertex_elements_state(pipe, state);
trace_dump_call_end();
}
static INLINE void static INLINE void
trace_context_set_blend_color(struct pipe_context *_pipe, trace_context_set_blend_color(struct pipe_context *_pipe,
const struct pipe_blend_color *state) const struct pipe_blend_color *state)
@ -1047,29 +1111,6 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe,
} }
static INLINE void
trace_context_set_vertex_elements(struct pipe_context *_pipe,
unsigned num_elements,
const struct pipe_vertex_element *elements)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
trace_dump_call_begin("pipe_context", "set_vertex_elements");
trace_dump_arg(ptr, pipe);
trace_dump_arg(uint, num_elements);
trace_dump_arg_begin("elements");
trace_dump_struct_array(vertex_element, elements, num_elements);
trace_dump_arg_end();
pipe->set_vertex_elements(pipe, num_elements, elements);
trace_dump_call_end();
}
static INLINE void static INLINE void
trace_context_surface_copy(struct pipe_context *_pipe, trace_context_surface_copy(struct pipe_context *_pipe,
struct pipe_surface *dest, struct pipe_surface *dest,
@ -1303,6 +1344,9 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.create_vs_state = trace_context_create_vs_state; tr_ctx->base.create_vs_state = trace_context_create_vs_state;
tr_ctx->base.bind_vs_state = trace_context_bind_vs_state; tr_ctx->base.bind_vs_state = trace_context_bind_vs_state;
tr_ctx->base.delete_vs_state = trace_context_delete_vs_state; tr_ctx->base.delete_vs_state = trace_context_delete_vs_state;
tr_ctx->base.create_vertex_elements_state = trace_context_create_vertex_elements_state;
tr_ctx->base.bind_vertex_elements_state = trace_context_bind_vertex_elements_state;
tr_ctx->base.delete_vertex_elements_state = trace_context_delete_vertex_elements_state;
tr_ctx->base.set_blend_color = trace_context_set_blend_color; tr_ctx->base.set_blend_color = trace_context_set_blend_color;
tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref; tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref;
tr_ctx->base.set_clip_state = trace_context_set_clip_state; tr_ctx->base.set_clip_state = trace_context_set_clip_state;
@ -1314,7 +1358,6 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures; tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures;
tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures; tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures;
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements;
if (pipe->surface_copy) if (pipe->surface_copy)
tr_ctx->base.surface_copy = trace_context_surface_copy; tr_ctx->base.surface_copy = trace_context_surface_copy;
if (pipe->surface_fill) if (pipe->surface_fill)

View File

@ -479,7 +479,6 @@ void trace_dump_vertex_element(const struct pipe_vertex_element *state)
trace_dump_member(uint, state, src_offset); trace_dump_member(uint, state, src_offset);
trace_dump_member(uint, state, vertex_buffer_index); trace_dump_member(uint, state, vertex_buffer_index);
trace_dump_member(uint, state, nr_components);
trace_dump_member(format, state, src_format); trace_dump_member(format, state, src_format);

View File

@ -31,13 +31,8 @@
#include "p_config.h" #include "p_config.h"
#ifndef XFree86Server
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#else
#include "xf86_ansic.h"
#include "xf86_libc.h"
#endif
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>

View File

@ -177,6 +177,12 @@ struct pipe_context {
void (*bind_gs_state)(struct pipe_context *, void *); void (*bind_gs_state)(struct pipe_context *, void *);
void (*delete_gs_state)(struct pipe_context *, void *); void (*delete_gs_state)(struct pipe_context *, void *);
void * (*create_vertex_elements_state)(struct pipe_context *,
unsigned num_elements,
const struct pipe_vertex_element *);
void (*bind_vertex_elements_state)(struct pipe_context *, void *);
void (*delete_vertex_elements_state)(struct pipe_context *, void *);
/*@}*/ /*@}*/
/** /**
@ -220,9 +226,6 @@ struct pipe_context {
unsigned num_buffers, unsigned num_buffers,
const struct pipe_vertex_buffer * ); const struct pipe_vertex_buffer * );
void (*set_vertex_elements)( struct pipe_context *,
unsigned num_elements,
const struct pipe_vertex_element * );
/*@}*/ /*@}*/

View File

@ -373,7 +373,6 @@ struct pipe_vertex_element
* this attribute live in? * this attribute live in?
*/ */
unsigned vertex_buffer_index:8; unsigned vertex_buffer_index:8;
unsigned nr_components:8;
enum pipe_format src_format; enum pipe_format src_format;
}; };

View File

@ -222,9 +222,9 @@ struct st_context {
void set_vertex_elements(unsigned num) void set_vertex_elements(unsigned num)
{ {
$self->num_vertex_elements = num; $self->num_vertex_elements = num;
$self->pipe->set_vertex_elements($self->pipe, cso_set_vertex_elements($self->cso,
$self->num_vertex_elements, $self->num_vertex_elements,
$self->vertex_elements); $self->vertex_elements);
} }
/* /*

View File

@ -86,6 +86,8 @@ draw_clear_quad(struct vg_context *st,
/* draw */ /* draw */
if (buf) { if (buf) {
cso_set_vertex_elements(st->cso_context, 2, st->velems);
util_draw_vertex_buffer(pipe, buf, 0, util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN, PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */ 4, /* verts */

View File

@ -292,12 +292,12 @@ static void draw_polygon(struct vg_context *ctx,
pipe->set_vertex_buffers(pipe, 1, &vbuffer); pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */ /* tell pipe about the vertex attributes */
memset(&velement, 0, sizeof(velement));
velement.src_offset = 0; velement.src_offset = 0;
velement.instance_divisor = 0; velement.instance_divisor = 0;
velement.vertex_buffer_index = 0; velement.vertex_buffer_index = 0;
velement.src_format = PIPE_FORMAT_R32G32_FLOAT; velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
velement.nr_components = COMPONENTS; cso_set_vertex_elements(ctx->cso_context, 1, &velement);
pipe->set_vertex_elements(pipe, 1, &velement);
/* draw */ /* draw */
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN,

View File

@ -210,6 +210,7 @@ void renderer_draw_quad(struct renderer *r,
buf = setup_vertex_data(r, x1, y1, x2, y2, depth); buf = setup_vertex_data(r, x1, y1, x2, y2, depth);
if (buf) { if (buf) {
cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(r->pipe, buf, 0, util_draw_vertex_buffer(r->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN, PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */ 4, /* verts */
@ -248,6 +249,7 @@ void renderer_draw_texture(struct renderer *r,
s0, t0, s1, t1, 0.0f); s0, t0, s1, t1, 0.0f);
if (buf) { if (buf) {
cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0, util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN, PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */ 4, /* verts */
@ -370,6 +372,7 @@ void renderer_copy_texture(struct renderer *ctx,
0.0f); 0.0f);
if (buf) { if (buf) {
cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0, util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN, PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */ 4, /* verts */
@ -535,6 +538,7 @@ void renderer_copy_surface(struct renderer *ctx,
(float) dstX1, (float) dstY1, z); (float) dstX1, (float) dstY1, z);
if (buf) { if (buf) {
cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0, util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN, PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */ 4, /* verts */
@ -587,6 +591,7 @@ void renderer_texture_quad(struct renderer *r,
s0, t0, s1, t1, 0.0f); s0, t0, s1, t1, 0.0f);
if (buf) { if (buf) {
cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0, util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN, PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */ 4, /* verts */

View File

@ -72,6 +72,7 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
struct vg_context *share) struct vg_context *share)
{ {
struct vg_context *ctx; struct vg_context *ctx;
unsigned i;
ctx = CALLOC_STRUCT(vg_context); ctx = CALLOC_STRUCT(vg_context);
@ -103,6 +104,13 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
ctx->blend_sampler.normalized_coords = 0; ctx->blend_sampler.normalized_coords = 0;
for (i = 0; i < 2; i++) {
ctx->velems[i].src_offset = i * 4 * sizeof(float);
ctx->velems[i].instance_divisor = 0;
ctx->velems[i].vertex_buffer_index = 0;
ctx->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
vg_set_error(ctx, VG_NO_ERROR); vg_set_error(ctx, VG_NO_ERROR);
ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create(); ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create();

View File

@ -146,6 +146,7 @@ struct vg_context
struct vg_shader *clear_vs; struct vg_shader *clear_vs;
struct vg_shader *texture_vs; struct vg_shader *texture_vs;
struct pipe_buffer *vs_const_buffer; struct pipe_buffer *vs_const_buffer;
struct pipe_vertex_element velems[2];
}; };
struct vg_object { struct vg_object {

View File

@ -68,6 +68,8 @@ renderer_draw(struct xorg_renderer *r)
if (buf) { if (buf) {
cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
util_draw_vertex_buffer(pipe, buf, 0, util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS, PIPE_PRIM_QUADS,
num_verts, /* verts */ num_verts, /* verts */
@ -92,6 +94,7 @@ renderer_init_state(struct xorg_renderer *r)
{ {
struct pipe_depth_stencil_alpha_state dsa; struct pipe_depth_stencil_alpha_state dsa;
struct pipe_rasterizer_state raster; struct pipe_rasterizer_state raster;
unsigned i;
/* set common initial clip state */ /* set common initial clip state */
memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
@ -103,6 +106,14 @@ renderer_init_state(struct xorg_renderer *r)
raster.gl_rasterization_rules = 1; raster.gl_rasterization_rules = 1;
cso_set_rasterizer(r->cso, &raster); cso_set_rasterizer(r->cso, &raster);
/* vertex elements state */
memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3);
for (i = 0; i < 3; i++) {
r->velems[i].src_offset = i * 4 * sizeof(float);
r->velems[i].instance_divisor = 0;
r->velems[i].vertex_buffer_index = 0;
r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
} }
@ -600,6 +611,8 @@ void renderer_draw_yuv(struct xorg_renderer *r,
if (buf) { if (buf) {
const int num_attribs = 2; /*pos + tex coord*/ const int num_attribs = 2; /*pos + tex coord*/
cso_set_vertex_elements(r->cso, num_attribs, r->velems);
util_draw_vertex_buffer(pipe, buf, 0, util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS, PIPE_PRIM_QUADS,
4, /* verts */ 4, /* verts */

View File

@ -28,6 +28,7 @@ struct xorg_renderer {
float buffer[BUF_SIZE]; float buffer[BUF_SIZE];
int buffer_size; int buffer_size;
struct pipe_vertex_element velems[3];
/* number of attributes per vertex for the current /* number of attributes per vertex for the current
* draw operation */ * draw operation */

View File

@ -249,6 +249,7 @@ if env['platform'] != 'winddk':
glapi_sources = [ glapi_sources = [
'glapi/glapi.c', 'glapi/glapi.c',
'glapi/glapi_dispatch.c', 'glapi/glapi_dispatch.c',
'glapi/glapi_entrypoint.c',
'glapi/glapi_getproc.c', 'glapi/glapi_getproc.c',
'glapi/glapi_nop.c', 'glapi/glapi_nop.c',
'glapi/glthread.c', 'glapi/glthread.c',

View File

@ -74,9 +74,9 @@ struct {
[BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 },
[BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 }, [BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 },
[BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 1, .ndst = 01 }, [BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 1, .ndst = 01 },
[BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 2, .ndst = 0 },
[BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 }, [BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 },
[BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 2, .ndst = 0 },
[BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 },
[BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 },
[BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 },

View File

@ -95,9 +95,17 @@ static void brwDeleteProgram( GLcontext *ctx,
struct gl_program *prog ) struct gl_program *prog )
{ {
if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; struct gl_fragment_program *fp = (struct gl_fragment_program *) prog;
struct brw_fragment_program *brw_fprog = brw_fragment_program(fprog); struct brw_fragment_program *brw_fp = brw_fragment_program(fp);
dri_bo_unreference(brw_fprog->const_buffer);
dri_bo_unreference(brw_fp->const_buffer);
}
if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
struct gl_vertex_program *vp = (struct gl_vertex_program *) prog;
struct brw_vertex_program *brw_vp = brw_vertex_program(vp);
dri_bo_unreference(brw_vp->const_buffer);
} }
_mesa_delete_program( ctx, prog ); _mesa_delete_program( ctx, prog );

Some files were not shown because too many files have changed in this diff Show More