-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathFragmentShader.cpp
111 lines (87 loc) · 5.03 KB
/
FragmentShader.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
107
108
109
110
111
#include "test/Modules.h"
#include "spvgentwo/TypeAlias.h"
#include "spvgentwo/Templates.h"
using namespace spvgentwo;
spvgentwo::Module test::fragmentShader(spvgentwo::IAllocator* _pAllocator, spvgentwo::ILogger* _pLogger)
{
// create a new spir-v module
Module module(_pAllocator, _pLogger);
// configure capabilities and extensions
module.addCapability(spv::Capability::Shader);
module.addCapability(spv::Capability::StorageImageExtendedFormats);
module.addCapability(spv::Capability::Float16);
module.addCapability(spv::Capability::Int8);
module.addCapability(spv::Capability::Kernel);
module.addCapability(spv::Capability::ImageQuery);
// global variables
Instruction* const uniColor = module.uniform<glsl::vec4>(u8"u_color", module.constant(make_vector(0.f, 0.f, 0.f, 1.f))); // use initializer
Instruction* const uniTex = module.uniform(u8"u_baseColor", dyn_sampled_image_t{}); //default 2d float texture
Instruction* const inUV = module.input<glsl::vec2>(u8"v_inUV"); // varying input UVs
dyn_image_t imgDesc{ dyn_scalar_t{spv::Op::OpTypeFloat, 16u}, spv::Dim::Dim2D };
imgDesc.format = spv::ImageFormat::Rg16;
Instruction* const uniImgRawRG16 = module.uniform(u8"u_imgRG16", imgDesc);
imgDesc.multiSampled = true;
Instruction* const uniImgRawRG16MS = module.uniform(u8"u_imgRG16MS", imgDesc);
imgDesc.multiSampled = false;
imgDesc.format = spv::ImageFormat::Unknown;
Instruction* const uniImageUnknownFmt = module.uniform(u8"u_imgUnknownFmt", dyn_sampled_image_t{ imgDesc });
imgDesc.format = spv::ImageFormat::Rg32f;
imgDesc.sampledType.bits = 32u;
imgDesc.accessQualifier = spv::AccessQualifier::WriteOnly;
imgDesc.samplerAccess = SamplerImageAccess::Unknown;
Instruction* const uniImgRawStorageRG32 = module.uniform(u8"u_imgStorageRG32", imgDesc);
// 3d volume tex
imgDesc.dimension = spv::Dim::Dim3D;
imgDesc.sampledType = { spv::Op::OpTypeInt, 8u };
imgDesc.format = spv::ImageFormat::Rgba8ui;
Instruction* const uni3DImgRawRGBA8 = module.uniform(u8"u_img3DRGBA8", imgDesc);
// void sample type tex
imgDesc.dimension = spv::Dim::Dim2D;
imgDesc.format = spv::ImageFormat::Rgba16;
imgDesc.sampledType = DynScalarVoid;
imgDesc.accessQualifier = spv::AccessQualifier::ReadOnly;
imgDesc.samplerAccess = SamplerImageAccess::Sampled;
Instruction* const uni2DImgVoidRGBA16 = module.uniform(u8"u_img2DRGBA16Void", dyn_sampled_image_t{ imgDesc });
Instruction* const constCoord2D = module.constant(make_vector(0u, 1u));
Instruction* const constCoord3D = module.constant(make_vector(0u, 1u, 2u));
// void main(); entry point
{
EntryPoint& entry = module.addEntryPoint(spv::ExecutionModel::Fragment, "main");
entry.addExecutionMode(spv::ExecutionMode::OriginUpperLeft);
BasicBlock& bb = *entry; // get entry block to this function
Instruction* mask = bb->opLoad(uniColor);
Instruction* alphaMask = bb->opVectorExtractDynamic(mask, module.constant(3u)); // extract alpha channel
Instruction* const unknownSampledImg = bb->opLoad(uniImageUnknownFmt);
Instruction* const unknownImg = bb->opImage(unknownSampledImg);
Instruction* format = bb->opImageQueryFormat(unknownImg);
Instruction* channelOrder = bb->opImageQueryOrder(unknownImg);
Instruction* sizeDim = bb->opImageQuerySizeLod(unknownImg, module.constant(0u));
sizeDim = bb->opImageQuerySize(unknownImg);
Instruction* lod = bb->opImageQueryLod(unknownSampledImg, constCoord2D);
Instruction* levels = bb->opImageQueryLevels(unknownImg);
Instruction* msImg = bb->opLoad(uniImgRawRG16MS);
Instruction* samples = bb->opImageQuerySamples(msImg);
Instruction* color = bb->opLoad(uniTex);
Instruction* uv = bb->opLoad(inUV);
Instruction* baseColor = bb->opImageSampleImplictLod(color, uv);
Instruction* alpha = bb->opVectorExtractDynamic(baseColor, module.constant(3u)); // extract alpha channel
Instruction* cond = bb->Less(alpha, alphaMask);
BasicBlock& merge = bb.If(cond, [](BasicBlock& trueBB)
{
trueBB->opKill(); // discard pixel if baseColor.a < u_color.a
});
Instruction* rawImgRg16 = merge->opLoad(uniImgRawRG16);
Instruction* rawTexelRG16 = merge->opImageRead(rawImgRg16, constCoord2D);
Instruction* rawImgRgba8 = merge->opLoad(uni3DImgRawRGBA8);
Instruction* rawTexelRGBA7 = merge->opImageRead(rawImgRgba8, constCoord3D);
Instruction* offsetCoord = merge->Add(constCoord2D, module.constant(make_vector(8u, 16u)));
Instruction* rg32 = merge->opFConvert(rawTexelRG16, 32u);
rg32 = merge->Mul(rg32, module.constant(0.5f));
Instruction* rawStorageImgRG32 = merge->opLoad(uniImgRawStorageRG32);
merge->opImageWrite(rawStorageImgRG32, offsetCoord, rg32);
Instruction* voidImgRGBA16 = merge->opLoad(uni2DImgVoidRGBA16);
merge->opImageSampleImplictLod(voidImgRGBA16, uv);
merge.returnValue();
}
return module;
}