Don't perform component swizzling on a null texture.

When sampling from an incomplete texture, the OpenGL spec states that
(0, 0, 0, 1) will be returned to the shader from the texture lookup
function. Swizzling is only described for filtered texture values.

Change-Id: Ie8a02b3b0b9e571fd2f86302e777a4ff985da022
Reviewed-on: https://swiftshader-review.googlesource.com/17488
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 7fd1f02..8301c1c 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3207,68 +3207,10 @@
 		case GL_TEXTURE_2D:
 		case GL_TEXTURE_EXTERNAL_OES:
 		case GL_TEXTURE_RECTANGLE_ARB:
-		{
-			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
-
-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
 			{
-				int surfaceLevel = mipmapLevel + baseLevel;
+				Texture2D *texture = static_cast<Texture2D*>(baseTexture);
 
-				if(surfaceLevel > maxLevel)
-				{
-					surfaceLevel = maxLevel;
-				}
-
-				egl::Image *surface = texture->getImage(surfaceLevel);
-				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
-			}
-		}
-		break;
-		case GL_TEXTURE_3D:
-		{
-			Texture3D *texture = static_cast<Texture3D*>(baseTexture);
-
-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
-			{
-				int surfaceLevel = mipmapLevel + baseLevel;
-
-				if(surfaceLevel > maxLevel)
-				{
-					surfaceLevel = maxLevel;
-				}
-
-				egl::Image *surface = texture->getImage(surfaceLevel);
-				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
-			}
-		}
-		break;
-		case GL_TEXTURE_2D_ARRAY:
-		{
-			Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
-
-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
-			{
-				int surfaceLevel = mipmapLevel + baseLevel;
-
-				if(surfaceLevel > maxLevel)
-				{
-					surfaceLevel = maxLevel;
-				}
-
-				egl::Image *surface = texture->getImage(surfaceLevel);
-				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
-			}
-		}
-		break;
-		case GL_TEXTURE_CUBE_MAP:
-		{
-			TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
-
-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
-			{
-				cubeTexture->updateBorders(mipmapLevel);
-
-				for(int face = 0; face < 6; face++)
+				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
 				{
 					int surfaceLevel = mipmapLevel + baseLevel;
 
@@ -3277,12 +3219,70 @@
 						surfaceLevel = maxLevel;
 					}
 
-					egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
-					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
+					egl::Image *surface = texture->getImage(surfaceLevel);
+					device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
 				}
 			}
-		}
-		break;
+			break;
+		case GL_TEXTURE_3D:
+			{
+				Texture3D *texture = static_cast<Texture3D*>(baseTexture);
+
+				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+				{
+					int surfaceLevel = mipmapLevel + baseLevel;
+
+					if(surfaceLevel > maxLevel)
+					{
+						surfaceLevel = maxLevel;
+					}
+
+					egl::Image *surface = texture->getImage(surfaceLevel);
+					device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
+				}
+			}
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			{
+				Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
+
+				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+				{
+					int surfaceLevel = mipmapLevel + baseLevel;
+
+					if(surfaceLevel > maxLevel)
+					{
+						surfaceLevel = maxLevel;
+					}
+
+					egl::Image *surface = texture->getImage(surfaceLevel);
+					device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
+				}
+			}
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			{
+				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
+
+				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+				{
+					cubeTexture->updateBorders(mipmapLevel);
+
+					for(int face = 0; face < 6; face++)
+					{
+						int surfaceLevel = mipmapLevel + baseLevel;
+
+						if(surfaceLevel > maxLevel)
+						{
+							surfaceLevel = maxLevel;
+						}
+
+						egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
+						device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
+					}
+				}
+			}
+			break;
 		default:
 			UNIMPLEMENTED();
 			break;
diff --git a/src/Shader/SamplerCore.cpp b/src/Shader/SamplerCore.cpp
index dbb4417..90aa984 100644
--- a/src/Shader/SamplerCore.cpp
+++ b/src/Shader/SamplerCore.cpp
@@ -131,144 +131,146 @@
 				convertFixed12(c, cf);
 			}
 
-			if(fixed12 && !hasFloatTexture())
+			if(fixed12)
 			{
-				if(state.textureFormat == FORMAT_R5G6B5)
+				if(!hasFloatTexture())
 				{
-					c.x = MulHigh(As<UShort4>(c.x), UShort4(0x10000000 / 0xF800));
-					c.y = MulHigh(As<UShort4>(c.y), UShort4(0x10000000 / 0xFC00));
-					c.z = MulHigh(As<UShort4>(c.z), UShort4(0x10000000 / 0xF800));
-				}
-				else
-				{
-					for(int component = 0; component < textureComponentCount(); component++)
+					if(state.textureFormat == FORMAT_R5G6B5)
 					{
-						if(hasUnsignedTextureComponent(component))
+						c.x = MulHigh(As<UShort4>(c.x), UShort4(0x10000000 / 0xF800));
+						c.y = MulHigh(As<UShort4>(c.y), UShort4(0x10000000 / 0xFC00));
+						c.z = MulHigh(As<UShort4>(c.z), UShort4(0x10000000 / 0xF800));
+					}
+					else
+					{
+						for(int component = 0; component < textureComponentCount(); component++)
 						{
-							c[component] = As<UShort4>(c[component]) >> 4;
-						}
-						else
-						{
-							c[component] = c[component] >> 3;
+							if(hasUnsignedTextureComponent(component))
+							{
+								c[component] = As<UShort4>(c[component]) >> 4;
+							}
+							else
+							{
+								c[component] = c[component] >> 3;
+							}
 						}
 					}
 				}
-			}
 
-			if(fixed12 && state.textureFilter != FILTER_GATHER)
-			{
-				int componentCount = textureComponentCount();
-				short defaultColorValue = colorsDefaultToZero ? 0x0000 : 0x1000;
-
-				switch(state.textureFormat)
+				if(state.textureFilter != FILTER_GATHER)
 				{
-				case FORMAT_R8_SNORM:
-				case FORMAT_G8R8_SNORM:
-				case FORMAT_X8B8G8R8_SNORM:
-				case FORMAT_A8B8G8R8_SNORM:
-				case FORMAT_R8:
-				case FORMAT_R5G6B5:
-				case FORMAT_G8R8:
-				case FORMAT_R8I:
-				case FORMAT_R8UI:
-				case FORMAT_G8R8I:
-				case FORMAT_G8R8UI:
-				case FORMAT_X8B8G8R8I:
-				case FORMAT_X8B8G8R8UI:
-				case FORMAT_A8B8G8R8I:
-				case FORMAT_A8B8G8R8UI:
-				case FORMAT_R16I:
-				case FORMAT_R16UI:
-				case FORMAT_G16R16:
-				case FORMAT_G16R16I:
-				case FORMAT_G16R16UI:
-				case FORMAT_X16B16G16R16I:
-				case FORMAT_X16B16G16R16UI:
-				case FORMAT_A16B16G16R16:
-				case FORMAT_A16B16G16R16I:
-				case FORMAT_A16B16G16R16UI:
-				case FORMAT_R32I:
-				case FORMAT_R32UI:
-				case FORMAT_G32R32I:
-				case FORMAT_G32R32UI:
-				case FORMAT_X32B32G32R32I:
-				case FORMAT_X32B32G32R32UI:
-				case FORMAT_A32B32G32R32I:
-				case FORMAT_A32B32G32R32UI:
-				case FORMAT_X8R8G8B8:
-				case FORMAT_X8B8G8R8:
-				case FORMAT_A8R8G8B8:
-				case FORMAT_A8B8G8R8:
-				case FORMAT_SRGB8_X8:
-				case FORMAT_SRGB8_A8:
-				case FORMAT_V8U8:
-				case FORMAT_Q8W8V8U8:
-				case FORMAT_X8L8V8U8:
-				case FORMAT_V16U16:
-				case FORMAT_A16W16V16U16:
-				case FORMAT_Q16W16V16U16:
-				case FORMAT_YV12_BT601:
-				case FORMAT_YV12_BT709:
-				case FORMAT_YV12_JFIF:
-					if(componentCount < 2) c.y = Short4(defaultColorValue);
-					if(componentCount < 3) c.z = Short4(defaultColorValue);
-					if(componentCount < 4) c.w = Short4(0x1000);
-					break;
-				case FORMAT_A8:
-					c.w = c.x;
-					c.x = Short4(0x0000);
-					c.y = Short4(0x0000);
-					c.z = Short4(0x0000);
-					break;
-				case FORMAT_L8:
-				case FORMAT_L16:
-					c.y = c.x;
-					c.z = c.x;
-					c.w = Short4(0x1000);
-					break;
-				case FORMAT_A8L8:
-					c.w = c.y;
-					c.y = c.x;
-					c.z = c.x;
-					break;
-				case FORMAT_R32F:
-					c.y = Short4(defaultColorValue);
-				case FORMAT_G32R32F:
-					c.z = Short4(defaultColorValue);
-				case FORMAT_X32B32G32R32F:
-				case FORMAT_X32B32G32R32F_UNSIGNED:
-					c.w = Short4(0x1000);
-				case FORMAT_A32B32G32R32F:
-					break;
-				case FORMAT_D32F:
-				case FORMAT_D32FS8:
-				case FORMAT_D32F_LOCKABLE:
-				case FORMAT_D32FS8_TEXTURE:
-				case FORMAT_D32F_SHADOW:
-				case FORMAT_D32FS8_SHADOW:
-					c.y = c.x;
-					c.z = c.x;
-					c.w = c.x;
-					break;
-				default:
-					ASSERT(false);
+					int componentCount = textureComponentCount();
+					short defaultColorValue = colorsDefaultToZero ? 0x0000 : 0x1000;
+
+					switch(state.textureFormat)
+					{
+					case FORMAT_R8_SNORM:
+					case FORMAT_G8R8_SNORM:
+					case FORMAT_X8B8G8R8_SNORM:
+					case FORMAT_A8B8G8R8_SNORM:
+					case FORMAT_R8:
+					case FORMAT_R5G6B5:
+					case FORMAT_G8R8:
+					case FORMAT_R8I:
+					case FORMAT_R8UI:
+					case FORMAT_G8R8I:
+					case FORMAT_G8R8UI:
+					case FORMAT_X8B8G8R8I:
+					case FORMAT_X8B8G8R8UI:
+					case FORMAT_A8B8G8R8I:
+					case FORMAT_A8B8G8R8UI:
+					case FORMAT_R16I:
+					case FORMAT_R16UI:
+					case FORMAT_G16R16:
+					case FORMAT_G16R16I:
+					case FORMAT_G16R16UI:
+					case FORMAT_X16B16G16R16I:
+					case FORMAT_X16B16G16R16UI:
+					case FORMAT_A16B16G16R16:
+					case FORMAT_A16B16G16R16I:
+					case FORMAT_A16B16G16R16UI:
+					case FORMAT_R32I:
+					case FORMAT_R32UI:
+					case FORMAT_G32R32I:
+					case FORMAT_G32R32UI:
+					case FORMAT_X32B32G32R32I:
+					case FORMAT_X32B32G32R32UI:
+					case FORMAT_A32B32G32R32I:
+					case FORMAT_A32B32G32R32UI:
+					case FORMAT_X8R8G8B8:
+					case FORMAT_X8B8G8R8:
+					case FORMAT_A8R8G8B8:
+					case FORMAT_A8B8G8R8:
+					case FORMAT_SRGB8_X8:
+					case FORMAT_SRGB8_A8:
+					case FORMAT_V8U8:
+					case FORMAT_Q8W8V8U8:
+					case FORMAT_X8L8V8U8:
+					case FORMAT_V16U16:
+					case FORMAT_A16W16V16U16:
+					case FORMAT_Q16W16V16U16:
+					case FORMAT_YV12_BT601:
+					case FORMAT_YV12_BT709:
+					case FORMAT_YV12_JFIF:
+						if(componentCount < 2) c.y = Short4(defaultColorValue);
+						if(componentCount < 3) c.z = Short4(defaultColorValue);
+						if(componentCount < 4) c.w = Short4(0x1000);
+						break;
+					case FORMAT_A8:
+						c.w = c.x;
+						c.x = Short4(0x0000);
+						c.y = Short4(0x0000);
+						c.z = Short4(0x0000);
+						break;
+					case FORMAT_L8:
+					case FORMAT_L16:
+						c.y = c.x;
+						c.z = c.x;
+						c.w = Short4(0x1000);
+						break;
+					case FORMAT_A8L8:
+						c.w = c.y;
+						c.y = c.x;
+						c.z = c.x;
+						break;
+					case FORMAT_R32F:
+						c.y = Short4(defaultColorValue);
+					case FORMAT_G32R32F:
+						c.z = Short4(defaultColorValue);
+					case FORMAT_X32B32G32R32F:
+					case FORMAT_X32B32G32R32F_UNSIGNED:
+						c.w = Short4(0x1000);
+					case FORMAT_A32B32G32R32F:
+						break;
+					case FORMAT_D32F:
+					case FORMAT_D32FS8:
+					case FORMAT_D32F_LOCKABLE:
+					case FORMAT_D32FS8_TEXTURE:
+					case FORMAT_D32F_SHADOW:
+					case FORMAT_D32FS8_SHADOW:
+						c.y = c.x;
+						c.z = c.x;
+						c.w = c.x;
+						break;
+					default:
+						ASSERT(false);
+					}
+				}
+
+				if((state.swizzleR != SWIZZLE_RED) ||
+				   (state.swizzleG != SWIZZLE_GREEN) ||
+				   (state.swizzleB != SWIZZLE_BLUE) ||
+				   (state.swizzleA != SWIZZLE_ALPHA))
+				{
+					const Vector4s col(c);
+					applySwizzle(state.swizzleR, c.x, col);
+					applySwizzle(state.swizzleG, c.y, col);
+					applySwizzle(state.swizzleB, c.z, col);
+					applySwizzle(state.swizzleA, c.w, col);
 				}
 			}
 		}
 
-		if(fixed12 &&
-		   ((state.swizzleR != SWIZZLE_RED) ||
-		    (state.swizzleG != SWIZZLE_GREEN) ||
-		    (state.swizzleB != SWIZZLE_BLUE) ||
-		    (state.swizzleA != SWIZZLE_ALPHA)))
-		{
-			const Vector4s col(c);
-			applySwizzle(state.swizzleR, c.x, col);
-			applySwizzle(state.swizzleG, c.y, col);
-			applySwizzle(state.swizzleB, c.z, col);
-			applySwizzle(state.swizzleA, c.w, col);
-		}
-
 		return c;
 	}
 
@@ -484,18 +486,18 @@
 					ASSERT(false);
 				}
 			}
-		}
 
-		if((state.swizzleR != SWIZZLE_RED) ||
-		   (state.swizzleG != SWIZZLE_GREEN) ||
-		   (state.swizzleB != SWIZZLE_BLUE) ||
-		   (state.swizzleA != SWIZZLE_ALPHA))
-		{
-			const Vector4f col(c);
-			applySwizzle(state.swizzleR, c.x, col);
-			applySwizzle(state.swizzleG, c.y, col);
-			applySwizzle(state.swizzleB, c.z, col);
-			applySwizzle(state.swizzleA, c.w, col);
+			if((state.swizzleR != SWIZZLE_RED) ||
+			   (state.swizzleG != SWIZZLE_GREEN) ||
+			   (state.swizzleB != SWIZZLE_BLUE) ||
+			   (state.swizzleA != SWIZZLE_ALPHA))
+			{
+				const Vector4f col(c);
+				applySwizzle(state.swizzleR, c.x, col);
+				applySwizzle(state.swizzleG, c.y, col);
+				applySwizzle(state.swizzleB, c.z, col);
+				applySwizzle(state.swizzleA, c.w, col);
+			}
 		}
 
 		return c;