Quellcode durchsuchen

Merge branch 'master' of github.com:bkaradzic/bgfx

bkaradzic vor 12 Jahren
Ursprung
Commit
ba1bd59488
6 geänderte Dateien mit 152 neuen und 27 gelöschten Zeilen
  1. 37 18
      include/bgfx.h
  2. 25 0
      src/bgfx.cpp
  3. 45 2
      src/bgfx_p.h
  4. 20 6
      src/renderer_d3d11.cpp
  5. 13 1
      src/renderer_d3d9.cpp
  6. 12 0
      src/renderer_gl.cpp

+ 37 - 18
include/bgfx.h

@@ -70,7 +70,7 @@
 #define BGFX_STATE_SRGBWRITE             UINT64_C(0x0010000000000000)
 #define BGFX_STATE_MSAA                  UINT64_C(0x0020000000000000)
 
-#define BGFX_STATE_RESERVED              UINT64_C(0xff00000000000000)
+#define BGFX_STATE_RESERVED_MASK         UINT64_C(0xff00000000000000)
 
 #define BGFX_STATE_NONE                  UINT64_C(0x0000000000000000)
 #define BGFX_STATE_MASK                  UINT64_C(0xffffffffffffffff)
@@ -640,18 +640,20 @@ namespace bgfx
 
 	/// Allocate transient index buffer.
 	///
-	/// @param[out] _tib is valid for the duration of frame, and it can be
-	///   reused for multiple draw calls.
-	/// @param _num number of indices to allocate.
+	/// @param[out] _tib TransientIndexBuffer structure is filled and is valid
+	///   for the duration of frame, and it can be reused for multiple draw
+	///   calls.
+	/// @param _num Number of indices to allocate.
 	///
 	void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint32_t _num);
 
 	/// Allocate transient vertex buffer.
 	///
-	/// @param[out] _tvb is valid for the duration of frame, and it can be
-	///   reused for multiple draw calls.
-	/// @param _num number of vertices to allocate.
-	/// @param _decl vertex declaration.
+	/// @param[out] _tvb TransientVertexBuffer structure is filled and is valid
+	///   for the duration of frame, and it can be reused for multiple draw
+	///   calls.
+	/// @param _num Number of vertices to allocate.
+	/// @param _decl Vertex declaration.
 	///
 	void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexDecl& _decl);
 
@@ -674,8 +676,8 @@ namespace bgfx
 
 	/// Create program with vertex and fragment shaders.
 	///
-	/// @param _vsh vertex shader.
-	/// @param _fsh fragment shader.
+	/// @param _vsh Vertex shader.
+	/// @param _fsh Fragment shader.
 	/// @returns Program handle if vertex shader output and fragment shader
 	///   input are matching, otherwise returns invalid program handle.
 	///
@@ -756,9 +758,17 @@ namespace bgfx
 	/// Set view rectangle. Draw primitive outside view will be clipped.
 	void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height);
 
-	/// Set view rectangle for multiple views .
+	/// Set view rectangle for multiple views.
 	void setViewRectMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height);
 
+	/// Set view scissor. Draw primitive outside view will be clipped. When
+	/// _x, _y, _width and _height are set to 0, scissor will be disabled.
+	void setViewScissor(uint8_t _id, uint16_t _x = 0, uint16_t _y = 0, uint16_t _width = 0, uint16_t _height = 0);
+
+	/// Set view scissor for multiple views. When _x, _y, _width and _height
+	/// are set to 0, scissor will be disabled.
+	void setViewScissorMask(uint32_t _viewMask, uint16_t _x = 0, uint16_t _y = 0, uint16_t _width = 0, uint16_t _height = 0);
+
 	/// Set view clear flags.
 	///
 	/// @param _id View id.
@@ -843,11 +853,20 @@ namespace bgfx
 	///
 	void setStencil(uint32_t _fstencil, uint32_t _bstencil = BGFX_STENCIL_NONE);
 
+	/// Set scissor for draw primitive.
+	uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height);
+
+	/// Set scissor from cache for draw primitive.
+	///
+	/// @param _cache Index in scissor cache.
+	///
+	void setScissor(uint16_t _cache);
+
 	/// Set model matrix for draw primitive. If it is not called model will
 	/// be rendered with identity model matrix.
 	///
-	/// @param _mtx pointer to first matrix in array.
-	/// @param _num number of matrices in array.
+	/// @param _mtx Pointer to first matrix in array.
+	/// @param _num Number of matrices in array.
 	/// @returns index into matrix cache in case the same model matrix has
 	///   to be used for other draw primitive call.
 	///
@@ -855,8 +874,8 @@ namespace bgfx
 
 	/// Set model matrix from matrix cache for draw primitive.
 	///
-	/// @param _cache index in matrix cache.
-	/// @param _num number of matrices from cache.
+	/// @param _cache Index in matrix cache.
+	/// @param _num Number of matrices from cache.
 	///
 	void setTransform(uint32_t _cache, uint16_t _num = 1);
 
@@ -896,14 +915,14 @@ namespace bgfx
 	/// Submit primitive for rendering into single view.
 	///
 	/// @param _id View id.
-	/// @param _depth depth for sorting.
+	/// @param _depth Depth for sorting.
 	///
 	void submit(uint8_t _id, int32_t _depth = 0);
 
 	/// Submit primitive for rendering into multiple views.
 	///
-	/// @param _viewMask mask to which views to submit draw primitive calls.
-	/// @param _depth depth for sorting.
+	/// @param _viewMask Mask to which views to submit draw primitive calls.
+	/// @param _depth Depth for sorting.
 	///
 	void submitMask(uint32_t _viewMask, int32_t _depth = 0);
 

+ 25 - 0
src/bgfx.cpp

@@ -733,6 +733,7 @@ namespace bgfx
 		memset(m_rt, 0xff, sizeof(m_rt) );
 		memset(m_clear, 0, sizeof(m_clear) );
 		memset(m_rect, 0, sizeof(m_rect) );
+		memset(m_scissor, 0, sizeof(m_scissor) );
 		memset(m_seq, 0, sizeof(m_seq) );
 		memset(m_seqMask, 0, sizeof(m_seqMask) );
 
@@ -1305,6 +1306,18 @@ namespace bgfx
 		s_ctx.setViewRectMask(_viewMask, _x, _y, _width, _height);
 	}
 
+	void setViewScissor(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+	{
+		BGFX_CHECK_MAIN_THREAD();
+		s_ctx.setViewScissor(_id, _x, _y, _width, _height);
+	}
+
+	void setViewScissorMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+	{
+		BGFX_CHECK_MAIN_THREAD();
+		s_ctx.setViewScissorMask(_viewMask, _x, _y, _width, _height);
+	}
+
 	void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
 	{
 		BGFX_CHECK_MAIN_THREAD();
@@ -1371,6 +1384,18 @@ namespace bgfx
 		s_ctx.m_submit->setStencil(_fstencil, _bstencil);
 	}
 
+	uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+	{
+		BGFX_CHECK_MAIN_THREAD();
+		return s_ctx.m_submit->setScissor(_x, _y, _width, _height);
+	}
+
+	void setScissor(uint16_t _cache)
+	{
+		BGFX_CHECK_MAIN_THREAD();
+		s_ctx.m_submit->setScissor(_cache);
+	}
+
 	uint32_t setTransform(const void* _mtx, uint16_t _num)
 	{
 		BGFX_CHECK_MAIN_THREAD();

+ 45 - 2
src/bgfx_p.h

@@ -172,6 +172,12 @@ namespace bgfx
 
 	struct Rect
 	{
+		bool isZero() const
+		{
+			uint64_t ui64 = *( (uint64_t*)this);
+			return UINT64_C(0) == ui64;
+		}
+
 		uint16_t m_x;
 		uint16_t m_y;
 		uint16_t m_width;
@@ -850,6 +856,7 @@ namespace bgfx
 			m_instanceDataStride = 0;
 			m_numInstances = 1;
 			m_num = 1;
+			m_scissor = 0;
 			m_vertexBuffer.idx = invalidHandle;
 			m_vertexDecl.idx = invalidHandle;
 			m_indexBuffer.idx = invalidHandle;
@@ -876,6 +883,7 @@ namespace bgfx
 		uint16_t m_instanceDataStride;
 		uint16_t m_numInstances;
 		uint16_t m_num;
+		uint16_t m_scissor;
 
 		VertexBufferHandle m_vertexBuffer;
 		VertexDeclHandle m_vertexDecl;
@@ -994,6 +1002,18 @@ namespace bgfx
 			m_state.m_stencil = packStencil(_fstencil, _bstencil);
 		}
 
+		uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+		{
+			BX_UNUSED(_x, _y, _width, _height);
+			m_state.m_scissor = 0;
+			return 0;
+		}
+
+		void setScissor(uint16_t _cache)
+		{
+			m_state.m_scissor = _cache;
+		}
+
 		uint32_t setTransform(const void* _mtx, uint16_t _num)
 		{
 			m_state.m_matrix = m_matrixCache.add(_mtx, _num);
@@ -1208,6 +1228,7 @@ namespace bgfx
 		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];
 		Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
 		Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
+		Rect m_scissor[BGFX_CONFIG_MAX_VIEWS];
 		Matrix4 m_view[BGFX_CONFIG_MAX_VIEWS];
 		Matrix4 m_proj[BGFX_CONFIG_MAX_VIEWS];
 		uint8_t m_other[BGFX_CONFIG_MAX_VIEWS];
@@ -2205,7 +2226,27 @@ namespace bgfx
 				viewMask >>= ntz;
 				view += ntz;
 
-				setViewRect(view, _x, _y, _width, _height);
+				setViewRect( (uint8_t)view, _x, _y, _width, _height);
+			}
+		}
+
+		void setViewScissor(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+		{
+			Rect& scissor = m_scissor[_id];
+			scissor.m_x = _x;
+			scissor.m_y = _y;
+			scissor.m_width = _width;
+			scissor.m_height = _height;
+		}
+
+		void setViewScissorMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+		{
+			for (uint32_t view = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, view += 1, ntz = uint32_cnttz(viewMask) )
+			{
+				viewMask >>= ntz;
+				view += ntz;
+
+				setViewScissor( (uint8_t)view, _x, _y, _width, _height);
 			}
 		}
 
@@ -2225,7 +2266,7 @@ namespace bgfx
 				viewMask >>= ntz;
 				view += ntz;
 
-				setViewClear(view, _flags, _rgba, _depth, _stencil);
+				setViewClear( (uint8_t)view, _flags, _rgba, _depth, _stencil);
 			}
 		}
 
@@ -2387,6 +2428,7 @@ namespace bgfx
 			memcpy(m_submit->m_rt, m_rt, sizeof(m_rt) );
 			memcpy(m_submit->m_clear, m_clear, sizeof(m_clear) );
 			memcpy(m_submit->m_rect, m_rect, sizeof(m_rect) );
+			memcpy(m_submit->m_scissor, m_scissor, sizeof(m_scissor) );
 			memcpy(m_submit->m_view, m_view, sizeof(m_view) );
 			memcpy(m_submit->m_proj, m_proj, sizeof(m_proj) );
 			memcpy(m_submit->m_other, m_other, sizeof(m_other) );
@@ -3068,6 +3110,7 @@ namespace bgfx
 		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];
 		Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
 		Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
+		Rect m_scissor[BGFX_CONFIG_MAX_VIEWS];
 		Matrix4 m_view[BGFX_CONFIG_MAX_VIEWS];
 		Matrix4 m_proj[BGFX_CONFIG_MAX_VIEWS];
 		uint8_t m_other[BGFX_CONFIG_MAX_VIEWS];

+ 20 - 6
src/renderer_d3d11.cpp

@@ -902,10 +902,11 @@ namespace bgfx
 			}
 		}
 
-		void setRasterizerState(uint64_t _state, bool _wireframe = false)
+		void setRasterizerState(uint64_t _state, bool _wireframe = false, bool _scissor = false)
 		{
 			_state &= BGFX_STATE_CULL_MASK|BGFX_STATE_MSAA;
 			_state |= _wireframe ? BGFX_STATE_PT_LINES : BGFX_STATE_NONE;
+			_state |= _scissor ? BGFX_STATE_RESERVED_MASK : 0;
 
 			ID3D11RasterizerState* rs = m_rasterizerStateCache.find(_state);
 			if (NULL == rs)
@@ -920,7 +921,7 @@ namespace bgfx
 				desc.DepthBiasClamp = 0.0f;
 				desc.SlopeScaledDepthBias = 0.0f;
 				desc.DepthClipEnable = false;
-				desc.ScissorEnable = false;
+				desc.ScissorEnable = _scissor;
 				desc.MultisampleEnable = !!(_state&BGFX_STATE_MSAA);
 				desc.AntialiasedLineEnable = false;
 
@@ -1367,7 +1368,7 @@ namespace bgfx
 			
  		s_renderCtx.setBlendState(state);
  		s_renderCtx.setDepthStencilState(state);
- 		s_renderCtx.setRasterizerState(state, false);
+ 		s_renderCtx.setRasterizerState(state);
 
 		Program& program = s_renderCtx.m_program[m_program.idx];
 		s_renderCtx.m_currentProgram = &program;
@@ -1446,7 +1447,7 @@ namespace bgfx
 
 			s_renderCtx.setBlendState(state);
 			s_renderCtx.setDepthStencilState(state, stencil);
-			s_renderCtx.setRasterizerState(state, false);
+			s_renderCtx.setRasterizerState(state);
 
 			Program& program = s_renderCtx.m_program[m_program.idx];
 			s_renderCtx.m_currentProgram = &program;
@@ -2308,6 +2309,7 @@ namespace bgfx
 		}
 
 		bool wireframe = !!(m_render->m_debug&BGFX_DEBUG_WIREFRAME);
+		bool scissor = false;
 		s_renderCtx.setDebugWireframe(wireframe);
 
 		uint16_t programIdx = invalidHandle;
@@ -2376,9 +2378,21 @@ namespace bgfx
 						m_clearQuad.clear(rect, clear);
 					}
 
+					Rect& scissorRect = m_render->m_scissor[view];
+					scissor = !scissorRect.isZero();
+					if (scissor)
+					{
+						D3D11_RECT rc;
+						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;
+						deviceCtx->RSSetScissorRects(1, &rc);
+					}
+
 					s_renderCtx.setBlendState(BGFX_STATE_DEFAULT);
 					s_renderCtx.setDepthStencilState(BGFX_STATE_DEFAULT, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) );
-					s_renderCtx.setRasterizerState(BGFX_STATE_DEFAULT, wireframe);
+					s_renderCtx.setRasterizerState(BGFX_STATE_DEFAULT, wireframe, scissor);
 
 					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
 					if (primType != s_primType[primIndex])
@@ -2415,7 +2429,7 @@ namespace bgfx
 
 					if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_MSAA) & changedFlags)
 					{
-						s_renderCtx.setRasterizerState(newFlags, wireframe);
+						s_renderCtx.setRasterizerState(newFlags, wireframe, scissor);
 					}
 
 					if (BGFX_STATE_ALPHA_REF_MASK & changedFlags)

+ 13 - 1
src/renderer_d3d9.cpp

@@ -2257,7 +2257,6 @@ namespace bgfx
 					}
 
 					Rect& rect = m_render->m_rect[view];
-
 					D3DVIEWPORT9 vp;
 					vp.X = rect.m_x;
 					vp.Y = rect.m_y;
@@ -2307,6 +2306,19 @@ namespace bgfx
 						}
 					}
 
+					Rect& scissorRect = m_render->m_scissor[view];
+					bool scissor = !scissorRect.isZero();
+					DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, scissor) );
+					if (scissor)
+					{
+						RECT rc;
+						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) );
+					}
+
 					DX_CHECK(device->SetRenderState(D3DRS_STENCILENABLE, FALSE) );
 					DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, TRUE) );
 					DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS) );

+ 12 - 0
src/renderer_gl.cpp

@@ -2739,6 +2739,18 @@ namespace bgfx
 						m_clearQuad.clear(rect, clear, height);
 					}
 
+					Rect& scissorRect = m_render->m_scissor[view];
+					bool scissor = !scissorRect.isZero();
+					if (scissor)
+					{
+						GL_CHECK(glEnable(GL_SCISSOR_TEST) );
+						GL_CHECK(glScissor(scissorRect.m_x, height-scissorRect.m_height-scissorRect.m_y, scissorRect.m_width, scissorRect.m_height) );
+					}
+					else
+					{
+						GL_CHECK(glDisable(GL_SCISSOR_TEST) );
+					}
+
 					GL_CHECK(glDisable(GL_STENCIL_TEST) );
 					GL_CHECK(glEnable(GL_DEPTH_TEST) );
 					GL_CHECK(glDepthFunc(GL_LESS) );