Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HLSL generator #3

Open
wants to merge 18 commits into
base: header_4_hlsl
Choose a base branch
from

Conversation

alichraghi
Copy link
Member

out.hlsl is basically the output of running this:

cd tools/hlsl_generator/
python3 gen.py out.hlsl

Comment on lines 31 to 33
//! General Decls
template<uint32_t StorageClass, typename T>
using pointer_t = vk::SpirvOpaqueType<spv::OpTypePointer, vk::Literal< vk::integral_constant<uint32_t, StorageClass> >, T>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pointer_t should be done in terms of

template<uint32_t StorageClass, typename T>
struct pointer
{
   using type = vk::SpirvOpaqueType<spv::OpTypePointer, vk::Literal< vk::integral_constant<uint32_t, StorageClass> >, T>;
};
// partial spec for BDA
template<typename T>
struct pointer<StorageClassPhysicalStorageBuffer,T>
{
   using type = vk::SpirvType<spv::OpTypePointer,sizeof(uint64_t),sizeof(uint64_t),vk::Literal< vk::integral_constant<uint32_t, StorageClass> >, T>;
};

template<uint32_t StorageClass, typename T>
using pointer_t = pointer::type;

and also have a is_pointer::value tester + is_pointer_v

Copy link
Member Author

@alichraghi alichraghi Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will go into type_traits.hlsl. right?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no it will go here because its spirv specific, it can be built with type_traits though, such as is_same_v

Comment on lines 40 to 43
//! Std 450 Extended set operations
template<typename SquareMatrix>
[[vk::ext_instruction(GLSLstd450MatrixInverse)]]
SquareMatrix matrixInverse(NBL_CONST_REF_ARG(SquareMatrix) mat);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you want to gen all the extended instruction set stuff

Comment on lines 103 to 111
case "SubgroupEqMask": builtin_type = "uint32_t4"
case "SubgroupGeMask": builtin_type = "uint32_t4"
case "SubgroupGtMask": builtin_type = "uint32_t4"
case "SubgroupLeMask": builtin_type = "uint32_t4"
case "SubgroupLtMask": builtin_type = "uint32_t4"
case "SubgroupSize": builtin_type = "uint32_t"
case "NumSubgroups": builtin_type = "uint32_t"
case "SubgroupId": builtin_type = "uint32_t"
case "SubgroupLocalInvocationId": builtin_type = "uint32_t"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some of the builtins also need caps or extensions

Comment on lines 138 to 166
writer.write("\n//! Instructions\n")
for instruction in grammer["instructions"]:
match instruction["class"]:
case "Atomic":
processInst(writer, instruction, InstOptions())
processInst(writer, instruction, InstOptions(shape=Shape.PTR_TEMPLATE))
case "Memory":
processInst(writer, instruction, InstOptions(shape=Shape.PTR_TEMPLATE))
processInst(writer, instruction, InstOptions(shape=Shape.PSB_RT))
case "Barrier" | "Bit":
processInst(writer, instruction, InstOptions())
case "Reserved":
match instruction["opname"]:
case "OpBeginInvocationInterlockEXT" | "OpEndInvocationInterlockEXT":
processInst(writer, instruction, InstOptions())
case "Non-Uniform":
match instruction["opname"]:
case "OpGroupNonUniformElect" | "OpGroupNonUniformAll" | "OpGroupNonUniformAny" | "OpGroupNonUniformAllEqual":
processInst(writer, instruction, InstOptions(result_ty="bool"))
case "OpGroupNonUniformBallot":
processInst(writer, instruction, InstOptions(result_ty="uint32_t4",op_ty="bool"))
case "OpGroupNonUniformInverseBallot" | "OpGroupNonUniformBallotBitExtract":
processInst(writer, instruction, InstOptions(result_ty="bool",op_ty="uint32_t4"))
case "OpGroupNonUniformBallotBitCount" | "OpGroupNonUniformBallotFindLSB" | "OpGroupNonUniformBallotFindMSB":
processInst(writer, instruction, InstOptions(result_ty="uint32_t",op_ty="uint32_t4"))
case _: processInst(writer, instruction, InstOptions())
case _: continue # TODO

writer.write(foot)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be good to print to a log anything to skipped

processInst(writer, instruction, InstOptions(shape=Shape.PTR_TEMPLATE))
case "Memory":
processInst(writer, instruction, InstOptions(shape=Shape.PTR_TEMPLATE))
processInst(writer, instruction, InstOptions(shape=Shape.PSB_RT))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Load/Store for BDA pointers should probably be handwritten

Comment on lines +131 to +136
writer.write("\n//! Group Operations\nnamespace group_operation\n{\n")
for go in group_operations:
name = go["enumerant"]
value = go["value"]
writer.write("\tstatic const uint32_t " + name + " = " + str(value) + ";\n")
writer.write("}\n")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just emit an enum?

Comment on lines 188 to 189
if cap == "Shader" or cap == "Kernel": continue
caps.append(cap)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anything with Kernel you need to skip emitting

Comment on lines 203 to 209
case "U":
fn_name = fn_name[0:m[1][0]] + fn_name[m[1][1]:]
result_types = ["uint32_t", "uint64_t"]
break
case "S":
fn_name = fn_name[0:m[1][0]] + fn_name[m[1][1]:]
result_types = ["int32_t", "int64_t"]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need a condition about being signed or unsigner

Also result types can be 16 bit ints too!

break
case "F":
fn_name = fn_name[0:m[1][0]] + fn_name[m[1][1]:]
result_types = ["float"]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use sized floats

Signed-off-by: Ali Cheraghi <[email protected]>
Comment on lines 31 to 49
//! General Decls
template<class T>
NBL_CONSTEXPR_STATIC_INLINE bool is_pointer_v = is_spirv_type<T>::value;

template<uint32_t StorageClass, typename T>
struct pointer
{
using type = vk::SpirvOpaqueType<spv::OpTypePointer, vk::Literal< vk::integral_constant<uint32_t, StorageClass> >, T>;
};
// partial spec for BDA
template<typename T>
struct pointer<spv::StorageClassPhysicalStorageBuffer, T>
{
using type = vk::SpirvType<spv::OpTypePointer, sizeof(uint64_t), sizeof(uint64_t), vk::Literal<vk::integral_constant<uint32_t, spv::StorageClassPhysicalStorageBuffer> >, T>;
};

template<uint32_t StorageClass, typename T>
using pointer_t = typename pointer<StorageClass, T>::type;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only is_ should be implemented via structs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wdym? it's from the snippet you sent here #3 (comment)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry I'm dumb.

Still the is_pointer_v is wrong cause you're checking for being a spir-v type, not OpTypePointer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants