start implementing vulkan Shader type

This commit is contained in:
niki
2022-02-06 22:56:24 +01:00
parent 4692a0490c
commit 197dfb9738
9 changed files with 157 additions and 44 deletions
+12 -1
View File
@@ -215,6 +215,17 @@ namespace love {
batchedDrawState.indexBuffer = new StreamBuffer(device, physicalDevice, BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
}
for (int i = 0; i < Shader::STANDARD_MAX_ENUM; i++) {
auto stype = (Shader::StandardShader)i;
if (!Shader::standardShaders[i]) {
std::vector<std::string> stages;
stages.push_back(Shader::getDefaultCode(stype, SHADERSTAGE_VERTEX));
stages.push_back(Shader::getDefaultCode(stype, SHADERSTAGE_PIXEL));
Shader::standardShaders[i] = newShader(stages, true);
}
}
return true;
}
@@ -759,7 +770,7 @@ namespace love {
rasterizer.rasterizerDiscardEnable = VK_FALSE;
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT;
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
rasterizer.depthBiasEnable = VK_FALSE;
rasterizer.depthBiasConstantFactor = 0.0f;
+10 -2
View File
@@ -3,6 +3,8 @@
#include "graphics/Graphics.h"
#include "StreamBuffer.h"
#include "ShaderStage.h"
#include "Shader.h"
#include <vulkan/vulkan.h>
#include <common/config.h>
@@ -66,8 +68,14 @@ namespace love {
void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, Texture* texture) override { std::cout << "drawQuads "; }
protected:
graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override { std::cout << "newShaderStageInternal "; return nullptr; }
graphics::Shader* newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override { std::cout << "newShaderInternal "; return nullptr; }
graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override {
std::cout << "newShaderStageInternal ";
return new ShaderStage(this, stage, source, gles, cachekey);
}
graphics::Shader* newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override {
std::cout << "newShaderInternal ";
return new Shader(stages);
}
graphics::StreamBuffer* newStreamBuffer(BufferUsage type, size_t size) override;
bool dispatch(int x, int y, int z) override { std::cout << "dispatch "; return false; }
void initCapabilities() override { std::cout << "initCapabilities "; }
+15 -16
View File
@@ -1,7 +1,5 @@
#include "Shader.h"
#include "libraries/glslang/glslang/Public/ShaderLang.h"
#include "libraries/glslang/SPIRV/GlslangToSpv.h"
#include <vector>
namespace love {
@@ -21,24 +19,25 @@ namespace love {
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[])
: graphics::Shader(stages) {
if (false) {
for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++) {
if (!stages[i])
continue;
for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++) {
if (!stages[i])
continue;
auto stage = dynamic_cast<ShaderStage*>(stages[i].get());
auto stage = dynamic_cast<ShaderStage*>(stages[i].get());
VkPipelineShaderStageCreateInfo shaderStageInfo{};
shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageInfo.stage = getStageBit(stage->getStageType());
shaderStageInfo.module = stage->getShaderModule();
shaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo shaderStageInfo{};
shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageInfo.stage = getStageBit(stage->getStageType());
shaderStageInfo.module = stage->getShaderModule();
shaderStageInfo.pName = "main";
shaderStages.push_back(shaderStageInfo);
}
shaderStages.push_back(shaderStageInfo);
}
}
int Shader::getVertexAttributeIndex(const std::string& name) {
return vertexAttributeIndices.at(name);
}
}
}
}
}
+25 -3
View File
@@ -3,10 +3,10 @@
#include <graphics/Shader.h>
#include <graphics/vulkan/ShaderStage.h>
#include "libraries/glslang/glslang/Public/ShaderLang.h"
#include "libraries/glslang/SPIRV/GlslangToSpv.h"
#include <vulkan/vulkan.h>
#include <map>
namespace love {
namespace graphics {
@@ -26,7 +26,7 @@ namespace love {
std::string getWarnings() const override { return ""; }
int getVertexAttributeIndex(const std::string& name) override { return 0; }
int getVertexAttributeIndex(const std::string& name) override;
const UniformInfo* getUniformInfo(const std::string& name) const override { return nullptr; }
const UniformInfo* getUniformInfo(BuiltinUniform builtin) const override { return nullptr; }
@@ -41,7 +41,29 @@ namespace love {
void setVideoTextures(Texture* ytexture, Texture* cbtexture, Texture* crtexture) override {}
private:
struct Vec4 {
float x, y, z, w;
};
struct LoveUniformsPerDraw {
Vec4 uniformsPerDraw[13];
};
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
std::map<std::string, int> vertexAttributeIndices = {
{ "VertexPosition", 0 },
{ "VertexTexCoord", 1 },
{ "VertexColor", 2 }
};
std::map<std::string, int> uniformBindings = {
{ "love_UniformsPerDraw", 0 },
{ "love_VideoYChannel", 1 },
{ "love_VideoCbChannel", 2 },
{ "love_VideoCrChannel", 3 },
{ "MainTex", 4 }
};
};
}
}
+53 -2
View File
@@ -9,12 +9,63 @@
namespace love {
namespace graphics {
namespace vulkan {
static int someIndex = 0;
static std::string getFileEnding(ShaderStageType type) {
switch (type) {
case SHADERSTAGE_VERTEX:
return ".vert";
case SHADERSTAGE_PIXEL:
return ".frag";
default:
throw love::Exception("unsupported shader stage type");
}
}
static std::vector<char> readFile(const std::string& filename) {
std::ifstream file(filename, std::ios::ate | std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error("failed to open file!");
}
size_t fileSize = (size_t)file.tellg();
std::vector<char> buffer(fileSize);
file.seekg(0);
file.read(buffer.data(), fileSize);
file.close();
return buffer;
}
static int shaderSourceId = 0;
std::vector<char> compileShader(const std::string& glsl, ShaderStageType stage) {
// fixme: use glslang or shaderc for this
std::string inputFileName = std::string("temp") + std::to_string(shaderSourceId++) + getFileEnding(stage);
std::string outputFileName = std::string("temp.spv");
std::ofstream out(inputFileName);
out << glsl;
out.close();
std::string command = std::string("glslc -fauto-bind-uniforms ") + inputFileName + " -o " + outputFileName;
system(command.c_str());
return readFile(outputFileName);
}
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) {
auto code = compileShader(glsl, stage);
VkShaderModuleCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = 0;
createInfo.pCode = nullptr;
createInfo.codeSize = code.size();
createInfo.pCode = reinterpret_cast<uint32_t*>(code.data());
Graphics* vkGfx = (Graphics*)gfx;
device = vkGfx->getDevice();