-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathGeometryShader.cpp
106 lines (83 loc) · 3.98 KB
/
GeometryShader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "test/Modules.h"
#include "spvgentwo/TypeAlias.h"
#include "spvgentwo/Templates.h"
using namespace spvgentwo;
Module test::geometryShader(IAllocator* _pAllocator, ILogger* _pLogger)
{
using namespace glsl;
// create a new spir-v module
Module module(_pAllocator, spv::AddressingModel::Logical, spv::MemoryModel::GLSL450, _pLogger);
// configure capabilities and extensions
module.addCapability(spv::Capability::Geometry);
//module.addExtension("GLSL.std.450"); // needed?
module.addSourceStringInstr()->opSource(spv::SourceLanguage::GLSL, 330u);
EntryPoint& entry = module.addEntryPoint(spv::ExecutionModel::Geometry, u8"main");
entry.addExecutionMode(spv::ExecutionMode::InputPoints);
entry.addExecutionMode(spv::ExecutionMode::Invocations, 1u);
entry.addExecutionMode(spv::ExecutionMode::OutputLineStrip);
entry.addExecutionMode(spv::ExecutionMode::OutputVertices, 2u);
Type type = module.newType();
// wouldnt it be nice to have proper relfection in c++?
struct gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[1];
};
type.Struct();
type.Member().VectorElement(4).Float(); // vec4 gl_Position
type.FloatM(); // float gl_PointSize
type.Member().ArrayElement(1u).Float(); // float gl_ClipDistance[];
Instruction* glPerVertexType = module.addType(type, u8"gl_PerVertex"); // just to assign the name
module.addDecorationInstr()->opDecorate(glPerVertexType, spv::Decoration::Block);
module.addDecorationInstr()->opMemberDecorate(glPerVertexType, 0, spv::Decoration::BuiltIn, spv::BuiltIn::Position);
module.addDecorationInstr()->opMemberDecorate(glPerVertexType, 1, spv::Decoration::BuiltIn, spv::BuiltIn::PointSize);
module.addDecorationInstr()->opMemberDecorate(glPerVertexType, 2, spv::Decoration::BuiltIn, spv::BuiltIn::ClipDistance);
module.addMemberName(glPerVertexType, u8"gl_Position", 0u);
module.addMemberName(glPerVertexType, u8"gl_PointSize", 1u);
module.addMemberName(glPerVertexType, u8"gl_ClipDistance", 2u);
const char* memberName = glPerVertexType->getName(1u);
Instruction* outPerVertex = module.output(type, u8"gl_out");
Instruction* inPerVertex = module.input(type.wrapArray(1u), u8"gl_in");
// void main();
{
BasicBlock& bb = *entry; // get entry block to this function
// test comp
{
Instruction* glin_PerVertexPtr = bb->opAccessChain(inPerVertex); // gl_in[0].gl_Position
Instruction* glin_PerVertex = bb->opLoad(glin_PerVertexPtr); // array
Instruction* struct_ = bb->opCompositeExtract(glin_PerVertex, 0u); // get the struct
Instruction* vec_y = bb->opCompositeExtract(struct_, 0u, 1u); // get vec -> get y element
vec_y = bb->Mul(vec_y, vec_y); // square
bb->opCompositeInsert(glin_PerVertex, vec_y, 0u, 0u, 1u);
}
Instruction* glin_PositionPtr = bb->opAccessChain(inPerVertex, 0u, 0u); // gl_in[0].gl_Position
Instruction* glin_Position = bb->opLoad(glin_PositionPtr);
Instruction* constNeg = module.constant(make_vector(-0.1f, 0.f, 0.f, 0.f));
Instruction* newPos = bb->Add(glin_Position, constNeg);
Instruction* glout_PositionPtr = bb->opAccessChain(outPerVertex, 0u); // gl_out.glPosition
bb->opStore(glout_PositionPtr, newPos);
bb->opEmitVertex();
Instruction* constPos = module.constant(make_vector(0.1f, 0.f, 0.f, 0.f));
newPos = bb->Add(glin_Position, constPos);
bb->opStore(glout_PositionPtr, newPos);
bb->opEmitVertex();
bb->opEndPrimitive();
entry->opReturn();
}
return module;
}
// SHADER:
//#version 330 core
//layout(points) in;
//layout(line_strip, max_vertices = 2) out;
//
//void main() {
// gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0);
// EmitVertex();
//
// gl_Position = gl_in[0].gl_Position + vec4(0.1, 0.0, 0.0, 0.0);
// EmitVertex();
//
// EndPrimitive();
//}