Browse Source

vulkan: fix vertex format

niki 3 years ago
parent
commit
7fe2a2d821
2 changed files with 48 additions and 77 deletions
  1. 45 73
      src/modules/graphics/vulkan/Graphics.cpp
  2. 3 4
      src/modules/graphics/vulkan/Graphics.h

+ 45 - 73
src/modules/graphics/vulkan/Graphics.cpp

@@ -8,6 +8,7 @@
 #include "Vulkan.h"
 #include "common/version.h"
 
+#include <algorithm>
 #include <vector>
 #include <cstring>
 #include <set>
@@ -320,40 +321,8 @@ namespace love {
 			void Graphics::draw(const DrawIndexedCommand& cmd) {
 				std::cout << "drawIndexed ";
 
-				std::vector<VkBuffer> buffers;
-				std::vector<VkDeviceSize> offsets;
-
-				bool useConstantColorBuffer;
-				GraphicsPipelineConfiguration configuration;
-				createVulkanVertexFormat(*cmd.attributes, useConstantColorBuffer, configuration);
-
-				for (uint32_t i = 0; i < 2; i++) {
-					if (cmd.buffers->useBits & (1u << i)) {
-						buffers.push_back((VkBuffer)cmd.buffers->info[i].buffer->getHandle());
-						offsets.push_back((VkDeviceSize)cmd.buffers->info[i].offset);
-					}
-					else {
-						buffers.push_back(VK_NULL_HANDLE);
-						offsets.push_back(0);
-					}
-				}
-
-				if (useConstantColorBuffer) {
-					buffers.push_back((VkBuffer)batchedDrawBuffers[currentFrame].constantColorBuffer->getHandle());
-					offsets.push_back((VkDeviceSize)0);
-				}
+				prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture);
 
-				if (cmd.texture == nullptr) {
-					setTexture(standardTexture);
-				}
-				else {
-					setTexture(cmd.texture);
-				}
-
-				ensureGraphicsPipelineConfiguration(configuration);
-
-				vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, getDescriptorSet(currentFrame), 0, nullptr);
-				vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, buffers.size(), buffers.data(), offsets.data());
 				vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), 0, getVulkanIndexBufferType(cmd.indexType));
 				vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.indexCount), 1, 0, 0, 0);
 			}
@@ -388,51 +357,16 @@ namespace love {
 				const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
 				const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4;
 
-				std::vector<VkBuffer> bufferVector;
-				std::vector<VkDeviceSize> offsets;
-
-				bool useConstantColorBuffer;
-				GraphicsPipelineConfiguration configuration;
-				createVulkanVertexFormat(attributes, useConstantColorBuffer, configuration);
-
-				for (uint32_t i = 0; i < 2; i++) {
-					if (buffers.useBits & (1u << i)) {
-						bufferVector.push_back((VkBuffer)buffers.info[i].buffer->getHandle());
-						offsets.push_back((VkDeviceSize)buffers.info[i].offset);
-					}
-					else {
-						if (useConstantColorBuffer) {
-							bufferVector.push_back(VK_NULL_HANDLE);
-							offsets.push_back(0);
-						}
-					}
-				}
-
-				if (useConstantColorBuffer) {
-					bufferVector.push_back((VkBuffer)batchedDrawBuffers[currentFrame].constantColorBuffer->getHandle());
-					offsets.push_back((VkDeviceSize)0);
-				}
-
-				if (texture == nullptr) {
-					setTexture(standardTexture);
-				}
-				else {
-					setTexture(texture);
-				}
+				prepareDraw(attributes, buffers, texture);
 
-				ensureGraphicsPipelineConfiguration(configuration);
-
-				vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, getDescriptorSet(currentFrame), 0, nullptr);
 				vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16));
-				vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, bufferVector.size(), bufferVector.data(), offsets.data());
-				vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(count * 6), 1, 0, 0, 0);
 				
 				int baseVertex = start * 4;
 
 				for (int quadindex = 0; quadindex < count; quadindex += MAX_QUADS_PER_DRAW) {
 					int quadcount = std::min(MAX_QUADS_PER_DRAW, count - quadindex);
 
-					// vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(quadcount * 6), 1, 0, baseVertex, 0);
+					vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(quadcount * 6), 1, 0, baseVertex, 0);
 					baseVertex += quadcount * 4;
 				}
 			}
@@ -444,7 +378,7 @@ namespace love {
 
 			Matrix4 Graphics::computeDeviceProjection(const Matrix4& projection, bool rendertotexture) const { 
 				uint32 flags = DEVICE_PROJECTION_DEFAULT;
-				return calculateDeviceProjection(projection, 0);
+				return calculateDeviceProjection(projection, flags);
 			}
 
 			// END IMPLEMENTATION OVERRIDDEN FUNCTIONS
@@ -463,7 +397,7 @@ namespace love {
 			}
 
 			VkDescriptorSet* Graphics::getDescriptorSet(int currentFrame) {
-				DecriptorSetConfiguration config;
+				DecriptorSetConfiguration config{};
 				config.texture = currentTexture;
 				config.buffer = getUniformBuffer();
 				for (auto i = 0; i < descriptorSetsMap.size(); i++) {
@@ -1164,6 +1098,8 @@ namespace love {
 				auto allBits = vertexAttributes.enableBits;
 
 				bool usesColor = false;
+
+				uint8_t highestBufferBinding = 0;
 				
 				for (uint32_t i = 0; i < VertexAttributes::MAX; i++) {	// change to loop like in opengl implementation ?
 					uint32 bit = 1u << i;
@@ -1182,6 +1118,8 @@ namespace love {
 							bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
 							bindingDescription.stride = vertexAttributes.bufferLayouts[bufferBinding].stride;
 							bindingDescriptions.push_back(bindingDescription);
+
+							highestBufferBinding = std::max(highestBufferBinding, bufferBinding);
 						}
 
 						VkVertexInputAttributeDescription attributeDescription{};
@@ -1196,7 +1134,7 @@ namespace love {
 
 				// do we need to use a constant VertexColor?
 				if (!usesColor) {
-					constexpr uint32_t constantColorBufferBinding = 2;
+					const auto constantColorBufferBinding = highestBufferBinding + 1;
 
 					VkVertexInputBindingDescription bindingDescription{};
 					bindingDescription.binding = constantColorBufferBinding;
@@ -1209,6 +1147,7 @@ namespace love {
 					attributeDescription.location = ATTRIB_COLOR;
 					attributeDescription.offset = 0;
 					attributeDescription.format = VK_FORMAT_R32G32B32A32_SFLOAT;
+					attributeDescriptions.push_back(attributeDescription);
 
 					useConstantVertexColor = true;
 				}
@@ -1220,6 +1159,39 @@ namespace love {
 				configuration.vertexInputAttributeDescriptions = attributeDescriptions;
 			}
 
+			void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) {
+				std::vector<VkBuffer> bufferVector;
+				std::vector<VkDeviceSize> offsets;
+
+				bool useConstantColorBuffer;
+				GraphicsPipelineConfiguration configuration;
+				createVulkanVertexFormat(attributes, useConstantColorBuffer, configuration);
+
+				for (uint32_t i = 0; i < 2; i++) {
+					if (buffers.useBits & (1u << i)) {
+						bufferVector.push_back((VkBuffer)buffers.info[i].buffer->getHandle());
+						offsets.push_back((VkDeviceSize)buffers.info[i].offset);
+					}
+				}
+
+				if (useConstantColorBuffer) {
+					bufferVector.push_back((VkBuffer)batchedDrawBuffers[currentFrame].constantColorBuffer->getHandle());
+					offsets.push_back((VkDeviceSize)0);
+				}
+
+				if (texture == nullptr) {
+					setTexture(standardTexture);
+				}
+				else {
+					setTexture(texture);
+				}
+
+				ensureGraphicsPipelineConfiguration(configuration);
+
+				vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, getDescriptorSet(currentFrame), 0, nullptr);
+				vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, bufferVector.size(), bufferVector.data(), offsets.data());
+			}
+
 			VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration configuration) {
 				auto shader = reinterpret_cast<love::graphics::vulkan::Shader*>(love::graphics::vulkan::Shader::standardShaders[Shader::STANDARD_DEFAULT]);
 				auto shaderStages = shader->getShaderStages();

+ 3 - 4
src/modules/graphics/vulkan/Graphics.h

@@ -59,7 +59,7 @@ namespace love {
 			};
 
 			struct SwapChainSupportDetails {
-				VkSurfaceCapabilitiesKHR capabilities;
+				VkSurfaceCapabilitiesKHR capabilities{};
 				std::vector<VkSurfaceFormatKHR> formats;
 				std::vector<VkPresentModeKHR> presentModes;
 			};
@@ -116,8 +116,6 @@ namespace love {
 				VkCommandBuffer beginSingleTimeCommands();
 				void endSingleTimeCommands(VkCommandBuffer);
 
-				void setShader(Shader*);
-
 			protected:
 				graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override { 
 					std::cout << "newShaderStageInternal "; 
@@ -174,7 +172,8 @@ namespace love {
 				VkDescriptorSet* getDescriptorSet(int currentFrame);
 				graphics::StreamBuffer* getUniformBuffer();
 				void createVulkanVertexFormat(VertexAttributes vertexAttributes, bool& useConstantVertexColor, GraphicsPipelineConfiguration& configuration);
-				
+				void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture);
+
 				VkInstance instance = VK_NULL_HANDLE;
 				VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
 				VkDevice device = VK_NULL_HANDLE;