Bläddra i källkod

Added framebuffer support test.

Branimir Karadžić 10 år sedan
förälder
incheckning
c4231c9731
5 ändrade filer med 127 tillägg och 21 borttagningar
  1. 7 6
      include/bgfxdefines.h
  2. 8 6
      src/bgfx.cpp
  3. 12 1
      src/renderer_d3d11.cpp
  4. 8 0
      src/renderer_d3d9.cpp
  5. 92 8
      src/renderer_gl.cpp

+ 7 - 6
include/bgfxdefines.h

@@ -345,12 +345,13 @@
 #define BGFX_CAPS_DRAW_INDIRECT          UINT64_C(0x0000000000002000)
 
 ///
-#define BGFX_CAPS_FORMAT_TEXTURE_NONE       UINT8_C(0x00)
-#define BGFX_CAPS_FORMAT_TEXTURE_COLOR      UINT8_C(0x01)
-#define BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB UINT8_C(0x02)
-#define BGFX_CAPS_FORMAT_TEXTURE_EMULATED   UINT8_C(0x04)
-#define BGFX_CAPS_FORMAT_TEXTURE_VERTEX     UINT8_C(0x08)
-#define BGFX_CAPS_FORMAT_TEXTURE_IMAGE      UINT8_C(0x10)
+#define BGFX_CAPS_FORMAT_TEXTURE_NONE        UINT8_C(0x00)
+#define BGFX_CAPS_FORMAT_TEXTURE_COLOR       UINT8_C(0x01)
+#define BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB  UINT8_C(0x02)
+#define BGFX_CAPS_FORMAT_TEXTURE_EMULATED    UINT8_C(0x04)
+#define BGFX_CAPS_FORMAT_TEXTURE_VERTEX      UINT8_C(0x08)
+#define BGFX_CAPS_FORMAT_TEXTURE_IMAGE       UINT8_C(0x10)
+#define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER UINT8_C(0x20)
 
 ///
 #define BGFX_VIEW_NONE   UINT8_C(0x00)

+ 8 - 6
src/bgfx.cpp

@@ -857,22 +857,24 @@ namespace bgfx
 		}
 
 		BX_TRACE("Supported texture formats:");
-		BX_TRACE("\t +-------- x = supported / * = emulated");
-		BX_TRACE("\t |+------- sRGB format");
-		BX_TRACE("\t ||+------ vertex format");
-		BX_TRACE("\t |||+----- image");
-		BX_TRACE("\t ||||  +-- name");
+		BX_TRACE("\t +--------- x = supported / * = emulated");
+		BX_TRACE("\t |+-------- sRGB format");
+		BX_TRACE("\t ||+------- vertex format");
+		BX_TRACE("\t |||+------ image");
+		BX_TRACE("\t ||||+----- framebuffer");
+		BX_TRACE("\t |||||  +-- name");
 		for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
 		{
 			if (TextureFormat::Unknown != ii
 			&&  TextureFormat::UnknownDepth != ii)
 			{
 				uint8_t flags = g_caps.formats[ii];
-				BX_TRACE("\t[%c%c%c%c] %s"
+				BX_TRACE("\t[%c%c%c%c%c] %s"
 					, flags&BGFX_CAPS_FORMAT_TEXTURE_COLOR       ? 'x' : flags&BGFX_CAPS_FORMAT_TEXTURE_EMULATED ? '*' : ' '
 					, flags&BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB  ? 'l' : ' '
 					, flags&BGFX_CAPS_FORMAT_TEXTURE_VERTEX      ? 'v' : ' '
 					, flags&BGFX_CAPS_FORMAT_TEXTURE_IMAGE       ? 'i' : ' '
+					, flags&BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER ? 'f' : ' '
 					, getName(TextureFormat::Enum(ii) )
 					);
 				BX_UNUSED(flags);

+ 12 - 1
src/renderer_d3d11.cpp

@@ -949,7 +949,10 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 			{
 				uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE;
 
-				const DXGI_FORMAT fmt     = s_textureFormat[ii].m_fmt;
+				const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) )
+					? s_textureFormat[ii].m_fmtDsv
+					: s_textureFormat[ii].m_fmt
+					;
 				const DXGI_FORMAT fmtSrgb = s_textureFormat[ii].m_fmtSrgb;
 
 				if (DXGI_FORMAT_UNKNOWN != fmt)
@@ -989,6 +992,14 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 								? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
 								: BGFX_CAPS_FORMAT_TEXTURE_NONE
 								;
+
+						support |= 0 != (data.OutFormatSupport & (0
+								| D3D11_FORMAT_SUPPORT_RENDER_TARGET
+								| D3D11_FORMAT_SUPPORT_DEPTH_STENCIL
+								) )
+								? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
+								: BGFX_CAPS_FORMAT_TEXTURE_NONE
+								;
 					}
 					else
 					{

+ 8 - 0
src/renderer_d3d9.cpp

@@ -548,6 +548,14 @@ namespace bgfx { namespace d3d9
 						, s_textureFormat[ii].m_fmt
 						) ) ? BGFX_CAPS_FORMAT_TEXTURE_VERTEX : BGFX_CAPS_FORMAT_TEXTURE_NONE;
 
+					support |= SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter
+						, m_deviceType
+						, adapterFormat
+						, isDepth(TextureFormat::Enum(ii) ) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET
+						, D3DRTYPE_TEXTURE
+						, s_textureFormat[ii].m_fmt
+						) ) ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER : BGFX_CAPS_FORMAT_TEXTURE_NONE;
+
 					g_caps.formats[ii] = support;
 				}
 			}

+ 92 - 8
src/renderer_gl.cpp

@@ -949,6 +949,27 @@ namespace bgfx { namespace gl
 		tfi.m_type        = _type;
 	}
 
+	void initTestTexture(TextureFormat::Enum _format, bool srgb = false)
+	{
+		const TextureFormatInfo& tfi = s_textureFormat[_format];
+		GLenum internalFmt = srgb
+			? tfi.m_internalFmtSrgb
+			: tfi.m_internalFmt
+			;
+
+		GLsizei size = (16*16*getBitsPerPixel(_format) )/8;
+		void* data = alloca(size);
+
+		if (isCompressed(_format) )
+		{
+			glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFmt, 16, 16, 0, size, data);
+		}
+		else
+		{
+			glTexImage2D(GL_TEXTURE_2D, 0, internalFmt, 16, 16, 0, tfi.m_fmt, tfi.m_type, data);
+		}
+	}
+
 	bool isTextureFormatValid(TextureFormat::Enum _format, bool srgb = false)
 	{
 		const TextureFormatInfo& tfi = s_textureFormat[_format];
@@ -965,24 +986,82 @@ namespace bgfx { namespace gl
 		GL_CHECK(glGenTextures(1, &id) );
 		GL_CHECK(glBindTexture(GL_TEXTURE_2D, id) );
 
-		GLsizei size = (16*16*getBitsPerPixel(_format) )/8;
-		void* data = alloca(size);
+		initTestTexture(_format);
 
-		if (isCompressed(_format) )
+		GLenum err = glGetError();
+		BX_WARN(0 == err, "TextureFormat::%s is not supported (%x: %s).", getName(_format), err, glEnumName(err) );
+
+		GL_CHECK(glDeleteTextures(1, &id) );
+
+		return 0 == err;
+	}
+
+	bool isFramebufferFormatValid(TextureFormat::Enum _format, bool srgb = false)
+	{
+		const TextureFormatInfo& tfi = s_textureFormat[_format];
+		GLenum internalFmt = srgb
+			? tfi.m_internalFmtSrgb
+			: tfi.m_internalFmt
+			;
+		if (GL_ZERO == internalFmt
+		||  !tfi.m_supported)
 		{
-			glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFmt, 16, 16, 0, size, data);
+			return false;
+		}
+
+		GLuint fbo;
+		GL_CHECK(glGenFramebuffers(1, &fbo) );
+		GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fbo) );
+
+		GLuint id;
+		GL_CHECK(glGenTextures(1, &id) );
+		GL_CHECK(glBindTexture(GL_TEXTURE_2D, id) );
+
+		initTestTexture(_format);
+
+		GLenum err = glGetError();
+
+		GLenum attachment;
+		if (isDepth(_format) )
+		{
+			const ImageBlockInfo& info = getBlockInfo(_format);
+			if (0 < info.stencilBits)
+			{
+				attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+			}
+			else if (0 == info.depthBits)
+			{
+				attachment = GL_STENCIL_ATTACHMENT;
+			}
+			else
+			{
+				attachment = GL_DEPTH_ATTACHMENT;
+			}
 		}
 		else
 		{
-			glTexImage2D(GL_TEXTURE_2D, 0, internalFmt, 16, 16, 0, tfi.m_fmt, tfi.m_type, data);
+			attachment = GL_COLOR_ATTACHMENT0;
 		}
 
-		GLenum err = glGetError();
-		BX_WARN(0 == err, "TextureFormat::%s is not supported (%x: %s).", getName(_format), err, glEnumName(err) );
+		glFramebufferTexture2D(GL_FRAMEBUFFER
+				, attachment
+				, GL_TEXTURE_2D
+				, id
+				, 0
+				);
+		err = glGetError();
+
+		if (0 == err)
+		{
+			err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+		}
+
+		GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
+		GL_CHECK(glDeleteFramebuffers(1, &fbo) );
 
 		GL_CHECK(glDeleteTextures(1, &id) );
 
-		return 0 == err;
+		return GL_FRAMEBUFFER_COMPLETE == err;
 	}
 
 	static void getFilters(uint32_t _flags, bool _hasMips, GLenum& _magFilter, GLenum& _minFilter)
@@ -1394,6 +1473,11 @@ namespace bgfx { namespace gl
 					: BGFX_CAPS_FORMAT_TEXTURE_NONE
 					;
 
+				supported |= isFramebufferFormatValid(TextureFormat::Enum(ii) )
+					? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
+					: BGFX_CAPS_FORMAT_TEXTURE_NONE
+					;
+
 				g_caps.formats[ii] = supported;
 			}