Skip to content

Instantly share code, notes, and snippets.

@ykafia
Last active June 16, 2023 11:09
Show Gist options
  • Save ykafia/14b74d44876b12035a48665413fc7b9b to your computer and use it in GitHub Desktop.
Save ykafia/14b74d44876b12035a48665413fc7b9b to your computer and use it in GitHub Desktop.
Bytecode mixin

Byte code mixin

What i have so far

Currently have made a spirv parser/assembler library. The api is not versatile to make sure of minimal allocation.

There's a WordBuffer class containing functions like AddOpVariable and AddOpTypeInteger with parameters. Each parameters is then put into a stack allocated array and pushed to the buffer.

SPIR-V instructions

SPIR-V are composed of 32bit integer words (not exactly byte code). Types have to be declared and are either 2 or 3 words depending the type declared. There's an implicit index given to these instruction which can be used by other instruction.

Example below

; Magic:     0x07230203 (SPIR-V)
; Version:   0x00010000 (Version: 1.0.0)
; Generator: 0x00080001 (Khronos Glslang Reference Front End; 1)
; Bound:     63
; Schema:    0

               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main" %31 %33 %42 %57
               OpExecutionMode %4 OriginLowerLeft
. . .

; All types, variables, and constants
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2                      ; void ()
          %6 = OpTypeFloat 32                         ; 32-bit float
          %7 = OpTypeVector %6 4                      ; vec4
          %8 = OpTypePointer Function %7              ; function-local vec4*
         %10 = OpConstant %6 1
         %11 = OpConstant %6 2
. . .

Where %6 = OpTypeFloat 32 is the 6th instruction declared in the buffer that implicitely has an Id. It is used right after with %7 = OpTypeVector %6 4. OpTypeFloat is a 2 word instruction, one word for OpTypeFloat and the other for the value 32 declaring a 32bit float type. OpTypeVector is a 3 word instruction, one word for OpTypeVector, one for the index of the type %6 and the last one for the number of components 4 which results in a float4/vec4 type.

Mixins and Mixing ideas

Mixins would be defined as a SPIR-V byte code containing partial informations.

Let's define MixinA containing the OpTypeFloat instruction and MixinB containing the OpTypeVector instruction referencing the OpTypeFloat instruction.

In MixinA, OpTypeFloat would be the first instruction with an implicit Id, it would be disassembled as %1 = OpTypeFloat 32. In MixinB, the same would happen with OpTypeVector, it would also reference the OpTypeFloat present in MixinA and everything would be disassembled as %1 = OpTypeVector %1.

The index clash is the core issue we're facing with mixing spir-v raw byte code.

Idea 1 : Bound offset

Each mixin object will have an additional parameter giving an offset to the current mixin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment