-
Notifications
You must be signed in to change notification settings - Fork 18
Description
TLDR: I may be mistaken, but I believe descriptor indexing doesn't seem to be supported by Shady's IR right now and/or vcc. Array values are treated as composites which cannot have null contents. Pointers to non-physical memory seems to be a problem.
I created a test case in my fork https://github.com/btipling/shady/pull/1/files#diff-a14b4d4ab4459569a94d0df9c8ac9cfec03a497be9534b1161247923638b4ab3
I tried to spend some time on it, and I think the solutions might be either support for pointers to uniform constant AS or a new node type.
My attempt to look into the issue myself:
LLVM IR treats sampler2D[] as a one sized array. Array values are treated as composites, and declaring an array of 1 with no actual contents will result in an error during composite creation as there are no actual contents and composite contents cannot be null as defined in grammar.json. Setting the array size to 0 will create problems when shd_get_composite_type_element_types is called, an access violation occurs when trying to determine a composite with no contents. My attempt to shoe horn in a hack to detect an array of samplers on a 0 sized array results in a pointer
%89 = ptr(Generic, %88): CrossDevice %89 = @exported("texSamplers") @descriptorset(0) @DescriptorBinding(1) @io(13) GlobalVariable(type: %88, address_space: Generic, is_ref: false, init: null)
Pointers as a solution to descriptor indexing run into address space issues, as "UniformConstant is not physical in this arena" errors. By passing that error results in an error "cannot fix pointer" in lower_physical_ptrs.c as it tries to treat it as a physical address pointer and physical seems to be required:
case PtrType_TAG: return _shd_check_type_ptr_type(a, node->payload.ptr_type);
I see other types of pointer passes in the code but I'm not sure how they are used and none of them seem to be for the uniform constant AS.
I was thinking I could try a new node type, but I realized that would be complex as now I would have to understand from the LLVM IR when a GEP instruction(I think?) is referring to a value of this new node type, I'd have to handle a new value and instruction for that value in the LLVM frontend and the SPIR-V backend. I think it might be doable, but I don't know if this is the right approach, or if I am missing something big.
Trying to work backwards from DI GLSL SPIR-V I see OpAccessChain used for indexing and an OpTypeRuntimeArray is created for the sampler. I see that OpAccessChain is something vcc does for Instruction_PtrCompositeElement_TAG which tracing that to the frontend looks like it is emitted via lea_helper for pointers during lower passes. Working around that code, which feels weird since it is assuming a physical AS wasn't successful.
Maybe the fix is treating DI as a pointer and supporting the address space. I am not sure.