CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/GPU/ShaderWriter.h
Views: 1401
#pragma once12#include <cstring>34#include "Common/GPU/Shader.h"5#include "Common/Data/Collections/Slice.h"67#include "Common/GPU/thin3d.h"89// Helps generate a shader compatible with all backends.10//11// Can use the uniform buffer support in thin3d.12//13// Using #defines and magic in this class, we partially define our own shader language that basically looks14// like GLSL, but has a few little oddities like splat3.1516struct InputDef {17const char *type;18const char *name;19int semantic;20};2122struct VaryingDef {23const char *type;24const char *name;25int semantic;26int index;27const char *precision;28};2930enum class ShaderWriterFlags {31NONE = 0,32FS_WRITE_DEPTH = 1,33FS_AUTO_STEREO = 2, // Automatically indexes makes samplers tagged with `array` by gl_ViewIndex. Useful for stereo rendering.34};35ENUM_CLASS_BITOPS(ShaderWriterFlags);3637class ShaderWriter {38public:39// Extensions are supported for both OpenGL ES and Vulkan (though of course, they're different).40ShaderWriter(char *buffer, const ShaderLanguageDesc &lang, ShaderStage stage, Slice<const char *> extensions = Slice<const char *>(), ShaderWriterFlags flags = ShaderWriterFlags::NONE) : p_(buffer), lang_(lang), stage_(stage), flags_(flags) {41buffer[0] = '\0';42Preamble(extensions);43}44ShaderWriter(const ShaderWriter &) = delete;4546// I tried to call all three write functions "W", but only MSVC47// managed to disentangle the ambiguities, so had to give up on that.4849// Assumes the input is zero-terminated.50// C : Copies a buffer directly to the stream.51template<size_t T>52ShaderWriter &C(const char(&text)[T]) {53memcpy(p_, text, T);54p_ += T - 1;55return *this;56}57// W: Writes a zero-terminated string to the stream.58ShaderWriter &W(const char *text) {59size_t len = strlen(text);60memcpy(p_, text, len + 1);61p_ += len;62return *this;63}6465// F: Formats into the buffer.66ShaderWriter &F(const char *format, ...);6768ShaderWriter &endl() {69return C("\n");70}7172// Useful for fragment shaders in GLES.73// We always default integers to high precision.74void HighPrecisionFloat();75void LowPrecisionFloat();7677// NOTE: samplers must live for the rest of ShaderWriter's lifetime. No way to express that in C++ though :(78void DeclareSamplers(Slice<SamplerDef> samplers);7980// Same as DeclareSamplers, but doesn't actually declare them.81// This is currently only required by FragmentShaderGenerator.82void ApplySamplerMetadata(Slice<SamplerDef> samplers);8384void ConstFloat(const char *name, float value);85void SetFlags(ShaderWriterFlags flags) { flags_ |= flags; }86ShaderWriterFlags Flags() const { return flags_; }87void SetTexBindingBase(int base) { texBindingBase_ = base; }8889ShaderWriter &SampleTexture2D(const char *texName, const char *uv);90ShaderWriter &SampleTexture2DOffset(const char *texName, const char *uv, int offX, int offY);91ShaderWriter &LoadTexture2D(const char *texName, const char *integer_uv, int level);92ShaderWriter &GetTextureSize(const char *szVariable, const char *texName);9394// Simple shaders with no special tricks.95void BeginVSMain(Slice<InputDef> inputs, Slice<UniformDef> uniforms, Slice<VaryingDef> varyings);96void BeginFSMain(Slice<UniformDef> uniforms, Slice<VaryingDef> varyings);97void BeginGSMain(Slice<VaryingDef> varyings, Slice<VaryingDef> outVaryings);9899// For simple shaders that output a single color, we can deal with this generically.100void EndVSMain(Slice<VaryingDef> varyings);101void EndFSMain(const char *vec4_color_variable);102void EndGSMain();103104const ShaderLanguageDesc &Lang() const {105return lang_;106}107108void Rewind(size_t offset) {109p_ -= offset;110}111112// Can probably remove this113char *GetPos() {114return p_;115}116117private:118// Several of the shader languages ignore samplers, beware of that.119void DeclareSampler2D(const SamplerDef &def);120void DeclareTexture2D(const SamplerDef &def);121const SamplerDef *GetSamplerDef(const char *name) const;122123void Preamble(Slice<const char *> extensions);124125char *p_;126const ShaderLanguageDesc &lang_;127const ShaderStage stage_;128Slice<SamplerDef> samplers_;129ShaderWriterFlags flags_ = ShaderWriterFlags::NONE;130Slice<SamplerDef> samplerDefs_;131int texBindingBase_ = 1;132};133134135