Browse Source

Merge pull request #33518 from BastiaanOlij/msaa_ext_modes

Add MSAA mode for Quest
Rémi Verschelde 5 years ago
parent
commit
4b8feff594

+ 6 - 0
doc/classes/VisualServer.xml

@@ -4238,6 +4238,12 @@
 		<constant name="VIEWPORT_MSAA_16X" value="4" enum="ViewportMSAA">
 		<constant name="VIEWPORT_MSAA_16X" value="4" enum="ViewportMSAA">
 			Multisample antialiasing is set to 16×.
 			Multisample antialiasing is set to 16×.
 		</constant>
 		</constant>
+		<constant name="VIEWPORT_MSAA_EXT_2X" value="5" enum="ViewportMSAA">
+			Multisample antialiasing is set to 2× on external texture. Special mode for GLES2 VR for the Oculus Quest.
+		</constant>
+		<constant name="VIEWPORT_MSAA_EXT_4X" value="6" enum="ViewportMSAA">
+			Multisample antialiasing is set to 4× on external texture. Special mode for GLES2 VR for the Oculus Quest.
+		</constant>
 		<constant name="VIEWPORT_USAGE_2D" value="0" enum="ViewportUsage">
 		<constant name="VIEWPORT_USAGE_2D" value="0" enum="ViewportUsage">
 			The Viewport does not render 3D but samples.
 			The Viewport does not render 3D but samples.
 		</constant>
 		</constant>

+ 42 - 9
drivers/gles2/rasterizer_storage_gles2.cpp

@@ -4694,7 +4694,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
 	/* For MSAA */
 	/* For MSAA */
 
 
 #ifndef JAVASCRIPT_ENABLED
 #ifndef JAVASCRIPT_ENABLED
-	if (rt->msaa != VS::VIEWPORT_MSAA_DISABLED && config.multisample_supported) {
+	if (rt->msaa >= VS::VIEWPORT_MSAA_2X && rt->msaa <= VS::VIEWPORT_MSAA_16X && config.multisample_supported) {
 
 
 		rt->multisample_active = true;
 		rt->multisample_active = true;
 
 
@@ -5090,6 +5090,11 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar
 			// free this
 			// free this
 			glDeleteFramebuffers(1, &rt->external.fbo);
 			glDeleteFramebuffers(1, &rt->external.fbo);
 
 
+			// and this
+			if (rt->external.depth != 0) {
+				glDeleteRenderbuffers(1, &rt->external.depth);
+			}
+
 			// clean up our texture
 			// clean up our texture
 			Texture *t = texture_owner.get(rt->external.texture);
 			Texture *t = texture_owner.get(rt->external.texture);
 			t->alloc_height = 0;
 			t->alloc_height = 0;
@@ -5102,6 +5107,7 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar
 
 
 			rt->external.fbo = 0;
 			rt->external.fbo = 0;
 			rt->external.color = 0;
 			rt->external.color = 0;
+			rt->external.depth = 0;
 		}
 		}
 	} else {
 	} else {
 		Texture *t;
 		Texture *t;
@@ -5136,6 +5142,7 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar
 			t->render_target = rt;
 			t->render_target = rt;
 
 
 			rt->external.texture = texture_owner.make_rid(t);
 			rt->external.texture = texture_owner.make_rid(t);
+
 		} else {
 		} else {
 			// bind our frame buffer
 			// bind our frame buffer
 			glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo);
 			glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo);
@@ -5154,16 +5161,42 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar
 		t->alloc_height = rt->width;
 		t->alloc_height = rt->width;
 		t->alloc_width = rt->height;
 		t->alloc_width = rt->height;
 
 
-		// is there a point to setting the internal formats? we don't know them..
+		// Switch our texture on our frame buffer
+#if ANDROID_ENABLED
+		if (rt->msaa >= VS::VIEWPORT_MSAA_EXT_2X && rt->msaa <= VS::VIEWPORT_MSAA_EXT_4X) {
+			// This code only applies to the Oculus Go and Oculus Quest. Due to the the tiled nature
+			// of the GPU we can do a single render pass by rendering directly into our texture chains
+			// texture and apply MSAA as we render.
+
+			// On any other hardware these two modes are ignored and we do not have any MSAA,
+			// the normal MSAA modes need to be used to enable our two pass approach
+
+			static const int msaa_value[] = { 2, 4 };
+			int msaa = msaa_value[rt->msaa - VS::VIEWPORT_MSAA_EXT_2X];
+
+			if (rt->external.depth == 0) {
+				// create a multisample depth buffer, we're not reusing Godots because Godot's didn't get created..
+				glGenRenderbuffers(1, &rt->external.depth);
+				glBindRenderbuffer(GL_RENDERBUFFER, rt->external.depth);
+				glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config.depth_internalformat, rt->width, rt->height);
+				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->external.depth);
+			}
 
 
-		// set our texture as the destination for our framebuffer
-		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0);
+			// and set our external texture as the texture...
+			glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0, msaa);
 
 
-		// seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :)
-		if (config.support_depth_texture) {
-			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
-		} else {
-			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+		} else
+#endif
+		{
+			// set our texture as the destination for our framebuffer
+			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0);
+
+			// seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :)
+			if (config.support_depth_texture) {
+				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
+			} else {
+				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+			}
 		}
 		}
 
 
 		// check status and unbind
 		// check status and unbind

+ 4 - 1
drivers/gles2/rasterizer_storage_gles2.h

@@ -1182,10 +1182,13 @@ public:
 		struct External {
 		struct External {
 			GLuint fbo;
 			GLuint fbo;
 			GLuint color;
 			GLuint color;
+			GLuint depth;
 			RID texture;
 			RID texture;
 
 
 			External() :
 			External() :
-					fbo(0) {
+					fbo(0),
+					color(0),
+					depth(0) {
 			}
 			}
 		} external;
 		} external;
 
 

+ 1 - 1
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -6961,7 +6961,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
 
 
 		rt->buffers.active = true;
 		rt->buffers.active = true;
 
 
-		static const int msaa_value[] = { 0, 2, 4, 8, 16 };
+		static const int msaa_value[] = { 0, 2, 4, 8, 16, 4, 16 }; // MSAA_EXT_nX is a GLES2 temporary hack ignored in GLES3 for now...
 		int msaa = msaa_value[rt->msaa];
 		int msaa = msaa_value[rt->msaa];
 
 
 		int max_samples = 0;
 		int max_samples = 0;

+ 1 - 1
scene/main/scene_tree.cpp

@@ -2066,7 +2066,7 @@ SceneTree::SceneTree() {
 	int ref_atlas_subdiv = GLOBAL_DEF("rendering/quality/reflections/atlas_subdiv", 8);
 	int ref_atlas_subdiv = GLOBAL_DEF("rendering/quality/reflections/atlas_subdiv", 8);
 	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_subdiv", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_subdiv", PROPERTY_HINT_RANGE, "0,32,or_greater")); //next_power_of_2 will return a 0 as min value
 	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_subdiv", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_subdiv", PROPERTY_HINT_RANGE, "0,32,or_greater")); //next_power_of_2 will return a 0 as min value
 	int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0);
 	int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0);
-	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"));
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,External 2x,External 4x"));
 	root->set_msaa(Viewport::MSAA(msaa_mode));
 	root->set_msaa(Viewport::MSAA(msaa_mode));
 
 
 	GLOBAL_DEF("rendering/quality/depth/hdr", true);
 	GLOBAL_DEF("rendering/quality/depth/hdr", true);

+ 2 - 2
scene/main/viewport.cpp

@@ -2955,7 +2955,7 @@ int Viewport::gui_get_canvas_sort_index() {
 
 
 void Viewport::set_msaa(MSAA p_msaa) {
 void Viewport::set_msaa(MSAA p_msaa) {
 
 
-	ERR_FAIL_INDEX(p_msaa, 5);
+	ERR_FAIL_INDEX(p_msaa, 7);
 	if (msaa == p_msaa)
 	if (msaa == p_msaa)
 		return;
 		return;
 	msaa = p_msaa;
 	msaa = p_msaa;
@@ -3187,7 +3187,7 @@ void Viewport::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
 	ADD_GROUP("Rendering", "");
 	ADD_GROUP("Rendering", "");
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"), "set_msaa", "get_msaa");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,External 2x,External 4x"), "set_msaa", "get_msaa");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_3d_linear"), "set_keep_3d_linear", "get_keep_3d_linear");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_3d_linear"), "set_keep_3d_linear", "get_keep_3d_linear");

+ 2 - 0
servers/visual_server.cpp

@@ -2171,6 +2171,8 @@ void VisualServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(VIEWPORT_MSAA_4X);
 	BIND_ENUM_CONSTANT(VIEWPORT_MSAA_4X);
 	BIND_ENUM_CONSTANT(VIEWPORT_MSAA_8X);
 	BIND_ENUM_CONSTANT(VIEWPORT_MSAA_8X);
 	BIND_ENUM_CONSTANT(VIEWPORT_MSAA_16X);
 	BIND_ENUM_CONSTANT(VIEWPORT_MSAA_16X);
+	BIND_ENUM_CONSTANT(VIEWPORT_MSAA_EXT_2X);
+	BIND_ENUM_CONSTANT(VIEWPORT_MSAA_EXT_4X);
 
 
 	BIND_ENUM_CONSTANT(VIEWPORT_USAGE_2D);
 	BIND_ENUM_CONSTANT(VIEWPORT_USAGE_2D);
 	BIND_ENUM_CONSTANT(VIEWPORT_USAGE_2D_NO_SAMPLING);
 	BIND_ENUM_CONSTANT(VIEWPORT_USAGE_2D_NO_SAMPLING);

+ 2 - 0
servers/visual_server.h

@@ -658,6 +658,8 @@ public:
 		VIEWPORT_MSAA_4X,
 		VIEWPORT_MSAA_4X,
 		VIEWPORT_MSAA_8X,
 		VIEWPORT_MSAA_8X,
 		VIEWPORT_MSAA_16X,
 		VIEWPORT_MSAA_16X,
+		VIEWPORT_MSAA_EXT_2X,
+		VIEWPORT_MSAA_EXT_4X,
 	};
 	};
 
 
 	virtual void viewport_set_msaa(RID p_viewport, ViewportMSAA p_msaa) = 0;
 	virtual void viewport_set_msaa(RID p_viewport, ViewportMSAA p_msaa) = 0;