[Mesa-dev] [PATCH 2/2] st/mesa: add support for gl_ClipDistance
--- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 48 +--- src/mesa/state_tracker/st_program.c| 18 ++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 1515fc1..bc3005e 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -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; @@ -4627,9 +4628,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. @@ -4806,7 +4815,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; @@ -4851,6 +4861,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); @@ -4980,6 +4991,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 * @@ -5018,6 +5048,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++) { @@ -5029,6 +5060,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; @@ -5045,6 +5081,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; @@ -5079,7 +5116,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[] = { diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index d62bfcd..aceaaf8 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/s
Re: [Mesa-dev] [PATCH 2/2] st/mesa: add support for gl_ClipDistance
On 12/17/2011 03:15 PM, Bryan Cain wrote: --- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 49 +--- src/mesa/state_tracker/st_program.c| 18 ++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index b929806..3e8df78 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -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; @@ -4618,9 +4619,16 @@ 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)& 0xf; Being nit-picky, but 0xf should be replaced by TGSI_WRITEMASK_XYZW to be totally clear. +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]); I'd like to see { } braces around the else clause. if ((outputSemanticName[i] == TGSI_SEMANTIC_PSIZE)&& proginfo->Id) { /* Writing to the point size result register requires special * handling to implement clamping. @@ -4797,7 +4805,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; @@ -4842,6 +4851,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); @@ -4971,6 +4981,27 @@ 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")) + { The { should go on the same line as the 'if' like elsewhere. + fprintf(stderr, "gl_ClipDistance found with size %i\n", var->type->length); Left-over debug code? + return var->type->length; + } + } + + return 0; +} + extern "C" { struct gl_shader * @@ -5009,6 +5040,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++) { @@ -5020,6 +5052,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; @@ -5036,6 +5073,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; @@ -5070,7 +5108,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]); +
[Mesa-dev] [PATCH 2/2] st/mesa: add support for gl_ClipDistance
--- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 49 +--- src/mesa/state_tracker/st_program.c| 18 ++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index b929806..3e8df78 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -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; @@ -4618,9 +4619,16 @@ 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) & 0xf; +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. @@ -4797,7 +4805,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; @@ -4842,6 +4851,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); @@ -4971,6 +4981,27 @@ 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")) + { + fprintf(stderr, "gl_ClipDistance found with size %i\n", var->type->length); + return var->type->length; + } + } + + return 0; +} + extern "C" { struct gl_shader * @@ -5009,6 +5040,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++) { @@ -5020,6 +5052,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; @@ -5036,6 +5073,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; @@ -5070,7 +5108,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[] = { diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index b83c561..b404503 1
[Mesa-dev] [PATCH 2/2] st/mesa: add support for gl_ClipDistance
--- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 39 ++- src/mesa/state_tracker/st_program.c| 18 + 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 9ef65c8..5e54465 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -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; @@ -4738,6 +4739,9 @@ st_translate_program( t->samplers[i] = ureg_DECL_sampler(ureg, i); } } + + /* Set the number of clip distances used in the shader. */ + ureg_property_num_clip_distances(ureg, program->num_clip_distances); /* Emit each instruction in turn: */ @@ -4797,7 +4801,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; @@ -4842,6 +4847,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); @@ -4971,6 +4977,27 @@ 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")) + { + fprintf(stderr, "gl_ClipDistance found with size %i\n", var->type->length); + return var->type->length; + } + } + + return 0; +} + extern "C" { struct gl_shader * @@ -5009,6 +5036,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++) { @@ -5020,6 +5048,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; @@ -5036,6 +5069,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; @@ -5070,7 +5104,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[] = { diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 04d3ef6..73581dd 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -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; @@ -541,6 +549,16 @@ st_translate_fragment_program(struct st_context *st,
[Mesa-dev] [PATCH 2/2] st/mesa: add support for gl_ClipDistance
--- src/mesa/state_tracker/st_glsl_to_tgsi.cpp |1 + src/mesa/state_tracker/st_program.c| 18 ++ 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 9ef65c8..d50176d 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -5036,6 +5036,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; diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 04d3ef6..73581dd 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -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; @@ -541,6 +549,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 -- 1.7.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev