Skip to content

Commit

Permalink
Merge branch 'main' into CI-vulkan
Browse files Browse the repository at this point in the history
  • Loading branch information
slime73 committed Jun 24, 2024
2 parents 5600a54 + b16e1d6 commit ce7a80d
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 106 deletions.
24 changes: 11 additions & 13 deletions src/common/android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,26 +98,24 @@ bool getSafeArea(int &top, int &left, int &bottom, int &right)
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
jobject activity = (jobject) SDL_AndroidGetActivity();
jclass clazz = env->GetObjectClass(activity);
jclass rectClass = env->FindClass("android/graphics/Rect");
jmethodID methodID = env->GetMethodID(clazz, "getSafeArea", "()Landroid/graphics/Rect;");
jobject safeArea = env->CallObjectMethod(activity, methodID);

static jmethodID methodID = env->GetMethodID(clazz, "getSafeArea", "()Z");

bool hasSafeArea = false;

if (methodID == nullptr)
// NoSuchMethodException is thrown in case methodID is null
env->ExceptionClear();
else if ((hasSafeArea = env->CallBooleanMethod(activity, methodID)))
if (safeArea != nullptr)
{
top = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaTop", "I"));
left = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaLeft", "I"));
bottom = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaBottom", "I"));
right = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaRight", "I"));
top = env->GetIntField(activity, env->GetFieldID(rectClass, "top", "I"));
left = env->GetIntField(activity, env->GetFieldID(rectClass, "left", "I"));
bottom = env->GetIntField(activity, env->GetFieldID(rectClass, "bottom", "I"));
right = env->GetIntField(activity, env->GetFieldID(rectClass, "right", "I"));
env->DeleteLocalRef(safeArea);
}

env->DeleteLocalRef(rectClass);
env->DeleteLocalRef(clazz);
env->DeleteLocalRef(activity);

return hasSafeArea;
return safeArea != nullptr;
}

bool openURL(const std::string &url)
Expand Down
55 changes: 15 additions & 40 deletions src/modules/graphics/vulkan/Graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2224,8 +2224,6 @@ VkRenderPass Graphics::getRenderPass(RenderPassConfiguration &configuration)
renderPasses[configuration] = renderPass;
}

renderPassUsages[renderPass] = true;

return renderPass;
}

Expand Down Expand Up @@ -2315,13 +2313,14 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
if (!renderPassState.active)
startRenderPass();

usedShadersInFrame.insert((dynamic_cast<Shader*>(Shader::current)));
auto s = dynamic_cast<Shader*>(Shader::current);

usedShadersInFrame.insert(s);

GraphicsPipelineConfiguration configuration{};

configuration.renderPass = renderPassState.beginInfo.renderPass;
configuration.vertexAttributes = attributes;
configuration.shader = (Shader*)Shader::current;
configuration.wireFrame = states.back().wireframe;
configuration.blendState = states.back().blend;
configuration.colorChannelMask = states.back().colorMask;
Expand All @@ -2341,11 +2340,15 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
configuration.dynamicState.cullmode = cullmode;
}

configuration.shader->setMainTex(texture);

ensureGraphicsPipelineConfiguration(configuration);
VkPipeline pipeline = s->getCachedGraphicsPipeline(this, configuration);
if (pipeline != renderPassState.pipeline)
{
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
renderPassState.pipeline = pipeline;
}

configuration.shader->cmdPushDescriptorSets(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS);
s->setMainTex(texture);
s->cmdPushDescriptorSets(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS);

VkBuffer vkbuffers[BufferBindings::MAX];
VkDeviceSize vkoffsets[BufferBindings::MAX];
Expand Down Expand Up @@ -2638,9 +2641,7 @@ static void eraseUnusedObjects(

void Graphics::cleanupUnusedObjects()
{
eraseUnusedObjects(renderPasses, renderPassUsages, vkDestroyRenderPass, device);
eraseUnusedObjects(framebuffers, framebufferUsages, vkDestroyFramebuffer, device);
eraseUnusedObjects(graphicsPipelines, pipelineUsages, vkDestroyPipeline, device);
}

void Graphics::requestSwapchainRecreation()
Expand Down Expand Up @@ -2670,17 +2671,17 @@ VkSampler Graphics::getCachedSampler(const SamplerState &samplerState)
}
}

VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration &configuration)
VkPipeline Graphics::createGraphicsPipeline(Shader *shader, const GraphicsPipelineConfiguration &configuration)
{
VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;

auto &shaderStages = configuration.shader->getShaderStages();
auto &shaderStages = shader->getShaderStages();

std::vector<VkVertexInputBindingDescription> bindingDescriptions;
std::vector<VkVertexInputAttributeDescription> attributeDescriptions;

createVulkanVertexFormat(configuration.shader, configuration.vertexAttributes, bindingDescriptions, attributeDescriptions);
createVulkanVertexFormat(shader, configuration.vertexAttributes, bindingDescriptions, attributeDescriptions);

VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
Expand Down Expand Up @@ -2812,7 +2813,7 @@ VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration &confi
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = &dynamicState;
pipelineInfo.layout = configuration.shader->getGraphicsPipelineLayout();
pipelineInfo.layout = shader->getGraphicsPipelineLayout();
pipelineInfo.subpass = 0;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
pipelineInfo.basePipelineIndex = -1;
Expand All @@ -2824,28 +2825,6 @@ VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration &confi
return graphicsPipeline;
}

void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration)
{
auto it = graphicsPipelines.find(configuration);
if (it != graphicsPipelines.end())
{
if (it->second != renderPassState.pipeline)
{
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, it->second);
renderPassState.pipeline = it->second;
pipelineUsages[it->second] = true;
}
}
else
{
VkPipeline pipeline = createGraphicsPipeline(configuration);
graphicsPipelines.insert({configuration, pipeline});
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
renderPassState.pipeline = pipeline;
pipelineUsages[pipeline] = true;
}
}

VkSampleCountFlagBits Graphics::getMsaaCount(int requestedMsaa) const
{
VkPhysicalDeviceProperties physicalDeviceProperties;
Expand Down Expand Up @@ -3112,10 +3091,6 @@ void Graphics::cleanup()
for (const auto &entry : framebuffers)
vkDestroyFramebuffer(device, entry.second, nullptr);
framebuffers.clear();

for (auto const &p : graphicsPipelines)
vkDestroyPipeline(device, p.second, nullptr);
graphicsPipelines.clear();

vkDestroyCommandPool(device, commandPool, nullptr);
vkDestroyPipelineCache(device, pipelineCache, nullptr);
Expand Down
47 changes: 2 additions & 45 deletions src/modules/graphics/vulkan/Graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,46 +170,6 @@ struct OptionalDeviceExtensions
bool spirv14 = false;
};

struct GraphicsPipelineConfiguration
{
VkRenderPass renderPass;
VertexAttributes vertexAttributes;
Shader *shader = nullptr;
bool wireFrame;
BlendState blendState;
ColorChannelMask colorChannelMask;
VkSampleCountFlagBits msaaSamples;
uint32_t numColorAttachments;
PrimitiveType primitiveType;

struct DynamicState
{
CullMode cullmode = CULL_NONE;
Winding winding = WINDING_MAX_ENUM;
StencilAction stencilAction = STENCIL_MAX_ENUM;
CompareMode stencilCompare = COMPARE_MAX_ENUM;
DepthState depthState{};
} dynamicState;

GraphicsPipelineConfiguration()
{
memset(this, 0, sizeof(GraphicsPipelineConfiguration));
}

bool operator==(const GraphicsPipelineConfiguration &other) const
{
return memcmp(this, &other, sizeof(GraphicsPipelineConfiguration)) == 0;
}
};

struct GraphicsPipelineConfigurationHasher
{
size_t operator() (const GraphicsPipelineConfiguration &configuration) const
{
return XXH32(&configuration, sizeof(GraphicsPipelineConfiguration), 0);
}
};

struct QueueFamilyIndices
{
Optional<uint32_t> graphicsFamily;
Expand Down Expand Up @@ -315,6 +275,8 @@ class Graphics final : public love::graphics::Graphics
int getVsync() const;
void mapLocalUniformData(void *data, size_t size, VkDescriptorBufferInfo &bufferInfo);

VkPipeline createGraphicsPipeline(Shader *shader, const GraphicsPipelineConfiguration &configuration);

uint32 getDeviceApiVersion() const { return deviceApiVersion; }

protected:
Expand Down Expand Up @@ -349,7 +311,6 @@ class Graphics final : public love::graphics::Graphics
void createDefaultShaders();
VkRenderPass createRenderPass(RenderPassConfiguration &configuration);
VkRenderPass getRenderPass(RenderPassConfiguration &configuration);
VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration &configuration);
void createColorResources();
VkFormat findSupportedFormat(const std::vector<VkFormat> &candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
VkFormat findDepthFormat();
Expand All @@ -364,7 +325,6 @@ class Graphics final : public love::graphics::Graphics
void beginFrame();
void startRecordingGraphicsCommands();
void endRecordingGraphicsCommands();
void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration);
void createVulkanVertexFormat(
Shader *shader,
const VertexAttributes &attributes,
Expand Down Expand Up @@ -412,10 +372,7 @@ class Graphics final : public love::graphics::Graphics
VkPipelineCache pipelineCache = VK_NULL_HANDLE;
std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
std::unordered_map<FramebufferConfiguration, VkFramebuffer, FramebufferConfigurationHasher> framebuffers;
std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
std::unordered_map<VkRenderPass, bool> renderPassUsages;
std::unordered_map<VkFramebuffer, bool> framebufferUsages;
std::unordered_map<VkPipeline, bool> pipelineUsages;
std::unordered_map<uint64, VkSampler> samplers;
VkCommandPool commandPool = VK_NULL_HANDLE;
std::vector<VkCommandBuffer> commandBuffers;
Expand Down
18 changes: 17 additions & 1 deletion src/modules/graphics/vulkan/Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ static bool usesLocalUniformData(const graphics::Shader::UniformInfo *info)

Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[], const CompileOptions &options)
: graphics::Shader(stages, options)
, builtinUniformInfo()
{
auto gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
vgfx = dynamic_cast<Graphics*>(gfx);
Expand Down Expand Up @@ -199,7 +200,8 @@ void Shader::unloadVolatile()
if (shaderModules.empty())
return;

vgfx->queueCleanUp([shaderModules = std::move(shaderModules), device = device, descriptorSetLayout = descriptorSetLayout, pipelineLayout = pipelineLayout, descriptorPools = descriptorPools, computePipeline = computePipeline](){
vgfx->queueCleanUp([shaderModules = std::move(shaderModules), device = device, descriptorSetLayout = descriptorSetLayout, pipelineLayout = pipelineLayout,
descriptorPools = descriptorPools, computePipeline = computePipeline, graphicsPipelines = std::move(graphicsPipelines)](){
for (const auto &pools : descriptorPools)
{
for (const auto pool : pools)
Expand All @@ -211,6 +213,8 @@ void Shader::unloadVolatile()
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
if (computePipeline != VK_NULL_HANDLE)
vkDestroyPipeline(device, computePipeline, nullptr);
for (const auto& kvp : graphicsPipelines)
vkDestroyPipeline(device, kvp.second, nullptr);
});

shaderModules.clear();
Expand Down Expand Up @@ -1199,6 +1203,18 @@ VkDescriptorSet Shader::allocateDescriptorSet()
}
}

VkPipeline Shader::getCachedGraphicsPipeline(Graphics *vgfx, const GraphicsPipelineConfiguration &configuration)
{
auto it = graphicsPipelines.find(configuration);
if (it != graphicsPipelines.end())
return it->second;

VkPipeline pipeline = vgfx->createGraphicsPipeline(this, configuration);
graphicsPipelines.insert({ configuration, pipeline });

return pipeline;
}

} // vulkan
} // graphics
} // love
58 changes: 51 additions & 7 deletions src/modules/graphics/vulkan/Shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
// Libraries
#include "VulkanWrapper.h"
#include "libraries/spirv_cross/spirv_reflect.hpp"
#include "libraries/xxHash/xxhash.h"

// C++
#include <map>
Expand All @@ -45,6 +46,45 @@ namespace graphics
namespace vulkan
{

struct GraphicsPipelineConfiguration
{
VkRenderPass renderPass;
VertexAttributes vertexAttributes;
bool wireFrame;
BlendState blendState;
ColorChannelMask colorChannelMask;
VkSampleCountFlagBits msaaSamples;
uint32_t numColorAttachments;
PrimitiveType primitiveType;

struct DynamicState
{
CullMode cullmode = CULL_NONE;
Winding winding = WINDING_MAX_ENUM;
StencilAction stencilAction = STENCIL_MAX_ENUM;
CompareMode stencilCompare = COMPARE_MAX_ENUM;
DepthState depthState{};
} dynamicState;

GraphicsPipelineConfiguration()
{
memset(this, 0, sizeof(GraphicsPipelineConfiguration));
}

bool operator==(const GraphicsPipelineConfiguration &other) const
{
return memcmp(this, &other, sizeof(GraphicsPipelineConfiguration)) == 0;
}
};

struct GraphicsPipelineConfigurationHasher
{
size_t operator() (const GraphicsPipelineConfiguration &configuration) const
{
return XXH32(&configuration, sizeof(GraphicsPipelineConfiguration), 0);
}
};

class Graphics;

class Shader final
Expand Down Expand Up @@ -95,6 +135,8 @@ class Shader final

void setMainTex(graphics::Texture *texture);

VkPipeline getCachedGraphicsPipeline(Graphics *vgfx, const GraphicsPipelineConfiguration &configuration);

private:
void compileShaders();
void createDescriptorSetLayout();
Expand All @@ -107,10 +149,10 @@ class Shader final
void setTextureDescriptor(const UniformInfo *info, love::graphics::Texture *texture, int index);
void setBufferDescriptor(const UniformInfo *info, love::graphics::Buffer *buffer, int index);

VkPipeline computePipeline;
VkPipeline computePipeline = VK_NULL_HANDLE;

VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout;
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
std::vector<VkDescriptorPoolSize> descriptorPoolSizes;

std::vector<std::vector<VkDescriptorPool>> descriptorPools;
Expand All @@ -124,7 +166,7 @@ class Shader final
std::vector<VkShaderModule> shaderModules;

Graphics *vgfx = nullptr;
VkDevice device;
VkDevice device = VK_NULL_HANDLE;

bool isCompute = false;
bool resourceDescriptorsDirty = false;
Expand All @@ -135,13 +177,15 @@ class Shader final
std::unique_ptr<StreamBuffer> uniformBufferObjectBuffer;
std::vector<uint8> localUniformData;
std::vector<uint8> localUniformStagingData;
uint32_t localUniformLocation;
uint32_t localUniformLocation = 0;
OptionalInt builtinUniformDataOffset;

std::unordered_map<std::string, AttributeInfo> attributes;

uint32_t currentFrame;
uint32_t currentDescriptorPool;
std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;

uint32_t currentFrame = 0;
uint32_t currentDescriptorPool = 0;
};

}
Expand Down

0 comments on commit ce7a80d

Please sign in to comment.