st/mesa: emit SQRT opcode when driver supports it
authorBrian Paul <brianp@vmware.com>
Fri, 1 Feb 2013 18:17:50 +0000 (11:17 -0700)
committerBrian Paul <brianp@vmware.com>
Mon, 4 Feb 2013 16:33:44 +0000 (09:33 -0700)
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index c6ac634a2abc7be70718c56165d625b89b90d766..b3da2016ddddeb8c23416e5fe93582ac0f5d20b9 100644 (file)
@@ -322,6 +322,7 @@ public:
    
    int glsl_version;
    bool native_integers;
+   bool have_sqrt;
 
    variable_storage *find_variable_storage(ir_variable *var);
 
@@ -1761,13 +1762,18 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
       break;
 
    case ir_unop_sqrt:
-      /* sqrt(x) = x * rsq(x). */
-      emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]);
-      emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]);
-      /* For incoming channels <= 0, set the result to 0. */
-      op[0].negate = ~op[0].negate;
-      emit(ir, TGSI_OPCODE_CMP, result_dst,
-                         op[0], result_src, st_src_reg_for_float(0.0));
+      if (have_sqrt) {
+         emit_scalar(ir, TGSI_OPCODE_SQRT, result_dst, op[0]);
+      }
+      else {
+         /* sqrt(x) = x * rsq(x). */
+         emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]);
+         emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]);
+         /* For incoming channels <= 0, set the result to 0. */
+         op[0].negate = ~op[0].negate;
+         emit(ir, TGSI_OPCODE_CMP, result_dst,
+              op[0], result_src, st_src_reg_for_float(0.0));
+      }
       break;
    case ir_unop_rsq:
       emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]);
@@ -4956,18 +4962,23 @@ get_mesa_program(struct gl_context *ctx,
    bool progress;
    struct gl_shader_compiler_options *options =
          &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)];
+   struct pipe_screen *pscreen = ctx->st->pipe->screen;
+   unsigned ptarget;
 
    switch (shader->Type) {
    case GL_VERTEX_SHADER:
       target = GL_VERTEX_PROGRAM_ARB;
+      ptarget = PIPE_SHADER_VERTEX;
       target_string = "vertex";
       break;
    case GL_FRAGMENT_SHADER:
       target = GL_FRAGMENT_PROGRAM_ARB;
+      ptarget = PIPE_SHADER_FRAGMENT;
       target_string = "fragment";
       break;
    case GL_GEOMETRY_SHADER:
       target = GL_GEOMETRY_PROGRAM_NV;
+      ptarget = PIPE_SHADER_GEOMETRY;
       target_string = "geometry";
       break;
    default:
@@ -4989,6 +5000,9 @@ get_mesa_program(struct gl_context *ctx,
    v->glsl_version = ctx->Const.GLSLVersion;
    v->native_integers = ctx->Const.NativeIntegers;
 
+   v->have_sqrt = pscreen->get_shader_param(pscreen, ptarget,
+                                            PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED);
+
    _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
                                               prog->Parameters);