Ver Fonte

Metal framebuffer attachment support

08-update: added a cube that has a texturecube that is rendered using framebuffer attachment. It looks the same as the one whose texture is updated with compute shader.
Attila Kocsis há 7 anos atrás
pai
commit
c39408173d
3 ficheiros alterados com 97 adições e 16 exclusões
  1. 55 2
      examples/08-update/update.cpp
  2. 2 0
      src/renderer_mtl.h
  3. 40 14
      src/renderer_mtl.mm

+ 55 - 2
examples/08-update/update.cpp

@@ -98,6 +98,16 @@ static const uint16_t s_cubeIndices[] =
 	21, 22, 23,
 };
 BX_STATIC_ASSERT(BX_COUNTOF(s_cubeIndices) == 36);
+	
+bx::Vec3 s_faceColors[] =
+{
+	{ 0.75f, 0.0f,  0.0f  },
+	{ 0.75f, 0.75f, 0.0f  },
+	{ 0.75f, 0.0f,  0.75f },
+	{ 0.0f,  0.75f, 0.0f  },
+	{ 0.0f,  0.75f, 0.75f },
+	{ 0.0f,  0.0f,  0.75f },
+};
 
 static void updateTextureCubeRectBgra8(
 	  bgfx::TextureHandle _handle
@@ -290,6 +300,23 @@ public:
 				, BGFX_TEXTURE_COMPUTE_WRITE
 				);
 		}
+		
+		{
+			m_textureCube[3] = bgfx::createTextureCube(
+													   kTextureSide
+													   , false
+													   , 1
+													   , bgfx::TextureFormat::RGBA8
+													   , BGFX_TEXTURE_RT
+													   );
+			
+			for (uint32_t ii = 0; ii < BX_COUNTOF(m_textureCubeFaceFb); ++ii)
+			{
+				bgfx::Attachment at;
+				at.init(m_textureCube[3], bgfx::Access::Write, ii);
+				m_textureCubeFaceFb[ii] = bgfx::createFrameBuffer(1, &at);
+			}
+		}
 
 		m_texture2d = bgfx::createTexture2D(
 			  kTexture2dSize
@@ -347,6 +374,14 @@ public:
 			}
 		}
 
+		for (uint32_t ii = 0; ii<BX_COUNTOF(m_textureCubeFaceFb); ++ii)
+		{
+			if (bgfx::isValid(m_textureCubeFaceFb[ii]))
+			{
+				bgfx::destroy(m_textureCubeFaceFb[ii]);
+			}
+		}
+
 		bgfx::destroy(m_ibh);
 		bgfx::destroy(m_vbh);
 		if (bgfx::isValid(m_program3d) )
@@ -502,13 +537,30 @@ public:
 				bgfx::setImage(0, m_textureCube[2], 0, bgfx::Access::Write);
 				bgfx::dispatch(0, m_programCompute, kTextureSide/16, kTextureSide/16);
 			}
+			
+			for (uint32_t ii = 0; ii < BX_COUNTOF(m_textureCubeFaceFb); ++ii)
+			{
+				bgfx::ViewId viewId = ii+2;
+				bgfx::setViewFrameBuffer(viewId, m_textureCubeFaceFb[ii]);
+
+				bx::Vec3 color = bx::add(s_faceColors[ii], bx::sin(time*4.0f)*0.25f);
+				uint32_t colorRGB8 =
+						  uint32_t(bx::toUnorm(color.x, 255.0f) ) << 24
+						| uint32_t(bx::toUnorm(color.y, 255.0f) ) << 16
+						| uint32_t(bx::toUnorm(color.z, 255.0f) ) << 8;
+
+				bgfx::setViewClear(viewId, BGFX_CLEAR_COLOR, colorRGB8);
+				bgfx::setViewRect(viewId, 0,0,512,512);
+
+				bgfx::touch(viewId);
+			}
 
 			for (uint32_t ii = 0; ii < BX_COUNTOF(m_textureCube); ++ii)
 			{
 				if (bgfx::isValid(m_textureCube[ii]))
 				{
 					float mtx[16];
-					bx::mtxSRT(mtx, 0.7f, 0.7f, 0.7f, time, time*0.37f, 0.0f, -2.0f +ii*2.0f, 0.0f, 0.0f);
+					bx::mtxSRT(mtx, 0.65f, 0.65f, 0.65f, time, time*0.37f, 0.0f, -2.5f +ii*1.8f, 0.0f, 0.0f);
 
 					// Set model matrix for rendering.
 					bgfx::setTransform(mtx);
@@ -661,7 +713,8 @@ public:
 	bgfx::TextureHandle m_textures[12];
 	bgfx::TextureHandle m_textures3d[3];
 	bgfx::TextureHandle m_texture2d;
-	bgfx::TextureHandle m_textureCube[3];
+	bgfx::TextureHandle m_textureCube[4];
+	bgfx::FrameBufferHandle m_textureCubeFaceFb[6];
 	bgfx::IndexBufferHandle m_ibh;
 	bgfx::VertexBufferHandle m_vbh;
 	bgfx::ProgramHandle m_program3d;

+ 2 - 0
src/renderer_mtl.h

@@ -1062,6 +1062,8 @@ namespace bgfx { namespace mtl
 
 		TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
 		TextureHandle m_depthHandle;
+		Attachment m_colorAttachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
+		Attachment m_depthAttachment;
 		uint8_t m_num; // number of color handles
 	};
 

+ 40 - 14
src/renderer_mtl.mm

@@ -1577,8 +1577,26 @@ namespace bgfx { namespace mtl
 			m_renderCommandEncoder.setVertexBuffer(vb.getBuffer(), offset, 1);
 			m_renderCommandEncoder.drawPrimitives(MTLPrimitiveTypeTriangleStrip, 0, 4, 1);
 		}
+		
+		void setAttachment(MTLRenderPassAttachmentDescriptor* _attachmentDescriptor, const Attachment& _at, uint8_t _textureType, bool _resolve)
+		{
+			_attachmentDescriptor.level = _at.mip;
+			if ( _textureType == TextureMtl::Texture3D )
+				_attachmentDescriptor.depthPlane = _at.layer;
+			else
+				_attachmentDescriptor.slice = _at.layer;
+			
+			if ( _resolve )
+			{
+				_attachmentDescriptor.resolveLevel = _at.mip;
+				if ( _textureType == TextureMtl::Texture3D )
+					_attachmentDescriptor.resolveDepthPlane = _at.layer;
+				else
+					_attachmentDescriptor.resolveSlice = _at.layer;
+			}
+		}
 
-		void setFrameBuffer(RenderPassDescriptor renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true)
+		void setFrameBuffer(RenderPassDescriptor _renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true)
 		{
 			if (!isValid(_fbh)
 			||  m_frameBuffers[_fbh.idx].m_swapChain)
@@ -1590,22 +1608,22 @@ namespace bgfx { namespace mtl
 
 				if (NULL != swapChain->m_backBufferColorMsaa)
 				{
-					renderPassDescriptor.colorAttachments[0].texture        = swapChain->m_backBufferColorMsaa;
-					renderPassDescriptor.colorAttachments[0].resolveTexture = NULL != m_screenshotTarget
+					_renderPassDescriptor.colorAttachments[0].texture        = swapChain->m_backBufferColorMsaa;
+					_renderPassDescriptor.colorAttachments[0].resolveTexture = NULL != m_screenshotTarget
 						? m_screenshotTarget.m_obj
 						: swapChain->currentDrawable().texture
 						;
 				}
 				else
 				{
-					renderPassDescriptor.colorAttachments[0].texture = NULL != m_screenshotTarget
+					_renderPassDescriptor.colorAttachments[0].texture = NULL != m_screenshotTarget
 						? m_screenshotTarget.m_obj
 						: swapChain->currentDrawable().texture
 						;
 				}
 
-				renderPassDescriptor.depthAttachment.texture   = swapChain->m_backBufferDepth;
-				renderPassDescriptor.stencilAttachment.texture = swapChain->m_backBufferStencil;
+				_renderPassDescriptor.depthAttachment.texture   = swapChain->m_backBufferDepth;
+				_renderPassDescriptor.stencilAttachment.texture = swapChain->m_backBufferStencil;
 			}
 			else
 			{
@@ -1614,35 +1632,40 @@ namespace bgfx { namespace mtl
 				for (uint32_t ii = 0; ii < frameBuffer.m_num; ++ii)
 				{
 					const TextureMtl& texture = m_textures[frameBuffer.m_colorHandle[ii].idx];
-					renderPassDescriptor.colorAttachments[ii].texture = texture.m_ptrMsaa
+					_renderPassDescriptor.colorAttachments[ii].texture = texture.m_ptrMsaa
 						? texture.m_ptrMsaa
 						: texture.m_ptr
 						;
-					renderPassDescriptor.colorAttachments[ii].resolveTexture = texture.m_ptrMsaa
+					_renderPassDescriptor.colorAttachments[ii].resolveTexture = texture.m_ptrMsaa
 						? texture.m_ptr.m_obj
 						: NULL
 						;
+					
+					setAttachment(_renderPassDescriptor.colorAttachments[ii], frameBuffer.m_colorAttachment[ii], texture.m_type, texture.m_ptrMsaa != NULL);
 				}
 
 				if (isValid(frameBuffer.m_depthHandle) )
 				{
 					const TextureMtl& texture = m_textures[frameBuffer.m_depthHandle.idx];
-					renderPassDescriptor.depthAttachment.texture = texture.m_ptrMsaa
+					_renderPassDescriptor.depthAttachment.texture = texture.m_ptrMsaa
 						? texture.m_ptrMsaa
 						: texture.m_ptr
 						;
-					renderPassDescriptor.stencilAttachment.texture = texture.m_ptrStencil;
+					_renderPassDescriptor.stencilAttachment.texture = texture.m_ptrStencil;
 
+					setAttachment(_renderPassDescriptor.depthAttachment, frameBuffer.m_depthAttachment, texture.m_type, NULL != texture.m_ptrMsaa);
+					setAttachment(_renderPassDescriptor.stencilAttachment, frameBuffer.m_depthAttachment, texture.m_type, NULL != texture.m_ptrMsaa);
+					
 					if (texture.m_textureFormat == TextureFormat::D24S8)
 					{
 						if (texture.m_ptr.pixelFormat() == 255 /* Depth24Unorm_Stencil8 */
 						||  texture.m_ptr.pixelFormat() == 260 /* Depth32Float_Stencil8 */)
 						{
-							renderPassDescriptor.stencilAttachment.texture = renderPassDescriptor.depthAttachment.texture;
+							_renderPassDescriptor.stencilAttachment.texture = _renderPassDescriptor.depthAttachment.texture;
 						}
 						else
 						{
-							renderPassDescriptor.stencilAttachment.texture = texture.m_ptrMsaa
+							_renderPassDescriptor.stencilAttachment.texture = texture.m_ptrMsaa
 								? texture.m_ptrMsaa
 								: texture.m_ptrStencil
 								;
@@ -3089,8 +3112,9 @@ namespace bgfx { namespace mtl
 
 		for (uint32_t ii = 0; ii < _num; ++ii)
 		{
-			TextureHandle handle = _attachment[ii].handle;
-
+			const Attachment& at = _attachment[ii];
+			TextureHandle handle = at.handle;
+			
 			if (isValid(handle) )
 			{
 				const TextureMtl& texture = s_renderMtl->m_textures[handle.idx];
@@ -3104,10 +3128,12 @@ namespace bgfx { namespace mtl
 				if (bimg::isDepth(bimg::TextureFormat::Enum(texture.m_textureFormat) ) )
 				{
 					m_depthHandle = handle;
+					m_depthAttachment = at;
 				}
 				else
 				{
 					m_colorHandle[m_num] = handle;
+					m_colorAttachment[m_num] = at;
 					m_num++;
 				}
 			}