Example #1
0
	def dtype(self):
		'''The numpy datatype used to represent this block member in a buffer.

		:rtype: :py:class:`numpy.dtype`
		:raises TypeError: If the block layout is not a standard layout.
		'''

		# Rule 1, 2 & 3
		if isinstance(self.datatype, (Scalar, Vector)):
			return self.datatype.machine_type

		# Rule 10 could be defined separately to be consisted with packed/shared layout dtypes.
		# However, all members are guaranteed to be preserved in standard formats, and this produces
		# dtypes that are easier to work with

		# Rule 4, 6, 8 & 10
		if isinstance(self.datatype, Array):
			element = self[0]
			item_dtype = element.dtype
			if isinstance(element.datatype, BasicType):
				item_dtype = dtype({'names': [element.datatype.name], 'formats': [item_dtype],
									'itemsize': self.array_stride})
			return dtype((item_dtype, len(self)))

		# Rules 5 & 7
		if isinstance(self.datatype, Matrix):
			if self.matrix_layout == MatrixLayout.column_major:
				item_dim = 'column'
				items, components = self.datatype.shape
			elif self.matrix_layout == MatrixLayout.row_major:
				item_dim = 'row'
				components, items = self.datatype.shape
			item_dtype = Vector.fromType(self.datatype.scalar_type, components).machine_type
			item_dtype = dtype({'names': ['-'.join((self.datatype.name, item_dim))],
			                    'formats': [item_dtype], 'itemsize': self.matrix_stride})
			return dtype((item_dtype, items))

		# Rule 9
		if isinstance(self.datatype, Struct):
			names = [c.name for c in self]
			dtypes = [c.dtype for c in self]
			offsets = []
			offset = 0
			for c in self:
				offset = roundUp(offset, c.alignment)
				offsets.append(offset)
				offset += c.dtype.itemsize
			struct_size = roundUp(offset, self.alignment)
			return dtype({'names': names, 'formats': dtypes, 'offsets': offsets,
			              'itemsize': struct_size})
Example #2
0
	def alignment(self):
		'''How the block member is to be aligned. Returns :py:obj:`None` if the layout of the block
		containing this object is not a standardized layout.

		:rtype: :py:obj:`int` or :py:obj:`None`
		'''

		if self.layout not in (BlockLayout.std140, BlockLayout.std430):
			return None

		if self.layout == BlockLayout.std140:
			alignment_rounding = Vector.vec4.machine_type.itemsize
		else:
			alignment_rounding = 1

		# Rule 1
		if isinstance(self.datatype, Scalar):
			return self.datatype.machine_type.itemsize
		# Rule 2 & 3
		elif isinstance(self.datatype, Vector):
			item_type, (components,) = self.datatype.machine_type.subdtype
			if components == 3:
				components = 4
			return item_type.itemsize * components

		# Rule 4, 6, 7 & 10
		if isinstance(self.datatype, Array):
			return roundUp(self[0].alignment, alignment_rounding)

		# Rules 5 & 7
		if isinstance(self.datatype, Matrix):
			if self.matrix_layout == MatrixLayout.column_major:
				items, components = self.datatype.shape
			elif self.matrix_layout == MatrixLayout.row_major:
				components, items = self.datatype.shape
			align_type = Array(Vector.fromType(self.datatype.scalar_type, components), items)
			return InterfaceBlockMember(self.block, self.name, align_type).alignment

		# Rule 9
		if isinstance(self.datatype, Struct):
			alignment = max(c.alignment for c in self)
			return roundUp(alignment, alignment_rounding)
Example #3
0
	def dtype(self):
		'''The memory layout of the uniform block.

		:rtype: :py:class:`numpy.dtype`
		:raises TypeError: If the block layout is not a standard layout.
		'''

		if self.layout.standardized:
			offsets = []
			offset = 0
			for m in self:
				offset = roundUp(offset, m.alignment)
				offsets.append(offset)
				offset += m.dtype.itemsize
			names, formats = zip(*((m.name, m.dtype) for m in self))
			return dtype({'names': list(names), 'formats': list(formats), 'offsets': offsets})
		else:
			raise TypeError("The layout for this interface block is not defined.")
Example #4
0
	def array_stride(self):
		if not (isinstance(self.datatype, Array) and self.layout.standardized):
			raise TypeError("Not an array with standardized layout.")
		return roundUp(self[0].dtype.itemsize, self.alignment)