Преглед на файлове

WIP: Getting OpenGL up to date
- Framebuffer pixel format evaluation no longer tests for non-normalized integer formats as they cause an error
- Shader compiler will now properly add 'flat' modifier for integer shader outputs/inputs when translating to GLSL
- Updated XShaderCompiler

BearishSun преди 8 години
родител
ревизия
a799813ebc

+ 5 - 0
Source/BansheeCore/Image/BsPixelUtil.cpp

@@ -1414,6 +1414,11 @@ namespace bs
 		return (PixelUtil::getFlags(format) & PFF_COMPRESSED) > 0;
 	}
 
+	bool PixelUtil::isNormalized(PixelFormat format)
+	{
+		return (PixelUtil::getFlags(format) & PFF_NORMALIZED) > 0;
+	}
+
 	bool PixelUtil::isDepth(PixelFormat format)
 	{
 		return (PixelUtil::getFlags(format) & PFF_DEPTH) > 0;

+ 3 - 0
Source/BansheeCore/Image/BsPixelUtil.h

@@ -126,6 +126,9 @@ namespace bs
 		/**	Checks is the provided pixel format a depth/stencil buffer format. */
 		static bool isDepth(PixelFormat format);
 
+		/** Checks does the provided format store data in normalized range. */
+		static bool isNormalized(PixelFormat format);
+
 		/** 
 		 * Checks is the provided format valid for the texture type and usage. 
 		 * 

+ 199 - 195
Source/BansheeGLRenderAPI/BsGLRenderTexture.cpp

@@ -139,12 +139,12 @@ namespace bs
 
 	GLRTTManager::GLRTTManager()
 		:mBlitReadFBO(0), mBlitWriteFBO(0)
-    {
+	{
 		detectFBOFormats();
 		
 		glGenFramebuffers(1, &mBlitReadFBO);
 		glGenFramebuffers(1, &mBlitWriteFBO);
-    }
+	}
 
 	GLRTTManager::~GLRTTManager()
 	{
@@ -153,148 +153,152 @@ namespace bs
 	}
 
 	bool GLRTTManager::_tryFormat(GLenum depthFormat, GLenum stencilFormat)
-    {
-        GLuint status, depthRB = 0, stencilRB = 0;
-        bool failed = false;
-
-        if(depthFormat != GL_NONE)
-        {
-            // Generate depth renderbuffer
-            glGenRenderbuffers(1, &depthRB);
-
-            // Bind it to FBO
-            glBindRenderbuffer(GL_RENDERBUFFER, depthRB);
-            
-            // Allocate storage for depth buffer
-            glRenderbufferStorage(GL_RENDERBUFFER, depthFormat,
-                                PROBE_SIZE, PROBE_SIZE);
-            
-            // Attach depth
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                    GL_RENDERBUFFER, depthRB);
-        }
-
-        if(stencilFormat != GL_NONE)
-        {
-            // Generate stencil renderbuffer
-            glGenRenderbuffers(1, &stencilRB);
-
-            // Bind it to FBO
-            glBindRenderbuffer(GL_RENDERBUFFER, stencilRB);
-            glGetError(); 
-
-            // Allocate storage for stencil buffer
-            glRenderbufferStorage(GL_RENDERBUFFER, stencilFormat,
-                                PROBE_SIZE, PROBE_SIZE); 
-
-            if(glGetError() != GL_NO_ERROR)
-                failed = true;
-
-            // Attach stencil
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                            GL_RENDERBUFFER, stencilRB);
-
-            if(glGetError() != GL_NO_ERROR)
-                failed = true;
-        }
-        
-        status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-
-        // Detach and destroy
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
-
-        if (depthRB)
-            glDeleteRenderbuffers(1, &depthRB);
-
-        if (stencilRB)
-            glDeleteRenderbuffers(1, &stencilRB);
-        
-        return status == GL_FRAMEBUFFER_COMPLETE && !failed;
-    }
-    
-    bool GLRTTManager::_tryPackedFormat(GLenum packedFormat)
-    {
-        GLuint packedRB = 0;
-        bool failed = false; // flag on GL errors
-
-        // Generate renderbuffer
-        glGenRenderbuffers(1, &packedRB);
-
-        // Bind it to FBO
-        glBindRenderbuffer(GL_RENDERBUFFER, packedRB);
-
-        // Allocate storage for buffer
-        glRenderbufferStorage(GL_RENDERBUFFER, packedFormat, PROBE_SIZE, PROBE_SIZE);
-        glGetError();
-
-        // Attach depth
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-            GL_RENDERBUFFER, packedRB);
-
-        if(glGetError() != GL_NO_ERROR)
-            failed = true;
-
-        // Attach stencil
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-            GL_RENDERBUFFER, packedRB);
-
-        if(glGetError() != GL_NO_ERROR)
-            failed = true;
-
-        GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-
-        // Detach and destroy
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
-        glDeleteRenderbuffers(1, &packedRB);
-
-        return status == GL_FRAMEBUFFER_COMPLETE && !failed;
-    }
-
-    void GLRTTManager::detectFBOFormats()
-    {
-        // Try all formats, and report which ones work as target
-        GLuint fb = 0, tid = 0;
-        GLint oldDrawbuffer = 0, oldReadbuffer = 0;
-        GLenum target = GL_TEXTURE_2D;
-
-        glGetIntegerv (GL_DRAW_BUFFER, &oldDrawbuffer);
-        glGetIntegerv (GL_READ_BUFFER, &oldReadbuffer);
-
-        for(size_t x=0; x<PF_COUNT; ++x)
-        {
-            mProps[x].valid = false;
+	{
+		GLuint status, depthRB = 0, stencilRB = 0;
+		bool failed = false;
+
+		if (depthFormat != GL_NONE)
+		{
+			// Generate depth renderbuffer
+			glGenRenderbuffers(1, &depthRB);
+
+			// Bind it to FBO
+			glBindRenderbuffer(GL_RENDERBUFFER, depthRB);
+
+			// Allocate storage for depth buffer
+			glRenderbufferStorage(GL_RENDERBUFFER, depthFormat,
+				PROBE_SIZE, PROBE_SIZE);
+
+			// Attach depth
+			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+				GL_RENDERBUFFER, depthRB);
+		}
+
+		if (stencilFormat != GL_NONE)
+		{
+			// Generate stencil renderbuffer
+			glGenRenderbuffers(1, &stencilRB);
+
+			// Bind it to FBO
+			glBindRenderbuffer(GL_RENDERBUFFER, stencilRB);
+			glGetError();
+
+			// Allocate storage for stencil buffer
+			glRenderbufferStorage(GL_RENDERBUFFER, stencilFormat,
+				PROBE_SIZE, PROBE_SIZE);
+
+			if (glGetError() != GL_NO_ERROR)
+				failed = true;
+
+			// Attach stencil
+			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+				GL_RENDERBUFFER, stencilRB);
+
+			if (glGetError() != GL_NO_ERROR)
+				failed = true;
+		}
+
+		status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+		// Detach and destroy
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+
+		if (depthRB)
+			glDeleteRenderbuffers(1, &depthRB);
+
+		if (stencilRB)
+			glDeleteRenderbuffers(1, &stencilRB);
+
+		return status == GL_FRAMEBUFFER_COMPLETE && !failed;
+	}
+
+	bool GLRTTManager::_tryPackedFormat(GLenum packedFormat)
+	{
+		GLuint packedRB = 0;
+		bool failed = false; // flag on GL errors
+
+		// Generate renderbuffer
+		glGenRenderbuffers(1, &packedRB);
+
+		// Bind it to FBO
+		glBindRenderbuffer(GL_RENDERBUFFER, packedRB);
+
+		// Allocate storage for buffer
+		glRenderbufferStorage(GL_RENDERBUFFER, packedFormat, PROBE_SIZE, PROBE_SIZE);
+		glGetError();
+
+		// Attach depth
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+			GL_RENDERBUFFER, packedRB);
+
+		if (glGetError() != GL_NO_ERROR)
+			failed = true;
+
+		// Attach stencil
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+			GL_RENDERBUFFER, packedRB);
+
+		if (glGetError() != GL_NO_ERROR)
+			failed = true;
+
+		GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+		// Detach and destroy
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+		glDeleteRenderbuffers(1, &packedRB);
+
+		return status == GL_FRAMEBUFFER_COMPLETE && !failed;
+	}
+
+	void GLRTTManager::detectFBOFormats()
+	{
+		// Try all formats, and report which ones work as target
+		GLuint fb = 0, tid = 0;
+		GLint oldDrawbuffer = 0, oldReadbuffer = 0;
+		GLenum target = GL_TEXTURE_2D;
+
+		glGetIntegerv(GL_DRAW_BUFFER, &oldDrawbuffer);
+		glGetIntegerv(GL_READ_BUFFER, &oldReadbuffer);
+
+		for (size_t x = 0; x < PF_COUNT; ++x)
+		{
+			mProps[x].valid = false;
 
 			// Fetch GL format token
 			GLenum fmt = GLPixelUtil::getGLInternalFormat((PixelFormat)x);
-            if(fmt == GL_NONE && x!=0)
-                continue;
+			if (fmt == GL_NONE && x != 0)
+				continue;
 
 			// No test for compressed formats
 			if(PixelUtil::isCompressed((PixelFormat)x))
 				continue;
 
-            // Create and attach framebuffer
-            glGenFramebuffers(1, &fb);
-            glBindFramebuffer(GL_FRAMEBUFFER, fb);
-            if (fmt!=GL_NONE && !PixelUtil::isDepth((PixelFormat)x))
-            {
+			// No test for unnormalized integer targets
+			if (!PixelUtil::isNormalized((PixelFormat)x) && !PixelUtil::isFloatingPoint((PixelFormat)x))
+				continue;
+
+			// Create and attach framebuffer
+			glGenFramebuffers(1, &fb);
+			glBindFramebuffer(GL_FRAMEBUFFER, fb);
+			if (fmt != GL_NONE && !PixelUtil::isDepth((PixelFormat)x))
+			{
 				// Create and attach texture
 				glGenTextures(1, &tid);
 				glBindTexture(target, tid);
 				
-                // Set some default parameters so it won't fail on NVidia cards         
+				// Set some default parameters so it won't fail on NVidia cards         
 				if (GLEW_VERSION_1_2)
 					glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
-                glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-                glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-                glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-                glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-                            
+				glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+				glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+				glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+				glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
 				glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
 				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, tid, 0);
-            }
+			}
 			else
 			{
 				// Draw to nowhere -- stencil/depth only
@@ -302,79 +306,79 @@ namespace bs
 				glReadBuffer(GL_NONE);
 			}
 
-            // Check status
-            GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+			// Check status
+			GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 
 			// Ignore status in case of fmt==GL_NONE, because no implementation will accept
 			// a buffer without *any* attachment. Buffers with only stencil and depth attachment
 			// might still be supported, so we must continue probing.
-            if(fmt == GL_NONE || status == GL_FRAMEBUFFER_COMPLETE)
-            {
-                mProps[x].valid = true;
-
-                // For each depth/stencil formats
-                for (UINT32 depth = 0; depth < DEPTHFORMAT_COUNT; ++depth)
-                {
-                    if (depthFormats[depth] != GL_DEPTH24_STENCIL8 && depthFormats[depth] != GL_DEPTH32F_STENCIL8)
-                    {
-                        if (_tryFormat(depthFormats[depth], GL_NONE))
-                        {
-                            /// Add mode to allowed modes
-                            FormatProperties::Mode mode;
-                            mode.depth = depth;
-                            mode.stencil = 0;
-                            mProps[x].modes.push_back(mode);
-                        }
-                    }
-                    else
-                    {
-                        // Packed depth/stencil format
-                        if (_tryPackedFormat(depthFormats[depth]))
-                        {
-                            /// Add mode to allowed modes
-                            FormatProperties::Mode mode;
-                            mode.depth = depth;
-                            mode.stencil = 0;   // unuse
-                            mProps[x].modes.push_back(mode);
-                        }
-                    }
-                }
-            }
-
-            // Delete texture and framebuffer
-            glBindFramebuffer(GL_FRAMEBUFFER, 0);
-            glDeleteFramebuffers(1, &fb);
+			if (fmt == GL_NONE || status == GL_FRAMEBUFFER_COMPLETE)
+			{
+				mProps[x].valid = true;
+
+				// For each depth/stencil formats
+				for (UINT32 depth = 0; depth < DEPTHFORMAT_COUNT; ++depth)
+				{
+					if (depthFormats[depth] != GL_DEPTH24_STENCIL8 && depthFormats[depth] != GL_DEPTH32F_STENCIL8)
+					{
+						if (_tryFormat(depthFormats[depth], GL_NONE))
+						{
+							/// Add mode to allowed modes
+							FormatProperties::Mode mode;
+							mode.depth = depth;
+							mode.stencil = 0;
+							mProps[x].modes.push_back(mode);
+						}
+					}
+					else
+					{
+						// Packed depth/stencil format
+						if (_tryPackedFormat(depthFormats[depth]))
+						{
+							/// Add mode to allowed modes
+							FormatProperties::Mode mode;
+							mode.depth = depth;
+							mode.stencil = 0;   // unuse
+							mProps[x].modes.push_back(mode);
+						}
+					}
+				}
+			}
+
+			// Delete texture and framebuffer
+			glBindFramebuffer(GL_FRAMEBUFFER, 0);
+			glDeleteFramebuffers(1, &fb);
 			
 			glFinish();
 			
-            if (fmt != GL_NONE)
-                glDeleteTextures(1, &tid);
-        }
-
-        glDrawBuffer(oldDrawbuffer);
-        glReadBuffer(oldReadbuffer);
-    }
-    
-    PixelFormat GLRTTManager::getSupportedAlternative(PixelFormat format)
-    {
-        if(checkFormat(format))
-            return format;
-
-        // Find first alternative
-        PixelComponentType pct = PixelUtil::getElementType(format);
-        switch(pct)
-        {
-        case PCT_BYTE: format = PF_RGBA8; break;
-        case PCT_FLOAT16: format = PF_RGBA16F; break;
-        case PCT_FLOAT32: format = PF_RGBA32F; break;
-        default: break;
-        }
-
-        if(checkFormat(format))
-            return format;
-
-        // If none at all, return to default
-        return PF_RGBA8;
-    }
+			if (fmt != GL_NONE)
+				glDeleteTextures(1, &tid);
+		}
+
+		glDrawBuffer(oldDrawbuffer);
+		glReadBuffer(oldReadbuffer);
+	}
+
+	PixelFormat GLRTTManager::getSupportedAlternative(PixelFormat format)
+	{
+		if (checkFormat(format))
+			return format;
+
+		// Find first alternative
+		PixelComponentType pct = PixelUtil::getElementType(format);
+		switch (pct)
+		{
+		case PCT_BYTE: format = PF_RGBA8; break;
+		case PCT_FLOAT16: format = PF_RGBA16F; break;
+		case PCT_FLOAT32: format = PF_RGBA32F; break;
+		default: break;
+		}
+
+		if (checkFormat(format))
+			return format;
+
+		// If none at all, return to default
+		return PF_RGBA8;
+	}
 	}
 }

+ 42 - 42
Source/BansheeGLRenderAPI/BsGLRenderTexture.h

@@ -10,7 +10,7 @@
 #define GL_DEPTH24_STENCIL8_EXT 0x88F0
 
 namespace bs
-{  
+{
 	/** @addtogroup GL
 	 *  @{
 	 */
@@ -43,8 +43,8 @@ namespace bs
 	 *
 	 * @note	Core thread only.
 	 */
-    class GLRenderTexture : public RenderTexture
-    {
+	class GLRenderTexture : public RenderTexture
+	{
 	public:
 		GLRenderTexture(const RENDER_TEXTURE_DESC& desc, UINT32 deviceIdx);
 		virtual ~GLRenderTexture();
@@ -63,66 +63,66 @@ namespace bs
 
 		RenderTextureProperties mProperties;
 		GLFrameBufferObject* mFB;
-    };
+	};
 
-    /**
-     * Manager that handles valid render texture formats.
-     * 			
+	/**
+	 * Manager that handles valid render texture formats.
+	 *
 	 * @note	Must be initialized when RenderSystem is first started.
-     */
-    class GLRTTManager : public Module<GLRTTManager>
-    {
-    public:
-        GLRTTManager();
+	 */
+	class GLRTTManager : public Module<GLRTTManager>
+	{
+	public:
+		GLRTTManager();
 		~GLRTTManager();
-        
-        /**
-         * Check if a certain format is usable as a render target format.
-         *
-         * @note	Thread safe.
-         */
-        bool checkFormat(PixelFormat format) const { return mProps[format].valid; }
-        
-        /**
-         * Get the closest supported alternative format. If format is supported, returns format.
-         *
-         * @note	Thread safe.
-         */
-        virtual PixelFormat getSupportedAlternative(PixelFormat format);
+
+		/**
+		 * Check if a certain format is usable as a render target format.
+		 *
+		 * @note	Thread safe.
+		 */
+		bool checkFormat(PixelFormat format) const { return mProps[format].valid; }
+
+		/**
+		 * Get the closest supported alternative format. If format is supported, returns format.
+		 *
+		 * @note	Thread safe.
+		 */
+		virtual PixelFormat getSupportedAlternative(PixelFormat format);
 
 		/** Returns a persistent FBO that is used as a source buffer for blit operations. */
 		GLuint getBlitReadFBO() const { return mBlitReadFBO; }
 
 		/** Returns a persistent FBO that is used as a destination buffer for blit operations. */
 		GLuint getBlitDrawFBO() const { return mBlitWriteFBO; }
-    private:
-        /** Frame buffer object properties for a certain texture format. */
-        struct FormatProperties
-        {
-            /** Allowed modes/properties for this pixel format. */
-            struct Mode
-            {
-                UINT32 depth;     /**< Depth format (0 = no depth). */
-                UINT32 stencil;   /**< Stencil format (0 = no stencil). */
-            };
-            
-            Vector<Mode> modes;
+	private:
+		/** Frame buffer object properties for a certain texture format. */
+		struct FormatProperties
+		{
+			/** Allowed modes/properties for this pixel format. */
+			struct Mode
+			{
+				UINT32 depth;     /**< Depth format (0 = no depth). */
+				UINT32 stencil;   /**< Stencil format (0 = no stencil). */
+			};
+
+			Vector<Mode> modes;
 			bool valid;
-        };
+		};
 
 		/** Detect which internal formats are allowed to be used on render target color or depth/stencil surfaces. */
-        void detectFBOFormats();
+		void detectFBOFormats();
 
 		/**	Checks are the specified depth & stencil formats compatible. */
 		bool _tryFormat(GLenum depthFormat, GLenum stencilFormat);
 
 		/**	Checks is the specified packed format valid for using in the render target. */
-        bool _tryPackedFormat(GLenum packedFormat);
+		bool _tryPackedFormat(GLenum packedFormat);
 
 		FormatProperties mProps[PF_COUNT];
 		GLuint mBlitReadFBO;
 		GLuint mBlitWriteFBO;
-    };
+	};
 	}
 	/** @} */
 }

+ 1 - 1
Source/CMakeLists.txt

@@ -6,7 +6,7 @@ set (BS_VERSION_MAJOR 0)
 set (BS_VERSION_MINOR 4)
 
 set (BS_PREBUILT_DEPENDENCIES_VERSION 7)
-set (BS_SRC_DEPENDENCIES_VERSION 13)
+set (BS_SRC_DEPENDENCIES_VERSION 14)
 
 # Configuration types
 if(CMAKE_CONFIGURATION_TYPES) # Multiconfig generator?

+ 1 - 1
Source/External/XShaderCompiler

@@ -1 +1 @@
-Subproject commit cc39e346339cc6d14852d9c34c5c3bb0fc0b1d5b
+Subproject commit cb706ed45fdeb1ec089af61c542d1dfc66349fec