def test_arb_example_std140(self): layout = Layout.STD430 struct_a = Struct( [ Scalar.int(), Vector.uvec2() # actually bvec2 ], layout, type_name="structA") struct_b = Struct([ Vector.uvec3(), Vector.vec2(), Array(Scalar.float(), 2, layout), Vector.vec2(), Array(Matrix(3, 3, DataType.FLOAT, layout), 2, layout) ], layout, type_name="structB") container = Struct([ Scalar.float(), Vector.vec2(), Vector.vec3(), struct_a, Scalar.float(), Array(Scalar.float(), 2, layout), Matrix(2, 3, DataType.FLOAT, layout), Array(struct_b, 2, layout) ], layout) self.run_test(container, [struct_a, struct_b], BufferUsage.STORAGE_BUFFER)
def test_pass_through_array_of_matrices(self): glsl_template = """ #version 450 #extension GL_ARB_separate_shader_objects : enable layout(local_size_x=1, local_size_y=1, local_size_z=1) in; layout({layout_in}, {order_in}, binding = 0) buffer BufferA {{ {dtype}[32][48] dataIn; }}; layout({layout_out}, {order_out}, binding = 1) buffer BufferB {{ {dtype}[32][48] dataOut; }}; void main() {{ vec3 pixel = gl_GlobalInvocationID; int h = int(pixel.x); int w = int(pixel.y); dataOut[h][w] = dataIn[h][w]; }} """ rng = np.random.RandomState(123) w = 48 h = 32 matrix_combinations = itertools.product(range(2, 5), range(2, 5), [DataType.FLOAT, DataType.DOUBLE]) layout_order_combinations = itertools.product(self.LAYOUTS, self.LAYOUTS, self.ORDERS, self.ORDERS) for combos1, combos2 in itertools.product(layout_order_combinations, matrix_combinations): layout_in, layout_out, order_in, order_out = combos1 matrix_in = Matrix(*combos2, layout=layout_in, order=order_in) shape = [h, w] + list(matrix_in.shape()) mat = rng.randint(0, 255, size=shape).astype(matrix_in.vector.scalar.numpy_dtype()) glsl = glsl_template.format(**{ "layout_in": self.LAYOUT_MAP[layout_in], "layout_out": self.LAYOUT_MAP[layout_out], "order_in": self.ORDERS_MAP[order_in], "order_out": self.ORDERS_MAP[order_out], "dtype": matrix_in.glsl_dtype() }) shader = self.shader_from_txt(glsl, verbose=False) shader.inspect() cache_in = ByteCache(shader.get_block_definition(0)) cache_in["dataIn"] = mat bytez_in = cache_in.definition.to_bytes(cache_in.get_as_dict()) cache_out = ByteCache(shader.get_block_definition(1)) bytez_out_count = cache_out.definition.size() bytez_out = self.run_compiled_program(shader, bytez_in, bytez_out_count, groups=(h, w, 1)) cache_out.set_from_dict(cache_out.definition.from_bytes(bytez_out)) self.assertTrue((cache_out["dataOut"] == mat).all())
def build_matrix_definition(self, matrix_index, layout, last_struct_index): # we assume that matrices always have the order decoration in bytecode (if they are part of a interface block) if last_struct_index is None: raise ByteCodeError.unexpected() member_indices = self.byte_code.find_member_ids(last_struct_index) member_orders = self.byte_code.find_orders(last_struct_index) # matrix is direct member of the last struct if matrix_index in member_indices: member = member_indices.index(matrix_index) # if the matrix is a member of an array which is a struct member, the array is also decorated with the # matrix order else: member = None for index in member_indices: if index in self.byte_code.types_array: type_index, _ = self.byte_code.types_array[index] if type_index == matrix_index: member = member_indices.index(index) break if member is None: raise ByteCodeError.unexpected() order_decoration = member_orders[member] order = { Decoration.ROW_MAJOR: Order.ROW_MAJOR, Decoration.COL_MAJOR: Order.COLUMN_MAJOR }[order_decoration] dtype, rows, cols = self.byte_code.types_matrix[matrix_index] return Matrix(cols, rows, dtype, layout, order)
def test_detection_type_nested_with_structs(self): rng = np.random.RandomState(321) simple = [Scalar.uint(), Scalar.int(), Scalar.float(), Scalar.double()] simple += [Vector(n, dtype) for n, dtype in itertools.product(range(2, 5), DataType.ALL)] for layout, _ in itertools.product([Layout.STD140, Layout.STD430], range(5)): matrices = [Matrix(n, m, dtype, layout) for n, m, dtype in itertools.product(range(2, 5), range(2, 5), [DataType.FLOAT, DataType.DOUBLE])] simple_and_matrices = simple + matrices struct = Struct(rng.choice(simple_and_matrices, size=3, replace=False), layout, type_name="SomeStruct") structs = [struct] for _ in range(4): members = [structs[-1]] + rng.choice(simple_and_matrices, size=2, replace=False).tolist() structs.append(Struct(rng.permutation(members), layout, type_name="SomeStruct{}".format(len(structs)))) container = structs[-1] structs = structs[:-1] glsl = self.build_glsl_program(((container, 0, BufferUsage.STORAGE_BUFFER),), structs) shader = self.shader_from_txt(glsl, verbose=False) shader.inspect() definition, _ = shader.code.get_block(0) self.assertTrue(container.compare(definition, quiet=True))
def test_matrices(self): # skipping ROW_MAJOR order for now since the glsl generation does not support it for n, m, dtype, order, layout in itertools.product( range(2, 5), range(2, 5), [DataType.FLOAT, DataType.DOUBLE], [Order.COLUMN_MAJOR], [Layout.STD140, Layout.STD430]): matrix = Matrix(n, m, dtype, layout, order) container = Struct([matrix], layout) self.run_test(container, [], BufferUsage.STORAGE_BUFFER)
def test_scalars_and_vectors_and_matrices(self): rng = np.random.RandomState(123) variables = [ Scalar.uint(), Scalar.int(), Scalar.float(), Scalar.double() ] variables += [ Vector(n, dtype) for n, dtype in itertools.product(range(2, 5), DataType.ALL) ] matrix_combinations = itertools.product(range(2, 5), range( 2, 5), [DataType.FLOAT, DataType.DOUBLE]) variables_std140 = variables + [ Matrix(n, m, dtype, Layout.STD140) for n, m, dtype in matrix_combinations ] variables_std430 = variables + [ Matrix(n, m, dtype, Layout.STD430) for n, m, dtype in matrix_combinations ] containers_std140 = [Struct(variables_std140, Layout.STD140)] containers_std430 = [Struct(variables_std430, Layout.STD430)] for _ in range(5): containers_std140.append( Struct(rng.permutation(variables_std140), Layout.STD140)) containers_std430.append( Struct(rng.permutation(variables_std430), Layout.STD430)) for container in containers_std140: self.run_test(container, [], BufferUsage.STORAGE_BUFFER) self.run_test(container, [], BufferUsage.UNIFORM_BUFFER) for container in containers_std430: self.run_test(container, [], BufferUsage.STORAGE_BUFFER)
def test_array_of_matrices(self): # skipping ROW_MAJOR order for now since the glsl generation does not support it rng = np.random.RandomState(123) matrix_combinations = itertools.product(range(2, 5), range( 2, 5), [DataType.FLOAT, DataType.DOUBLE]) for (n, m, dtype), layout, _ in itertools.product( matrix_combinations, [Layout.STD140, Layout.STD430], range(3)): matrix = Matrix(n, m, dtype, layout) container = Struct( [Array(matrix, Random.shape(rng, 3, 5), layout)], layout) self.run_test(container, [], BufferUsage.STORAGE_BUFFER)
def test_detection_type_arrays_of_matrices(self): rng = np.random.RandomState(321) matrix_attributes = itertools.product(range(2, 5), range(2, 5), [DataType.FLOAT, DataType.DOUBLE]) for (n, m, dtype), layout, _ in itertools.product(matrix_attributes, [Layout.STD140, Layout.STD430], range(3)): matrix = Matrix(n, m, dtype, layout) container = Struct([Array(matrix, Random.shape(rng, 3, 5), layout)], layout) glsl = self.build_glsl_program(((container, 0, BufferUsage.STORAGE_BUFFER),)) shader = self.shader_from_txt(glsl, verbose=False) shader.inspect() detected_definition, _ = shader.code.get_block(0) self.assertTrue(container.compare(detected_definition, quiet=True))
def test_nested_with_arrays_of_structs(self): rng = np.random.RandomState(123) simple = [Scalar.uint(), Scalar.int(), Scalar.float(), Scalar.double()] simple += [ Vector(n, dtype) for n, dtype in itertools.product(range(2, 5), DataType.ALL) ] for layout, _ in itertools.product([Layout.STD140, Layout.STD430], range(10)): matrices = [ Matrix(n, m, dtype, layout) for n, m, dtype in itertools.product(range(2, 5), range( 2, 5), [DataType.FLOAT, DataType.DOUBLE]) ] simple_and_matrices = simple + matrices struct = Struct(rng.choice(simple_and_matrices, size=4, replace=False), layout, type_name="SomeStruct") structs = [struct] arrays = [Array(struct, Random.shape(rng, 2, 3), layout)] for _ in range(2): members = [arrays[-1]] + rng.choice( simple_and_matrices, size=3, replace=False).tolist() structs.append( Struct(rng.permutation(members), layout, type_name="SomeStruct{}".format(len(structs)))) arrays.append( Array(structs[-1], Random.shape(rng, 2, 3), layout)) container = structs[-1] structs = structs[:-1] self.run_test(container, structs, BufferUsage.STORAGE_BUFFER) if layout == Layout.STD140: self.run_test(container, structs, BufferUsage.UNIFORM_BUFFER)