mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
start implementing vulkan Shader type
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 "; }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user