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

WIP: Implement composite specialization constants #208

Closed
wants to merge 6 commits into from

Conversation

Qining
Copy link
Contributor

@Qining Qining commented Mar 17, 2016

Creating specialization constant aggregate variables with specialization
constants and OpSpecConstantComposite should has been already supported, issue #163.

Version/profile/semantics checking for the validity of using
specialization constants is not done yet.

Tests not added yet.

Approach:

  1. Propagate 'SpecConstant' label in executeInitializer() to mark
    variable's initializer as 'SpecConstant' if it should be marked.

  2. Handle contant variables with 'SpecConstant' initializer in
    executeInitializer(), propgate the 'SpecConstant' label to the variable
    and cache the initializer subtree.

  3. Add function to create SpvConstants from initializer subtree. This
    may be able to replace the current SpvConstants creation routine which is using
    ConstantUnionArray.

Other:

  1. Renamed the SpvConstants creation functions:
    createSpvSpecConstant => createSpvConstant
    createSpvConstant => createSpvConstantFromConstUnionArray

Creating specialization constant aggregate variables with specialization
constants and OpSpecConstantComposite should has been already supported.

Creating specialization constants with math operations, specialization
constants and OpSpecConstantOp <real op> is not supported yet.

Version/profile/semantics checking for the validity of using
specialization constants is not done yet.

Approach:
1) Propagate 'SpecConstant' label in executeInitializer() to mark
variable's initializer as 'SpecConstant' if it should be marked.

2) Handle contant variables with 'SpecConstant' initializer in
executeInitializer(), propgate the 'SpecConstant' label to the variable
and cache the initializer subtree.

3) Add function to create SpvConstants from initializer subtree. This
may be able to replace the current SpvConstants creation routine which is using
ConstantUnionArray.

Other:
1) Renamed the SpvConstants creation functions:
  createSpvSpecConstant => createSpvConstant
  createSpvConstant => createSpvConstantFromConstUnionArray
@Qining
Copy link
Contributor Author

Qining commented Mar 17, 2016

Example shader:

#version 450
layout(constant_id = 200) const float myfloat = 1.25;
layout(constant_id = 201) const int myint = 14;
struct structtype {
  float f;
  int i;
};
const structtype outer_struct_var = {myfloat, myint};
void main(){}

Generated SPIR-V code:

; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 1
; Bound: 12
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Vertex %4 "main"
               OpSource GLSL 450
               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
               OpSourceExtension "GL_GOOGLE_include_directive"
               OpName %4 "main"
               OpName %10 "structtype"
               OpMemberName %10 0 "f"
               OpMemberName %10 1 "i"
               OpDecorate %7 SpecId 200
               OpDecorate %9 SpecId 201
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeFloat 32
          %7 = OpSpecConstant %6 1.25
          %8 = OpTypeInt 32 1
          %9 = OpSpecConstant %8 14
         %10 = OpTypeStruct %6 %8
         %11 = OpSpecConstantComposite %10 %7 %9
          %4 = OpFunction %2 None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd

Fixed crash:
```
layout(constant_id = 100) const float myfloat = 3.14;
const vec4 spec_const_vec = vec2(myfloat, 1.0, 2.0, 3.0);

out vec4 color;

void main() {
  color += spec_const_vec;
}
```

Tests added.
@Qining
Copy link
Contributor Author

Qining commented Mar 17, 2016

@dekimir @dneto0 @antiagainst @AWoloszyn @johnkslang PTAL.

const expr is not yet implemented.

Qining added 4 commits March 17, 2016 16:58
…the typical usage of dot and bracket dereferencing, but not yet finished for all usages.
Issue fixed:
```
layout(constant_id = xxx) const int a_spec_const_int = 5
int global_int_array_with_spec_length[a_spec_const_int];

void main() {
  int len = global_int_array_with_spec_length.length();
  ...
}
```

Original SPIR-V code generated:
```
  CONST_ID Constant INT_TYPE 5
  ...
  Store LEN_VAR_ID CONST_ID
```

Now, the SPIR-V code generate:
```
  CONST_ID SpecConstant INT_TYPE 5
  ...
  Store LEN_VAR_ID CONST_ID
```
@Qining Qining force-pushed the spec-constants-expression branch from 19a2a73 to 6eaa9f1 Compare March 18, 2016 22:01
@Qining Qining changed the title WIP: SpecConstants can be used in expressions WIP: Implement composite specialization constants Mar 18, 2016
// 1) All of its child nodes are constants, either ConstantUnion or symbols
// with constant storage and 'SpecConstant' label.
// 2) At least one of its child should be 'SpecConstant'.
void propagateSpecConstant(TIntermTyped* node) {
Copy link
Member

Choose a reason for hiding this comment

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

Normally, the tree is built bottom up, and should be built with correct typing each step along the way.

E.g., When two nodes are combined with an operator (which becomes their parent), all the correct promotions and type setting of the result are done at that point in time. So, no multi-level tree should exist where the intermediate nodes don't already correctly reflect the combination of their children. Yet, this seems like a recursive "patch up" that implies a multi-level tree was built and left lying around for a while, while carrying incorrect information.

Maybe that works for this, I'm still thinking it through, just want to be clear what the typical pattern is, and see, is there a reason going against it is better?

Copy link
Member

Choose a reason for hiding this comment

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

The specification (KHR_vulkan_glsl) is also specific about what operations propagate "specialization constantness", so it makes sense to localize the propagation to where those operators are implemented. (That is, a general algorithm would accept too many things as being valid.)

Qining added a commit to Qining/glslang that referenced this pull request Mar 21, 2016
Fix issue KhronosGroup#163, support creation and usage of composite type
specialization constants.

e.g.:
```
layout(constant_id = 200) const float myfloat = 1.25;
layout(constant_id = 201) const int myint = 14;
struct structtype {
  float f;
  int i;
};
const structtype outer_struct_var = {myfloat, myint};
void main(){}
```
generated code (use glslangValidator):
```
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 12

                              Capability Shader
               1:             ExtInstImport  "GLSL.std.450"
                              MemoryModel Logical GLSL450
                              EntryPoint Vertex 4  "main"
                              Source GLSL 450
                              Name 4  "main"
                              Name 10  "structtype"
                              MemberName 10(structtype) 0  "f"
                              MemberName 10(structtype) 1  "i"
                              Decorate 7 SpecId 200
                              Decorate 9 SpecId 201
               2:             TypeVoid
               3:             TypeFunction 2
               6:             TypeFloat 32
               7:    6(float) SpecConstant 1067450368
               8:             TypeInt 32 1
               9:      8(int) SpecConstant 14
  10(structtype):             TypeStruct 6(float) 8(int)
              11:10(structtype) SpecConstantComposite 7 9
         4(main):           2 Function None 3
               5:             Label
                              Return
                              FunctionEnd
```

Rname two function names to match their functionalities.
1) Rename `GlslangToSpvTraverser::createSpvSpecConstant()` to
`createSpvConstant()`;
2) Rename `GlslangToSpvTraverser::createSpvConstant()` to
`createSpvConstantFromConstUnionArray()`

Add function `GlslangToSpvTraverser::createSpvConstantFromSubTree()` to
handle constant creation from sub trees (e.g.: specialization constants).

Related PR: KhronosGroup#208
@Qining
Copy link
Contributor Author

Qining commented Mar 24, 2016

Close as #211 replaces this CL.

@Qining Qining closed this Mar 24, 2016
Qining added a commit to Qining/glslang that referenced this pull request Mar 24, 2016
Fix issue KhronosGroup#163, support creation and reference of composite type
specialization constants.

e.g.:
```
layout(constant_id = 200) const float myfloat = 1.25;
layout(constant_id = 201) const int myint = 14;
struct structtype {
  float f;
  int i;
};
const structtype outer_struct_var = {myfloat, myint};
void main(){}
```
generated code (use glslangValidator):
```
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 12

                              Capability Shader
               1:             ExtInstImport  "GLSL.std.450"
                              MemoryModel Logical GLSL450
                              EntryPoint Vertex 4  "main"
                              Source GLSL 450
                              Name 4  "main"
                              Name 10  "structtype"
                              MemberName 10(structtype) 0  "f"
                              MemberName 10(structtype) 1  "i"
                              Decorate 7 SpecId 200
                              Decorate 9 SpecId 201
               2:             TypeVoid
               3:             TypeFunction 2
               6:             TypeFloat 32
               7:    6(float) SpecConstant 1067450368
               8:             TypeInt 32 1
               9:      8(int) SpecConstant 14
  10(structtype):             TypeStruct 6(float) 8(int)
              11:10(structtype) SpecConstantComposite 7 9
         4(main):           2 Function None 3
               5:             Label
                              Return
                              FunctionEnd
```

Rname two function names to match their functionalities.
1) Rename `GlslangToSpvTraverser::createSpvSpecConstant()` to
`createSpvConstant()`;
2) Rename `GlslangToSpvTraverser::createSpvConstant()` to
`createSpvConstantFromConstUnionArray()`

Add function `GlslangToSpvTraverser::createSpvConstantFromSubTree()` to
handle constant creation from sub trees (e.g.: specialization constants).

Related PR: KhronosGroup#208
Qining added a commit to Qining/glslang that referenced this pull request Mar 24, 2016
Fix issue KhronosGroup#163, support creation and reference of composite type
specialization constants.

e.g.:
```
layout(constant_id = 200) const float myfloat = 1.25;
layout(constant_id = 201) const int myint = 14;
struct structtype {
  float f;
  int i;
};
const structtype outer_struct_var = {myfloat, myint};
void main(){}
```
generated code (use glslangValidator):
```
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 12

                              Capability Shader
               1:             ExtInstImport  "GLSL.std.450"
                              MemoryModel Logical GLSL450
                              EntryPoint Vertex 4  "main"
                              Source GLSL 450
                              Name 4  "main"
                              Name 10  "structtype"
                              MemberName 10(structtype) 0  "f"
                              MemberName 10(structtype) 1  "i"
                              Decorate 7 SpecId 200
                              Decorate 9 SpecId 201
               2:             TypeVoid
               3:             TypeFunction 2
               6:             TypeFloat 32
               7:    6(float) SpecConstant 1067450368
               8:             TypeInt 32 1
               9:      8(int) SpecConstant 14
  10(structtype):             TypeStruct 6(float) 8(int)
              11:10(structtype) SpecConstantComposite 7 9
         4(main):           2 Function None 3
               5:             Label
                              Return
                              FunctionEnd
```

Rname two function names to match their functionalities.
1) Rename `GlslangToSpvTraverser::createSpvSpecConstant()` to
`createSpvConstant()`;
2) Rename `GlslangToSpvTraverser::createSpvConstant()` to
`createSpvConstantFromConstUnionArray()`

Add function `GlslangToSpvTraverser::createSpvConstantFromSubTree()` to
handle constant creation from sub trees (e.g.: specialization constants).

Related PR: KhronosGroup#208
qingyuanzNV pushed a commit to qingyuanzNV/glslang that referenced this pull request Oct 18, 2022
…loop_control_bit

Reserve loop control bit for upcoming trip count (min,max,avg) control
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.

2 participants