Selaa lähdekoodia

Added bgfx::isFrameBufferValid API.

Бранимир Караџић 4 vuotta sitten
vanhempi
sitoutus
6109697ade
11 muutettua tiedostoa jossa 279 lisäystä ja 108 poistoa
  1. 10 0
      bindings/bf/bgfx.bf
  2. 11 0
      bindings/cs/bgfx.cs
  3. 17 0
      bindings/d/funcs.d
  4. 1 1
      bindings/d/types.d
  5. 12 0
      include/bgfx/bgfx.h
  6. 13 0
      include/bgfx/c99/bgfx.h
  7. 1 1
      include/bgfx/defines.h
  8. 7 1
      scripts/bgfx.idl
  9. 192 103
      src/bgfx.cpp
  10. 6 0
      src/bgfx.idl.inl
  11. 9 2
      src/bgfx_p.h

+ 10 - 0
bindings/bf/bgfx.bf

@@ -2994,6 +2994,16 @@ public static class bgfx
 	[LinkName("bgfx_is_texture_valid")]
 	public static extern bool is_texture_valid(uint16 _depth, bool _cubeMap, uint16 _numLayers, TextureFormat _format, uint64 _flags);
 	
+	/// <summary>
+	/// Validate frame buffer parameters.
+	/// </summary>
+	///
+	/// <param name="_num">Number of attachments.</param>
+	/// <param name="_attachment">Attachment texture info. See: `bgfx::Attachment`.</param>
+	///
+	[LinkName("bgfx_is_frame_buffer_valid")]
+	public static extern bool is_frame_buffer_valid(uint8 _num, Attachment* _attachment);
+	
 	/// <summary>
 	/// Calculate amount of memory required for texture.
 	/// </summary>

+ 11 - 0
bindings/cs/bgfx.cs

@@ -2950,6 +2950,17 @@ public static partial class bgfx
 	[return: MarshalAs(UnmanagedType.I1)]
 	public static extern unsafe bool is_texture_valid(ushort _depth, bool _cubeMap, ushort _numLayers, TextureFormat _format, ulong _flags);
 	
+	/// <summary>
+	/// Validate frame buffer parameters.
+	/// </summary>
+	///
+	/// <param name="_num">Number of attachments.</param>
+	/// <param name="_attachment">Attachment texture info. See: `bgfx::Attachment`.</param>
+	///
+	[DllImport(DllName, EntryPoint="bgfx_is_frame_buffer_valid", CallingConvention = CallingConvention.Cdecl)]
+	[return: MarshalAs(UnmanagedType.I1)]
+	public static extern unsafe bool is_frame_buffer_valid(byte _num, Attachment* _attachment);
+	
 	/// <summary>
 	/// Calculate amount of memory required for texture.
 	/// </summary>

+ 17 - 0
bindings/d/funcs.d

@@ -698,6 +698,14 @@ version(BindBgfx_Static)
 	 */
 	bool bgfx_is_texture_valid(ushort _depth, bool _cubeMap, ushort _numLayers, bgfx_texture_format_t _format, ulong _flags);
 	
+	/**
+	 * Validate frame buffer parameters.
+	 * Params:
+	 * _num = Number of attachments.
+	 * _attachment = Attachment texture info. See: `bgfx::Attachment`.
+	 */
+	bool bgfx_is_frame_buffer_valid(byte _num, const(bgfx_attachment_t)* _attachment);
+	
 	/**
 	 * Calculate amount of memory required for texture.
 	 * Params:
@@ -2897,6 +2905,15 @@ else
 		alias da_bgfx_is_texture_valid = bool function(ushort _depth, bool _cubeMap, ushort _numLayers, bgfx_texture_format_t _format, ulong _flags);
 		da_bgfx_is_texture_valid bgfx_is_texture_valid;
 		
+		/**
+		 * Validate frame buffer parameters.
+		 * Params:
+		 * _num = Number of attachments.
+		 * _attachment = Attachment texture info. See: `bgfx::Attachment`.
+		 */
+		alias da_bgfx_is_frame_buffer_valid = bool function(byte _num, const(bgfx_attachment_t)* _attachment);
+		da_bgfx_is_frame_buffer_valid bgfx_is_frame_buffer_valid;
+		
 		/**
 		 * Calculate amount of memory required for texture.
 		 * Params:

+ 1 - 1
bindings/d/types.d

@@ -10,7 +10,7 @@ public import core.stdc.stdarg : va_list;
 
 extern(C) @nogc nothrow:
 
-enum uint BGFX_API_VERSION = 112;
+enum uint BGFX_API_VERSION = 113;
 
 alias bgfx_view_id_t = ushort;
 

+ 12 - 0
include/bgfx/bgfx.h

@@ -2629,6 +2629,18 @@ namespace bgfx
 		, uint64_t _flags
 		);
 
+	/// Validate frame buffer parameters.
+	///
+	/// @param[in] _num Number of attachments.
+	/// @param[in] _attachment Attachment texture info. See: `bgfx::Attachment`.
+	///
+	/// @returns True if frame buffer can be successfully created.
+	///
+	bool isFrameBufferValid(
+		  uint8_t _num
+		, const Attachment* _attachment
+		);
+
 	/// Calculate amount of memory required for texture.
 	///
 	/// @param[out] _info Resulting texture info structure. See: `TextureInfo`.

+ 13 - 0
include/bgfx/c99/bgfx.h

@@ -1705,6 +1705,17 @@ BGFX_C_API void bgfx_destroy_program(bgfx_program_handle_t _handle);
  */
 BGFX_C_API bool bgfx_is_texture_valid(uint16_t _depth, bool _cubeMap, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags);
 
+/**
+ * Validate frame buffer parameters.
+ *
+ * @param[in] _num Number of attachments.
+ * @param[in] _attachment Attachment texture info. See: `bgfx::Attachment`.
+ *
+ * @returns True if frame buffer can be successfully created.
+ *
+ */
+BGFX_C_API bool bgfx_is_frame_buffer_valid(uint8_t _num, const bgfx_attachment_t* _attachment);
+
 /**
  * Calculate amount of memory required for texture.
  *
@@ -3402,6 +3413,7 @@ typedef enum bgfx_function_id
     BGFX_FUNCTION_ID_CREATE_COMPUTE_PROGRAM,
     BGFX_FUNCTION_ID_DESTROY_PROGRAM,
     BGFX_FUNCTION_ID_IS_TEXTURE_VALID,
+    BGFX_FUNCTION_ID_IS_FRAME_BUFFER_VALID,
     BGFX_FUNCTION_ID_CALC_TEXTURE_SIZE,
     BGFX_FUNCTION_ID_CREATE_TEXTURE,
     BGFX_FUNCTION_ID_CREATE_TEXTURE_2D,
@@ -3601,6 +3613,7 @@ struct bgfx_interface_vtbl
     bgfx_program_handle_t (*create_compute_program)(bgfx_shader_handle_t _csh, bool _destroyShaders);
     void (*destroy_program)(bgfx_program_handle_t _handle);
     bool (*is_texture_valid)(uint16_t _depth, bool _cubeMap, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags);
+    bool (*is_frame_buffer_valid)(uint8_t _num, const bgfx_attachment_t* _attachment);
     void (*calc_texture_size)(bgfx_texture_info_t * _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format);
     bgfx_texture_handle_t (*create_texture)(const bgfx_memory_t* _mem, uint64_t _flags, uint8_t _skip, bgfx_texture_info_t* _info);
     bgfx_texture_handle_t (*create_texture_2d)(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem);

+ 1 - 1
include/bgfx/defines.h

@@ -15,7 +15,7 @@
 #ifndef BGFX_DEFINES_H_HEADER_GUARD
 #define BGFX_DEFINES_H_HEADER_GUARD
 
-#define BGFX_API_VERSION UINT32_C(112)
+#define BGFX_API_VERSION UINT32_C(113)
 
 /**
  * Color RGB/alpha/depth write. When it's not specified write will be disabled.

+ 7 - 1
scripts/bgfx.idl

@@ -1,7 +1,7 @@
 -- vim: syntax=lua
 -- bgfx interface
 
-version(112)
+version(113)
 
 typedef "bool"
 typedef "char"
@@ -1593,6 +1593,12 @@ func.isTextureValid
 	.format    "TextureFormat::Enum" --- Texture format. See: `TextureFormat::Enum`.
 	.flags     "uint64_t"            --- Texture flags. See `BGFX_TEXTURE_*`.
 
+--- Validate frame buffer parameters.
+func.isFrameBufferValid
+	"bool"                              --- True if frame buffer can be successfully created.
+	.num            "uint8_t"           --- Number of attachments.
+	.attachment     "const Attachment*" --- Attachment texture info. See: `bgfx::Attachment`.
+
 --- Calculate amount of memory required for texture.
 func.calcTextureSize
 	"void"

+ 192 - 103
src/bgfx.cpp

@@ -16,7 +16,8 @@
 #	include <objc/message.h>
 #endif // BX_PLATFORM_OSX
 
-BX_ERROR_RESULT(BGFX_ERROR_TEXTURE_VALIDATION,  BX_MAKEFOURCC('b', 'g', 0, 1) );
+BX_ERROR_RESULT(BGFX_ERROR_TEXTURE_VALIDATION,      BX_MAKEFOURCC('b', 'g', 0, 1) );
+BX_ERROR_RESULT(BGFX_ERROR_FRAME_BUFFER_VALIDATION, BX_MAKEFOURCC('b', 'g', 0, 2) );
 
 namespace bgfx
 {
@@ -4328,8 +4329,24 @@ namespace bgfx
 		s_ctx->destroyProgram(_handle);
 	}
 
-	void checkFrameBuffer(uint8_t _num, const Attachment* _attachment)
+#define BGFX_ERROR_CHECK(_condition, _err, _result, _msg, _format, ...) \
+	if (!BX_IGNORE_C4127(_condition) )                                  \
+	{                                                                   \
+		BX_ERROR_SET(_err, _result, _msg);                              \
+		BX_TRACE("%.*s: '%.*s' - " _format                              \
+			, bxErrorScope.getName().getLength()                        \
+			, bxErrorScope.getName().getPtr()                           \
+			, _err->getMessage().getLength()                            \
+			, _err->getMessage().getPtr()                               \
+			, ##__VA_ARGS__                                             \
+			);                                                          \
+		return;                                                         \
+	}
+
+	void isFrameBufferValid(uint8_t _num, const Attachment* _attachment, bx::Error* _err)
 	{
+		BX_ERROR_SCOPE(_err, "Frame buffer validation");
+
 		uint8_t color = 0;
 		uint8_t depth = 0;
 
@@ -4337,60 +4354,104 @@ namespace bgfx
 
 		const uint16_t firstAttachmentWidth  = bx::max<uint16_t>(firstTexture.m_width  >> _attachment[0].mip, 1);
 		const uint16_t firstAttachmentHeight = bx::max<uint16_t>(firstTexture.m_height >> _attachment[0].mip, 1);
-		BX_UNUSED(firstAttachmentWidth, firstAttachmentHeight);
 
 		for (uint32_t ii = 0; ii < _num; ++ii)
 		{
-			const TextureHandle texHandle = _attachment[ii].handle;
-			BGFX_CHECK_HANDLE("createFrameBuffer texture", s_ctx->m_textureHandle, texHandle);
+			const Attachment&   at = _attachment[ii];
+			const TextureHandle texHandle = at.handle;
 			const TextureRef& tr = s_ctx->m_textureRef[texHandle.idx];
 
-			BX_ASSERT(_attachment[ii].mip < tr.m_numMips
-				, "Invalid texture mip level (%d > %d)."
-				, _attachment[ii].mip
-				, tr.m_numMips - 1
+			BGFX_ERROR_CHECK(true
+				&& isValid(texHandle)
+				&& s_ctx->m_textureHandle.isValid(texHandle.idx)
+				, _err
+				, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+				, "Invalid texture attachment."
+				, "Attachment %d, texture handle %d."
+				, ii
+				, texHandle.idx
 				);
 
-			const uint16_t numLayers = tr.is3D()
-				? bx::max<uint16_t>(tr.m_depth >> _attachment[ii].mip, 1)
-				: tr.m_numLayers * (tr.isCubeMap() ? 6 : 1)
-				;
-			BX_UNUSED(numLayers);
-
-			BX_ASSERT( (_attachment[ii].layer + _attachment[ii].numLayers) <= numLayers
-				, "Invalid texture layer range (layer %d + num %d > total %d)."
-				, _attachment[ii].layer
-				, _attachment[ii].numLayers
-				, numLayers
+			BGFX_ERROR_CHECK(
+				  at.mip < tr.m_numMips
+				, _err
+				, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+				, "Invalid texture mip level."
+				, "Attachment %d, Mip %d, texture number of mips %d."
+				, ii
+				, at.mip
+				, tr.m_numMips
 				);
 
-			BX_ASSERT(_attachment[0].numLayers == _attachment[ii].numLayers
-				, "Mismatch in attachment layer count (%d != %d)."
-				, _attachment[ii].numLayers
+			{
+				const uint16_t numLayers = tr.is3D()
+					? bx::max<uint16_t>(tr.m_depth >> at.mip, 1)
+					: tr.m_numLayers * (tr.isCubeMap() ? 6 : 1)
+					;
+
+				BGFX_ERROR_CHECK(
+					(at.layer + at.numLayers) <= numLayers
+					, _err
+					, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+					, "Invalid texture layer range."
+					, "Attachment %d, Layer: %d, Num: %d, Max number of layers: %d."
+					, ii
+					, at.layer
+					, at.numLayers
+					, numLayers
+					);
+			}
+
+			BGFX_ERROR_CHECK(
+				  _attachment[0].numLayers == at.numLayers
+				, _err
+				, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+				, "Mismatch in attachment layer count."
+				, "Attachment %d, Given: %d, Expected: %d."
+				, ii
+				, at.numLayers
 				, _attachment[0].numLayers
 				);
 
-			BX_ASSERT(firstTexture.m_bbRatio == tr.m_bbRatio
+			BGFX_ERROR_CHECK(
+				  firstTexture.m_bbRatio == tr.m_bbRatio
+				, _err
+				, BGFX_ERROR_FRAME_BUFFER_VALIDATION
 				, "Mismatch in texture back-buffer ratio."
+				, "Attachment %d, Given: %d, Expected: %d."
+				, ii
+				, tr.m_bbRatio
+				, firstTexture.m_bbRatio
 				);
 
-			BX_ASSERT(firstTexture.m_numSamples == tr.m_numSamples
-				, "Mismatch in texture sample count (%d != %d)."
+			BGFX_ERROR_CHECK(
+				  firstTexture.m_numSamples == tr.m_numSamples
+				, _err
+				, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+				, "Mismatch in texture sample count."
+				, "Attachment %d, Given: %d, Expected: %d."
+				, ii
 				, tr.m_numSamples
 				, firstTexture.m_numSamples
 				);
 
 			if (BackbufferRatio::Count == firstTexture.m_bbRatio)
 			{
-				const uint16_t width  = bx::max<uint16_t>(tr.m_width  >> _attachment[ii].mip, 1);
-				const uint16_t height = bx::max<uint16_t>(tr.m_height >> _attachment[ii].mip, 1);
-				BX_UNUSED(width, height);
-
-				BX_ASSERT(width == firstAttachmentWidth && height == firstAttachmentHeight
-					, "Mismatch in texture size (%dx%d != %dx%d)."
+				const uint16_t width  = bx::max<uint16_t>(tr.m_width  >> at.mip, 1);
+				const uint16_t height = bx::max<uint16_t>(tr.m_height >> at.mip, 1);
+
+				BGFX_ERROR_CHECK(true
+					&& width  == firstAttachmentWidth
+					&& height == firstAttachmentHeight
+					, _err
+					, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+					, "Mismatch in texture size."
+					, "Attachment %d, Given: %dx%d, Expected: %dx%d."
+					, ii
 					, width
 					, height
-					, firstAttachmentWidth, firstAttachmentHeight
+					, firstAttachmentWidth
+					, firstAttachmentHeight
 					);
 			}
 
@@ -4403,70 +4464,98 @@ namespace bgfx
 				++color;
 			}
 
-			BX_ASSERT(0 == (tr.m_flags & BGFX_TEXTURE_READ_BACK)
-				, "Frame buffer texture cannot be read back texture. Attachment %d: has flags 0x%016" PRIx64 "."
+			BGFX_ERROR_CHECK(
+				  0 == (tr.m_flags & BGFX_TEXTURE_READ_BACK)
+				, _err
+				, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+				, "Frame buffer texture cannot be created with `BGFX_TEXTURE_READ_BACK`."
+				, "Attachment %d, texture flags 0x%016" PRIx64 "."
 				, ii
 				, tr.m_flags
 				);
 
-			BX_ASSERT(0 != (tr.m_flags & BGFX_TEXTURE_RT_MASK)
-				, "Frame buffer texture is not created with one of `BGFX_TEXTURE_RT*` flags. Attachment %d: has flags 0x%016" PRIx64 "."
+			BGFX_ERROR_CHECK(
+				  0 != (tr.m_flags & BGFX_TEXTURE_RT_MASK)
+				, _err
+				, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+				, "Frame buffer texture is not created with one of `BGFX_TEXTURE_RT*` flags."
+				, "Attachment %d, texture flags 0x%016" PRIx64 "."
 				, ii
 				, tr.m_flags
 				);
 		}
 
-		BX_ASSERT(true
-			&& color <= g_caps.limits.maxFBAttachments
-			&& depth <= 1
-			, "Too many frame buffer attachments (num attachments: %d, max color attachments %d)!"
+		BGFX_ERROR_CHECK(
+			  color <= g_caps.limits.maxFBAttachments
+			, _err
+			, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+			, "Too many frame buffer color attachments."
+			, "Num: %d, Max: %d."
 			, _num
 			, g_caps.limits.maxFBAttachments
 			);
+
+		BGFX_ERROR_CHECK(
+			  depth <= 1
+			, _err
+			, BGFX_ERROR_FRAME_BUFFER_VALIDATION
+			, "There can be only one depth texture attachment."
+			, "Num depth attachments %d."
+			, depth
+			);
+	}
+
+	bool isFrameBufferValid(uint8_t _num, const Attachment* _attachment)
+	{
+		BGFX_MUTEX_SCOPE(s_ctx->m_resourceApiLock);
+		bx::Error err;
+		isFrameBufferValid(_num, _attachment, &err);
+		return err.isOk();
 	}
 
 	static void isTextureValid(uint16_t _depth, bool _cubeMap, uint16_t _numLayers, TextureFormat::Enum _format, uint64_t _flags, bx::Error* _err)
 	{
-		BX_ERROR_SCOPE(_err);
+		BX_ERROR_SCOPE(_err, "Texture validation");
 
 		const bool is3DTexture = 1 < _depth;
 
-		if (_cubeMap && is3DTexture)
-		{
-			_err->setError(BGFX_ERROR_TEXTURE_VALIDATION
-				, "Texture can't be depth and cube map at the same time."
-				);
-			return;
-		}
+		BGFX_ERROR_CHECK(false
+			|| !_cubeMap
+			|| !is3DTexture
+			, _err
+			, BGFX_ERROR_TEXTURE_VALIDATION
+			, "Texture can't be 3D and cube map at the same time."
+			, ""
+			);
 
-		if (is3DTexture
-		&& 	0 == (g_caps.supported & BGFX_CAPS_TEXTURE_3D) )
-		{
-			_err->setError(BGFX_ERROR_TEXTURE_VALIDATION
-				, "Texture3D is not supported! "
-				  "Use bgfx::getCaps to check BGFX_CAPS_TEXTURE_3D backend renderer capabilities."
-				);
-			return;
-		}
+		BGFX_ERROR_CHECK(false
+			|| is3DTexture
+			|| 0 != (g_caps.supported & BGFX_CAPS_TEXTURE_3D)
+			, _err
+			, BGFX_ERROR_TEXTURE_VALIDATION
+			, "Texture3D is not supported! "
+			  "Use bgfx::getCaps to check `BGFX_CAPS_TEXTURE_3D` backend renderer capabilities."
+			, ""
+			);
 
-		if (0 != (_flags & BGFX_TEXTURE_RT_MASK)
-		&&  0 != (_flags & BGFX_TEXTURE_READ_BACK) )
-		{
-			_err->setError(BGFX_ERROR_TEXTURE_VALIDATION
-				, "Can't create render target with BGFX_TEXTURE_READ_BACK flag."
-				);
-			return;
-		}
+		BGFX_ERROR_CHECK(false
+			|| 0 == (_flags & BGFX_TEXTURE_RT_MASK)
+			|| 0 == (_flags & BGFX_TEXTURE_READ_BACK)
+			, _err
+			, BGFX_ERROR_TEXTURE_VALIDATION
+			, "Can't create render target with `BGFX_TEXTURE_READ_BACK` flag."
+			, ""
+			);
 
-		if (1 < _numLayers
-		&&  0 == (g_caps.supported & BGFX_CAPS_TEXTURE_2D_ARRAY) )
-		{
-			_err->setError(BGFX_ERROR_TEXTURE_VALIDATION
-				, "Texture array is not supported! "
-				  "Use bgfx::getCaps to check BGFX_CAPS_TEXTURE_2D_ARRAY backend renderer capabilities."
-				);
-			return;
-		}
+		BGFX_ERROR_CHECK(false
+			|| 1 >= _numLayers
+			|| 0 != (g_caps.supported & BGFX_CAPS_TEXTURE_2D_ARRAY)
+			, _err
+			, BGFX_ERROR_TEXTURE_VALIDATION
+			, "Texture array is not supported! "
+			  "Use bgfx::getCaps to check `BGFX_CAPS_TEXTURE_2D_ARRAY` backend renderer capabilities."
+			, ""
+			);
 
 		bool formatSupported;
 		if (0 != (_flags & (BGFX_TEXTURE_RT | BGFX_TEXTURE_RT_WRITE_ONLY)) )
@@ -4511,36 +4600,36 @@ namespace bgfx
 				) );
 		}
 
-		if (!formatSupported)
-		{
-			_err->setError(BGFX_ERROR_TEXTURE_VALIDATION
-				, "Texture format is not supported! "
-				  "Use bgfx::isTextureValid to check support for texture format before creating it."
-				);
-			return;
-		}
+		BGFX_ERROR_CHECK(
+			  formatSupported
+			, _err
+			, BGFX_ERROR_TEXTURE_VALIDATION
+			, "Texture format is not supported! "
+			  "Use bgfx::isTextureValid to check support for texture format before creating it."
+			, ""
+			);
 
-		if (0 != (_flags & BGFX_TEXTURE_MSAA_SAMPLE)
-		&&  0 == (g_caps.formats[_format] & BGFX_CAPS_FORMAT_TEXTURE_MSAA) )
-		{
-			_err->setError(BGFX_ERROR_TEXTURE_VALIDATION
-				, "MSAA sampling for this texture format is not supported."
-				);
-			return;
-		}
+		BGFX_ERROR_CHECK(false
+			|| 0 == (_flags & BGFX_TEXTURE_MSAA_SAMPLE)
+			|| 0 != (g_caps.formats[_format] & BGFX_CAPS_FORMAT_TEXTURE_MSAA)
+			, _err
+			, BGFX_ERROR_TEXTURE_VALIDATION
+			, "MSAA sampling for this texture format is not supported."
+			, ""
+			);
 
-		if (0 != (_flags & BGFX_TEXTURE_SRGB)
-		&&  0 == (g_caps.formats[_format] & srgbCaps & (0
-				| BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB
-				| BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB
-				| BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB
-				) ) )
-		{
-			_err->setError(BGFX_ERROR_TEXTURE_VALIDATION
-				, "sRGB sampling for this texture format is not supported."
-				);
-			return;
-		}
+		BGFX_ERROR_CHECK(false
+			|| 0 == (_flags & BGFX_TEXTURE_SRGB)
+			|| 0 != (g_caps.formats[_format] & srgbCaps & (0
+					| BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB
+					| BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB
+					| BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB
+					) )
+			, _err
+			, BGFX_ERROR_TEXTURE_VALIDATION
+			, "sRGB sampling for this texture format is not supported."
+			, ""
+			);
 	}
 
 	bool isTextureValid(uint16_t _depth, bool _cubeMap, uint16_t _numLayers, TextureFormat::Enum _format, uint64_t _flags)

+ 6 - 0
src/bgfx.idl.inl

@@ -433,6 +433,11 @@ BGFX_C_API bool bgfx_is_texture_valid(uint16_t _depth, bool _cubeMap, uint16_t _
 	return bgfx::isTextureValid(_depth, _cubeMap, _numLayers, (bgfx::TextureFormat::Enum)_format, _flags);
 }
 
+BGFX_C_API bool bgfx_is_frame_buffer_valid(uint8_t _num, const bgfx_attachment_t* _attachment)
+{
+	return bgfx::isFrameBufferValid(_num, (const bgfx::Attachment*)_attachment);
+}
+
 BGFX_C_API void bgfx_calc_texture_size(bgfx_texture_info_t * _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format)
 {
 	bgfx::TextureInfo & info = *(bgfx::TextureInfo *)_info;
@@ -1316,6 +1321,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version)
 			bgfx_create_compute_program,
 			bgfx_destroy_program,
 			bgfx_is_texture_valid,
+			bgfx_is_frame_buffer_valid,
 			bgfx_calc_texture_size,
 			bgfx_create_texture,
 			bgfx_create_texture_2d,

+ 9 - 2
src/bgfx_p.h

@@ -73,7 +73,6 @@ namespace bgfx
 #endif // BX_COMPILER_CLANG_ANALYZER
 
 	void trace(const char* _filePath, uint16_t _line, const char* _format, ...);
-	void checkFrameBuffer(uint8_t _num, const Attachment* _attachment);
 
 	inline bool operator==(const VertexLayoutHandle& _lhs, const VertexLayoutHandle& _rhs) { return _lhs.idx == _rhs.idx; }
 	inline bool operator==(const UniformHandle& _lhs,    const UniformHandle&    _rhs) { return _lhs.idx == _rhs.idx; }
@@ -114,6 +113,7 @@ namespace bgfx
 #include <bx/cpu.h>
 #include <bx/debug.h>
 #include <bx/endian.h>
+#include <bx/error.h>
 #include <bx/float4x4_t.h>
 #include <bx/handlealloc.h>
 #include <bx/hash.h>
@@ -279,6 +279,7 @@ namespace bgfx
 	extern InternalData g_internalData;
 	extern PlatformData g_platformData;
 	extern bool g_platformDataChangedSinceReset;
+	extern void isFrameBufferValid(uint8_t _num, const Attachment* _attachment, bx::Error* _err);
 
 #if BGFX_CONFIG_MAX_DRAW_CALLS < (64<<10)
 	typedef uint16_t RenderItemCount;
@@ -4534,7 +4535,13 @@ namespace bgfx
 		{
 			BGFX_MUTEX_SCOPE(m_resourceApiLock);
 
-			checkFrameBuffer(_num, _attachment);
+			bx::Error err;
+			isFrameBufferValid(_num, _attachment, &err);
+
+			if (!err.isOk() )
+			{
+				return BGFX_INVALID_HANDLE;
+			}
 
 			FrameBufferHandle handle = { m_frameBufferHandle.alloc() };
 			BX_WARN(isValid(handle), "Failed to allocate frame buffer handle.");