program.h (6201B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 struct VertexAttrib; 6 7 namespace glsl { 8 9 // Type holding group of scalars interpolated across rasterized rows and spans, 10 // shuttling values between vertex shaders and fragment shaders. 11 // GCC requires power-of-two vector sizes, so must use glsl type as workaround 12 // to operate in Float-sized chunks. 13 typedef vec3 Interpolants; 14 15 // Clip distances, if enabled, are always stored in the first SIMD chunk of the 16 // interpolants. 17 static ALWAYS_INLINE Float get_clip_distances(const Interpolants& interp) { 18 return interp.x; 19 } 20 21 struct VertexShaderImpl; 22 struct FragmentShaderImpl; 23 24 struct ProgramImpl { 25 virtual ~ProgramImpl() {} 26 virtual int get_uniform(const char* name) const = 0; 27 virtual void bind_attrib(const char* name, int index) = 0; 28 virtual int get_attrib(const char* name) const = 0; 29 virtual size_t interpolants_size() const = 0; 30 virtual VertexShaderImpl* get_vertex_shader() = 0; 31 virtual FragmentShaderImpl* get_fragment_shader() = 0; 32 virtual const char* get_name() const = 0; 33 }; 34 35 typedef ProgramImpl* (*ProgramLoader)(); 36 37 // The maximum size of the gl_ClipDistance array. 38 constexpr int32_t gl_MaxClipDistances = 4; 39 40 struct VertexShaderImpl { 41 typedef void (*SetUniform1iFunc)(VertexShaderImpl*, int index, int value); 42 typedef void (*SetUniform4fvFunc)(VertexShaderImpl*, int index, 43 const float* value); 44 typedef void (*SetUniformMatrix4fvFunc)(VertexShaderImpl*, int index, 45 const float* value); 46 typedef void (*InitBatchFunc)(VertexShaderImpl*); 47 typedef void (*LoadAttribsFunc)(VertexShaderImpl*, VertexAttrib* attribs, 48 uint32_t start, int instance, int count); 49 typedef void (*RunPrimitiveFunc)(VertexShaderImpl*, char* interps, 50 size_t interp_stride); 51 52 SetUniform1iFunc set_uniform_1i_func = nullptr; 53 SetUniform4fvFunc set_uniform_4fv_func = nullptr; 54 SetUniformMatrix4fvFunc set_uniform_matrix4fv_func = nullptr; 55 InitBatchFunc init_batch_func = nullptr; 56 LoadAttribsFunc load_attribs_func = nullptr; 57 RunPrimitiveFunc run_primitive_func = nullptr; 58 59 enum FLAGS { 60 CLIP_DISTANCE = 1 << 0, 61 }; 62 int flags = 0; 63 void enable_clip_distance() { flags |= CLIP_DISTANCE; } 64 ALWAYS_INLINE bool use_clip_distance() const { 65 return (flags & CLIP_DISTANCE) != 0; 66 } 67 68 vec4 gl_Position; 69 Float gl_ClipDistance[gl_MaxClipDistances]; 70 71 void set_uniform_1i(int index, int value) { 72 (*set_uniform_1i_func)(this, index, value); 73 } 74 75 void set_uniform_4fv(int index, const float* value) { 76 (*set_uniform_4fv_func)(this, index, value); 77 } 78 79 void set_uniform_matrix4fv(int index, const float* value) { 80 (*set_uniform_matrix4fv_func)(this, index, value); 81 } 82 83 void init_batch() { (*init_batch_func)(this); } 84 85 ALWAYS_INLINE void load_attribs(VertexAttrib* attribs, uint32_t start, 86 int instance, int count) { 87 (*load_attribs_func)(this, attribs, start, instance, count); 88 } 89 90 ALWAYS_INLINE void run_primitive(char* interps, size_t interp_stride) { 91 (*run_primitive_func)(this, interps, interp_stride); 92 } 93 }; 94 95 // The number of pixels in a step. 96 constexpr int32_t swgl_StepSize = 4; 97 98 struct FragmentShaderImpl { 99 typedef void (*InitSpanFunc)(FragmentShaderImpl*, const void* interps, 100 const void* step); 101 typedef void (*RunFunc)(FragmentShaderImpl*); 102 typedef void (*SkipFunc)(FragmentShaderImpl*, int steps); 103 typedef void (*InitSpanWFunc)(FragmentShaderImpl*, const void* interps, 104 const void* step); 105 typedef void (*RunWFunc)(FragmentShaderImpl*); 106 typedef void (*SkipWFunc)(FragmentShaderImpl*, int steps); 107 typedef int (*DrawSpanRGBA8Func)(FragmentShaderImpl*); 108 typedef int (*DrawSpanR8Func)(FragmentShaderImpl*); 109 110 InitSpanFunc init_span_func = nullptr; 111 RunFunc run_func = nullptr; 112 SkipFunc skip_func = nullptr; 113 InitSpanWFunc init_span_w_func = nullptr; 114 RunWFunc run_w_func = nullptr; 115 SkipWFunc skip_w_func = nullptr; 116 DrawSpanRGBA8Func draw_span_RGBA8_func = nullptr; 117 DrawSpanR8Func draw_span_R8_func = nullptr; 118 119 enum FLAGS { 120 DISCARD = 1 << 0, 121 PERSPECTIVE = 1 << 1, 122 }; 123 int flags = 0; 124 void enable_discard() { flags |= DISCARD; } 125 void enable_perspective() { flags |= PERSPECTIVE; } 126 ALWAYS_INLINE bool use_discard() const { return (flags & DISCARD) != 0; } 127 ALWAYS_INLINE bool use_perspective() const { 128 return (flags & PERSPECTIVE) != 0; 129 } 130 131 vec4 gl_FragCoord; 132 vec4 gl_FragColor; 133 vec4 gl_SecondaryFragColor; 134 135 vec2_scalar swgl_StepZW; 136 Bool swgl_IsPixelDiscarded = false; 137 // The current buffer position for committing span output. 138 uint32_t* swgl_OutRGBA8 = nullptr; 139 uint8_t* swgl_OutR8 = nullptr; 140 // The remaining number of pixels in the span. 141 int32_t swgl_SpanLength = 0; 142 143 ALWAYS_INLINE void step_fragcoord(int steps = 4) { gl_FragCoord.x += steps; } 144 145 ALWAYS_INLINE void step_perspective(int steps = 4) { 146 gl_FragCoord.z += swgl_StepZW.x * steps; 147 gl_FragCoord.w += swgl_StepZW.y * steps; 148 } 149 150 template <bool W = false> 151 ALWAYS_INLINE void init_span(const void* interps, const void* step) { 152 (*(W ? init_span_w_func : init_span_func))(this, interps, step); 153 } 154 155 template <bool W = false> 156 ALWAYS_INLINE void run() { 157 (*(W ? run_w_func : run_func))(this); 158 } 159 160 template <bool W = false> 161 ALWAYS_INLINE void skip(int steps = 4) { 162 (*(W ? skip_w_func : skip_func))(this, steps); 163 } 164 165 ALWAYS_INLINE int draw_span(uint32_t* buf, int len) { 166 swgl_OutRGBA8 = buf; 167 swgl_SpanLength = len; 168 return (*draw_span_RGBA8_func)(this); 169 } 170 171 ALWAYS_INLINE bool has_draw_span(uint32_t*) { 172 return draw_span_RGBA8_func != nullptr; 173 } 174 175 ALWAYS_INLINE int draw_span(uint8_t* buf, int len) { 176 swgl_OutR8 = buf; 177 swgl_SpanLength = len; 178 return (*draw_span_R8_func)(this); 179 } 180 181 ALWAYS_INLINE bool has_draw_span(uint8_t*) { 182 return draw_span_R8_func != nullptr; 183 } 184 }; 185 186 } // namespace glsl