#include <assert.h>
#include "shader_enums.h"
-#include "blob.h"
#include "c11/threads.h"
+#include "util/blob.h"
#include "util/macros.h"
#ifdef __cplusplus
}
#endif
+typedef void (*glsl_type_size_align_func)(const struct glsl_type *type,
+ unsigned *size, unsigned *align);
+
enum glsl_base_type {
/* Note: GLSL_TYPE_UINT, GLSL_TYPE_INT, and GLSL_TYPE_FLOAT must be 0, 1,
* and 2 so that they will fit in the 2 bits of glsl_type::sampled_type.
GLSL_TYPE_ERROR
};
+/* Return the bit size of a type. Note that this differs from
+ * glsl_get_bit_size in that it returns 32 bits for bools, whereas at
+ * the NIR level we would want to return 1 bit for bools.
+ */
+static unsigned glsl_base_type_bit_size(enum glsl_base_type type)
+{
+ switch (type) {
+ case GLSL_TYPE_BOOL:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_FLOAT: /* TODO handle mediump */
+ case GLSL_TYPE_SUBROUTINE:
+ return 32;
+
+ case GLSL_TYPE_FLOAT16:
+ case GLSL_TYPE_UINT16:
+ case GLSL_TYPE_INT16:
+ return 16;
+
+ case GLSL_TYPE_UINT8:
+ case GLSL_TYPE_INT8:
+ return 8;
+
+ case GLSL_TYPE_DOUBLE:
+ case GLSL_TYPE_INT64:
+ case GLSL_TYPE_UINT64:
+ case GLSL_TYPE_IMAGE:
+ case GLSL_TYPE_SAMPLER:
+ return 64;
+
+ default:
+ /* For GLSL_TYPE_STRUCT etc, it should be ok to return 0. This usually
+ * happens when calling this method through is_64bit and is_16bit
+ * methods
+ */
+ return 0;
+ }
+
+ return 0;
+}
+
static inline bool glsl_base_type_is_16bit(enum glsl_base_type type)
{
- return type == GLSL_TYPE_FLOAT16 ||
- type == GLSL_TYPE_UINT16 ||
- type == GLSL_TYPE_INT16;
+ return glsl_base_type_bit_size(type) == 16;
}
static inline bool glsl_base_type_is_64bit(enum glsl_base_type type)
{
- return type == GLSL_TYPE_DOUBLE ||
- type == GLSL_TYPE_UINT64 ||
- type == GLSL_TYPE_INT64 ||
- type == GLSL_TYPE_IMAGE ||
- type == GLSL_TYPE_SAMPLER;
+ return glsl_base_type_bit_size(type) == 64;
}
static inline bool glsl_base_type_is_integer(enum glsl_base_type type)
*/
const glsl_type *get_explicit_interface_type(bool supports_std430) const;
+ /** Returns an explicitly laid out type given a type and size/align func
+ *
+ * The size/align func is only called for scalar and vector types and the
+ * returned type is otherwise laid out in the natural way as follows:
+ *
+ * - Arrays and matrices have a stride of ALIGN(elem_size, elem_align).
+ *
+ * - Structure types have their elements in-order and as tightly packed as
+ * possible following the alignment required by the size/align func.
+ *
+ * - All composite types (structures, matrices, and arrays) have an
+ * alignment equal to the highest alighment of any member of the composite.
+ *
+ * The types returned by this function are likely not suitable for most UBO
+ * or SSBO layout because they do not add the extra array and substructure
+ * alignment that is required by std140 and std430.
+ */
+ const glsl_type *get_explicit_type_for_size_align(glsl_type_size_align_func type_info,
+ unsigned *size, unsigned *align) const;
+
/**
* Alignment in bytes of the start of this type in OpenCL memory.
*/
*/
unsigned cl_size() const;
+ /**
+ * Size in bytes of this type based on its explicit data.
+ *
+ * When using SPIR-V shaders (ARB_gl_spirv), memory layouts are expressed
+ * through explicit offset, stride and matrix layout, so the size
+ * can/should be computed used those values.
+ *
+ * Note that the value returned by this method is only correct if such
+ * values are set, so only with SPIR-V shaders. Should not be used with
+ * GLSL shaders.
+ */
+ unsigned explicit_size(bool align_to_stride=false) const;
+
/**
* \brief Can this type be implicitly converted to another?
*
}
/**
- * Query whether or not a type is an integral type
+ * Query whether or not a type is an integer.
*/
bool is_integer() const
+ {
+ return glsl_base_type_is_integer(base_type);
+ }
+
+ /**
+ * Query whether or not a type is an 32-bit integer.
+ */
+ bool is_integer_32() const
{
return (base_type == GLSL_TYPE_UINT) || (base_type == GLSL_TYPE_INT);
}
*/
bool is_integer_32_64() const
{
- return is_integer() || is_integer_64();
+ return is_integer_32() || is_integer_64();
}
/**
return size;
}
+ /**
+ * Return bit size for this type.
+ */
+ unsigned bit_size() const
+ {
+ return glsl_base_type_bit_size(this->base_type);
+ }
+
+
/**
* Query whether or not a type is an atomic_uint.
*/
unsigned implicit_sized_array:1;
#ifdef __cplusplus
+#define DEFAULT_CONSTRUCTORS(_type, _precision, _name) \
+ type(_type), name(_name), location(-1), offset(-1), xfb_buffer(0), \
+ xfb_stride(0), interpolation(0), centroid(0), \
+ sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), patch(0), \
+ precision(_precision), memory_read_only(0), \
+ memory_write_only(0), memory_coherent(0), memory_volatile(0), \
+ memory_restrict(0), image_format(0), explicit_xfb_buffer(0), \
+ implicit_sized_array(0)
+
+ glsl_struct_field(const struct glsl_type *_type,
+ int _precision,
+ const char *_name)
+ : DEFAULT_CONSTRUCTORS(_type, _precision, _name)
+ {
+ /* empty */
+ }
+
glsl_struct_field(const struct glsl_type *_type, const char *_name)
- : type(_type), name(_name), location(-1), offset(-1), xfb_buffer(0),
- xfb_stride(0), interpolation(0), centroid(0),
- sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), patch(0),
- precision(GLSL_PRECISION_NONE), memory_read_only(0),
- memory_write_only(0), memory_coherent(0), memory_volatile(0),
- memory_restrict(0), image_format(0), explicit_xfb_buffer(0),
- implicit_sized_array(0)
+ : DEFAULT_CONSTRUCTORS(_type, GLSL_PRECISION_NONE, _name)
{
/* empty */
}
glsl_struct_field()
- : type(NULL), name(NULL), location(-1), offset(-1), xfb_buffer(0),
- xfb_stride(0), interpolation(0), centroid(0),
- sample(0), matrix_layout(0), patch(0),
- precision(0), memory_read_only(0),
- memory_write_only(0), memory_coherent(0), memory_volatile(0),
- memory_restrict(0), image_format(0), explicit_xfb_buffer(0),
- implicit_sized_array(0)
+ : DEFAULT_CONSTRUCTORS(NULL, GLSL_PRECISION_NONE, NULL)
{
/* empty */
}
+#undef DEFAULT_CONSTRUCTORS
#endif
};