glsl: add ARB_derivative control support
authorIlia Mirkin <imirkin@alum.mit.edu>
Thu, 14 Aug 2014 03:33:04 +0000 (23:33 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 15 Aug 2014 00:25:32 +0000 (20:25 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/builtin_functions.cpp
src/glsl/glcpp/glcpp-parse.y
src/glsl/glsl_parser_extras.cpp
src/glsl/glsl_parser_extras.h
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_constant_expression.cpp
src/glsl/ir_validate.cpp

index 185fe98b33d7207852af872b07fd60c162f8fa58..c882ec8dd0d2adc0a5952d1fdcaa00d921e3b96d 100644 (file)
@@ -317,6 +317,14 @@ fs_oes_derivatives(const _mesa_glsl_parse_state *state)
            state->OES_standard_derivatives_enable);
 }
 
+static bool
+fs_derivative_control(const _mesa_glsl_parse_state *state)
+{
+   return state->stage == MESA_SHADER_FRAGMENT &&
+          (state->is_version(450, 0) ||
+           state->ARB_derivative_control_enable);
+}
+
 static bool
 tex1d_lod(const _mesa_glsl_parse_state *state)
 {
@@ -618,6 +626,12 @@ private:
    B1(dFdx);
    B1(dFdy);
    B1(fwidth);
+   B1(dFdxCoarse);
+   B1(dFdyCoarse);
+   B1(fwidthCoarse);
+   B1(dFdxFine);
+   B1(dFdyFine);
+   B1(fwidthFine);
    B1(noise1);
    B1(noise2);
    B1(noise3);
@@ -2148,6 +2162,12 @@ builtin_builder::create_builtins()
    F(dFdx)
    F(dFdy)
    F(fwidth)
+   F(dFdxCoarse)
+   F(dFdyCoarse)
+   F(fwidthCoarse)
+   F(dFdxFine)
+   F(dFdyFine)
+   F(fwidthFine)
    F(noise1)
    F(noise2)
    F(noise3)
@@ -4010,7 +4030,11 @@ builtin_builder::_textureQueryLevels(const glsl_type *sampler_type)
 }
 
 UNOP(dFdx, ir_unop_dFdx, fs_oes_derivatives)
+UNOP(dFdxCoarse, ir_unop_dFdx_coarse, fs_derivative_control)
+UNOP(dFdxFine, ir_unop_dFdx_fine, fs_derivative_control)
 UNOP(dFdy, ir_unop_dFdy, fs_oes_derivatives)
+UNOP(dFdyCoarse, ir_unop_dFdy_coarse, fs_derivative_control)
+UNOP(dFdyFine, ir_unop_dFdy_fine, fs_derivative_control)
 
 ir_function_signature *
 builtin_builder::_fwidth(const glsl_type *type)
@@ -4023,6 +4047,30 @@ builtin_builder::_fwidth(const glsl_type *type)
    return sig;
 }
 
+ir_function_signature *
+builtin_builder::_fwidthCoarse(const glsl_type *type)
+{
+   ir_variable *p = in_var(type, "p");
+   MAKE_SIG(type, fs_derivative_control, 1, p);
+
+   body.emit(ret(add(abs(expr(ir_unop_dFdx_coarse, p)),
+                     abs(expr(ir_unop_dFdy_coarse, p)))));
+
+   return sig;
+}
+
+ir_function_signature *
+builtin_builder::_fwidthFine(const glsl_type *type)
+{
+   ir_variable *p = in_var(type, "p");
+   MAKE_SIG(type, fs_derivative_control, 1, p);
+
+   body.emit(ret(add(abs(expr(ir_unop_dFdx_fine, p)),
+                     abs(expr(ir_unop_dFdy_fine, p)))));
+
+   return sig;
+}
+
 ir_function_signature *
 builtin_builder::_noise1(const glsl_type *type)
 {
index a6169739406a97d528ccd8f3e174b1e528f02605..f1119eb805ad4b5f95f6973e6efcb31a25bd150d 100644 (file)
@@ -2469,6 +2469,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
 
              if (extensions->ARB_shader_image_load_store)
                 add_builtin_define(parser, "GL_ARB_shader_image_load_store", 1);
+
+              if (extensions->ARB_derivative_control)
+                 add_builtin_define(parser, "GL_ARB_derivative_control", 1);
           }
        }
 
index ad91c4661433ec629ecc0be59ec7b2646db391ee..490c3c8eea33047dd9d328c94694bf84dd9ec901 100644 (file)
@@ -514,6 +514,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
    EXT(ARB_arrays_of_arrays,           true,  false,     ARB_arrays_of_arrays),
    EXT(ARB_compute_shader,             true,  false,     ARB_compute_shader),
    EXT(ARB_conservative_depth,         true,  false,     ARB_conservative_depth),
+   EXT(ARB_derivative_control,         true,  false,     ARB_derivative_control),
    EXT(ARB_draw_buffers,               true,  false,     dummy_true),
    EXT(ARB_draw_instanced,             true,  false,     ARB_draw_instanced),
    EXT(ARB_explicit_attrib_location,   true,  false,     ARB_explicit_attrib_location),
index ce66e2fa45b087e362964282dee9a766f1843c79..c8b94781c70e426b7672941c911cebec54083c47 100644 (file)
@@ -393,6 +393,8 @@ struct _mesa_glsl_parse_state {
    bool ARB_compute_shader_warn;
    bool ARB_conservative_depth_enable;
    bool ARB_conservative_depth_warn;
+   bool ARB_derivative_control_enable;
+   bool ARB_derivative_control_warn;
    bool ARB_draw_buffers_enable;
    bool ARB_draw_buffers_warn;
    bool ARB_draw_instanced_enable;
index 28fd94b95c9a06bc0de1c0200d94ee441e809734..4a4d30477ce7570350b3737fa6b91da566a1d569 100644 (file)
@@ -248,7 +248,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
    case ir_unop_sin_reduced:
    case ir_unop_cos_reduced:
    case ir_unop_dFdx:
+   case ir_unop_dFdx_coarse:
+   case ir_unop_dFdx_fine:
    case ir_unop_dFdy:
+   case ir_unop_dFdy_coarse:
+   case ir_unop_dFdy_fine:
    case ir_unop_bitfield_reverse:
    case ir_unop_interpolate_at_centroid:
       this->type = op0->type;
@@ -509,7 +513,11 @@ static const char *const operator_strs[] = {
    "sin_reduced",
    "cos_reduced",
    "dFdx",
+   "dFdxCoarse",
+   "dFdxFine",
    "dFdy",
+   "dFdyCoarse",
+   "dFdyFine",
    "packSnorm2x16",
    "packSnorm4x8",
    "packUnorm2x16",
index 31c354556e44a3dbadc55af181d5db3d161acef2..18623b96868fd914d2e9f68cbdaef7ba06416e3f 100644 (file)
@@ -1205,7 +1205,11 @@ enum ir_expression_operation {
     */
    /*@{*/
    ir_unop_dFdx,
+   ir_unop_dFdx_coarse,
+   ir_unop_dFdx_fine,
    ir_unop_dFdy,
+   ir_unop_dFdy_coarse,
+   ir_unop_dFdy_fine,
    /*@}*/
 
    /**
index 5570ed46f8a58ba386d60875750ed9acdec035fb..96060217c97246a4553532e2943df96a5908c8f8 100644 (file)
@@ -851,7 +851,11 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       break;
 
    case ir_unop_dFdx:
+   case ir_unop_dFdx_coarse:
+   case ir_unop_dFdx_fine:
    case ir_unop_dFdy:
+   case ir_unop_dFdy_coarse:
+   case ir_unop_dFdy_fine:
       assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
       for (unsigned c = 0; c < op[0]->type->components(); c++) {
         data.f[c] = 0.0;
index 4f85b7db83366d4e56d15e064e7019d9111f0389..5b20677825ce3caad5fd95807483de7b6afe2341 100644 (file)
@@ -317,7 +317,11 @@ ir_validate::visit_leave(ir_expression *ir)
    case ir_unop_sin_reduced:
    case ir_unop_cos_reduced:
    case ir_unop_dFdx:
+   case ir_unop_dFdx_coarse:
+   case ir_unop_dFdx_fine:
    case ir_unop_dFdy:
+   case ir_unop_dFdy_coarse:
+   case ir_unop_dFdy_fine:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
       assert(ir->operands[0]->type == ir->type);
       break;