Bläddra i källkod

Predefined uniforms refactoring.

Branimir Karadžić 11 år sedan
förälder
incheckning
6e73d4ea34
9 ändrade filer med 366 tillägg och 562 borttagningar
  1. 2 0
      src/bgfx.cpp
  2. 4 0
      src/bgfx_p.h
  3. 264 0
      src/renderer.h
  4. 29 189
      src/renderer_d3d11.cpp
  5. 1 0
      src/renderer_d3d11.h
  6. 31 150
      src/renderer_d3d9.cpp
  7. 1 0
      src/renderer_d3d9.h
  8. 33 223
      src/renderer_gl.cpp
  9. 1 0
      src/renderer_gl.h

+ 2 - 0
src/bgfx.cpp

@@ -750,6 +750,8 @@ namespace bgfx
 
 		m_constEnd = m_constantBuffer->getPos();
 
+		m_compute.m_matrix = m_draw.m_matrix;
+		m_compute.m_num    = m_draw.m_num;
 		m_compute.m_numX = bx::uint16_max(_numX, 1);
 		m_compute.m_numY = bx::uint16_max(_numY, 1);
 		m_compute.m_numZ = bx::uint16_max(_numZ, 1);

+ 4 - 0
src/bgfx_p.h

@@ -1108,9 +1108,11 @@ namespace bgfx
 		{
 			m_constBegin = 0;
 			m_constEnd   = 0;
+			m_matrix     = 0;
 			m_numX = 0;
 			m_numY = 0;
 			m_numZ = 0;
+			m_num  = 0;
 
 			for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii)
 			{
@@ -1120,10 +1122,12 @@ namespace bgfx
 
 		uint32_t m_constBegin;
 		uint32_t m_constEnd;
+		uint32_t m_matrix;
 
 		uint16_t m_numX;
 		uint16_t m_numY;
 		uint16_t m_numZ;
+		uint16_t m_num;
 
 		ComputeBinding m_bind[BGFX_MAX_COMPUTE_BINDINGS];
 	};

+ 264 - 0
src/renderer.h

@@ -0,0 +1,264 @@
+/*
+ * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "bgfx_p.h"
+
+namespace bgfx
+{
+	struct ViewState
+	{
+		ViewState(Frame* _render, bool _hmdEnabled)
+			: m_alphaRef(0.0f)
+			, m_invViewCached(UINT16_MAX)
+			, m_invProjCached(UINT16_MAX)
+			, m_invViewProjCached(UINT16_MAX)
+		{
+			m_view[0] = _render->m_view;
+			m_view[1] = m_viewTmp[1];
+
+			if (_hmdEnabled)
+			{
+				HMD& hmd = _render->m_hmd;
+
+				m_view[0] = m_viewTmp[0];
+				Matrix4 viewAdjust;
+				bx::mtxIdentity(viewAdjust.un.val);
+
+				for (uint32_t eye = 0; eye < 2; ++eye)
+				{
+					const HMD::Eye& hmdEye = hmd.eye[eye];
+					viewAdjust.un.val[12] = hmdEye.viewOffset[0];
+					viewAdjust.un.val[13] = hmdEye.viewOffset[1];
+					viewAdjust.un.val[14] = hmdEye.viewOffset[2];
+
+					for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
+					{
+						if (BGFX_VIEW_STEREO == (_render->m_viewFlags[ii] & BGFX_VIEW_STEREO) )
+						{
+							bx::float4x4_mul(&m_view[eye][ii].un.f4x4
+								, &_render->m_view[ii].un.f4x4
+								, &viewAdjust.un.f4x4
+								);
+						}
+						else
+						{
+							memcpy(&m_view[0][ii].un.f4x4, &_render->m_view[ii].un.f4x4, sizeof(Matrix4) );
+						}
+					}
+				}
+			}
+
+			for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
+			{
+				for (uint32_t eye = 0; eye < uint32_t(_hmdEnabled)+1; ++eye)
+				{
+					bx::float4x4_mul(&m_viewProj[eye][ii].un.f4x4
+						, &m_view[eye][ii].un.f4x4
+						, &_render->m_proj[eye][ii].un.f4x4
+						);
+				}
+			}
+		}
+
+		template<uint16_t mtxRegs, typename RendererContext, typename Program, typename Draw>
+		void setPredefined(RendererContext* _renderer, uint8_t view, uint8_t eye, Program& _program, Frame* _render, const Draw& _draw)
+		{
+			for (uint32_t ii = 0, num = _program.m_numPredefined; ii < num; ++ii)
+			{
+				PredefinedUniform& predefined = _program.m_predefined[ii];
+				uint8_t flags = predefined.m_type&BGFX_UNIFORM_FRAGMENTBIT;
+				switch (predefined.m_type&(~BGFX_UNIFORM_FRAGMENTBIT) )
+				{
+				case PredefinedUniform::ViewRect:
+					{
+						float frect[4];
+						frect[0] = m_rect.m_x;
+						frect[1] = m_rect.m_y;
+						frect[2] = m_rect.m_width;
+						frect[3] = m_rect.m_height;
+
+						_renderer->setShaderUniform4f(flags
+							, predefined.m_loc
+							, &frect[0]
+							, 1
+							);
+					}
+					break;
+
+				case PredefinedUniform::ViewTexel:
+					{
+						float frect[4];
+						frect[0] = 1.0f/float(m_rect.m_width);
+						frect[1] = 1.0f/float(m_rect.m_height);
+
+						_renderer->setShaderUniform4f(flags
+							, predefined.m_loc
+							, &frect[0]
+							, 1
+							);
+					}
+					break;
+
+				case PredefinedUniform::View:
+					{
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, m_view[eye][view].un.val
+							, bx::uint32_min(mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::InvView:
+					{
+						uint16_t viewEye = (view << 1) | eye;
+						if (viewEye != m_invViewCached)
+						{
+							m_invViewCached = viewEye;
+							bx::float4x4_inverse(&m_invView.un.f4x4
+								, &m_view[eye][view].un.f4x4
+								);
+						}
+
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, m_invView.un.val
+							, bx::uint32_min(mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::Proj:
+					{
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, _render->m_proj[eye][view].un.val
+							, bx::uint32_min(mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::InvProj:
+					{
+						uint16_t viewEye = (view << 1) | eye;
+						if (viewEye != m_invProjCached)
+						{
+							m_invProjCached = viewEye;
+							bx::float4x4_inverse(&m_invProj.un.f4x4
+								, &_render->m_proj[eye][view].un.f4x4
+								);
+						}
+
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, m_invProj.un.val
+							, bx::uint32_min(mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::ViewProj:
+					{
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, m_viewProj[eye][view].un.val
+							, bx::uint32_min(mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::InvViewProj:
+					{
+						uint16_t viewEye = (view << 1) | eye;
+						if (viewEye != m_invViewProjCached)
+						{
+							m_invViewProjCached = viewEye;
+							bx::float4x4_inverse(&m_invViewProj.un.f4x4
+								, &m_viewProj[eye][view].un.f4x4
+								);
+						}
+
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, m_invViewProj.un.val
+							, bx::uint32_min(mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::Model:
+					{
+						const Matrix4& model = _render->m_matrixCache.m_cache[_draw.m_matrix];
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, model.un.val
+							, bx::uint32_min(_draw.m_num*mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::ModelView:
+					{
+						Matrix4 modelView;
+						const Matrix4& model = _render->m_matrixCache.m_cache[_draw.m_matrix];
+						bx::float4x4_mul(&modelView.un.f4x4
+							, &model.un.f4x4
+							, &m_view[eye][view].un.f4x4
+							);
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, modelView.un.val
+							, bx::uint32_min(mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::ModelViewProj:
+					{
+						Matrix4 modelViewProj;
+						const Matrix4& model = _render->m_matrixCache.m_cache[_draw.m_matrix];
+						bx::float4x4_mul(&modelViewProj.un.f4x4
+							, &model.un.f4x4
+							, &m_viewProj[eye][view].un.f4x4
+							);
+						_renderer->setShaderUniform4x4f(flags
+							, predefined.m_loc
+							, modelViewProj.un.val
+							, bx::uint32_min(mtxRegs, predefined.m_count)
+							);
+					}
+					break;
+
+				case PredefinedUniform::AlphaRef:
+					{
+						_renderer->setShaderUniform4f(flags
+							, predefined.m_loc
+							, &m_alphaRef
+							, 1
+							);
+					}
+					break;
+
+				default:
+					BX_CHECK(false, "predefined %d not handled", predefined.m_type);
+					break;
+				}
+			}
+		}
+
+		Matrix4  m_viewTmp[2][BGFX_CONFIG_MAX_VIEWS];
+		Matrix4  m_viewProj[2][BGFX_CONFIG_MAX_VIEWS];
+		Matrix4* m_view[2];
+		Rect     m_rect;
+		Matrix4  m_invView;
+		Matrix4  m_invProj;
+		Matrix4  m_invViewProj;
+		float    m_alphaRef;
+		uint16_t m_invViewCached;
+		uint16_t m_invProjCached;
+		uint16_t m_invViewProjCached;
+	};
+
+} // namespace bgfx

+ 29 - 189
src/renderer_d3d11.cpp

@@ -1056,7 +1056,7 @@ namespace bgfx
 
 			PredefinedUniform& predefined = program.m_predefined[0];
 			uint8_t flags = predefined.m_type;
-			setShaderConstant(flags, predefined.m_loc, proj, 4);
+			setShaderUniform(flags, predefined.m_loc, proj, 4);
 
 			commitShaderConstants();
 			m_textures[_blitter.m_texture.idx].commit(0);
@@ -1285,7 +1285,7 @@ namespace bgfx
 			}
 		}
 
-		void setShaderConstant(uint8_t _flags, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
+		void setShaderUniform(uint8_t _flags, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
 		{
 			if (_flags&BGFX_UNIFORM_FRAGMENTBIT)
 			{
@@ -1299,6 +1299,16 @@ namespace bgfx
 			}
 		}
 
+		void setShaderUniform4f(uint8_t _flags, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
+		{
+			setShaderUniform(_flags, _regIndex, _val, _numRegs);
+		}
+
+		void setShaderUniform4x4f(uint8_t _flags, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
+		{
+			setShaderUniform(_flags, _regIndex, _val, _numRegs);
+		}
+
 		void commitShaderConstants()
 		{
 			if (0 < m_vsChanges)
@@ -1951,7 +1961,7 @@ namespace bgfx
 		case UniformType::_uniform: \
 		case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
 				{ \
-					setShaderConstant(type, loc, data, num); \
+					setShaderUniform(type, loc, data, num); \
 				} \
 				break;
 
@@ -1976,7 +1986,7 @@ namespace bgfx
 							 mtx.un.val[ 9] = value[7];
 							 mtx.un.val[10] = value[8];
 							 mtx.un.val[11] = 0.0f;
-							 setShaderConstant(type, loc, &mtx.un.val[0], 3);
+							 setShaderUniform(type, loc, &mtx.un.val[0], 3);
 						 }
 					}
 					break;
@@ -2997,10 +3007,6 @@ namespace bgfx
 		currentState.m_flags = BGFX_STATE_NONE;
 		currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
 
-		Matrix4  mtxViewTmp[2][BGFX_CONFIG_MAX_VIEWS];
-		Matrix4* mtxView[2] = { _render->m_view, mtxViewTmp[1] };
-		Matrix4  mtxViewProj[2][BGFX_CONFIG_MAX_VIEWS];
-
 		const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
 		_render->m_hmdEnabled = hmdEnabled;
 
@@ -3008,52 +3014,9 @@ namespace bgfx
 		{
 			HMD& hmd = _render->m_hmd;
 			m_ovr.getEyePose(hmd);
-
-			mtxView[0] = mtxViewTmp[0];
-			Matrix4 viewAdjust;
-			bx::mtxIdentity(viewAdjust.un.val);
-
-			for (uint32_t eye = 0; eye < 2; ++eye)
-			{
-				const HMD::Eye& hmdEye = hmd.eye[eye];
-				viewAdjust.un.val[12] = hmdEye.viewOffset[0];
-				viewAdjust.un.val[13] = hmdEye.viewOffset[1];
-				viewAdjust.un.val[14] = hmdEye.viewOffset[2];
-
-				for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
-				{
-					if (BGFX_VIEW_STEREO == (_render->m_viewFlags[ii] & BGFX_VIEW_STEREO) )
-					{
-						bx::float4x4_mul(&mtxView[eye][ii].un.f4x4
-							, &_render->m_view[ii].un.f4x4
-							, &viewAdjust.un.f4x4
-							);
-					}
-					else
-					{
-						memcpy(&mtxView[0][ii].un.f4x4, &_render->m_view[ii].un.f4x4, sizeof(Matrix4) );
-					}
-				}
-			}
-		}
-
-		for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
-		{
-			for (uint32_t eye = 0; eye < uint32_t(hmdEnabled)+1; ++eye)
-			{
-				bx::float4x4_mul(&mtxViewProj[eye][ii].un.f4x4
-					, &mtxView[eye][ii].un.f4x4
-					, &_render->m_proj[eye][ii].un.f4x4
-					);
-			}
 		}
 
-		Matrix4 invView;
-		Matrix4 invProj;
-		Matrix4 invViewProj;
-		uint16_t invViewCached = UINT16_MAX;
-		uint16_t invProjCached = UINT16_MAX;
-		uint16_t invViewProjCached = UINT16_MAX;
+		ViewState viewState(_render, hmdEnabled);
 
 		bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);
 		bool scissorEnabled = false;
@@ -3063,7 +3026,6 @@ namespace bgfx
 		SortKey key;
 		uint8_t view = 0xff;
 		FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
-		float alphaRef = 0.0f;
 
 		const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
 		uint8_t primIndex = uint8_t(primType>>BGFX_STATE_PT_SHIFT);
@@ -3085,7 +3047,7 @@ namespace bgfx
 			bool viewRestart = false;
 			uint8_t eye = 0;
 			uint8_t restartState = 0;
-			Rect rect = _render->m_rect[0];
+			viewState.m_rect = _render->m_rect[0];
 
 			int32_t numItems = _render->m_num;
 			for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;)
@@ -3139,15 +3101,15 @@ namespace bgfx
 
 					PIX_ENDEVENT();
 
-					rect = _render->m_rect[view];
+					viewState.m_rect = _render->m_rect[view];
 					if (viewRestart)
 					{
 						wchar_t* viewNameW = s_viewNameW[view];
 						viewNameW[3] = eye ? L'R' : L'L';
 						PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), viewNameW);
 
-						rect.m_x = eye * (rect.m_width+1)/2;
-						rect.m_width /= 2;
+						viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2;
+						viewState.m_rect.m_width /= 2;
 					}
 					else
 					{
@@ -3158,13 +3120,13 @@ namespace bgfx
 
 					const Rect& scissorRect = _render->m_scissor[view];
 					viewHasScissor = !scissorRect.isZero();
-					viewScissorRect = viewHasScissor ? scissorRect : rect;
+					viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
 
 					D3D11_VIEWPORT vp;
-					vp.TopLeftX = rect.m_x;
-					vp.TopLeftY = rect.m_y;
-					vp.Width    = rect.m_width;
-					vp.Height   = rect.m_height;
+					vp.TopLeftX = viewState.m_rect.m_x;
+					vp.TopLeftY = viewState.m_rect.m_y;
+					vp.Width    = viewState.m_rect.m_width;
+					vp.Height   = viewState.m_rect.m_height;
 					vp.MinDepth = 0.0f;
 					vp.MaxDepth = 1.0f;
 					deviceCtx->RSSetViewports(1, &vp);
@@ -3172,7 +3134,7 @@ namespace bgfx
 
 					if (BGFX_CLEAR_NONE != clear.m_flags)
 					{
-						clearQuad(_clearQuad, rect, clear, _render->m_clearColor);
+						clearQuad(_clearQuad, viewState.m_rect, clear, _render->m_clearColor);
 						prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update after clear quad.
 					}
 				}
@@ -3226,6 +3188,8 @@ namespace bgfx
 							}
 						}
 
+						viewState.setPredefined<4>(this, view, eye, program, _render, compute);
+
 						if (constantsChanged
 						||  program.m_numPredefined > 0)
 						{
@@ -3392,7 +3356,7 @@ namespace bgfx
 					if (BGFX_STATE_ALPHA_REF_MASK & changedFlags)
 					{
 						uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
-						alphaRef = ref/255.0f;
+						viewState.m_alphaRef = ref/255.0f;
 					}
 
 					const uint64_t pt = newFlags&BGFX_STATE_PT_MASK;
@@ -3463,131 +3427,7 @@ namespace bgfx
 						}
 					}
 
-					for (uint32_t ii = 0, num = program.m_numPredefined; ii < num; ++ii)
-					{
-						PredefinedUniform& predefined = program.m_predefined[ii];
-						uint8_t flags = predefined.m_type&BGFX_UNIFORM_FRAGMENTBIT;
-						switch (predefined.m_type&(~BGFX_UNIFORM_FRAGMENTBIT) )
-						{
-						case PredefinedUniform::ViewRect:
-							{
-								float frect[4];
-								frect[0] = rect.m_x;
-								frect[1] = rect.m_y;
-								frect[2] = rect.m_width;
-								frect[3] = rect.m_height;
-
-								setShaderConstant(flags, predefined.m_loc, &frect[0], 1);
-							}
-							break;
-
-						case PredefinedUniform::ViewTexel:
-							{
-								float frect[4];
-								frect[0] = 1.0f/float(rect.m_width);
-								frect[1] = 1.0f/float(rect.m_height);
-
-								setShaderConstant(flags, predefined.m_loc, &frect[0], 1);
-							}
-							break;
-
-						case PredefinedUniform::View:
-							{
-								setShaderConstant(flags
-									, predefined.m_loc
-									, mtxView[eye][view].un.val
-									, bx::uint32_min(4, predefined.m_count)
-									);
-							}
-							break;
-
-						case PredefinedUniform::InvView:
-							{
-								uint16_t viewEye = (view << 1) | eye;
-								if (viewEye != invViewCached)
-								{
-									invViewCached = viewEye;
-									bx::float4x4_inverse(&invView.un.f4x4, &mtxView[eye][view].un.f4x4);
-								}
-
-								setShaderConstant(flags, predefined.m_loc, invView.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::Proj:
-							{
-								setShaderConstant(flags, predefined.m_loc, _render->m_proj[eye][view].un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::InvProj:
-							{
-								uint16_t viewEye = (view << 1) | eye;
-								if (viewEye != invProjCached)
-								{
-									invProjCached = viewEye;
-									bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[eye][view].un.f4x4);
-								}
-
-								setShaderConstant(flags, predefined.m_loc, invProj.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ViewProj:
-							{
-								setShaderConstant(flags, predefined.m_loc, mtxViewProj[eye][view].un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::InvViewProj:
-							{
-								uint16_t viewEye = (view << 1) | eye;
-								if (viewEye != invViewProjCached)
-								{
-									invViewProjCached = viewEye;
-									bx::float4x4_inverse(&invViewProj.un.f4x4, &mtxViewProj[eye][view].un.f4x4);
-								}
-
-								setShaderConstant(flags, predefined.m_loc, invViewProj.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::Model:
-							{
-								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								setShaderConstant(flags, predefined.m_loc, model.un.val, bx::uint32_min(draw.m_num*4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ModelView:
-							{
-								Matrix4 modelView;
-								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								bx::float4x4_mul(&modelView.un.f4x4, &model.un.f4x4, &mtxView[eye][view].un.f4x4);
-								setShaderConstant(flags, predefined.m_loc, modelView.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ModelViewProj:
-							{
-								Matrix4 modelViewProj;
-								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								bx::float4x4_mul(&modelViewProj.un.f4x4, &model.un.f4x4, &mtxViewProj[eye][view].un.f4x4);
-								setShaderConstant(flags, predefined.m_loc, modelViewProj.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::AlphaRef:
-							{
-								setShaderConstant(flags, predefined.m_loc, &alphaRef, 1);
-							}
-							break;
-
-						default:
-							BX_CHECK(false, "predefined %d not handled", predefined.m_type);
-							break;
-						}
-					}
+					viewState.setPredefined<4>(this, view, eye, program, _render, draw);
 
 					if (constantsChanged
 					||  program.m_numPredefined > 0)

+ 1 - 0
src/renderer_d3d11.h

@@ -25,6 +25,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4005) // warning C4005: '' : macro redefinitio
 #endif
 BX_PRAGMA_DIAGNOSTIC_POP()
 
+#include "renderer.h"
 #include "renderer_d3d.h"
 #include "ovr.h"
 #include "renderdoc.h"

+ 31 - 150
src/renderer_d3d9.cpp

@@ -914,7 +914,7 @@ namespace bgfx
 
 			PredefinedUniform& predefined = program.m_predefined[0];
 			uint8_t flags = predefined.m_type;
-			setShaderConstantF(flags, predefined.m_loc, proj, 4);
+			setShaderUniform(flags, predefined.m_loc, proj, 4);
 
 			m_textures[_blitter.m_texture.idx].commit(0);
 		}
@@ -1047,18 +1047,28 @@ namespace bgfx
 			m_rtMsaa = _msaa;
 		}
 
-		void setShaderConstantF(uint8_t _flags, uint16_t _regIndex, const float* _val, uint16_t _numRegs)
+		void setShaderUniform(uint8_t _flags, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
 		{
 			if (_flags&BGFX_UNIFORM_FRAGMENTBIT)
 			{
-				DX_CHECK(m_device->SetPixelShaderConstantF(_regIndex, _val, _numRegs) );
+				DX_CHECK(m_device->SetPixelShaderConstantF(_regIndex, (const float*)_val, _numRegs) );
 			}
 			else
 			{
-				DX_CHECK(m_device->SetVertexShaderConstantF(_regIndex, _val, _numRegs) );
+				DX_CHECK(m_device->SetVertexShaderConstantF(_regIndex, (const float*)_val, _numRegs) );
 			}
 		}
 
+		void setShaderUniform4f(uint8_t _flags, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
+		{
+			setShaderUniform(_flags, _regIndex, _val, _numRegs);
+		}
+
+		void setShaderUniform4x4f(uint8_t _flags, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
+		{
+			setShaderUniform(_flags, _regIndex, _val, _numRegs);
+		}
+
 		void reset()
 		{
 			preReset();
@@ -2812,25 +2822,13 @@ namespace bgfx
 		currentState.m_flags = BGFX_STATE_NONE;
 		currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
 
-		Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
-		for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
-		{
-			bx::float4x4_mul(&viewProj[ii].un.f4x4, &_render->m_view[ii].un.f4x4, &_render->m_proj[0][ii].un.f4x4);
-		}
-
-		Matrix4 invView;
-		Matrix4 invProj;
-		Matrix4 invViewProj;
-		uint8_t invViewCached = 0xff;
-		uint8_t invProjCached = 0xff;
-		uint8_t invViewProjCached = 0xff;
+		ViewState viewState(_render, false);
 
 		DX_CHECK(device->SetRenderState(D3DRS_FILLMODE, _render->m_debug&BGFX_DEBUG_WIREFRAME ? D3DFILL_WIREFRAME : D3DFILL_SOLID) );
 		uint16_t programIdx = invalidHandle;
 		SortKey key;
 		uint8_t view = 0xff;
 		FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
-		float alphaRef = 0.0f;
 		uint32_t blendFactor = 0;
 
 		const uint64_t pt = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
@@ -2891,16 +2889,16 @@ namespace bgfx
 						setFrameBuffer(fbh);
 					}
 
-					const Rect& rect = _render->m_rect[view];
+					viewState.m_rect        = _render->m_rect[view];
 					const Rect& scissorRect = _render->m_scissor[view];
-					viewHasScissor = !scissorRect.isZero();
-					viewScissorRect = viewHasScissor ? scissorRect : rect;
+					viewHasScissor  = !scissorRect.isZero();
+					viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
 
 					D3DVIEWPORT9 vp;
-					vp.X = rect.m_x;
-					vp.Y = rect.m_y;
-					vp.Width = rect.m_width;
-					vp.Height = rect.m_height;
+					vp.X      = viewState.m_rect.m_x;
+					vp.Y      = viewState.m_rect.m_y;
+					vp.Width  = viewState.m_rect.m_width;
+					vp.Height = viewState.m_rect.m_height;
 					vp.MinZ = 0.0f;
 					vp.MaxZ = 1.0f;
 					DX_CHECK(device->SetViewport(&vp) );
@@ -2909,7 +2907,7 @@ namespace bgfx
 
 					if (BGFX_CLEAR_NONE != clear.m_flags)
 					{
-						clearQuad(_clearQuad, rect, clear, _render->m_clearColor);
+						clearQuad(_clearQuad, viewState.m_rect, clear, _render->m_clearColor);
 						prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update after clear quad.
 					}
 
@@ -2932,9 +2930,9 @@ namespace bgfx
 						if (viewHasScissor)
 						{
 							RECT rc;
-							rc.left = viewScissorRect.m_x;
-							rc.top = viewScissorRect.m_y;
-							rc.right = viewScissorRect.m_x + viewScissorRect.m_width;
+							rc.left   = viewScissorRect.m_x;
+							rc.top    = viewScissorRect.m_y;
+							rc.right  = viewScissorRect.m_x + viewScissorRect.m_width;
 							rc.bottom = viewScissorRect.m_y + viewScissorRect.m_height;
 							DX_CHECK(device->SetScissorRect(&rc) );
 						}
@@ -2945,9 +2943,9 @@ namespace bgfx
 						scissorRect.intersect(viewScissorRect, _render->m_rectCache.m_cache[scissor]);
 						DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, true) );
 						RECT rc;
-						rc.left = scissorRect.m_x;
-						rc.top = scissorRect.m_y;
-						rc.right = scissorRect.m_x + scissorRect.m_width;
+						rc.left   = scissorRect.m_x;
+						rc.top    = scissorRect.m_y;
+						rc.right  = scissorRect.m_x + scissorRect.m_width;
 						rc.bottom = scissorRect.m_y + scissorRect.m_height;
 						DX_CHECK(device->SetScissorRect(&rc) );
 					}
@@ -3047,7 +3045,7 @@ namespace bgfx
 					if (BGFX_STATE_ALPHA_REF_MASK & changedFlags)
 					{
 						uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
-						alphaRef = ref/255.0f;
+						viewState.m_alphaRef = ref/255.0f;
 					}
 
 					if ( (BGFX_STATE_PT_POINTS|BGFX_STATE_POINT_SIZE_MASK) & changedFlags)
@@ -3164,124 +3162,7 @@ namespace bgfx
 						}
 					}
 
-					for (uint32_t ii = 0, num = program.m_numPredefined; ii < num; ++ii)
-					{
-						PredefinedUniform& predefined = program.m_predefined[ii];
-						uint8_t flags = predefined.m_type&BGFX_UNIFORM_FRAGMENTBIT;
-						switch (predefined.m_type&(~BGFX_UNIFORM_FRAGMENTBIT) )
-						{
-						case PredefinedUniform::ViewRect:
-							{
-								float rect[4];
-								rect[0] = _render->m_rect[view].m_x;
-								rect[1] = _render->m_rect[view].m_y;
-								rect[2] = _render->m_rect[view].m_width;
-								rect[3] = _render->m_rect[view].m_height;
-
-								setShaderConstantF(flags, predefined.m_loc, &rect[0], 1);
-							}
-							break;
-
-						case PredefinedUniform::ViewTexel:
-							{
-								float rect[4];
-								rect[0] = 1.0f/float(_render->m_rect[view].m_width);
-								rect[1] = 1.0f/float(_render->m_rect[view].m_height);
-
-								setShaderConstantF(flags, predefined.m_loc, &rect[0], 1);
-							}
-							break;
-
-						case PredefinedUniform::View:
-							{
-								setShaderConstantF(flags, predefined.m_loc, _render->m_view[view].un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::InvView:
-							{
-								if (view != invViewCached)
-								{
-									invViewCached = view;
-									bx::float4x4_inverse(&invView.un.f4x4, &_render->m_view[view].un.f4x4);
-								}
-
-								setShaderConstantF(flags, predefined.m_loc, invView.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::Proj:
-							{
-								setShaderConstantF(flags, predefined.m_loc, _render->m_proj[0][view].un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::InvProj:
-							{
-								if (view != invProjCached)
-								{
-									invProjCached = view;
-									bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[0][view].un.f4x4);
-								}
-
-								setShaderConstantF(flags, predefined.m_loc, invProj.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ViewProj:
-							{
-								setShaderConstantF(flags, predefined.m_loc, viewProj[view].un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::InvViewProj:
-							{
-								if (view != invViewProjCached)
-								{
-									invViewProjCached = view;
-									bx::float4x4_inverse(&invViewProj.un.f4x4, &viewProj[view].un.f4x4);
-								}
-
-								setShaderConstantF(flags, predefined.m_loc, invViewProj.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::Model:
-							{
- 								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								setShaderConstantF(flags, predefined.m_loc, model.un.val, bx::uint32_min(draw.m_num*4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ModelView:
-							{
-								Matrix4 modelView;
-								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								bx::float4x4_mul(&modelView.un.f4x4, &model.un.f4x4, &_render->m_view[view].un.f4x4);
-								setShaderConstantF(flags, predefined.m_loc, modelView.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ModelViewProj:
-							{
-								Matrix4 modelViewProj;
-								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								bx::float4x4_mul(&modelViewProj.un.f4x4, &model.un.f4x4, &viewProj[view].un.f4x4);
-								setShaderConstantF(flags, predefined.m_loc, modelViewProj.un.val, bx::uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::AlphaRef:
-							{
-								setShaderConstantF(flags, predefined.m_loc, &alphaRef, 1);
-							}
-							break;
-
-						default:
-							BX_CHECK(false, "predefined %d not handled", predefined.m_type);
-							break;
-						}
-					}
+					viewState.setPredefined<4>(this, view, 0, program, _render, draw);
 				}
 
 				{

+ 1 - 0
src/renderer_d3d9.h

@@ -38,6 +38,7 @@
 #	define D3DSTREAMSOURCE_INSTANCEDATA (2<<30)
 #endif // D3DSTREAMSOURCE_INSTANCEDATA
 
+#include "renderer.h"
 #include "renderer_d3d.h"
 
 namespace bgfx

+ 33 - 223
src/renderer_gl.cpp

@@ -1739,6 +1739,23 @@ namespace bgfx
 			}
 		}
 
+		void setShaderUniform4f(uint8_t /*_flags*/, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
+		{
+			GL_CHECK(glUniform4fv(_regIndex
+				, _numRegs
+				, (const GLfloat*)_val
+				) );
+		}
+
+		void setShaderUniform4x4f(uint8_t /*_flags*/, uint16_t _regIndex, const void* _val, uint16_t _numRegs)
+		{
+			GL_CHECK(glUniformMatrix4fv(_regIndex
+				, _numRegs
+				, GL_FALSE
+				, (const GLfloat*)_val
+				) );
+		}
+
 		uint32_t setFrameBuffer(FrameBufferHandle _fbh, uint32_t _height, bool _msaa = true)
 		{
 			if (isValid(m_fbh)
@@ -4135,10 +4152,6 @@ namespace bgfx
 		currentState.m_flags = BGFX_STATE_NONE;
 		currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
 
-		Matrix4  mtxViewTmp[2][BGFX_CONFIG_MAX_VIEWS];
-		Matrix4* mtxView[2] = { _render->m_view, mtxViewTmp[1] };
-		Matrix4  mtxViewProj[2][BGFX_CONFIG_MAX_VIEWS];
-
 		const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
 		_render->m_hmdEnabled = hmdEnabled;
 
@@ -4146,52 +4159,9 @@ namespace bgfx
 		{
 			HMD& hmd = _render->m_hmd;
 			m_ovr.getEyePose(hmd);
-
-			mtxView[0] = mtxViewTmp[0];
-			Matrix4 viewAdjust;
-			bx::mtxIdentity(viewAdjust.un.val);
-
-			for (uint32_t eye = 0; eye < 2; ++eye)
-			{
-				const HMD::Eye& hmdEye = hmd.eye[eye];
-				viewAdjust.un.val[12] = hmdEye.viewOffset[0];
-				viewAdjust.un.val[13] = hmdEye.viewOffset[1];
-				viewAdjust.un.val[14] = hmdEye.viewOffset[2];
-
-				for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
-				{
-					if (BGFX_VIEW_STEREO == (_render->m_viewFlags[ii] & BGFX_VIEW_STEREO) )
-					{
-						bx::float4x4_mul(&mtxView[eye][ii].un.f4x4
-							, &_render->m_view[ii].un.f4x4
-							, &viewAdjust.un.f4x4
-							);
-					}
-					else
-					{
-						memcpy(&mtxView[0][ii].un.f4x4, &_render->m_view[ii].un.f4x4, sizeof(Matrix4) );
-					}
-				}
-			}
 		}
 
-		for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
-		{
-			for (uint32_t eye = 0; eye < uint32_t(hmdEnabled)+1; ++eye)
-			{
-				bx::float4x4_mul(&mtxViewProj[eye][ii].un.f4x4
-					, &mtxView[eye][ii].un.f4x4
-					, &_render->m_proj[eye][ii].un.f4x4
-					);
-			}
-		}
-
-		Matrix4 invView;
-		Matrix4 invProj;
-		Matrix4 invViewProj;
-		uint16_t invViewCached = UINT16_MAX;
-		uint16_t invProjCached = UINT16_MAX;
-		uint16_t invViewProjCached = UINT16_MAX;
+		ViewState viewState(_render, hmdEnabled);
 
 		uint16_t programIdx = invalidHandle;
 		SortKey key;
@@ -4201,7 +4171,6 @@ namespace bgfx
 					? _render->m_hmd.height
 					: _render->m_resolution.m_height
 					;
-		float alphaRef = 0.0f;
 		uint32_t blendFactor = 0;
 
 		const uint64_t pt = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
@@ -4231,7 +4200,7 @@ namespace bgfx
 			bool viewRestart = false;
 			uint8_t eye = 0;
 			uint8_t restartState = 0;
-			Rect rect = _render->m_rect[0];
+			viewState.m_rect = _render->m_rect[0];
 
 			int32_t numItems = _render->m_num;
 			for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;)
@@ -4287,15 +4256,15 @@ namespace bgfx
 						eye = 0;
 					}
 
-					rect = _render->m_rect[view];
+					viewState.m_rect = _render->m_rect[view];
 					if (viewRestart)
 					{
 						char* viewName = s_viewName[view];
 						viewName[3] = eye ? 'R' : 'L';
 						GL_CHECK(glInsertEventMarker(0, viewName) );
 						
-						rect.m_x = eye * (rect.m_width+1)/2;
-						rect.m_width /= 2;
+						viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2;
+						viewState.m_rect.m_width /= 2;
 					}
 					else
 					{
@@ -4306,19 +4275,19 @@ namespace bgfx
 
 					const Rect& scissorRect = _render->m_scissor[view];
 					viewHasScissor = !scissorRect.isZero();
-					viewScissorRect = viewHasScissor ? scissorRect : rect;
+					viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
 
-					GL_CHECK(glViewport(rect.m_x
-						, height-rect.m_height-rect.m_y
-						, rect.m_width
-						, rect.m_height
+					GL_CHECK(glViewport(viewState.m_rect.m_x
+						, height-viewState.m_rect.m_height-viewState.m_rect.m_y
+						, viewState.m_rect.m_width
+						, viewState.m_rect.m_height
 						) );
 
 					Clear& clear = _render->m_clear[view];
 
 					if (BGFX_CLEAR_NONE != clear.m_flags)
 					{
-						clearQuad(_clearQuad, rect, clear, height, _render->m_clearColor);
+						clearQuad(_clearQuad, viewState.m_rect, clear, height, _render->m_clearColor);
 					}
 
 					GL_CHECK(glDisable(GL_STENCIL_TEST) );
@@ -4375,6 +4344,8 @@ namespace bgfx
 								commit(*program.m_constantBuffer);
 							}
 
+							viewState.setPredefined<1>(this, view, eye, program, _render, compute);
+
 							GL_CHECK(glDispatchCompute(compute.m_numX, compute.m_numY, compute.m_numZ) );
 							GL_CHECK(glMemoryBarrier(barrier) );
 						}
@@ -4537,7 +4508,7 @@ namespace bgfx
 					if (BGFX_STATE_ALPHA_REF_MASK & changedFlags)
 					{
 						uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
-						alphaRef = ref/255.0f;
+						viewState.m_alphaRef = ref/255.0f;
 					}
 
 #if BGFX_CONFIG_RENDERER_OPENGL
@@ -4699,169 +4670,7 @@ namespace bgfx
 						commit(*program.m_constantBuffer);
 					}
 
-					for (uint32_t ii = 0, num = program.m_numPredefined; ii < num; ++ii)
-					{
-						PredefinedUniform& predefined = program.m_predefined[ii];
-						switch (predefined.m_type)
-						{
-						case PredefinedUniform::ViewRect:
-							{
-								float frect[4];
-								frect[0] = rect.m_x;
-								frect[1] = rect.m_y;
-								frect[2] = rect.m_width;
-								frect[3] = rect.m_height;
-
-								GL_CHECK(glUniform4fv(predefined.m_loc
-									, 1
-									, &frect[0]
-								) );
-							}
-							break;
-
-						case PredefinedUniform::ViewTexel:
-							{
-								float frect[4];
-								frect[0] = 1.0f/float(rect.m_width);
-								frect[1] = 1.0f/float(rect.m_height);
-
-								GL_CHECK(glUniform4fv(predefined.m_loc
-									, 1
-									, &frect[0]
-								) );
-							}
-							break;
-
-						case PredefinedUniform::View:
-							{
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, 1
-									, GL_FALSE
-									, mtxView[eye][view].un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::InvView:
-							{
-								uint16_t viewEye = (view << 1) | eye;
-								if (viewEye != invViewCached)
-								{
-									invViewCached = viewEye;
-									bx::float4x4_inverse(&invView.un.f4x4, &mtxView[eye][view].un.f4x4);
-								}
-
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, 1
-									, GL_FALSE
-									, invView.un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::Proj:
-							{
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, 1
-									, GL_FALSE
-									, _render->m_proj[0][view].un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::InvProj:
-							{
-								uint16_t viewEye = (view << 1) | eye;
-								if (viewEye != invProjCached)
-								{
-									invProjCached = viewEye;
-									bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[eye][view].un.f4x4);
-								}
-
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, 1
-									, GL_FALSE
-									, invProj.un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::ViewProj:
-							{
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, 1
-									, GL_FALSE
-									, mtxViewProj[eye][view].un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::InvViewProj:
-							{
-								uint16_t viewEye = (view << 1) | eye;
-								if (viewEye != invViewProjCached)
-								{
-									invViewProjCached = viewEye;
-									bx::float4x4_inverse(&invViewProj.un.f4x4, &mtxViewProj[eye][view].un.f4x4);
-								}
-
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, 1
-									, GL_FALSE
-									, invViewProj.un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::Model:
-							{
-								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, bx::uint32_min(predefined.m_count, draw.m_num)
-									, GL_FALSE
-									, model.un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::ModelView:
-							{
-								Matrix4 modelView;
-								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								bx::float4x4_mul(&modelView.un.f4x4, &model.un.f4x4, &mtxView[eye][view].un.f4x4);
-
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, 1
-									, GL_FALSE
-									, modelView.un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::ModelViewProj:
-							{
-								Matrix4 modelViewProj;
-								const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
-								bx::float4x4_mul(&modelViewProj.un.f4x4, &model.un.f4x4, &mtxViewProj[eye][view].un.f4x4);
-
-								GL_CHECK(glUniformMatrix4fv(predefined.m_loc
-									, 1
-									, GL_FALSE
-									, modelViewProj.un.val
-									) );
-							}
-							break;
-
-						case PredefinedUniform::AlphaRef:
-							{
-								GL_CHECK(glUniform1f(predefined.m_loc, alphaRef) );
-							}
-							break;
-
-						case PredefinedUniform::Count:
-							break;
-						}
-					}
+					viewState.setPredefined<1>(this, view, eye, program, _render, draw);
 
 					{
 						for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
@@ -5326,3 +5135,4 @@ namespace bgfx
 } // namespace bgfx
 
 #endif // (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL)
+

+ 1 - 0
src/renderer_gl.h

@@ -86,6 +86,7 @@ typedef uint64_t GLuint64;
 #	endif // BX_PLATFORM_EMSCRIPTEN
 #endif // BGFX_CONFIG_RENDERER_OPENGL
 
+#include "renderer.h"
 #include "ovr.h"
 #include "renderdoc.h"