Browse Source

vulkan: adjust code styling

niki 2 years ago
parent
commit
a93d153792

+ 0 - 4
src/common/math.h

@@ -70,10 +70,6 @@ struct Rect
 	{
 		return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
 	}
-
-	bool operator != (const Rect& rhs) const {
-		return !(*this == rhs);
-	}
 };
 
 inline int nextP2(int x)

+ 1 - 2
src/common/runtime.h

@@ -673,8 +673,7 @@ int luax_catchexcept(lua_State *L, const T& func)
 	catch (const std::exception &e)
 	{
 		should_error = true;
-		const char* msg = e.what();
-		lua_pushstring(L, msg);
+		lua_pushstring(L, e.what());
 	}
 
 	if (should_error)

+ 9 - 11
src/modules/graphics/Shader.cpp

@@ -49,7 +49,7 @@ static const char global_syntax[] = R"(
 	#define mediump
 	#define highp
 #endif
-#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH) || defined(USE_VULKAN)
+#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
 	#define LOVE_HIGHP_OR_MEDIUMP highp
 #else
 	#define LOVE_HIGHP_OR_MEDIUMP mediump
@@ -248,8 +248,8 @@ LOVE_IO_LOCATION(0) attribute vec4 VertexPosition;
 LOVE_IO_LOCATION(1) attribute vec4 VertexTexCoord;
 LOVE_IO_LOCATION(2) attribute vec4 VertexColor;
 
-LOVE_IO_LOCATION(0) varying vec4 VaryingTexCoord;
-LOVE_IO_LOCATION(1) varying vec4 VaryingColor;
+varying vec4 VaryingTexCoord;
+varying vec4 VaryingColor;
 
 vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition);
 
@@ -316,8 +316,8 @@ static const char pixel_main[] = R"(
 #endif
 
 uniform sampler2D MainTex;
-LOVE_IO_LOCATION(0) varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
-LOVE_IO_LOCATION(1) varying mediump vec4 VaryingColor;
+varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
+varying mediump vec4 VaryingColor;
 
 vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord);
 
@@ -351,8 +351,8 @@ static const char pixel_main_custom[] = R"(
 #define LOVE_MULTI_CANVASES 1
 #endif
 
-LOVE_IO_LOCATION(0) varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
-LOVE_IO_LOCATION(1) varying mediump vec4 VaryingColor;
+varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
+varying mediump vec4 VaryingColor;
 
 void effect();
 
@@ -574,8 +574,7 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
 	ss << ((!gles && (lang == Shader::LANGUAGE_GLSL1 || glsl1on3)) ? "#line 0\n" : "#line 1\n");
 	ss << code;
 
-	auto result = ss.str();
-	return result;
+	return ss.str();
 }
 
 Shader::Shader(StrongRef<ShaderStage> _stages[])
@@ -877,8 +876,7 @@ bool Shader::validateInternal(StrongRef<ShaderStage> stages[], std::string &err,
 		{
 			LocalUniform u = {};
 			auto &values = u.initializerValues;
-			// const glslang::TConstUnionArray *constarray = info.getConstArray(); was this function deprecated in a later version?
-			const glslang::TConstUnionArray* constarray = nullptr;
+			const glslang::TConstUnionArray *constarray = info.getConstArray();
 
 			// Store initializer values for local uniforms. Some love graphics
 			// backends strip these out of the shader so we need to be able to

+ 1 - 4
src/modules/graphics/ShaderStage.cpp

@@ -18,8 +18,6 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#include <iostream>
-
 #include "ShaderStage.h"
 #include "common/Exception.h"
 #include "Graphics.h"
@@ -178,8 +176,7 @@ ShaderStage::ShaderStage(Graphics *gfx, ShaderStageType stage, const std::string
 
 		std::string err = "Error validating " + std::string(stagename) + " shader:\n\n"
 			+ std::string(glslangShader->getInfoLog()) + "\n"
-			+ std::string(glslangShader->getInfoDebugLog()) + "\n\nShader Code:\n" 
-			+ glsl;
+			+ std::string(glslangShader->getInfoDebugLog());
 
 		delete glslangShader;
 		throw love::Exception("%s", err.c_str());

+ 2 - 2
src/modules/graphics/opengl/Texture.h

@@ -46,8 +46,8 @@ public:
 	bool loadVolatile() override;
 	void unloadVolatile() override;
 
-	void copyFromBuffer(love::graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) override;
-	void copyToBuffer(love::graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) override;
+	void copyFromBuffer(love::graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect) override;
+	void copyToBuffer(love::graphics::Buffer *dest, int slice, int mipmap, const Rect &rect, size_t destoffset, int destwidth, size_t size) override;
 
 	void setSamplerState(const SamplerState &s) override;
 

+ 48 - 27
src/modules/graphics/vulkan/Buffer.cpp

@@ -1,12 +1,17 @@
 #include "Buffer.h"
 #include "Graphics.h"
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-
-static VkBufferUsageFlags getUsageBit(BufferUsage mode) {
-	switch (mode) {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+static VkBufferUsageFlags getUsageBit(BufferUsage mode)
+{
+	switch (mode)
+	{
 	case BUFFERUSAGE_VERTEX: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
 	case BUFFERUSAGE_INDEX: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
 	case BUFFERUSAGE_UNIFORM: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
@@ -15,35 +20,37 @@ static VkBufferUsageFlags getUsageBit(BufferUsage mode) {
 	}
 }
 
-static VkBufferUsageFlags getVulkanUsageFlags(BufferUsageFlags flags) {
+static VkBufferUsageFlags getVulkanUsageFlags(BufferUsageFlags flags)
+{
 	VkBufferUsageFlags vkFlags = 0;
-	for (int i = 0; i < BUFFERUSAGE_MAX_ENUM; i++) {
+	for (int i = 0; i < BUFFERUSAGE_MAX_ENUM; i++)
+	{
 		BufferUsageFlags flag = static_cast<BufferUsageFlags>(1u << i);
-		if (flags & flag) {
+		if (flags & flag)
 			vkFlags |= getUsageBit((BufferUsage)i);
-		}
 	}
 	return vkFlags;
 }
 
-Buffer::Buffer(love::graphics::Graphics* gfx, const Settings& settings, const std::vector<DataDeclaration>& format, const void* data, size_t size, size_t arraylength)
-	: love::graphics::Buffer(gfx, settings, format, size, arraylength), usageFlags(settings.usageFlags), gfx(gfx) {
+Buffer::Buffer(love::graphics::Graphics *gfx, const Settings &settings, const std::vector<DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
+	: love::graphics::Buffer(gfx, settings, format, size, arraylength)
+	, usageFlags(settings.usageFlags)
+	, vgfx(dynamic_cast<Graphics*>(gfx)) 
+{
 	loadVolatile();
 }
 
-bool Buffer::loadVolatile() {
-	Graphics* vgfx = (Graphics*)gfx;
+bool Buffer::loadVolatile()
+{
 	allocator = vgfx->getVmaAllocator();
 
 	VkBufferCreateInfo bufferInfo{};
 	bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
 	bufferInfo.size = getSize();
-	if (dataUsage == BUFFERDATAUSAGE_READBACK) {
+	if (dataUsage == BUFFERDATAUSAGE_READBACK)
 		bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-	}
-	else {
+	else
 		bufferInfo.usage = getVulkanUsageFlags(usageFlags);
-	}
 
 	VmaAllocationCreateInfo allocCreateInfo = {};
 	allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
@@ -54,11 +61,11 @@ bool Buffer::loadVolatile() {
 	return true;
 }
 
-void Buffer::unloadVolatile() {
+void Buffer::unloadVolatile()
+{
 	if (buffer == VK_NULL_HANDLE)
 		return;
 
-	Graphics* vgfx = (Graphics*)gfx;
 	auto device = vgfx->getDevice();
 
 	vgfx->queueCleanUp(
@@ -70,29 +77,43 @@ void Buffer::unloadVolatile() {
 	buffer = VK_NULL_HANDLE;
 }
 
-Buffer::~Buffer() {
+Buffer::~Buffer()
+{
 	unloadVolatile();
 }
 
-void* Buffer::map(MapType map, size_t offset, size_t size) {
+ptrdiff_t Buffer::getHandle() const
+{
+	return (ptrdiff_t) buffer;
+}
+
+ptrdiff_t Buffer::getTexelBufferHandle() const
+{
+	throw love::Exception("unimplemented Buffer::getTexelBufferHandle");
+	return (ptrdiff_t) nullptr;	// todo ?
+}
+
+void* Buffer::map(MapType map, size_t offset, size_t size)
+{
 	char* data = (char*)allocInfo.pMappedData;
 	return (void*) (data + offset);
 }
 
-bool Buffer::fill(size_t offset, size_t size, const void *data) {
+bool Buffer::fill(size_t offset, size_t size, const void *data)
+{
 	void* dst = (void*)((char*)allocInfo.pMappedData + offset);
 	memcpy(dst, data, size);
 	return true;
 }
 
-void Buffer::unmap(size_t usedoffset, size_t usedsize) {
+void Buffer::unmap(size_t usedoffset, size_t usedsize)
+{
 	(void)usedoffset;
 	(void)usedsize;
 }
 
-void Buffer::copyTo(love::graphics::Buffer* dest, size_t sourceoffset, size_t destoffset, size_t size) {
-	Graphics* vgfx = (Graphics*)gfx;
-
+void Buffer::copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
+{
 	auto commandBuffer = vgfx->getReadbackCommandBuffer();
 
 	VkBufferCopy bufferCopy{};

+ 22 - 20
src/modules/graphics/vulkan/Buffer.h

@@ -1,5 +1,4 @@
-#ifndef LOVE_GRAPHICS_VULKAN_BUFFER_H
-#define LOVE_GRAPHICS_VULKAN_BUFFER_H
+#pragma once
 
 #include "graphics/Buffer.h"
 #include "graphics/Volatile.h"
@@ -7,40 +6,43 @@
 #include "VulkanWrapper.h"
 
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-class Buffer : public love::graphics::Buffer, public Volatile {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+class Graphics;
+
+class Buffer
+	: public love::graphics::Buffer
+	, public Volatile
+{
 public:
-	Buffer(love::graphics::Graphics* gfx, const Settings& settings, const std::vector<DataDeclaration>& format, const void* data, size_t size, size_t arraylength);
+	Buffer(love::graphics::Graphics *gfx, const Settings& settings, const std::vector<DataDeclaration> &format, const void *data, size_t size, size_t arraylength);
 	virtual ~Buffer();
 
 	virtual bool loadVolatile() override;
 	virtual void unloadVolatile() override;
 
-	void* map(MapType map, size_t offset, size_t size) override;
+	void *map(MapType map, size_t offset, size_t size) override;
 	void unmap(size_t usedoffset, size_t usedsize) override;
-	bool fill(size_t offset, size_t size, const void* data) override;
-	void copyTo(love::graphics::Buffer* dest, size_t sourceoffset, size_t destoffset, size_t size) override;
-	ptrdiff_t getHandle() const override {
-		return (ptrdiff_t) buffer;	// todo ?
-	}
-	ptrdiff_t getTexelBufferHandle() const override {
-		throw love::Exception("unimplemented Buffer::getTexelBufferHandle");
-		return (ptrdiff_t) nullptr;	// todo ?
-	}
+	bool fill(size_t offset, size_t size, const void *data) override;
+	void copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size) override;
+	ptrdiff_t getHandle() const override;
+	ptrdiff_t getTexelBufferHandle() const override;
 
 private:
 	// todo use a staging buffer for improved performance
 	VkBuffer buffer = VK_NULL_HANDLE;
-	love::graphics::Graphics* gfx;
+	Graphics *vgfx = nullptr;
 	VmaAllocator allocator;
 	VmaAllocation allocation;
 	VmaAllocationInfo allocInfo;
 	BufferUsageFlags usageFlags;
 };
+
 } // vulkan
 } // graphics
 } // love
-
-#endif

File diff suppressed because it is too large
+ 228 - 183
src/modules/graphics/vulkan/Graphics.cpp


+ 95 - 66
src/modules/graphics/vulkan/Graphics.h

@@ -1,5 +1,4 @@
-#ifndef LOVE_GRAPHICS_VULKAN_GRAPHICS_H
-#define LOVE_GRAPHICS_VULKAN_GRAPHICS_H
+#pragma once
 
 // löve
 #include "common/config.h"
@@ -20,27 +19,36 @@
 #include <functional>
 
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-struct RenderPassConfiguration {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+struct RenderPassConfiguration
+{
 	std::vector<VkFormat> colorFormats;
 
-	struct StaticRenderPassConfiguration {
+	struct StaticRenderPassConfiguration
+	{
 		VkImageLayout initialColorImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 		VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
 		VkFormat depthFormat = VK_FORMAT_UNDEFINED;
 		bool resolve = false;
 	} staticData;
 
-    bool operator==(const RenderPassConfiguration& conf) const {
+    bool operator==(const RenderPassConfiguration &conf) const
+	{
 		return colorFormats == conf.colorFormats && 
 			(memcmp(&staticData, &conf.staticData, sizeof(StaticRenderPassConfiguration)) == 0);
     }
 };
 
-struct RenderPassConfigurationHasher {
-    size_t operator()(const RenderPassConfiguration &configuration) const {
+struct RenderPassConfigurationHasher
+{
+    size_t operator()(const RenderPassConfiguration &configuration) const
+	{
 		size_t hashes[] = { 
 			XXH32(configuration.colorFormats.data(), configuration.colorFormats.size() * sizeof(VkFormat), 0),
 			XXH32(&configuration.staticData, sizeof(configuration.staticData), 0),
@@ -49,10 +57,12 @@ struct RenderPassConfigurationHasher {
     }
 };
 
-struct FramebufferConfiguration {
+struct FramebufferConfiguration
+{
 	std::vector<VkImageView> colorViews;
 
-	struct StaticFramebufferConfiguration {
+	struct StaticFramebufferConfiguration
+	{
 		VkImageView depthView = VK_NULL_HANDLE;
 		VkImageView resolveView = VK_NULL_HANDLE;
 
@@ -62,14 +72,17 @@ struct FramebufferConfiguration {
 		VkRenderPass renderPass = VK_NULL_HANDLE;
 	} staticData;
 
-	bool operator==(const FramebufferConfiguration& conf) const {
+	bool operator==(const FramebufferConfiguration &conf) const
+	{
 		return colorViews == conf.colorViews &&
 			(memcmp(&staticData, &conf.staticData, sizeof(StaticFramebufferConfiguration)) == 0);
 	}
 };
 
-struct FramebufferConfigurationHasher {
-	size_t operator()(const FramebufferConfiguration& configuration) const {
+struct FramebufferConfigurationHasher
+{
+	size_t operator()(const FramebufferConfiguration &configuration) const
+	{
 		size_t hashes[] = {
 			XXH32(configuration.colorViews.data(), configuration.colorViews.size() * sizeof(VkImageView), 0),
 			XXH32(&configuration.staticData, sizeof(configuration.staticData), 0),
@@ -79,16 +92,19 @@ struct FramebufferConfigurationHasher {
 	}
 };
 
-struct OptionalInstanceExtensions {
+struct OptionalInstanceExtensions
+{
     bool physicalDeviceProperties2 = false;
 };
 
-struct OptionalDeviceFeatures {
+struct OptionalDeviceFeatures
+{
 	bool extendedDynamicState = false;
 	bool pushDescriptor = false;
 };
 
-struct OptionalDeviceExtensionFunctions {
+struct OptionalDeviceExtensionFunctions
+{
 	// extended dynamic state
 	PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT = nullptr;
 	PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT = nullptr;
@@ -106,7 +122,8 @@ struct OptionalDeviceExtensionFunctions {
 	PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR = nullptr;
 };
 
-struct GraphicsPipelineConfiguration {
+struct GraphicsPipelineConfiguration
+{
     VkRenderPass renderPass;
 	VertexAttributes vertexAttributes;
 	Shader* shader = nullptr;
@@ -117,7 +134,8 @@ struct GraphicsPipelineConfiguration {
 	uint32_t numColorAttachments;
 	PrimitiveType primitiveType;
 
-	struct DynamicState {
+	struct DynamicState
+	{
 		CullMode cullmode = CULL_NONE;
 		Winding winding = WINDING_MAX_ENUM;
 		StencilAction stencilAction = STENCIL_MAX_ENUM;
@@ -125,34 +143,42 @@ struct GraphicsPipelineConfiguration {
 		DepthState depthState{};
 	} dynamicState;
 
-	GraphicsPipelineConfiguration() {
+	GraphicsPipelineConfiguration()
+	{
 		memset(this, 0, sizeof(GraphicsPipelineConfiguration));
 	}
 
-	bool operator==(const GraphicsPipelineConfiguration& other) const {
+	bool operator==(const GraphicsPipelineConfiguration &other) const
+	{
 		return memcmp(this, &other, sizeof(GraphicsPipelineConfiguration)) == 0;
 	}
 };
 
-struct GraphicsPipelineConfigurationHasher {
-	size_t operator() (const GraphicsPipelineConfiguration &configuration) const {
+struct GraphicsPipelineConfigurationHasher
+{
+	size_t operator() (const GraphicsPipelineConfiguration &configuration) const
+	{
 		return XXH32(&configuration, sizeof(GraphicsPipelineConfiguration), 0);
 	}
 };
 
-struct SamplerStateHasher {
-	size_t operator()(const SamplerState &samplerState) const {
+struct SamplerStateHasher
+{
+	size_t operator()(const SamplerState &samplerState) const
+	{
 		return XXH32(&samplerState, sizeof(SamplerState), 0);
 	}
 };
 
-struct BatchedDrawBuffers {
+struct BatchedDrawBuffers
+{
 	StreamBuffer* vertexBuffer1;
 	StreamBuffer* vertexBuffer2;
 	StreamBuffer* indexBuffer;
 	StreamBuffer* constantColorBuffer;
 
-	~BatchedDrawBuffers() {
+	~BatchedDrawBuffers()
+	{
 		delete vertexBuffer1;
 		delete vertexBuffer2;
 		delete indexBuffer;
@@ -160,22 +186,26 @@ struct BatchedDrawBuffers {
 	}
 };
 
-struct QueueFamilyIndices {
+struct QueueFamilyIndices
+{
 	std::optional<uint32_t> graphicsFamily;
 	std::optional<uint32_t> presentFamily;
 
-	bool isComplete() const {
+	bool isComplete() const
+	{
 		return graphicsFamily.has_value() && presentFamily.has_value();
 	}
 };
 
-struct SwapChainSupportDetails {
+struct SwapChainSupportDetails
+{
 	VkSurfaceCapabilitiesKHR capabilities{};
 	std::vector<VkSurfaceFormatKHR> formats;
 	std::vector<VkPresentModeKHR> presentModes;
 };
 
-class Graphics final : public love::graphics::Graphics {
+class Graphics final : public love::graphics::Graphics
+{
 public:
 #ifdef LOVE_ANDROID
 	Graphics() {
@@ -196,27 +226,27 @@ public:
 	const VmaAllocator getVmaAllocator() const;
 
 	// implementation for virtual functions
-	love::graphics::Texture* newTexture(const love::graphics::Texture::Settings& settings, const love::graphics::Texture::Slices* data) override;
-	love::graphics::Buffer* newBuffer(const love::graphics::Buffer::Settings& settings, const std::vector<love::graphics::Buffer::DataDeclaration>& format, const void* data, size_t size, size_t arraylength) override;
+	love::graphics::Texture *newTexture(const love::graphics::Texture::Settings &settings, const love::graphics::Texture::Slices *data) override;
+	love::graphics::Buffer *newBuffer(const love::graphics::Buffer::Settings &settings, const std::vector<love::graphics::Buffer::DataDeclaration>& format, const void *data, size_t size, size_t arraylength) override;
 	void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override;
-	void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override;
-	Matrix4 computeDeviceProjection(const Matrix4& projection, bool rendertotexture) const override;
-	void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override { }
-	void present(void* screenshotCallbackdata) override;
+	void clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth) override;
+	Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override;
+	void discard(const std::vector<bool> &colorbuffers, bool depthstencil) override { }
+	void present(void *screenshotCallbackdata) override;
 	void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
-	bool setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override;
+	bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override;
 	void unSetMode() override;
 	void setActive(bool active) override;
 	int getRequestedBackbufferMSAA() const override;
 	int getBackbufferMSAA() const  override;
 	void setColor(Colorf c) override;
-	void setScissor(const Rect& rect) override;
+	void setScissor(const Rect &rect) override;
 	void setScissor() override;
 	void setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override;
 	void setDepthMode(CompareMode compare, bool write) override;
 	void setFrontFaceWinding(Winding winding) override;
 	void setColorMask(ColorChannelMask mask) override;
-	void setBlendState(const BlendState& blend) override;
+	void setBlendState(const BlendState &blend) override;
 	void setPointSize(float size) override;
 	void setWireframe(bool enable) override;
 	PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override;
@@ -224,12 +254,12 @@ public:
 	Renderer getRenderer() const override;
 	bool usesGLSLES() const override;
 	RendererInfo getRendererInfo() const override;
-	void draw(const DrawCommand& cmd) override;
-	void draw(const DrawIndexedCommand& cmd) override;
-	void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) override;
+	void draw(const DrawCommand &cmd) override;
+	void draw(const DrawIndexedCommand &cmd) override;
+	void drawQuads(int start, int count, const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture) override;
 
-	graphics::GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset) override;
-	graphics::GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty) override;
+	graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) override;
+	graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty) override;
 
 	VkCommandBuffer getDataTransferCommandBuffer();
 	VkCommandBuffer getReadbackCommandBuffer();
@@ -243,7 +273,7 @@ public:
 
 	uint32_t getNumImagesInFlight() const;
 	const VkDeviceSize getMinUniformBufferOffsetAlignment() const;
-	graphics::Texture* getDefaultTexture() const;
+	graphics::Texture *getDefaultTexture() const;
 	VkSampler getCachedSampler(const SamplerState&);
 
 	void setComputeShader(Shader*);
@@ -252,13 +282,13 @@ public:
 	const OptionalDeviceExtensionFunctions &getExtensionFunctions() const;
 
 protected:
-	graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override;
-	graphics::Shader* newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
-	graphics::StreamBuffer* newStreamBuffer(BufferUsage type, size_t size) override;
+	graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
+	graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
+	graphics::StreamBuffer *newStreamBuffer(BufferUsage type, size_t size) override;
 	bool dispatch(int x, int y, int z) override;
 	void initCapabilities() override;
-	void getAPIStats(int& shaderswitches) const override;
-	void setRenderTargetsInternal(const RenderTargets& rts, int pixelw, int pixelh, bool hasSRGBtexture) override;
+	void getAPIStats(int &shaderswitches) const override;
+	void setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture) override;
 
 private:
 	void createVulkanInstance();
@@ -272,21 +302,21 @@ private:
 	void createSurface();
 	bool checkDeviceExtensionSupport(VkPhysicalDevice device);
 	SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
-	VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
-	VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
-	VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
-	VkCompositeAlphaFlagBitsKHR chooseCompositeAlpha(const VkSurfaceCapabilitiesKHR& capabilities);
+	VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats);
+	VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR> &availablePresentModes);
+	VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities);
+	VkCompositeAlphaFlagBitsKHR chooseCompositeAlpha(const VkSurfaceCapabilitiesKHR &capabilities);
 	void createSwapChain();
 	void createImageViews();
 	void createDefaultRenderPass();
 	void createDefaultFramebuffers();
-    VkFramebuffer createFramebuffer(FramebufferConfiguration);
-    VkFramebuffer getFramebuffer(FramebufferConfiguration);
+    VkFramebuffer createFramebuffer(FramebufferConfiguration&);
+    VkFramebuffer getFramebuffer(FramebufferConfiguration&);
 	void createDefaultShaders();
-    VkRenderPass createRenderPass(RenderPassConfiguration);
-	VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration);
+    VkRenderPass createRenderPass(RenderPassConfiguration&);
+	VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration&);
 	void createColorResources();
-	VkFormat findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
+	VkFormat findSupportedFormat(const std::vector<VkFormat> &candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
 	VkFormat findDepthFormat();
 	void createDepthResources();
 	void createCommandPool();
@@ -300,7 +330,7 @@ private:
 	void beginFrame();
 	void startRecordingGraphicsCommands(bool newFrame);
 	void endRecordingGraphicsCommands(bool present);
-	void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration);
+	void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration&);
 	graphics::Shader::BuiltinUniformData getCurrentBuiltinUniformData();
 	void updatedBatchedDrawBuffers();
 	bool usesConstantVertexColor(const VertexAttributes&);
@@ -308,8 +338,8 @@ private:
 		VertexAttributes vertexAttributes, 
 		std::vector<VkVertexInputBindingDescription> &bindingDescriptions, 
 		std::vector<VkVertexInputAttributeDescription> &attributeDescriptions);
-	void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType, CullMode);
-	void startRenderPass(const RenderTargets& rts, int pixelw, int pixelh, bool hasSRGBtexture);
+	void prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType, CullMode);
+	void startRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture);
 	void startDefaultRenderPass();
 	void endRenderPass();
 	VkSampler createSampler(const SamplerState&);
@@ -378,8 +408,7 @@ private:
 	float currentViewportHeight = 0;
 	VkSampleCountFlagBits currentMsaaSamples = VK_SAMPLE_COUNT_1_BIT;
 };
+
 } // vulkan
 } // graphics
 } // love
-
-#endif

+ 25 - 17
src/modules/graphics/vulkan/GraphicsReadback.cpp

@@ -4,21 +4,26 @@
 #include "Graphics.h"
 #include "data/ByteData.h"
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-
-GraphicsReadback::GraphicsReadback(love::graphics::Graphics* gfx, ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset)
-	: graphics::GraphicsReadback(gfx, method, buffer, offset, size, dest, destoffset) {
-	vgfx = dynamic_cast<Graphics*>(gfx);
-
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+GraphicsReadback::GraphicsReadback(love::graphics::Graphics *gfx, ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset)
+	: graphics::GraphicsReadback(gfx, method, buffer, offset, size, dest, destoffset)
+	, vgfx(dynamic_cast<Graphics*>(gfx))
+{
 	// Immediate readback of readback-type buffers doesn't need a staging buffer.
-	if (method != READBACK_IMMEDIATE || buffer->getDataUsage() != BUFFERDATAUSAGE_READBACK) {
+	if (method != READBACK_IMMEDIATE || buffer->getDataUsage() != BUFFERDATAUSAGE_READBACK)
+	{
 		stagingBuffer = gfx->getTemporaryBuffer(size, DATAFORMAT_FLOAT, 0, BUFFERDATAUSAGE_READBACK);
 		gfx->copyBuffer(buffer, stagingBuffer, offset, 0, size);
 	}
 
-	if (method == READBACK_IMMEDIATE) {
+	if (method == READBACK_IMMEDIATE)
+	{
 		vgfx->submitGpuCommands(false);
 		if (stagingBuffer.get()) {
 			status = readbackBuffer(stagingBuffer, 0, size);
@@ -36,10 +41,10 @@ GraphicsReadback::GraphicsReadback(love::graphics::Graphics* gfx, ReadbackMethod
 		});
 }
 
-GraphicsReadback::GraphicsReadback(love::graphics::Graphics* gfx, ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty)
-	: graphics::GraphicsReadback(gfx, method, texture, slice, mipmap, rect, dest, destx, desty) {
-	vgfx = dynamic_cast<Graphics*>(gfx);
-
+GraphicsReadback::GraphicsReadback(love::graphics::Graphics *gfx, ReadbackMethod method, love::graphics::Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty)
+	: graphics::GraphicsReadback(gfx, method, texture, slice, mipmap, rect, dest, destx, desty)
+	, vgfx(dynamic_cast<Graphics*>(gfx))
+{
 	size_t size = getPixelFormatSliceSize(textureFormat, rect.w, rect.h);
 
 	stagingBuffer = vgfx->getTemporaryBuffer(size, DATAFORMAT_FLOAT, 0, BUFFERDATAUSAGE_READBACK);
@@ -57,15 +62,18 @@ GraphicsReadback::GraphicsReadback(love::graphics::Graphics* gfx, ReadbackMethod
 		vgfx->submitGpuCommands(false);
 }
 
-GraphicsReadback::~GraphicsReadback() {
+GraphicsReadback::~GraphicsReadback()
+{
 }
 
-void GraphicsReadback::wait() {
+void GraphicsReadback::wait()
+{
 	if (status == STATUS_WAITING)
 		vgfx->submitGpuCommands(false);
 }
 
-void GraphicsReadback::update() {
+void GraphicsReadback::update()
+{
 }
 
 } // vulkan

+ 12 - 11
src/modules/graphics/vulkan/GraphicsReadback.h

@@ -1,18 +1,21 @@
-#ifndef LOVE_GRAPHICS_VULKAN_GRAPHICS_READBACK_H
-#define LOVE_GRAPHICS_VULKAN_GRAPHICS_READBACK_H
+#pragma once
 
 #include "graphics/GraphicsReadback.h"
 
-namespace love {
-namespace graphics {
-namespace vulkan {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
 
 class Graphics;
 
-class GraphicsReadback : public graphics::GraphicsReadback {
+class GraphicsReadback : public graphics::GraphicsReadback
+{
 public:
-	GraphicsReadback(love::graphics::Graphics* gfx, ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset);
-	GraphicsReadback(love::graphics::Graphics* gfx, ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty);
+	GraphicsReadback(love::graphics::Graphics *gfx, ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset);
+	GraphicsReadback(love::graphics::Graphics *gfx, ReadbackMethod method, love::graphics::Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty);
 	virtual ~GraphicsReadback();
 
 	void wait() override;
@@ -20,12 +23,10 @@ public:
 
 private:
 
-	Graphics* vgfx;
+	Graphics *vgfx = nullptr;
 	StrongRef<love::graphics::Buffer> stagingBuffer;
 };
 
 } // vulkan
 } // graphics
 } // love
-
-#endif

+ 192 - 160
src/modules/graphics/vulkan/Shader.cpp

@@ -7,9 +7,13 @@
 
 #include <vector>
 
-namespace love {
-namespace graphics {
-namespace vulkan {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
 static const TBuiltInResource defaultTBuiltInResource = {
 	/* .MaxLights = */ 32,
 	/* .MaxClipPlanes = */ 6,
@@ -120,8 +124,10 @@ static const TBuiltInResource defaultTBuiltInResource = {
 static const uint32_t STREAMBUFFER_DEFAULT_SIZE = 16;
 static const uint32_t DESCRIPTOR_POOL_SIZE = 1;
 
-static VkShaderStageFlagBits getStageBit(ShaderStageType type) {
-	switch (type) {
+static VkShaderStageFlagBits getStageBit(ShaderStageType type)
+{
+	switch (type)
+	{
 	case SHADERSTAGE_VERTEX:
 		return VK_SHADER_STAGE_VERTEX_BIT;
 	case SHADERSTAGE_PIXEL:
@@ -133,8 +139,10 @@ static VkShaderStageFlagBits getStageBit(ShaderStageType type) {
 	}
 }
 
-static EShLanguage getGlslShaderType(ShaderStageType stage) {
-	switch (stage) {
+static EShLanguage getGlslShaderType(ShaderStageType stage)
+{
+	switch (stage)
+	{
 	case SHADERSTAGE_VERTEX:
 		return EShLangVertex;
 	case SHADERSTAGE_PIXEL:
@@ -147,30 +155,30 @@ static EShLanguage getGlslShaderType(ShaderStageType stage) {
 }
 
 Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[])
-	: graphics::Shader(stages) {
-	gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
-	auto vgfx = (Graphics*)gfx;
+	: graphics::Shader(stages)
+{
+	auto gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
+	vgfx = dynamic_cast<Graphics*>(gfx);
 	auto &optionalDeviceFeaures = vgfx->getOptionalDeviceFeatures();
-	if (optionalDeviceFeaures.pushDescriptor) {
+	if (optionalDeviceFeaures.pushDescriptor)
 		pfn_vkCmdPushDescriptorSetKHR = vgfx->getExtensionFunctions().vkCmdPushDescriptorSetKHR;
-	}
 
 	loadVolatile();
 }
 
-bool Shader::loadVolatile() {
+bool Shader::loadVolatile()
+{
 	computePipeline = VK_NULL_HANDLE;
 
-	for (int i = 0; i < BUILTIN_MAX_ENUM; i++) {
+	for (int i = 0; i < BUILTIN_MAX_ENUM; i++)
 		builtinUniformInfo[i] = nullptr;
-	}
 
 	compileShaders();
 	calculateUniformBufferSizeAligned();
 	createDescriptorSetLayout();
 	createPipelineLayout();
 	createStreamBuffers();
-	descriptorSetsVector.resize(((Graphics*)gfx)->getNumImagesInFlight());
+	descriptorSetsVector.resize(vgfx->getNumImagesInFlight());
 	currentFrame = 0;
 	currentUsedUniformStreamBuffersCount = 0;
 	currentUsedDescriptorSetsCount = 0;
@@ -178,19 +186,17 @@ bool Shader::loadVolatile() {
 	return true;
 }
 
-void Shader::unloadVolatile() {
-	if (shaderModules.empty()) {
+void Shader::unloadVolatile()
+{
+	if (shaderModules.empty())
 		return;
-	}
 
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
 	gfx->queueCleanUp([shaderModules = std::move(shaderModules), device = device, descriptorSetLayout = descriptorSetLayout, pipelineLayout = pipelineLayout, descriptorPools = descriptorPools, computePipeline = computePipeline](){
-		for (const auto pool : descriptorPools) {
+		for (const auto pool : descriptorPools)
 			vkDestroyDescriptorPool(device, pool, nullptr);
-		}
-		for (const auto shaderModule : shaderModules) {
+		for (const auto shaderModule : shaderModules)
 			vkDestroyShaderModule(device, shaderModule, nullptr);
-		}
 		vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
 		vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
 		if (computePipeline != VK_NULL_HANDLE)
@@ -211,19 +217,23 @@ void Shader::unloadVolatile() {
 	descriptorSetsVector.clear();
 }
 
-const std::vector<VkPipelineShaderStageCreateInfo>& Shader::getShaderStages() const {
+const std::vector<VkPipelineShaderStageCreateInfo>& Shader::getShaderStages() const
+{
 	return shaderStages;
 }
 
-const VkPipelineLayout Shader::getGraphicsPipelineLayout() const {
+const VkPipelineLayout Shader::getGraphicsPipelineLayout() const
+{
 	return pipelineLayout;
 }
 
-VkPipeline Shader::getComputePipeline() const {
+VkPipeline Shader::getComputePipeline() const
+{
 	return computePipeline;
 }
 
-static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture* texture, bool sampler) {
+static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture* texture, bool sampler)
+{
 	auto vkTexture = (Texture*)texture;
 
 	auto imageInfo = new VkDescriptorImageInfo();
@@ -236,48 +246,52 @@ static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture* textu
 	return imageInfo;
 }
 
-void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frameIndex, VkPipelineBindPoint bindPoint) {
+void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frameIndex, VkPipelineBindPoint bindPoint)
+{
 	// detect whether a new frame has begun
-	if (currentFrame != frameIndex) {
+	if (currentFrame != frameIndex)
+	{
 		currentFrame = frameIndex;
 
 		currentUsedUniformStreamBuffersCount = 0;
 		currentUsedDescriptorSetsCount = 0;
 
 		// we needed more memory last frame, let's collapse all buffers into a single one.
-		if (streamBuffers.at(currentFrame).size() > 1) {
+		if (streamBuffers.at(currentFrame).size() > 1)
+		{
 			size_t newSize = 0;
-			for (auto streamBuffer : streamBuffers.at(currentFrame)) {
+			for (auto streamBuffer : streamBuffers.at(currentFrame))
+			{
 				newSize += streamBuffer->getSize();
 				delete streamBuffer;
 			}
 			streamBuffers.at(currentFrame).clear();
-			streamBuffers.at(currentFrame).push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, newSize));
+			streamBuffers.at(currentFrame).push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, newSize));
 		}
 		// no collapse necessary, can just call nextFrame to reset the current (only) streambuffer
-		else {
+		else
 			streamBuffers.at(currentFrame).at(0)->nextFrame();
-		}
 	}
 	// still the same frame
-	else {
+	else
+	{
 		auto usedStreamBufferMemory = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
-		if (usedStreamBufferMemory >= streamBuffers.at(currentFrame).back()->getSize()) {
+		if (usedStreamBufferMemory >= streamBuffers.at(currentFrame).back()->getSize())
+		{
 			// we ran out of memory in the current frame, need to allocate more.
-			streamBuffers.at(currentFrame).push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
+			streamBuffers.at(currentFrame).push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
 			currentUsedUniformStreamBuffersCount = 0;
 		}
 	}
 
 	VkDescriptorSet currentDescriptorSet;
 
-	if (pfn_vkCmdPushDescriptorSetKHR) {
+	if (pfn_vkCmdPushDescriptorSetKHR)
 		currentDescriptorSet = 0;
-	}
-	else {
-		if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size())) {
+	else
+	{
+		if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size()))
 			descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
-		}
 
 		currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
 	}
@@ -350,14 +364,7 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 		}
 	}
 
-	if (currentDescriptorSet) {
-		vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr);
-
-		vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr);
-
-		currentUsedDescriptorSetsCount++;
-	}
-	else {
+	if (pfn_vkCmdPushDescriptorSetKHR) 
 		pfn_vkCmdPushDescriptorSetKHR(
 			commandBuffer, 
 			bindPoint, 
@@ -365,49 +372,63 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 			0, 
 			static_cast<uint32_t>(descriptorWrite.size()),
 			descriptorWrite.data());
+	else
+	{
+		vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr);
+
+		vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr);
+
+		currentUsedDescriptorSetsCount++;
 	}
 
-	for (const auto imageInfo : imageInfos) {
+	for (const auto imageInfo : imageInfos)
 		delete imageInfo;
-	}
-	if (bufferInfo) {
+	if (bufferInfo)
 		delete bufferInfo;
-	}
 
 	currentUsedUniformStreamBuffersCount++;
 }
 
-Shader::~Shader() {
+Shader::~Shader()
+{
 	unloadVolatile();
 }
 
-void Shader::attach() {
-	if (!isCompute) {
-		if (Shader::current != this) {
+void Shader::attach()
+{
+	if (!isCompute)
+	{
+		if (Shader::current != this)
+		{
 			Graphics::flushBatchedDrawsGlobal();
 			Shader::current = this;
 			Vulkan::shaderSwitch();
 		}
 	}
 	else
-		((Graphics*)gfx)->setComputeShader(this);
+		vgfx->setComputeShader(this);
 }
 
-int Shader::getVertexAttributeIndex(const std::string& name) {
+int Shader::getVertexAttributeIndex(const std::string& name)
+{
 	auto it = attributes.find(name);
 	return it == attributes.end() ? -1 : it->second;
 }
 
-const Shader::UniformInfo* Shader::getUniformInfo(const std::string& name) const {
+const Shader::UniformInfo* Shader::getUniformInfo(const std::string& name) const
+{
 	return &uniformInfos.at(name);
 }
 
-const Shader::UniformInfo* Shader::getUniformInfo(BuiltinUniform builtin) const {
+const Shader::UniformInfo* Shader::getUniformInfo(BuiltinUniform builtin) const
+{
 	return builtinUniformInfo[builtin];
 }
 
-void Shader::sendTextures(const UniformInfo* info, graphics::Texture** textures, int count) {
-	for (unsigned i = 0; i < count; i++) {
+void Shader::sendTextures(const UniformInfo* info, graphics::Texture** textures, int count)
+{
+	for (unsigned i = 0; i < count; i++)
+	{
 		auto oldTexture = info->textures[i];
 		info->textures[i] = textures[i];
 		info->textures[i]->retain();
@@ -416,8 +437,8 @@ void Shader::sendTextures(const UniformInfo* info, graphics::Texture** textures,
 	}
 }
 
-void Shader::calculateUniformBufferSizeAligned() {
-	auto vgfx = (Graphics*)gfx;
+void Shader::calculateUniformBufferSizeAligned()
+{
 	auto minAlignment = vgfx->getMinUniformBufferOffsetAlignment();
 	size_t size = localUniformStagingData.size();
 	auto factor = static_cast<VkDeviceSize>(std::ceil(
@@ -426,19 +447,22 @@ void Shader::calculateUniformBufferSizeAligned() {
 	uniformBufferSizeAligned = factor * minAlignment;
 }
 
-void Shader::buildLocalUniforms(spirv_cross::Compiler& comp, const spirv_cross::SPIRType& type, size_t baseoff, const std::string& basename) {
+void Shader::buildLocalUniforms(spirv_cross::Compiler& comp, const spirv_cross::SPIRType &type, size_t baseoff, const std::string &basename)
+{
 	using namespace spirv_cross;
 
 	const auto& membertypes = type.member_types;
 
-	for (size_t uindex = 0; uindex < membertypes.size(); uindex++) {
+	for (size_t uindex = 0; uindex < membertypes.size(); uindex++)
+	{
 		const auto& memberType = comp.get_type(membertypes[uindex]);
 		size_t memberSize = comp.get_declared_struct_member_size(type, uindex);
 		size_t offset = baseoff + comp.type_struct_member_offset(type, uindex);
 
 		std::string name = basename + comp.get_member_name(type.self, uindex);
 
-		switch (memberType.basetype) {
+		switch (memberType.basetype)
+		{
 		case SPIRType::Struct:
 			name += ".";
 			buildLocalUniforms(comp, memberType, offset, name);
@@ -458,49 +482,49 @@ void Shader::buildLocalUniforms(spirv_cross::Compiler& comp, const spirv_cross::
 		u.components = 1;
 		u.data = localUniformStagingData.data() + offset;
 
-		if (memberType.columns == 1) {
-			if (memberType.basetype == SPIRType::Int) {
+		if (memberType.columns == 1)
+		{
+			if (memberType.basetype == SPIRType::Int)
 				u.baseType = UNIFORM_INT;
-			}
-			else if (memberType.basetype == SPIRType::UInt) {
+			else if (memberType.basetype == SPIRType::UInt)
 				u.baseType = UNIFORM_UINT;
-			}
-			else {
+			else
 				u.baseType = UNIFORM_FLOAT;
-			}
 			u.components = memberType.vecsize;
 		}
-		else {
+		else
+		{
 			u.baseType = UNIFORM_MATRIX;
 			u.matrix.rows = memberType.vecsize;
 			u.matrix.columns = memberType.columns;
 		}
 
 		const auto& reflectionIt = validationReflection.localUniforms.find(u.name);
-		if (reflectionIt != validationReflection.localUniforms.end()) {
+		if (reflectionIt != validationReflection.localUniforms.end())
+		{
 			const auto& localUniform = reflectionIt->second;
 			const auto& values = localUniform.initializerValues;
-			if (!values.empty()) {
+			if (!values.empty())
 				memcpy(
 					u.data,
 					values.data(),
 					std::min(u.dataSize, values.size() * sizeof(LocalUniformValue)));
-			}
 		}
 
 		uniformInfos[u.name] = u;
 
 		BuiltinUniform builtin = BUILTIN_MAX_ENUM;
-		if (getConstant(u.name.c_str(), builtin)) {
-			if (builtin == BUILTIN_UNIFORMS_PER_DRAW) {
+		if (getConstant(u.name.c_str(), builtin))
+		{
+			if (builtin == BUILTIN_UNIFORMS_PER_DRAW)
 				builtinUniformDataOffset = offset;
-			}
 			builtinUniformInfo[builtin] = &uniformInfos[u.name];
 		}
 	}
 }
 
-void Shader::compileShaders() {
+void Shader::compileShaders()
+{
 	using namespace glslang;
 	using namespace spirv_cross;
 
@@ -508,11 +532,10 @@ void Shader::compileShaders() {
 
 	auto program = new TProgram();
 
-	gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
-	auto vgfx = (Graphics*)gfx;
 	device = vgfx->getDevice();
 
-	for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++) {
+	for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++)
+	{
 		if (!stages[i])
 			continue;
 
@@ -543,7 +566,8 @@ void Shader::compileShaders() {
 		bool forceDefault = false;
 		bool forwardCompat = true;
 
-		if (!tshader->parse(&defaultTBuiltInResource, defaultVersion, defaultProfile, forceDefault, forwardCompat, EShMsgSuppressWarnings)) {
+		if (!tshader->parse(&defaultTBuiltInResource, defaultVersion, defaultProfile, forceDefault, forwardCompat, EShMsgSuppressWarnings))
+		{
 			const char* msg1 = tshader->getInfoLog();
 			const char* msg2 = tshader->getInfoDebugLog();
 
@@ -554,17 +578,16 @@ void Shader::compileShaders() {
 		glslangShaders.push_back(tshader);
 	}
 
-	if (!program->link(EShMsgDefault)) {
+	if (!program->link(EShMsgDefault))
 		throw love::Exception("link failed! %s\n", program->getInfoLog());
-	}
 
-	if (!program->mapIO()) {
+	if (!program->mapIO())
 		throw love::Exception("mapIO failed");
-	}
 
 	uniformInfos.clear();
 
-	for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++) {
+	for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++)
+	{
 		auto shaderStage = (ShaderStageType)i;
 		auto glslangStage = getGlslShaderType(shaderStage);
 		auto intermediate = program->getIntermediate(glslangStage);
@@ -586,8 +609,7 @@ void Shader::compileShaders() {
 		createInfo.codeSize = spirv.size() * sizeof(uint32_t);
 		createInfo.pCode = spirv.data();
 
-		Graphics* vkGfx = (Graphics*)gfx;
-		auto device = vkGfx->getDevice();
+		auto device = vgfx->getDevice();
 
 		VkShaderModule shaderModule;
 
@@ -612,8 +634,10 @@ void Shader::compileShaders() {
 		auto shaderResources = comp.get_shader_resources(active);
 		comp.set_enabled_interface_variables(std::move(active));
 
-		for (const auto& resource : shaderResources.uniform_buffers) {
-			if (resource.name == "gl_DefaultUniformBlock") {
+		for (const auto& resource : shaderResources.uniform_buffers)
+		{
+			if (resource.name == "gl_DefaultUniformBlock")
+			{
 				const auto& type = comp.get_type(resource.base_type_id);
 				size_t uniformBufferObjectSize = comp.get_declared_struct_size(type);
 				auto defaultUniformBlockSize = comp.get_declared_struct_size(type);
@@ -625,12 +649,12 @@ void Shader::compileShaders() {
 				std::string basename("");
 				buildLocalUniforms(comp, type, 0, basename);
 			}
-			else {
+			else
 				throw love::Exception("unimplemented: non default uniform blocks.");
-			}
 		}
 
-		for (const auto& r : shaderResources.sampled_images) {
+		for (const auto& r : shaderResources.sampled_images)
+		{
 			const SPIRType& basetype = comp.get_type(r.base_type_id);
 			const SPIRType& type = comp.get_type(r.type_id);
 			const SPIRType& imagetype = comp.get_type(basetype.image.type);
@@ -643,7 +667,8 @@ void Shader::compileShaders() {
 			info.isDepthSampler = type.image.depth;
 			info.components = 1;
 
-			switch (imagetype.basetype) {
+			switch (imagetype.basetype)
+			{
 			case SPIRType::Float:
 				info.dataBaseType = DATA_BASETYPE_FLOAT;
 				break;
@@ -657,7 +682,8 @@ void Shader::compileShaders() {
 				break;
 			}
 
-			switch (basetype.image.dim) {
+			switch (basetype.image.dim)
+			{
 			case spv::Dim2D:
 				info.textureType = basetype.image.arrayed ? TEXTURE_2D_ARRAY : TEXTURE_2D;
 				info.textures = new love::graphics::Texture * [info.count];
@@ -679,7 +705,8 @@ void Shader::compileShaders() {
 				throw love::Exception("unknown dim");
 			}
 
-			if (info.baseType == UNIFORM_SAMPLER) {
+			if (info.baseType == UNIFORM_SAMPLER)
+			{
 				auto tex = vgfx->getDefaultTexture();
 				for (int i = 0; i < info.count; i++) {
 					info.textures[i] = tex;
@@ -687,18 +714,17 @@ void Shader::compileShaders() {
 				}
 			}
 			// fixme
-			else if (info.baseType == UNIFORM_TEXELBUFFER) {
+			else if (info.baseType == UNIFORM_TEXELBUFFER)
 				throw love::Exception("texel buffers not supported yet");
-			}
 
 			uniformInfos[r.name] = info;
 			BuiltinUniform builtin;
-			if (getConstant(r.name.c_str(), builtin)) {
+			if (getConstant(r.name.c_str(), builtin))
 				builtinUniformInfo[builtin] = &uniformInfos[info.name];
-			}
 		}
 
-		for (const auto& r : shaderResources.storage_buffers) {
+		for (const auto& r : shaderResources.storage_buffers)
+		{
 			const auto& type = comp.get_type(r.type_id);
 
 			UniformInfo u{};
@@ -709,27 +735,27 @@ void Shader::compileShaders() {
 			u.location = comp.get_decoration(r.id, spv::DecorationBinding);
 			
 			const auto reflectionit = validationReflection.storageBuffers.find(u.name);
-			if (reflectionit != validationReflection.storageBuffers.end()) {
+			if (reflectionit != validationReflection.storageBuffers.end())
+			{
 				u.bufferStride = reflectionit->second.stride;
 				u.bufferMemberCount = reflectionit->second.memberCount;
 				u.access = reflectionit->second.access;
 			}
-			else {
+			else
 				continue;
-			}
 
 			// todo: some stuff missing
 
 			u.buffers = new love::graphics::Buffer * [u.count];
 
-			for (int i = 0; i < u.count; i++) {
+			for (int i = 0; i < u.count; i++)
 				u.buffers[i] = nullptr;
-			}
 
 			uniformInfos[u.name] = u;
 		}
 
-		for (const auto& r : shaderResources.storage_images) {
+		for (const auto& r : shaderResources.storage_images)
+		{
 			const auto& type = comp.get_type(r.type_id);
 
 			UniformInfo u{};
@@ -740,53 +766,53 @@ void Shader::compileShaders() {
 			u.textures = new love::graphics::Texture * [u.count];
 			u.location = comp.get_decoration(r.id, spv::DecorationBinding);
 
-			for (int i = 0; i < u.count; i++) {
+			for (int i = 0; i < u.count; i++)
 				u.textures[i] = nullptr;
-			}
 
 			// some stuff missing ?
 
 			uniformInfos[u.name] = u;
 		}
 
-		if (shaderStage == SHADERSTAGE_VERTEX) {
-			for (const auto& r : shaderResources.stage_inputs) {
+		if (shaderStage == SHADERSTAGE_VERTEX)
+			for (const auto& r : shaderResources.stage_inputs)
+			{
 				const auto& name = r.name;
 				const int attributeLocation = static_cast<int>(comp.get_decoration(r.id, spv::DecorationLocation));
 				attributes[name] = attributeLocation;
 			}
-		}
 	}
 
 	delete program;
-	for (auto shader : glslangShaders) {
+	for (auto shader : glslangShaders)
 		delete shader;
-	}
 }
 
-void Shader::createDescriptorSetLayout() {
+void Shader::createDescriptorSetLayout()
+{
 	std::vector<VkDescriptorSetLayoutBinding> bindings;
 
-	for (auto const& [key, val] : uniformInfos) {
+	for (auto const& [key, val] : uniformInfos)
+	{
 		auto type = Vulkan::getDescriptorType(val.baseType);
-		if (type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
+		if (type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
+		{
 			VkDescriptorSetLayoutBinding layoutBinding{};
 
 			layoutBinding.binding = val.location;
 			layoutBinding.descriptorType = type;
 			layoutBinding.descriptorCount = val.count;
-			if (isCompute) {
+			if (isCompute)
 				layoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
-			}
-			else {
+			else
 				layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
-			}
 
 			bindings.push_back(layoutBinding);
 		}
 	}
 
-	if (!localUniformStagingData.empty()) {
+	if (!localUniformStagingData.empty())
+	{
 		VkDescriptorSetLayoutBinding uniformBinding{};
 		uniformBinding.binding = uniformLocation;
 		uniformBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@@ -805,23 +831,23 @@ void Shader::createDescriptorSetLayout() {
 	if (pfn_vkCmdPushDescriptorSetKHR)
 		layoutInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
 
-	if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
+	if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS)
 		throw love::Exception("failed to create descriptor set layout");
-	}
 }
 
-void Shader::createPipelineLayout() {
+void Shader::createPipelineLayout()
+{
 	VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
 	pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
 	pipelineLayoutInfo.setLayoutCount = 1;
 	pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
 	pipelineLayoutInfo.pushConstantRangeCount = 0;
 
-	if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
+	if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS)
 		throw love::Exception("failed to create pipeline layout");
-	}
 
-	if (isCompute) {
+	if (isCompute)
+	{
 		assert(shaderStages.size() == 1);
 
 		VkComputePipelineCreateInfo computeInfo{};
@@ -829,38 +855,39 @@ void Shader::createPipelineLayout() {
 		computeInfo.stage = shaderStages.at(0);
 		computeInfo.layout = pipelineLayout;
 
-		if (vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &computeInfo, nullptr, &computePipeline) != VK_SUCCESS) {
+		if (vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &computeInfo, nullptr, &computePipeline) != VK_SUCCESS)
 			throw love::Exception("failed to create compute pipeline");
-		}
 	}
 }
 
-void Shader::createStreamBuffers() {
-	auto vgfx = (Graphics*)gfx;
+void Shader::createStreamBuffers()
+{
 	const auto numImagesInFlight = vgfx->getNumImagesInFlight();
 	streamBuffers.resize(numImagesInFlight);
-	for (uint32_t i = 0; i < numImagesInFlight; i++) {
-		streamBuffers[i].push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
-	}
+	for (uint32_t i = 0; i < numImagesInFlight; i++)
+		streamBuffers[i].push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
 }
 
-void Shader::setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cbtexture, graphics::Texture* crtexture) {
+void Shader::setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cbtexture, graphics::Texture* crtexture)
+{
 	// if the shader doesn't actually use these textures they might get optimized out
 	// in that case this function becomes a noop.
-	if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_Y] != nullptr) {
+	if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_Y] != nullptr)
+	{
 		auto oldTexture = builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_Y]->textures[0];
 		ytexture->retain();
 		oldTexture->release();
 		builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_Y]->textures[0] = ytexture;
-
 	}
-	if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CB] != nullptr) {
+	if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CB] != nullptr)
+	{
 		auto oldTexture = builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CB]->textures[0];
 		cbtexture->retain();
 		oldTexture->release();
 		builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CB]->textures[0] = cbtexture;
 	}
-	if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CR] != nullptr) {
+	if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CR] != nullptr)
+	{
 		auto oldTexture = builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CR]->textures[0];
 		crtexture->retain();
 		oldTexture->release();
@@ -868,19 +895,23 @@ void Shader::setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cb
 	}
 }
 
-bool Shader::hasUniform(const std::string& name) const {
+bool Shader::hasUniform(const std::string& name) const
+{
 	return uniformInfos.find(name) != uniformInfos.end();
 }
 
-void Shader::setUniformData(BuiltinUniformData& data) {
+void Shader::setUniformData(BuiltinUniformData& data)
+{
 	char* ptr = (char*) builtinUniformInfo[BUILTIN_UNIFORMS_PER_DRAW]->data + builtinUniformDataOffset;
 	memcpy(ptr, &data, sizeof(BuiltinUniformData));
 }
 
-void Shader::setMainTex(graphics::Texture* texture) {
+void Shader::setMainTex(graphics::Texture* texture)
+{
 	// if the shader doesn't actually use the texture it might get optimized out
 	// in that case this function becomes a noop.
-	if (builtinUniformInfo[BUILTIN_TEXTURE_MAIN] != nullptr) {
+	if (builtinUniformInfo[BUILTIN_TEXTURE_MAIN] != nullptr)
+	{
 		auto oldTexture = builtinUniformInfo[BUILTIN_TEXTURE_MAIN]->textures[0];
 		texture->retain();
 		oldTexture->release();
@@ -888,8 +919,10 @@ void Shader::setMainTex(graphics::Texture* texture) {
 	}
 }
 
-VkDescriptorSet Shader::allocateDescriptorSet() {
-	if (freeDescriptorSets.empty()) {
+VkDescriptorSet Shader::allocateDescriptorSet()
+{
+	if (freeDescriptorSets.empty())
+	{
 		// fixme: we can optimize this, since sizes should never change for a given shader.
 		std::vector<VkDescriptorPoolSize> sizes;
 
@@ -899,7 +932,8 @@ VkDescriptorSet Shader::allocateDescriptorSet() {
 
 		sizes.push_back(size);
 
-		for (const auto& [key, val] : uniformInfos) {
+		for (const auto& [key, val] : uniformInfos)
+		{
 			VkDescriptorPoolSize size{};
 			auto type = Vulkan::getDescriptorType(val.baseType);
 			if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
@@ -917,9 +951,8 @@ VkDescriptorSet Shader::allocateDescriptorSet() {
 		createInfo.pPoolSizes = sizes.data();
 
 		VkDescriptorPool pool;
-		if (vkCreateDescriptorPool(device, &createInfo, nullptr, &pool) != VK_SUCCESS) {
+		if (vkCreateDescriptorPool(device, &createInfo, nullptr, &pool) != VK_SUCCESS)
 			throw love::Exception("failed to create descriptor pool");
-		}
 		descriptorPools.push_back(pool);
 
 		std::vector<VkDescriptorSetLayout> layouts(DESCRIPTOR_POOL_SIZE, descriptorSetLayout);
@@ -933,19 +966,18 @@ VkDescriptorSet Shader::allocateDescriptorSet() {
 		std::vector<VkDescriptorSet> descriptorSet;
 		descriptorSet.resize(DESCRIPTOR_POOL_SIZE);
 		VkResult result = vkAllocateDescriptorSets(device, &allocInfo, descriptorSet.data());
-		if (result != VK_SUCCESS) {
+		if (result != VK_SUCCESS)
 			throw love::Exception("failed to allocate descriptor set");
-		}
 
-		for (const auto ds : descriptorSet) {
+		for (const auto ds : descriptorSet)
 			freeDescriptorSets.push(ds);
-		}
 	}
 
 	auto ds = freeDescriptorSets.front();
 	freeDescriptorSets.pop();
 	return ds;
 }
+
 } // vulkan
 } // graphics
 } // love

+ 20 - 9
src/modules/graphics/vulkan/Shader.h

@@ -1,13 +1,15 @@
-#ifndef LOVE_GRAPHICS_VULKAN_SHADER_H
-#define LOVE_GRAPHICS_VULKAN_SHADER_H
+#pragma once
 
+// LÖVE
 #include <graphics/Shader.h>
 #include <graphics/vulkan/ShaderStage.h>
 #include "Vulkan.h"
 
+// Libraries
 #include "VulkanWrapper.h"
 #include "libraries/spirv_cross/spirv_reflect.hpp"
 
+// C++
 #include <map>
 #include <memory>
 #include <iostream>
@@ -15,10 +17,19 @@
 #include <queue>
 
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-class Shader final : public graphics::Shader, public Volatile {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+class Graphics;
+
+class Shader final
+	: public graphics::Shader
+	, public Volatile
+{
 public:
 	Shader(StrongRef<love::graphics::ShaderStage> stages[]);
 	virtual ~Shader();
@@ -94,7 +105,8 @@ private:
 
 	std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
 	std::vector<VkShaderModule> shaderModules;
-	Graphics* gfx;
+
+	Graphics *vgfx = nullptr;
 	VkDevice device;
 
 	bool isCompute = false;
@@ -113,8 +125,7 @@ private:
 	uint32_t currentUsedUniformStreamBuffersCount;
 	uint32_t currentUsedDescriptorSetsCount;
 };
+
 }
 }
 }
-
-#endif

+ 13 - 7
src/modules/graphics/vulkan/ShaderStage.cpp

@@ -1,23 +1,29 @@
 #include "ShaderStage.h"
-
 #include "Graphics.h"
 
 #include "libraries/glslang/glslang/Public/ShaderLang.h"
 #include "libraries/glslang/SPIRV/GlslangToSpv.h"
 
-#include <iostream>
 #include <fstream>
-
 #include <cstdio>
 
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-ShaderStage::ShaderStage(love::graphics::Graphics* gfx, ShaderStageType stage, const std::string& glsl, bool gles, const std::string& cachekey)
+ShaderStage::ShaderStage(love::graphics::Graphics *gfx, ShaderStageType stage, const std::string &glsl, bool gles, const std::string &cachekey)
 	: love::graphics::ShaderStage(gfx, stage, glsl, gles, cachekey) {
 	// the compilation is done in Shader.
 }
+
+ptrdiff_t ShaderStage::getHandle() const
+{
+	return 0;
+}
+
 } // love
 } // graphics
 } // vulkan

+ 13 - 12
src/modules/graphics/vulkan/ShaderStage.h

@@ -1,24 +1,25 @@
-#ifndef LOVE_GRAPHICS_VULKAN_SHADERSTAGE_H
-#define LOVE_GRAPHICS_VULKAN_SHADERSTAGE_H
+#pragma once
 
 #include "graphics/ShaderStage.h"
 #include "modules/graphics/Graphics.h"
 
 #include "VulkanWrapper.h"
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-class ShaderStage final : public graphics::ShaderStage {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+class ShaderStage final : public graphics::ShaderStage
+{
 public:
-	ShaderStage(love::graphics::Graphics* gfx, ShaderStageType stage, const std::string& glsl, bool gles, const std::string& cachekey);
+	ShaderStage(love::graphics::Graphics *gfx, ShaderStageType stage, const std::string &glsl, bool gles, const std::string &cachekey);
 
-	ptrdiff_t getHandle() const {
-		return 0;
-	}
+	ptrdiff_t getHandle() const override;
 };
+
 }
 }
 }
-
-#endif

+ 35 - 16
src/modules/graphics/vulkan/StreamBuffer.cpp

@@ -3,11 +3,17 @@
 #include "Graphics.h"
 
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-static VkBufferUsageFlags getUsageFlags(BufferUsage mode) {
-	switch (mode) {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+static VkBufferUsageFlags getUsageFlags(BufferUsage mode)
+{
+	switch (mode)
+	{
 	case BUFFERUSAGE_VERTEX: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
 	case BUFFERUSAGE_INDEX: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
 	case BUFFERUSAGE_UNIFORM: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
@@ -16,13 +22,15 @@ static VkBufferUsageFlags getUsageFlags(BufferUsage mode) {
 	}
 }
 
-StreamBuffer::StreamBuffer(graphics::Graphics* gfx, BufferUsage mode, size_t size)
-	:	love::graphics::StreamBuffer(mode, size), gfx(gfx) {
+StreamBuffer::StreamBuffer(graphics::Graphics *gfx, BufferUsage mode, size_t size)
+	: love::graphics::StreamBuffer(mode, size)
+	, vgfx(dynamic_cast<Graphics*>(gfx))
+{
 	loadVolatile();
 }
 
-bool StreamBuffer::loadVolatile() {
-	Graphics* vgfx = (Graphics*)gfx;
+bool StreamBuffer::loadVolatile()
+{
 	allocator = vgfx->getVmaAllocator();
 
 	VkBufferCreateInfo bufferInfo{};
@@ -42,37 +50,48 @@ bool StreamBuffer::loadVolatile() {
 	return true;
 }
 
-void StreamBuffer::unloadVolatile() {
+void StreamBuffer::unloadVolatile()
+{
 	if (buffer == VK_NULL_HANDLE)
 		return;
 
-	auto vgfx = (Graphics*)gfx;
 	vgfx->queueCleanUp([allocator=allocator, buffer=buffer, allocation=allocation](){
 		vmaDestroyBuffer(allocator, buffer, allocation);
 	});
 	buffer = VK_NULL_HANDLE;
 }
 
-StreamBuffer::~StreamBuffer() {
+StreamBuffer::~StreamBuffer()
+{
 	unloadVolatile();
 }
 
-love::graphics::StreamBuffer::MapInfo StreamBuffer::map(size_t minsize) {
+ptrdiff_t StreamBuffer::getHandle() const
+{
+	return (ptrdiff_t) buffer;
+}
+
+love::graphics::StreamBuffer::MapInfo StreamBuffer::map(size_t minsize)
+{
 	(void)minsize;
 	return love::graphics::StreamBuffer::MapInfo((uint8*) allocInfo.pMappedData + usedGPUMemory, getSize());
 }
 
-size_t StreamBuffer::unmap(size_t usedSize) {
+size_t StreamBuffer::unmap(size_t usedSize)
+{
 	return usedGPUMemory;
 }
 
-void StreamBuffer::markUsed(size_t usedSize) {
+void StreamBuffer::markUsed(size_t usedSize)
+{
 	usedGPUMemory += usedSize;
 }
 
-void StreamBuffer::nextFrame() {
+void StreamBuffer::nextFrame()
+{
 	usedGPUMemory = 0;
 }
+
 } // vulkan
 } // graphics
 } // love

+ 18 - 13
src/modules/graphics/vulkan/StreamBuffer.h

@@ -1,5 +1,4 @@
-#ifndef LOVE_GRAPHICS_VULKAN_STREAMBUFFER_H
-#define LOVE_GRAPHICS_VULKAN_STREAMBUFFER_H
+#pragma once
 
 #include "graphics/Volatile.h"
 #include "modules/graphics/StreamBuffer.h"
@@ -7,12 +6,21 @@
 
 #include "VulkanWrapper.h"
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-class StreamBuffer : public love::graphics::StreamBuffer, public graphics::Volatile {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+class Graphics;
+
+class StreamBuffer
+	: public love::graphics::StreamBuffer
+	, public graphics::Volatile
+{
 public:
-	StreamBuffer(graphics::Graphics* gfx, BufferUsage mode, size_t size);
+	StreamBuffer(graphics::Graphics *gfx, BufferUsage mode, size_t size);
 	virtual ~StreamBuffer();
 
 	virtual bool loadVolatile() override;
@@ -25,12 +33,10 @@ public:
 
 	void nextFrame() override;
 
-	ptrdiff_t getHandle() const override {
-		return (ptrdiff_t) buffer;
-	}
+	ptrdiff_t getHandle() const override;
 
 private:
-	graphics::Graphics* gfx;
+	Graphics *vgfx = nullptr;
 	VmaAllocator allocator;
 	VmaAllocation allocation;
 	VmaAllocationInfo allocInfo;
@@ -38,8 +44,7 @@ private:
 	size_t usedGPUMemory;
 
 };
+
 } // vulkan
 } // graphics
 } // love
-
-#endif

+ 86 - 51
src/modules/graphics/vulkan/Texture.cpp

@@ -4,22 +4,26 @@
 
 #include <limits>
 
-// make vulkan::Graphics functions available
-#define vgfx ((Graphics*)gfx)
-
-namespace love {
-namespace graphics {
-namespace vulkan {
-Texture::Texture(love::graphics::Graphics* gfx, const Settings& settings, const Slices* data)
-	: love::graphics::Texture(gfx, settings, data), gfx(gfx), slices(settings.type) {
-	if (data) {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
+Texture::Texture(love::graphics::Graphics *gfx, const Settings &settings, const Slices *data)
+	: love::graphics::Texture(gfx, settings, data)
+	, vgfx(dynamic_cast<Graphics*>(gfx))
+	, slices(settings.type)
+{
+	if (data)
 		slices = *data;
-	}
 
 	loadVolatile();
 }
 
-bool Texture::loadVolatile() {
+bool Texture::loadVolatile()
+{
 	allocator = vgfx->getVmaAllocator();
 	device = vgfx->getDevice();
 
@@ -44,10 +48,10 @@ bool Texture::loadVolatile() {
 
 	layerCount = 1;
 
-	if (texType == TEXTURE_2D_ARRAY) {
+	if (texType == TEXTURE_2D_ARRAY)
 		layerCount = getLayerCount();
-	}
-	else if (texType == TEXTURE_CUBE) {
+	else if (texType == TEXTURE_CUBE)
+	{
 		layerCount = 6;
 		createFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
 	}
@@ -70,9 +74,8 @@ bool Texture::loadVolatile() {
 
 	VmaAllocationCreateInfo imageAllocationCreateInfo{};
 
-	if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS) {
+	if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS)
 		throw love::Exception("failed to create image");
-	}
 
 	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
 
@@ -90,37 +93,36 @@ bool Texture::loadVolatile() {
 
 	bool hasdata = slices.get(0, 0) != nullptr;
 
-	if (hasdata) {
-		for (int mip = 0; mip < layerCount; mip++) {
+	if (hasdata)
+		for (int mip = 0; mip < layerCount; mip++)
+		{
 			// fixme: deal with compressed images.
 
 			int sliceCount;
-			if (texType == TEXTURE_CUBE) {
+			if (texType == TEXTURE_CUBE)
 				sliceCount = 6;
-			} else {
+			else
 				sliceCount = slices.getSliceCount();
-			}
-			for (int slice = 0; slice < sliceCount; slice++) {
+			for (int slice = 0; slice < sliceCount; slice++)
+			{
 				auto* id = slices.get(slice, mip);
-				if (id != nullptr) {
+				if (id != nullptr)
 					uploadImageData(id, mip, slice, 0, 0);
-				}
 			}
 		}
-	} else {
+	else
 		clear();
-	}
 	createTextureImageView();
 	textureSampler = vgfx->getCachedSampler(samplerState);
 
-	if (slices.getMipmapCount() <= 1 && getMipmapsMode() != MIPMAPS_NONE) {
+	if (slices.getMipmapCount() <= 1 && getMipmapsMode() != MIPMAPS_NONE)
 		generateMipmaps();
-	}
 
 	return true;
 }
 
-void Texture::unloadVolatile() {
+void Texture::unloadVolatile()
+{
 	if (textureImage == VK_NULL_HANDLE)
 		return;
 
@@ -137,20 +139,44 @@ void Texture::unloadVolatile() {
 	textureImage = VK_NULL_HANDLE;
 }
 
-Texture::~Texture() {
+Texture::~Texture()
+{
 	unloadVolatile();
 }
 
-void Texture::setSamplerState(const SamplerState &s) {
+ptrdiff_t Texture::getRenderTargetHandle() const
+{
+	return (ptrdiff_t)textureImageView;
+}
+
+ptrdiff_t Texture::getSamplerHandle() const
+{
+	return (ptrdiff_t)textureSampler;
+}
+
+int Texture::getMSAA() const
+{
+	return 0;
+}
+
+ptrdiff_t Texture::getHandle() const
+{
+	return (ptrdiff_t)textureImage;
+}
+
+void Texture::setSamplerState(const SamplerState &s)
+{
 	love::graphics::Texture::setSamplerState(s);
 	textureSampler = vgfx->getCachedSampler(s);
 }
 
-VkImageLayout Texture::getImageLayout() const {
+VkImageLayout Texture::getImageLayout() const
+{
 	return imageLayout;
 }
 
-void Texture::createTextureImageView() {
+void Texture::createTextureImageView()
+{
 	auto vulkanFormat = Vulkan::getTextureFormat(format);
 
 	VkImageViewCreateInfo viewInfo{};
@@ -168,12 +194,12 @@ void Texture::createTextureImageView() {
 	viewInfo.components.b = vulkanFormat.swizzleB;
 	viewInfo.components.a = vulkanFormat.swizzleA;
 
-	if (vkCreateImageView(device, &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) {
+	if (vkCreateImageView(device, &viewInfo, nullptr, &textureImageView) != VK_SUCCESS)
 		throw love::Exception("could not create texture image view");
-	}
 }
 
-void Texture::clear() {
+void Texture::clear()
+{
 	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
 
 	auto clearColor = getClearValue();
@@ -185,7 +211,8 @@ void Texture::clear() {
 	range.baseArrayLayer = 0;
 	range.layerCount = VK_REMAINING_ARRAY_LAYERS;
 
-	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL) {
+	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
+	{
 		Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, 
 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 
 			0, range.levelCount, 0, range.layerCount);
@@ -196,16 +223,17 @@ void Texture::clear() {
 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 
 			0, range.levelCount, 0, range.layerCount);
 	}
-	else {
+	else
 		vkCmdClearColorImage(commandBuffer, textureImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &range);
-	}
 }
 
-VkClearColorValue Texture::getClearValue() {
+VkClearColorValue Texture::getClearValue()
+{
 	auto vulkanFormat = Vulkan::getTextureFormat(format);
 
 	VkClearColorValue clearColor{};
-	switch (vulkanFormat.internalFormatRepresentation) {
+	switch (vulkanFormat.internalFormatRepresentation)
+	{
 	case FORMATREPRESENTATION_FLOAT:
 		clearColor.float32[0] = 0.0f;
 		clearColor.float32[1] = 0.0f;
@@ -228,7 +256,8 @@ VkClearColorValue Texture::getClearValue() {
 	return clearColor;
 }
 
-void Texture::generateMipmapsInternal() {
+void Texture::generateMipmapsInternal()
+{
 	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
 
 	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
@@ -249,7 +278,8 @@ void Texture::generateMipmapsInternal() {
 
 	uint32_t mipLevels = static_cast<uint32_t>(getMipmapCount());
 
-	for (uint32_t i = 1; i < mipLevels; i++) {
+	for (uint32_t i = 1; i < mipLevels; i++)
+	{
 		barrier.subresourceRange.baseMipLevel = i - 1;
 		barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
 		barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
@@ -309,7 +339,8 @@ void Texture::generateMipmapsInternal() {
 			1, &barrier);
 }
 
-void Texture::uploadByteData(PixelFormat pixelformat, const void* data, size_t size, int level, int slice, const Rect& r) {
+void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r)
+{
 	VkBuffer stagingBuffer;
 	VmaAllocation vmaAllocation;
 
@@ -346,7 +377,8 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void* data, size_t s
 	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
 
 
-	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL) {
+	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
+	{
 		Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, 
 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 
 			level, 1, slice, 1);
@@ -365,7 +397,7 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void* data, size_t s
 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
 			level, 1, slice, 1);
 	}
-	else {
+	else
 		vkCmdCopyBufferToImage(
 			commandBuffer,
 			stagingBuffer,
@@ -374,14 +406,14 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void* data, size_t s
 			1,
 			&region
 		);
-	}
 
 	vgfx->queueCleanUp([allocator = allocator, stagingBuffer, vmaAllocation]() {
 		vmaDestroyBuffer(allocator, stagingBuffer, vmaAllocation);
 	});
 }
 
-void Texture::copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) {
+void Texture::copyFromBuffer(graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect)
+{
 	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
 
 	VkImageSubresourceLayers layers{};
@@ -398,7 +430,8 @@ void Texture::copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int
 	region.imageExtent.width = static_cast<uint32_t>(rect.w);
 	region.imageExtent.height = static_cast<uint32_t>(rect.h);
 
-	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL) {
+	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
+	{
 		Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
 
 		vkCmdCopyBufferToImage(commandBuffer, (VkBuffer)source->getHandle(), textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
@@ -409,7 +442,8 @@ void Texture::copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int
 		vkCmdCopyBufferToImage(commandBuffer, (VkBuffer)source->getHandle(), textureImage, VK_IMAGE_LAYOUT_GENERAL, 1, &region);
 }
 
-void Texture::copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) {
+void Texture::copyToBuffer(graphics::Buffer *dest, int slice, int mipmap, const Rect &rect, size_t destoffset, int destwidth, size_t size)
+{
 	auto commandBuffer = vgfx->getReadbackCommandBuffer();
 
 	VkImageSubresourceLayers layers{};
@@ -427,7 +461,8 @@ void Texture::copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const
 	region.imageExtent.height = static_cast<uint32_t>(rect.h);
 	region.imageExtent.depth = 1;
 
-	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL) {
+	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
+	{
 		Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
 
 		vkCmdCopyImageToBuffer(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, (VkBuffer) dest->getHandle(), 1, &region);

+ 23 - 18
src/modules/graphics/vulkan/Texture.h

@@ -1,20 +1,26 @@
-#ifndef LOVE_GRAPHICS_VULKAN_TEXTURE_H
-#define LOVE_GRAPHICS_VULKAN_TEXTURE_H
+#pragma once
 
 #include "graphics/Texture.h"
 #include "graphics/Volatile.h"
 
 #include "VulkanWrapper.h"
 
-#include <iostream>
 
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-class Texture : public graphics::Texture, public Volatile {
+class Graphics;
+
+class Texture
+	: public graphics::Texture
+	, public Volatile
+{
 public:
-	Texture(love::graphics::Graphics* gfx, const Settings& settings, const Slices* data);
+	Texture(love::graphics::Graphics *gfx, const Settings &settings, const Slices *data);
 	~Texture();
 
 	virtual bool loadVolatile() override;
@@ -24,18 +30,18 @@ public:
 
 	VkImageLayout getImageLayout() const;
 
-	void copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) override;
-	void copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) override;
+	void copyFromBuffer(graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect) override;
+	void copyToBuffer(graphics::Buffer *dest, int slice, int mipmap, const Rect &rect, size_t destoffset, int destwidth, size_t size) override;
 
-	ptrdiff_t getRenderTargetHandle() const override { return (ptrdiff_t)textureImageView; };
-	ptrdiff_t getSamplerHandle() const override { return (ptrdiff_t)textureSampler; };
+	ptrdiff_t getRenderTargetHandle() const override;
+	ptrdiff_t getSamplerHandle() const override;
 
-	void uploadByteData(PixelFormat pixelformat, const void* data, size_t size, int level, int slice, const Rect& r) override;
+	void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r) override;
 
 	void generateMipmapsInternal()  override;
 
-	int getMSAA() const override { return 0; };
-	ptrdiff_t getHandle() const override { return (ptrdiff_t)textureImage; }
+	int getMSAA() const override;
+	ptrdiff_t getHandle() const override;
 
 private:
 	void createTextureImageView();
@@ -43,7 +49,7 @@ private:
 
 	VkClearColorValue getClearValue();
 
-	graphics::Graphics* gfx = nullptr;
+	Graphics *vgfx = nullptr;
 	VkDevice device = VK_NULL_HANDLE;
 	VmaAllocator allocator = VK_NULL_HANDLE;
 	VkImage textureImage = VK_NULL_HANDLE;
@@ -54,8 +60,7 @@ private:
 	Slices slices;
 	int layerCount = 0;
 };
+
 } // vulkan
 } // graphics
 } // love
-
-#endif

+ 124 - 74
src/modules/graphics/vulkan/Vulkan.cpp

@@ -3,34 +3,45 @@
 #include <sstream>
 
 
-namespace love {
-namespace graphics {
-namespace vulkan {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan
+{
+
 static uint32_t numShaderSwitches;
 static int vsync = 1;
 
-void Vulkan::shaderSwitch() {
+void Vulkan::shaderSwitch()
+{
 	numShaderSwitches++;
 }
 
-uint32_t Vulkan::getNumShaderSwitches() {
+uint32_t Vulkan::getNumShaderSwitches()
+{
 	return numShaderSwitches;
 }
 
-void Vulkan::resetShaderSwitches() {
+void Vulkan::resetShaderSwitches()
+{
 	numShaderSwitches = 0;
 }
 
-void Vulkan::setVsync(int value) {
+void Vulkan::setVsync(int value)
+{
 	vsync = value;
 }
 
-int Vulkan::getVsync() {
+int Vulkan::getVsync()
+{
 	return vsync;
 }
 
-VkFormat Vulkan::getVulkanVertexFormat(DataFormat format) {
-	switch (format) {
+VkFormat Vulkan::getVulkanVertexFormat(DataFormat format)
+{
+	switch (format)
+	{
 	case DATAFORMAT_FLOAT:
 		return VK_FORMAT_R32_SFLOAT;
 	case DATAFORMAT_FLOAT_VEC2:
@@ -110,10 +121,12 @@ VkFormat Vulkan::getVulkanVertexFormat(DataFormat format) {
 	}
 }
 
-TextureFormat Vulkan::getTextureFormat(PixelFormat format) {
+TextureFormat Vulkan::getTextureFormat(PixelFormat format)
+{
 	TextureFormat textureFormat{};
 
-	switch (format) {
+	switch (format)
+	{
 		case PIXELFORMAT_UNKNOWN:
 			throw love::Exception("unknown pixel format");
 		case PIXELFORMAT_NORMAL:
@@ -353,8 +366,10 @@ TextureFormat Vulkan::getTextureFormat(PixelFormat format) {
 
 // values taken from https://pcisig.com/membership/member-companies
 // as specified at https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceProperties.html
-std::string Vulkan::getVendorName(uint32_t vendorId) {
-	switch (vendorId) {
+std::string Vulkan::getVendorName(uint32_t vendorId)
+{
+	switch (vendorId)
+	{
 	case 4130:
 		return "AMD";
 	case 4318:
@@ -376,7 +391,8 @@ std::string Vulkan::getVendorName(uint32_t vendorId) {
 	}
 }
 
-std::string Vulkan::getVulkanApiVersion(uint32_t version) {
+std::string Vulkan::getVulkanApiVersion(uint32_t version)
+{
 	std::stringstream ss;
 
 	ss << VK_API_VERSION_MAJOR(version) 
@@ -386,8 +402,10 @@ std::string Vulkan::getVulkanApiVersion(uint32_t version) {
 	return ss.str();
 }
 
-VkPrimitiveTopology Vulkan::getPrimitiveTypeTopology(graphics::PrimitiveType primitiveType) {
-	switch (primitiveType) {
+VkPrimitiveTopology Vulkan::getPrimitiveTypeTopology(graphics::PrimitiveType primitiveType)
+{
+	switch (primitiveType)
+	{
 	case PRIMITIVE_POINTS:
 		return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
 	case PRIMITIVE_TRIANGLES:
@@ -401,8 +419,10 @@ VkPrimitiveTopology Vulkan::getPrimitiveTypeTopology(graphics::PrimitiveType pri
 	}
 }
 
-VkBlendFactor Vulkan::getBlendFactor(BlendFactor blendFactor) {
-	switch (blendFactor) {
+VkBlendFactor Vulkan::getBlendFactor(BlendFactor blendFactor)
+{
+	switch (blendFactor)
+	{
 	case BLENDFACTOR_ZERO:
 		return VK_BLEND_FACTOR_ZERO;
 	case BLENDFACTOR_ONE:
@@ -430,8 +450,10 @@ VkBlendFactor Vulkan::getBlendFactor(BlendFactor blendFactor) {
 	}
 }
 
-VkBlendOp Vulkan::getBlendOp(BlendOperation op) {
-	switch (op) {
+VkBlendOp Vulkan::getBlendOp(BlendOperation op)
+{
+	switch (op)
+	{
 	case BLENDOP_ADD:
 		return VK_BLEND_OP_ADD;
 	case BLENDOP_MAX:
@@ -447,35 +469,34 @@ VkBlendOp Vulkan::getBlendOp(BlendOperation op) {
 	}
 }
 
-VkBool32 Vulkan::getBool(bool b) {
-	if (b) {
+VkBool32 Vulkan::getBool(bool b)
+{
+	if (b)
 		return VK_TRUE;
-	} else {
+	else
 		return VK_FALSE;
-	}
 }
 
-VkColorComponentFlags Vulkan::getColorMask(ColorChannelMask mask) {
+VkColorComponentFlags Vulkan::getColorMask(ColorChannelMask mask)
+{
 	VkColorComponentFlags flags = 0;
 
-	if (mask.r) {
+	if (mask.r)
 		flags |= VK_COLOR_COMPONENT_R_BIT;
-	}
-	if (mask.g) {
+	if (mask.g)
 		flags |= VK_COLOR_COMPONENT_G_BIT;
-	}
-	if (mask.b) {
+	if (mask.b)
 		flags |= VK_COLOR_COMPONENT_B_BIT;
-	}
-	if (mask.a) {
+	if (mask.a)
 		flags |= VK_COLOR_COMPONENT_A_BIT;
-	}
 
 	return flags;
 }
 
-VkFrontFace Vulkan::getFrontFace(Winding winding) {
-	switch (winding) {
+VkFrontFace Vulkan::getFrontFace(Winding winding)
+{
+	switch (winding)
+	{
 	case WINDING_CW:
 		return VK_FRONT_FACE_CLOCKWISE;
 	case WINDING_CCW:
@@ -485,8 +506,10 @@ VkFrontFace Vulkan::getFrontFace(Winding winding) {
 	}
 }
 
-VkCullModeFlags Vulkan::getCullMode(CullMode cullmode) {
-	switch (cullmode) {
+VkCullModeFlags Vulkan::getCullMode(CullMode cullmode)
+{
+	switch (cullmode)
+	{
 	case CULL_BACK:
 		return VK_CULL_MODE_BACK_BIT;
 	case CULL_FRONT:
@@ -498,8 +521,10 @@ VkCullModeFlags Vulkan::getCullMode(CullMode cullmode) {
 	}
 }
 
-VkImageType Vulkan::getImageType(TextureType textureType) {
-	switch (textureType) {
+VkImageType Vulkan::getImageType(TextureType textureType)
+{
+	switch (textureType)
+	{
 	case TEXTURE_2D:
 	case TEXTURE_2D_ARRAY:
 	case TEXTURE_CUBE:
@@ -511,8 +536,10 @@ VkImageType Vulkan::getImageType(TextureType textureType) {
 	}
 }
 
-VkImageViewType Vulkan::getImageViewType(TextureType textureType) {
-	switch (textureType) {
+VkImageViewType Vulkan::getImageViewType(TextureType textureType)
+{
+	switch (textureType)
+	{
 	case TEXTURE_2D:
 		return VK_IMAGE_VIEW_TYPE_2D;
 	case TEXTURE_2D_ARRAY:
@@ -526,16 +553,18 @@ VkImageViewType Vulkan::getImageViewType(TextureType textureType) {
 	}
 }
 
-VkPolygonMode Vulkan::getPolygonMode(bool wireframe) {
-	if (wireframe) {
+VkPolygonMode Vulkan::getPolygonMode(bool wireframe)
+{
+	if (wireframe)
 		return VK_POLYGON_MODE_LINE;
-	} else {
+	else
 		return VK_POLYGON_MODE_FILL;
-	}
 }
 
-VkFilter Vulkan::getFilter(SamplerState::FilterMode mode) {
-	switch (mode) {
+VkFilter Vulkan::getFilter(SamplerState::FilterMode mode)
+{
+	switch (mode)
+	{
 	case SamplerState::FILTER_LINEAR:
 		return VK_FILTER_LINEAR;
 	case SamplerState::FILTER_NEAREST:
@@ -545,8 +574,10 @@ VkFilter Vulkan::getFilter(SamplerState::FilterMode mode) {
 	}
 }
 
-VkSamplerAddressMode Vulkan::getWrapMode(SamplerState::WrapMode mode) {
-	switch (mode) {
+VkSamplerAddressMode Vulkan::getWrapMode(SamplerState::WrapMode mode)
+{
+	switch (mode)
+	{
 		//fixme: not accounting for different clamps (how does that work in vulkan?)
 	case SamplerState::WRAP_CLAMP:
 	case SamplerState::WRAP_CLAMP_ZERO:
@@ -561,8 +592,10 @@ VkSamplerAddressMode Vulkan::getWrapMode(SamplerState::WrapMode mode) {
 	}
 }
 
-VkCompareOp Vulkan::getCompareOp(CompareMode mode) {
-	switch (mode) {
+VkCompareOp Vulkan::getCompareOp(CompareMode mode)
+{
+	switch (mode)
+	{
 	case COMPARE_LESS:
 		return VK_COMPARE_OP_LESS;
 	case COMPARE_LEQUAL:
@@ -584,8 +617,10 @@ VkCompareOp Vulkan::getCompareOp(CompareMode mode) {
 	}
 }
 
-VkSamplerMipmapMode Vulkan::getMipMapMode(SamplerState::MipmapFilterMode mode) {
-	switch (mode) {
+VkSamplerMipmapMode Vulkan::getMipMapMode(SamplerState::MipmapFilterMode mode)
+{
+	switch (mode)
+	{
 	case SamplerState::MIPMAP_FILTER_NEAREST:
 		return VK_SAMPLER_MIPMAP_MODE_NEAREST;
 	case SamplerState::MIPMAP_FILTER_NONE:
@@ -595,9 +630,10 @@ VkSamplerMipmapMode Vulkan::getMipMapMode(SamplerState::MipmapFilterMode mode) {
 	}
 }
 
-
-VkDescriptorType Vulkan::getDescriptorType(graphics::Shader::UniformType type) {
-	switch (type) {
+VkDescriptorType Vulkan::getDescriptorType(graphics::Shader::UniformType type)
+{
+	switch (type)
+	{
 	case graphics::Shader::UniformType::UNIFORM_FLOAT:
 	case graphics::Shader::UniformType::UNIFORM_MATRIX:
 	case graphics::Shader::UniformType::UNIFORM_INT:
@@ -617,8 +653,10 @@ VkDescriptorType Vulkan::getDescriptorType(graphics::Shader::UniformType type) {
 	}
 }
 
-VkStencilOp Vulkan::getStencilOp(StencilAction action) {
-	switch (action) {
+VkStencilOp Vulkan::getStencilOp(StencilAction action)
+{
+	switch (action)
+	{
 	case STENCIL_KEEP:
 		return VK_STENCIL_OP_KEEP;
 	case STENCIL_ZERO:
@@ -640,8 +678,10 @@ VkStencilOp Vulkan::getStencilOp(StencilAction action) {
 	}
 }
 
-VkIndexType Vulkan::getVulkanIndexBufferType(IndexDataType type) {
-	switch (type) {
+VkIndexType Vulkan::getVulkanIndexBufferType(IndexDataType type)
+{
+	switch (type)
+	{
 	case INDEX_UINT16: return VK_INDEX_TYPE_UINT16;
 	case INDEX_UINT32: return VK_INDEX_TYPE_UINT32;
 	default:
@@ -650,7 +690,8 @@ VkIndexType Vulkan::getVulkanIndexBufferType(IndexDataType type) {
 }
 
 void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout,
-	uint32_t baseLevel, uint32_t levelCount, uint32_t baseLayer, uint32_t layerCount) {
+	uint32_t baseLevel, uint32_t levelCount, uint32_t baseLayer, uint32_t layerCount)
+{
 	VkImageMemoryBarrier barrier{};
 	barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
 	barrier.oldLayout = oldLayout;
@@ -667,63 +708,72 @@ void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage ima
 	VkPipelineStageFlags sourceStage;
 	VkPipelineStageFlags destinationStage;
 
-	if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
+	if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
+	{
 		barrier.srcAccessMask = 0;
 		barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
 		destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
 	}
-	else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
+	{
 		barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
 		barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
 		destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
 	}
-	else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
+	{
 		barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
 		barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
 		destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
 	}
-	else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
+	{
 		barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
 		barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
 		destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
 	}
-	else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
+	{
 		barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
 		barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
 		destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
 	}
-	else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
+	{
 		barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
 		barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
 		destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
 	}
-	else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
+	{
 		barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
 		barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
 		destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
 	}
-	else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
+	{
 		barrier.srcAccessMask = 0;
 		barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
 		destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
 	}
-	else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
+	{
 		barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
 		barrier.dstAccessMask = 0;
 
@@ -731,16 +781,16 @@ void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage ima
 		destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
 	}
 	// we use general for images that are both sampled and compute write
-	else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_GENERAL) {
+	else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_GENERAL)
+	{
 		barrier.srcAccessMask = 0;
 		barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
 
 		sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
 		destinationStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
 	}
-	else {
+	else
 		throw std::invalid_argument("unsupported layout transition!");
-	}
 
 	vkCmdPipelineBarrier(
 		commandBuffer,

+ 15 - 10
src/modules/graphics/vulkan/Vulkan.h

@@ -1,20 +1,25 @@
-#ifndef LOVE_GRAPHICS_VULKAN_VULKAN_H
-#define LOVE_GRAPHICS_VULKAN_VULKAN_H
+#pragma once
 
 #include "graphics/Graphics.h"
 #include "VulkanWrapper.h"
 
-namespace love {
-namespace graphics {
-namespace vulkan {
-enum InternalFormatRepresentation {
+namespace love
+{
+namespace graphics
+{
+namespace vulkan 
+{
+
+enum InternalFormatRepresentation
+{
 	FORMATREPRESENTATION_FLOAT,
 	FORMATREPRESENTATION_UINT,
 	FORMATREPRESENTATION_SINT,
 	FORMATREPRESENTATION_MAX_ENUM
 };
 
-struct TextureFormat {
+struct TextureFormat
+{
 	InternalFormatRepresentation internalFormatRepresentation;
 	VkFormat internalFormat = VK_FORMAT_UNDEFINED;
 
@@ -24,7 +29,8 @@ struct TextureFormat {
 	VkComponentSwizzle swizzleA = VK_COMPONENT_SWIZZLE_IDENTITY;
 };
 
-class Vulkan {
+class Vulkan
+{
 public:
 	static void shaderSwitch();
 	static uint32_t getNumShaderSwitches();
@@ -59,8 +65,7 @@ public:
 		VkCommandBuffer, VkImage, VkImageLayout oldLayout, VkImageLayout newLayout,
 		uint32_t baseLevel = 0, uint32_t levelCount = 1, uint32_t baseLayer = 0, uint32_t layerCount = 1);
 };
+
 } // vulkan
 } // graphics
 } // love
-
-#endif

+ 1 - 4
src/modules/graphics/vulkan/VulkanWrapper.h

@@ -1,5 +1,4 @@
-#ifndef LOVE_GRAPHICS_VULKAN_VULKANWRAPPER_H
-#define LOVE_GRAPHICS_VULKAN_VULKANWRAPPER_H
+#pragma once
 
 #include "common/config.h"
 
@@ -13,5 +12,3 @@
 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
 #endif
 #include "vk_mem_alloc.h"
-
-#endif //LOVE_GRAPHICS_VULKAN_VULKANWRAPPER_H

Some files were not shown because too many files changed in this diff