#include "program/prog_statevars.h"
#include "program/prog_instruction.h"
+static struct gl_builtin_uniform_element gl_NumSamples_elements[] = {
+ {NULL, {STATE_NUM_SAMPLES, 0, 0}, SWIZZLE_XXXX}
+};
static struct gl_builtin_uniform_element gl_DepthRange_elements[] = {
{"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
+ STATEVAR(gl_NumSamples),
STATEVAR(gl_DepthRange),
STATEVAR(gl_ClipPlane),
STATEVAR(gl_Point),
namespace {
+/**
+ * Data structure that accumulates fields for the gl_PerVertex interface
+ * block.
+ */
+class per_vertex_accumulator
+{
+public:
+ per_vertex_accumulator();
+ void add_field(int slot, const glsl_type *type, const char *name);
+ const glsl_type *construct_interface_instance() const;
+
+private:
+ glsl_struct_field fields[10];
+ unsigned num_fields;
+};
+
+
+per_vertex_accumulator::per_vertex_accumulator()
+ : fields(),
+ num_fields(0)
+{
+}
+
+
+void
+per_vertex_accumulator::add_field(int slot, const glsl_type *type,
+ const char *name)
+{
+ assert(this->num_fields < ARRAY_SIZE(this->fields));
+ this->fields[this->num_fields].type = type;
+ this->fields[this->num_fields].name = name;
+ this->fields[this->num_fields].row_major = false;
+ this->fields[this->num_fields].location = slot;
+ this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_NONE;
+ this->fields[this->num_fields].centroid = 0;
+ this->fields[this->num_fields].sample = 0;
+ this->num_fields++;
+}
+
+
+const glsl_type *
+per_vertex_accumulator::construct_interface_instance() const
+{
+ return glsl_type::get_interface_instance(this->fields, this->num_fields,
+ GLSL_INTERFACE_PACKING_STD140,
+ "gl_PerVertex");
+}
+
+
class builtin_variable_generator
{
public:
const glsl_type * const mat3_t;
const glsl_type * const mat4_t;
- /**
- * Array where the contents of the gl_PerVertex interface instance are
- * accumulated.
- */
- glsl_struct_field per_vertex_fields[10];
-
- /**
- * Number of elements of per_vertex_fields which have been populated.
- */
- unsigned num_per_vertex_fields;
+ per_vertex_accumulator per_vertex_in;
+ per_vertex_accumulator per_vertex_out;
};
bool_t(glsl_type::bool_type), int_t(glsl_type::int_type),
float_t(glsl_type::float_type), vec2_t(glsl_type::vec2_type),
vec3_t(glsl_type::vec3_type), vec4_t(glsl_type::vec4_type),
- mat3_t(glsl_type::mat3_type), mat4_t(glsl_type::mat4_type),
- num_per_vertex_fields(0)
+ mat3_t(glsl_type::mat3_type), mat4_t(glsl_type::mat4_type)
{
}
enum ir_variable_mode mode, int slot)
{
ir_variable *var = new(symtab) ir_variable(type, name, mode);
+ var->data.how_declared = ir_var_declared_implicitly;
- switch (var->mode) {
+ switch (var->data.mode) {
case ir_var_auto:
case ir_var_shader_in:
case ir_var_uniform:
case ir_var_system_value:
- var->read_only = true;
+ var->data.read_only = true;
break;
case ir_var_shader_out:
break;
break;
}
- var->location = slot;
- var->explicit_location = (slot >= 0);
- var->explicit_index = 0;
+ var->data.location = slot;
+ var->data.explicit_location = (slot >= 0);
+ var->data.explicit_index = 0;
/* Once the variable is created an initialized, add it to the symbol table
* and add the declaration to the IR stream.
ir_var_auto, -1);
var->constant_value = new(var) ir_constant(value);
var->constant_initializer = new(var) ir_constant(value);
- var->has_initializer = true;
+ var->data.has_initializer = true;
return var;
}
add_const("gl_MaxVaryingComponents", state->ctx->Const.MaxVarying * 4);
}
+ if (state->is_version(150, 0)) {
+ add_const("gl_MaxVertexOutputComponents",
+ state->Const.MaxVertexOutputComponents);
+ add_const("gl_MaxGeometryInputComponents",
+ state->Const.MaxGeometryInputComponents);
+ add_const("gl_MaxGeometryOutputComponents",
+ state->Const.MaxGeometryOutputComponents);
+ add_const("gl_MaxFragmentInputComponents",
+ state->Const.MaxFragmentInputComponents);
+ add_const("gl_MaxGeometryTextureImageUnits",
+ state->Const.MaxGeometryTextureImageUnits);
+ add_const("gl_MaxGeometryOutputVertices",
+ state->Const.MaxGeometryOutputVertices);
+ add_const("gl_MaxGeometryTotalOutputComponents",
+ state->Const.MaxGeometryTotalOutputComponents);
+ add_const("gl_MaxGeometryUniformComponents",
+ state->Const.MaxGeometryUniformComponents);
+
+ /* Note: the GLSL 1.50-4.40 specs require
+ * gl_MaxGeometryVaryingComponents to be present, and to be at least 64.
+ * But they do not define what it means (and there does not appear to be
+ * any corresponding constant in the GL specs). However,
+ * ARB_geometry_shader4 defines MAX_GEOMETRY_VARYING_COMPONENTS_ARB to
+ * be the maximum number of components available for use as geometry
+ * outputs. So we assume this is a synonym for
+ * gl_MaxGeometryOutputComponents.
+ */
+ add_const("gl_MaxGeometryVaryingComponents",
+ state->Const.MaxGeometryOutputComponents);
+ }
+
if (compatibility) {
/* Note: gl_MaxLights stopped being listed as an explicit constant in
* GLSL 1.30, however it continues to be referred to (as a minimum size
*/
add_const("gl_MaxTextureCoords", state->Const.MaxTextureCoords);
}
+
+ if (state->ARB_shader_atomic_counters_enable) {
+ add_const("gl_MaxVertexAtomicCounters",
+ state->Const.MaxVertexAtomicCounters);
+ add_const("gl_MaxGeometryAtomicCounters",
+ state->Const.MaxGeometryAtomicCounters);
+ add_const("gl_MaxFragmentAtomicCounters",
+ state->Const.MaxFragmentAtomicCounters);
+ add_const("gl_MaxCombinedAtomicCounters",
+ state->Const.MaxCombinedAtomicCounters);
+ add_const("gl_MaxAtomicCounterBindings",
+ state->Const.MaxAtomicBufferBindings);
+ add_const("gl_MaxTessControlAtomicCounters", 0);
+ add_const("gl_MaxTessEvaluationAtomicCounters", 0);
+ }
}
void
builtin_variable_generator::generate_uniforms()
{
+ add_uniform(int_t, "gl_NumSamples");
add_uniform(type("gl_DepthRangeParameters"), "gl_DepthRange");
add_uniform(array(vec4_t, VERT_ATTRIB_MAX), "gl_CurrentAttribVertMESA");
add_uniform(array(vec4_t, VARYING_SLOT_MAX), "gl_CurrentAttribFragMESA");
*/
ir_variable *var;
var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveIDIn");
- var->interpolation = INTERP_QUALIFIER_FLAT;
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
var = add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
- var->interpolation = INTERP_QUALIFIER_FLAT;
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
}
if (state->is_version(150, 0)) {
ir_variable *var =
add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
- var->interpolation = INTERP_QUALIFIER_FLAT;
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
}
/* gl_FragColor and gl_FragData were deprecated starting in desktop GLSL
if (state->AMD_shader_stencil_export_warn)
var->warn_extension = "GL_AMD_shader_stencil_export";
}
+
+ if (state->ARB_sample_shading_enable) {
+ add_system_value(SYSTEM_VALUE_SAMPLE_ID, int_t, "gl_SampleID");
+ add_system_value(SYSTEM_VALUE_SAMPLE_POS, vec2_t, "gl_SamplePosition");
+ /* From the ARB_sample_shading specification:
+ * "The number of elements in the array is ceil(<s>/32), where
+ * <s> is the maximum number of color samples supported by the
+ * implementation."
+ * Since no drivers expose more than 32x MSAA, we can simply set
+ * the array size to 1 rather than computing it.
+ */
+ add_output(FRAG_RESULT_SAMPLE_MASK, array(int_t, 1), "gl_SampleMask");
+ }
+
+ if (state->ARB_gpu_shader5_enable) {
+ add_system_value(SYSTEM_VALUE_SAMPLE_MASK_IN, array(int_t, 1), "gl_SampleMaskIn");
+ }
}
const char *name_as_gs_input)
{
switch (state->target) {
- case geometry_shader:
- assert(this->num_per_vertex_fields <
- ARRAY_SIZE(this->per_vertex_fields));
- this->per_vertex_fields[this->num_per_vertex_fields].type = type;
- this->per_vertex_fields[this->num_per_vertex_fields].name = name;
- this->per_vertex_fields[this->num_per_vertex_fields].row_major = false;
- this->per_vertex_fields[this->num_per_vertex_fields].location = slot;
- this->num_per_vertex_fields++;
+ case MESA_SHADER_GEOMETRY:
+ this->per_vertex_in.add_field(slot, type, name);
/* FALLTHROUGH */
- case vertex_shader:
- add_output(slot, type, name);
+ case MESA_SHADER_VERTEX:
+ this->per_vertex_out.add_field(slot, type, name);
break;
- case fragment_shader:
+ case MESA_SHADER_FRAGMENT:
add_input(slot, type, name);
break;
}
add_varying(loc, type, name, name "In")
/* gl_Position and gl_PointSize are not visible from fragment shaders. */
- if (state->target != fragment_shader) {
+ if (state->target != MESA_SHADER_FRAGMENT) {
ADD_VARYING(VARYING_SLOT_POS, vec4_t, "gl_Position");
ADD_VARYING(VARYING_SLOT_PSIZ, float_t, "gl_PointSize");
}
if (compatibility) {
ADD_VARYING(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord");
ADD_VARYING(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord");
- if (state->target == fragment_shader) {
+ if (state->target == MESA_SHADER_FRAGMENT) {
ADD_VARYING(VARYING_SLOT_COL0, vec4_t, "gl_Color");
ADD_VARYING(VARYING_SLOT_COL1, vec4_t, "gl_SecondaryColor");
} else {
}
}
- if (state->target == geometry_shader) {
- const glsl_type *per_vertex_type =
- glsl_type::get_interface_instance(this->per_vertex_fields,
- this->num_per_vertex_fields,
- GLSL_INTERFACE_PACKING_STD140,
- "gl_in");
- ir_variable *var = add_variable("gl_in", array(per_vertex_type, 0),
- ir_var_shader_in, 0);
- var->interface_type = per_vertex_type;
+ if (state->target == MESA_SHADER_GEOMETRY) {
+ const glsl_type *per_vertex_in_type =
+ this->per_vertex_in.construct_interface_instance();
+ add_variable("gl_in", array(per_vertex_in_type, 0),
+ ir_var_shader_in, -1);
+ }
+ if (state->target == MESA_SHADER_VERTEX || state->target == MESA_SHADER_GEOMETRY) {
+ const glsl_type *per_vertex_out_type =
+ this->per_vertex_out.construct_interface_instance();
+ const glsl_struct_field *fields = per_vertex_out_type->fields.structure;
+ for (unsigned i = 0; i < per_vertex_out_type->length; i++) {
+ ir_variable *var =
+ add_variable(fields[i].name, fields[i].type, ir_var_shader_out,
+ fields[i].location);
+ var->data.interpolation = fields[i].interpolation;
+ var->data.centroid = fields[i].centroid;
+ var->data.sample = fields[i].sample;
+ var->init_interface_type(per_vertex_out_type);
+ }
}
}
gen.generate_varyings();
switch (state->target) {
- case vertex_shader:
+ case MESA_SHADER_VERTEX:
gen.generate_vs_special_vars();
break;
- case geometry_shader:
+ case MESA_SHADER_GEOMETRY:
gen.generate_gs_special_vars();
break;
- case fragment_shader:
+ case MESA_SHADER_FRAGMENT:
gen.generate_fs_special_vars();
break;
}