Browse Source

metal: more work on shader texture bindings

Alex Szpakowski 4 years ago
parent
commit
6f3e590a82
2 changed files with 49 additions and 7 deletions
  1. 20 4
      src/modules/graphics/metal/Graphics.mm
  2. 29 3
      src/modules/graphics/metal/Shader.mm

+ 20 - 4
src/modules/graphics/metal/Graphics.mm

@@ -143,6 +143,12 @@ love::graphics::Graphics *createInstance()
 	return instance;
 }
 
+struct DefaultVertexAttributes
+{
+	float floats[4];
+	int ints[4];
+};
+
 Graphics *Graphics::graphicsInstance = nullptr;
 
 Graphics::Graphics()
@@ -172,10 +178,20 @@ Graphics::Graphics()
 
 	uniformBuffer = CreateStreamBuffer(device, BUFFERTYPE_UNIFORM, 1024 * 1024 * 1);
 
-	float defaultAttributes[4] = {0.0f, 0.0f, 0.0f, 1.0f};
-	Buffer::Settings attribsettings(Buffer::TYPEFLAG_VERTEX, 0, BUFFERUSAGE_STATIC);
-	std::vector<Buffer::DataDeclaration> dataformat = {{"Default", DATAFORMAT_FLOAT_VEC4, 0}};
-	defaultAttributesBuffer = newBuffer(attribsettings, dataformat, defaultAttributes, sizeof(float) * 4, 0);
+	{
+		std::vector<Buffer::DataDeclaration> dataformat = {
+			{"floats", DATAFORMAT_FLOAT_VEC4, 0},
+			{"ints", DATAFORMAT_INT32_VEC4, 0},
+		};
+
+		DefaultVertexAttributes defaults = {
+			{0.0f, 0.0f, 0.0f, 1.0f},
+			{0, 0, 0, 1},
+		};
+		Buffer::Settings attribsettings(Buffer::TYPEFLAG_VERTEX, 0, BUFFERUSAGE_STATIC);
+
+		defaultAttributesBuffer = newBuffer(attribsettings, dataformat, &defaults, sizeof(DefaultVertexAttributes), 0);
+	}
 
 	uint8 defaultpixel[] = {255, 255, 255, 255};
 	for (int i = 0; i < TEXTURE_MAX_ENUM; i++)

+ 29 - 3
src/modules/graphics/metal/Shader.mm

@@ -187,7 +187,9 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
 
 			for (const auto &resource : resources.sampled_images)
 			{
+				// TODO: set MainTex to binding 0
 				int binding = msl.get_decoration(resource.id, spv::DecorationBinding);
+				const SPIRType &type = msl.get_type(resource.base_type_id);
 
 				BuiltinUniform builtin = BUILTIN_MAX_ENUM;
 				if (getConstant(resource.name.c_str(), builtin))
@@ -207,12 +209,36 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
 				u.baseType = UNIFORM_SAMPLER;
 				u.name = resource.name;
 				u.location = 0;
-				u.textures = new love::graphics::Texture*[1];
-				u.textures[0] = nullptr;
 				u.data = malloc(sizeof(int) * 1);
 				u.ints[0] = binding;
 //				printf("binding for %s: %d\n", u.name.c_str(), binding);
 
+				switch (type.image.dim)
+				{
+				case spv::Dim2D:
+					u.textureType = type.image.arrayed ? TEXTURE_2D_ARRAY : TEXTURE_2D;
+					u.textures = new love::graphics::Texture*[1];
+					u.textures[0] = nullptr;
+					break;
+				case spv::Dim3D:
+					u.textureType = TEXTURE_VOLUME;
+					u.textures = new love::graphics::Texture*[1];
+					u.textures[0] = nullptr;
+					break;
+				case spv::DimCube:
+					if (type.image.arrayed)
+						throw love::Exception("Cubemap Arrays are not currently supported.");
+					u.textureType = TEXTURE_CUBE;
+					u.textures = new love::graphics::Texture*[1];
+					u.textures[0] = nullptr;
+					break;
+				case spv::DimBuffer:
+					// TODO: are texel buffers sampled images in glslang?
+					break;
+				default:
+					break;
+				}
+
 				uniforms[u.name] = u;
 			}
 
@@ -352,7 +378,7 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
 			{
 				spv::StorageClass storage = msl.get_storage_class(var);
 				const std::string &name = msl.get_name(var);
-				printf("var: %s\n", name.c_str());
+//				printf("var: %s\n", name.c_str());
 
 				if (i == ShaderStage::STAGE_VERTEX && storage == spv::StorageClassInput)
 					attributes[name] = msl.get_decoration(var, spv::DecorationLocation);