// File: rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::type_to_packed_alignment(spirv_cross::SPIRType const&, spirv_cross::Bitset const&, spirv_cross::BufferPackingStandard)
uint32_t CompilerGLSL::type_to_packed_alignment(const SPIRType &type, const Bitset &flags,
                                                BufferPackingStandard packing)
{
	if (!type.array.empty())
	{
		uint32_t minimum_alignment = 1;
		if (packing_is_vec4_padded(packing))
			minimum_alignment = 16;

		auto *tmp = &get<SPIRType>(type.parent_type);
		while (!tmp->array.empty())
			tmp = &get<SPIRType>(tmp->parent_type);

		// Get the alignment of the base type, then maybe round up.
		return max(minimum_alignment, type_to_packed_alignment(*tmp, flags, packing));
	}

	if (type.basetype == SPIRType::Struct)
	{
		// Rule 9. Structs alignments are maximum alignment of its members.
		uint32_t alignment = 0;
		for (uint32_t i = 0; i < type.member_types.size(); i++)
		{
			auto member_flags = ir.meta[type.self].members.at(i).decoration_flags;
			alignment =
			    max(alignment, type_to_packed_alignment(get<SPIRType>(type.member_types[i]), member_flags, packing));
		}

		// In std140, struct alignment is rounded up to 16.
		if (packing_is_vec4_padded(packing))
			alignment = max(alignment, 16u);

		return alignment;
	}
	else
	{
		const uint32_t base_alignment = type_to_packed_base_size(type, packing);

		// Vectors are *not* aligned in HLSL, but there's an extra rule where vectors cannot straddle
		// a vec4, this is handled outside since that part knows our current offset.
		if (type.columns == 1 && packing_is_hlsl(packing))
			return base_alignment;

		// From 7.6.2.2 in GL 4.5 core spec.
		// Rule 1
		if (type.vecsize == 1 && type.columns == 1)
			return base_alignment;

		// Rule 2
		if ((type.vecsize == 2 || type.vecsize == 4) && type.columns == 1)
			return type.vecsize * base_alignment;

		// Rule 3
		if (type.vecsize == 3 && type.columns == 1)
			return 4 * base_alignment;

		// Rule 4 implied. Alignment does not change in std430.

		// Rule 5. Column-major matrices are stored as arrays of
		// vectors.
		if (flags.get(DecorationColMajor) && type.columns > 1)
		{
			if (packing_is_vec4_padded(packing))
				return 4 * base_alignment;
			else if (type.vecsize == 3)
				return 4 * base_alignment;
			else
				return type.vecsize * base_alignment;
		}

		// Rule 6 implied.

		// Rule 7.
		if (flags.get(DecorationRowMajor) && type.vecsize > 1)
		{
			if (packing_is_vec4_padded(packing))
				return 4 * base_alignment;
			else if (type.columns == 3)
				return 4 * base_alignment;
			else
				return type.columns * base_alignment;
		}

		// Rule 8 implied.
	}

	SPIRV_CROSS_THROW("Did not find suitable rule for type. Bogus decorations?");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0x18(%rbp), %rdi
addq $0x20, %rdi
callq 0x8690
testb $0x1, %al
jne 0x5d692
movl $0x1, -0x28(%rbp)
movl -0x24(%rbp), %edi
callq 0x5da90
testb $0x1, %al
jne 0x5d60f
jmp 0x5d616
movl $0x10, -0x28(%rbp)
movq -0xd0(%rbp), %rdi
movq -0x18(%rbp), %rax
movl 0x9c(%rax), %esi
callq 0xea90
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
addq $0x20, %rdi
callq 0x8690
xorb $-0x1, %al
testb $0x1, %al
jne 0x5d645
jmp 0x5d661
movq -0xd0(%rbp), %rdi
movq -0x30(%rbp), %rax
movl 0x9c(%rax), %esi
callq 0xea90
movq %rax, -0x30(%rbp)
jmp 0x5d630
movq -0xd0(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x20(%rbp), %rdx
movl -0x24(%rbp), %ecx
callq 0x5d5c0
movl %eax, -0x34(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x9f7e0
movl (%rax), %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x18(%rbp), %rax
cmpl $0xc, 0xc(%rax)
jne 0x5d800
movl $0x0, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movq %rax, -0xd8(%rbp)
movq -0x18(%rbp), %rdi
addq $0x68, %rdi
callq 0x8650
movq %rax, %rcx
movq -0xd8(%rbp), %rax
cmpq %rcx, %rax
jae 0x5d7c8
movq -0xd0(%rbp), %rdi
addq $0x38, %rdi
movq -0x18(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, %esi
callq 0xead0
movq %rax, %rdi
addq $0xd0, %rdi
movl -0x3c(%rbp), %eax
movl %eax, %esi
callq 0x9f820
movq %rax, %rsi
addq $0x60, %rsi
leaq -0x80(%rbp), %rdi
callq 0xef10
movq -0x18(%rbp), %rdi
addq $0x68, %rdi
movl -0x3c(%rbp), %eax
movl %eax, %esi
callq 0x8570
movq -0xd0(%rbp), %rdi
movl (%rax), %esi
callq 0xea90
movq %rax, -0xe0(%rbp)
jmp 0x5d73e
movq -0xe0(%rbp), %rsi
movq -0xd0(%rbp), %rdi
movl -0x24(%rbp), %ecx
leaq -0x80(%rbp), %rdx
callq 0x5d5c0
movl %eax, -0xe4(%rbp)
jmp 0x5d760
movl -0xe4(%rbp), %eax
movl %eax, -0x84(%rbp)
leaq -0x38(%rbp), %rdi
leaq -0x84(%rbp), %rsi
callq 0x9f7e0
movq %rax, -0xf0(%rbp)
jmp 0x5d785
movq -0xf0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x38(%rbp)
leaq -0x80(%rbp), %rdi
callq 0xf250
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x5d6ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x80(%rbp), %rdi
callq 0xf250
jmp 0x5da7a
movl -0x24(%rbp), %edi
callq 0x5da90
testb $0x1, %al
jne 0x5d7d6
jmp 0x5d7f5
movl $0x10, -0x98(%rbp)
leaq -0x38(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x9f7e0
movl (%rax), %eax
movl %eax, -0x38(%rbp)
movl -0x38(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0xd0(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x24(%rbp), %edx
callq 0x5d490
movl %eax, -0x9c(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jne 0x5d83f
movl -0x24(%rbp), %edi
callq 0x5dad0
testb $0x1, %al
jne 0x5d831
jmp 0x5d83f
movl -0x9c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x18(%rbp), %rax
cmpl $0x1, 0x14(%rax)
jne 0x5d861
movq -0x18(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jne 0x5d861
movl -0x9c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x18(%rbp), %rax
cmpl $0x2, 0x14(%rax)
je 0x5d875
movq -0x18(%rbp), %rax
cmpl $0x4, 0x14(%rax)
jne 0x5d895
movq -0x18(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jne 0x5d895
movq -0x18(%rbp), %rax
movl 0x14(%rax), %eax
imull -0x9c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x18(%rbp), %rax
cmpl $0x3, 0x14(%rax)
jne 0x5d8ba
movq -0x18(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jne 0x5d8ba
movl -0x9c(%rbp), %eax
shll $0x2, %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x20(%rbp), %rdi
movl $0x5, %esi
callq 0xef50
testb $0x1, %al
jne 0x5d8ce
jmp 0x5d928
movq -0x18(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jbe 0x5d928
movl -0x24(%rbp), %edi
callq 0x5da90
testb $0x1, %al
jne 0x5d8e6
jmp 0x5d8f7
movl -0x9c(%rbp), %eax
shll $0x2, %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x18(%rbp), %rax
cmpl $0x3, 0x14(%rax)
jne 0x5d912
movl -0x9c(%rbp), %eax
shll $0x2, %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x18(%rbp), %rax
movl 0x14(%rax), %eax
imull -0x9c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x20(%rbp), %rdi
movl $0x4, %esi
callq 0xef50
testb $0x1, %al
jne 0x5d93c
jmp 0x5d996
movq -0x18(%rbp), %rax
cmpl $0x1, 0x14(%rax)
jbe 0x5d996
movl -0x24(%rbp), %edi
callq 0x5da90
testb $0x1, %al
jne 0x5d954
jmp 0x5d965
movl -0x9c(%rbp), %eax
shll $0x2, %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x18(%rbp), %rax
cmpl $0x3, 0x18(%rax)
jne 0x5d980
movl -0x9c(%rbp), %eax
shll $0x2, %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
movq -0x18(%rbp), %rax
movl 0x18(%rax), %eax
imull -0x9c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x5da6e
jmp 0x5d998
movb $0x1, -0xc2(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x100(%rbp)
leaq -0xc1(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x7650
movq -0xf8(%rbp), %rdx
leaq 0xe381c(%rip), %rsi     # 0x1411ed
leaq -0xc0(%rbp), %rdi
callq 0x7520
jmp 0x5d9df
movq -0x100(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x9c50
jmp 0x5d9f4
movq -0x100(%rbp), %rdi
movb $0x0, -0xc2(%rbp)
leaq 0x1503cf(%rip), %rsi    # 0x1addd8
leaq -0x53d80(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0x5da86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x5da49
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x7708
leaq -0xc1(%rbp), %rdi
callq 0x73d0
testb $0x1, -0xc2(%rbp)
jne 0x5da60
jmp 0x5da6c
movq -0x100(%rbp), %rdi
callq 0x72c0
jmp 0x5da7a
movl -0x4(%rbp), %eax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq -0x90(%rbp), %rdi
callq 0x7640
nopw %cs:(%rax,%rax)