st/mesa: add support for gl_ClipDistance

This commit is contained in:
Bryan Cain 2012-01-02 14:49:46 -06:00
parent 6951870e57
commit 59be691638
2 changed files with 61 additions and 5 deletions

View File

@ -304,6 +304,7 @@ public:
int samplers_used;
bool indirect_addr_temps;
bool indirect_addr_consts;
int num_clip_distances;
int glsl_version;
bool native_integers;
@ -4641,9 +4642,17 @@ st_translate_program(
}
for (i = 0; i < numOutputs; i++) {
t->outputs[i] = ureg_DECL_output(ureg,
outputSemanticName[i],
outputSemanticIndex[i]);
if (outputSemanticName[i] == TGSI_SEMANTIC_CLIPDIST) {
int mask = ((1 << (program->num_clip_distances - 4*outputSemanticIndex[i])) - 1) & TGSI_WRITEMASK_XYZW;
t->outputs[i] = ureg_DECL_output_masked(ureg,
outputSemanticName[i],
outputSemanticIndex[i],
mask);
} else {
t->outputs[i] = ureg_DECL_output(ureg,
outputSemanticName[i],
outputSemanticIndex[i]);
}
if ((outputSemanticName[i] == TGSI_SEMANTIC_PSIZE) && proginfo->Id) {
/* Writing to the point size result register requires special
* handling to implement clamping.
@ -4834,7 +4843,8 @@ out:
static struct gl_program *
get_mesa_program(struct gl_context *ctx,
struct gl_shader_program *shader_program,
struct gl_shader *shader)
struct gl_shader *shader,
int num_clip_distances)
{
glsl_to_tgsi_visitor* v = new glsl_to_tgsi_visitor();
struct gl_program *prog;
@ -4879,6 +4889,7 @@ get_mesa_program(struct gl_context *ctx,
v->options = options;
v->glsl_version = ctx->Const.GLSLVersion;
v->native_integers = ctx->Const.NativeIntegers;
v->num_clip_distances = num_clip_distances;
_mesa_generate_parameters_list_for_uniforms(shader_program, shader,
prog->Parameters);
@ -5008,6 +5019,25 @@ get_mesa_program(struct gl_context *ctx,
return prog;
}
/**
* Searches through the IR for a declaration of gl_ClipDistance and returns the
* declared size of the gl_ClipDistance array. Returns 0 if gl_ClipDistance is
* not declared in the IR.
*/
int get_clip_distance_size(exec_list *ir)
{
foreach_iter (exec_list_iterator, iter, *ir) {
ir_instruction *inst = (ir_instruction *)iter.get();
ir_variable *var = inst->as_variable();
if (var == NULL) continue;
if (!strcmp(var->name, "gl_ClipDistance")) {
return var->type->length;
}
}
return 0;
}
extern "C" {
struct gl_shader *
@ -5046,6 +5076,7 @@ st_new_shader_program(struct gl_context *ctx, GLuint name)
GLboolean
st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
{
int num_clip_distances[MESA_SHADER_TYPES];
assert(prog->LinkStatus);
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
@ -5057,6 +5088,11 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
const struct gl_shader_compiler_options *options =
&ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)];
/* We have to determine the length of the gl_ClipDistance array before
* the array is lowered to two vec4s by lower_clip_distance().
*/
num_clip_distances[i] = get_clip_distance_size(ir);
do {
progress = false;
@ -5073,6 +5109,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|| progress;
progress = lower_quadop_vector(ir, false) || progress;
progress = lower_clip_distance(ir) || progress;
if (options->MaxIfDepth == 0)
progress = lower_discard(ir) || progress;
@ -5107,7 +5144,8 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i],
num_clip_distances[i]);
if (linked_prog) {
static const GLenum targets[] = {

View File

@ -244,6 +244,14 @@ st_prepare_vertex_program(struct gl_context *ctx,
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
stvp->output_semantic_index[slot] = 0;
break;
case VERT_RESULT_CLIP_DIST0:
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
stvp->output_semantic_index[slot] = 0;
break;
case VERT_RESULT_CLIP_DIST1:
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
stvp->output_semantic_index[slot] = 1;
break;
case VERT_RESULT_EDGE:
assert(0);
break;
@ -547,6 +555,16 @@ st_translate_fragment_program(struct st_context *st,
input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
break;
case FRAG_ATTRIB_CLIP_DIST0:
input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
case FRAG_ATTRIB_CLIP_DIST1:
input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
input_semantic_index[slot] = 1;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
/* In most cases, there is nothing special about these
* inputs, so adopt a convention to use the generic
* semantic name and the mesa FRAG_ATTRIB_ number as the