metal: initial barebones texture reflection in shaders

This commit is contained in:
Alex Szpakowski
2020-07-29 18:11:20 -03:00
parent 426798ab10
commit eea78884d3
3 changed files with 44 additions and 6 deletions
+1 -1
View File
@@ -231,7 +231,7 @@ love::graphics::ShaderStage *Graphics::newShaderStageInternal(ShaderStage::Stage
love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel) love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
{ {
return new Shader(vertex, pixel); return new Shader(device, vertex, pixel);
} }
love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags)
+7 -1
View File
@@ -67,7 +67,7 @@ public:
} }
}; };
Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel); Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel);
virtual ~Shader(); virtual ~Shader();
// Implements Shader. // Implements Shader.
@@ -86,6 +86,9 @@ public:
static int getUniformBufferBinding(); static int getUniformBufferBinding();
uint8 *getLocalUniformBufferData() { return localUniformBufferData; }
size_t getLocalUniformBufferSize() const { return localUniformBufferSize; }
private: private:
struct RenderPipelineHasher struct RenderPipelineHasher
@@ -101,6 +104,9 @@ private:
UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM]; UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
std::map<std::string, UniformInfo> uniforms; std::map<std::string, UniformInfo> uniforms;
uint8 *localUniformBufferData;
size_t localUniformBufferSize;
std::map<std::string, int> attributes; std::map<std::string, int> attributes;
std::unordered_map<RenderPipelineKey, const void *, RenderPipelineHasher> cachedRenderPipelines; std::unordered_map<RenderPipelineKey, const void *, RenderPipelineHasher> cachedRenderPipelines;
+36 -4
View File
@@ -121,13 +121,13 @@ static EShLanguage getGLSLangStage(ShaderStage::StageType stage)
return EShLangCount; return EShLangCount;
} }
Shader::Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel) Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
: love::graphics::Shader(vertex, pixel) : love::graphics::Shader(vertex, pixel)
, functions() , functions()
, builtinUniformInfo() , builtinUniformInfo()
, localUniformBufferData(nullptr)
, localUniformBufferSize(0)
{ @autoreleasepool { { @autoreleasepool {
auto gfx = Graphics::getInstance();
using namespace glslang; using namespace glslang;
using namespace spirv_cross; using namespace spirv_cross;
@@ -186,11 +186,34 @@ Shader::Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage
for (const auto &resource : resources.sampled_images) for (const auto &resource : resources.sampled_images)
{ {
int binding = msl.get_decoration(resource.id, spv::DecorationBinding);
BuiltinUniform builtin = BUILTIN_MAX_ENUM; BuiltinUniform builtin = BUILTIN_MAX_ENUM;
if (getConstant(resource.name.c_str(), builtin)) if (getConstant(resource.name.c_str(), builtin))
{ {
// TODO // TODO
} }
auto it = uniforms.find(resource.name);
if (it != uniforms.end())
{
if (it->second.ints[0] != binding)
throw love::Exception("texture binding mismatch for %s: %d vs %d", resource.name.c_str(), it->second.ints[0], binding);
}
else
{
UniformInfo u = {};
u.baseType = UNIFORM_SAMPLER;
u.name = resource.name;
u.location = 0;
u.textures = new love::graphics::Texture*[1];
u.textures[0] = nullptr;
u.data = malloc(sizeof(int) * 1);
u.ints[0] = binding;
// printf("binding for %s: %d\n", u.name.c_str(), binding);
uniforms[u.name] = u;
}
} }
for (const auto &resource : resources.uniform_buffers) for (const auto &resource : resources.uniform_buffers)
@@ -240,7 +263,7 @@ Shader::Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage
encoding:NSUTF8StringEncoding]; encoding:NSUTF8StringEncoding];
NSError *err = nil; NSError *err = nil;
id<MTLLibrary> library = [gfx->device newLibraryWithSource:nssource options:nil error:&err]; id<MTLLibrary> library = [device newLibraryWithSource:nssource options:nil error:&err];
if (library == nil && err != nil) if (library == nil && err != nil)
{ {
NSLog(@"errors: %@", err); NSLog(@"errors: %@", err);
@@ -274,6 +297,15 @@ Shader::~Shader()
CFBridgingRelease(kvp.second); CFBridgingRelease(kvp.second);
cachedRenderPipelines.clear(); cachedRenderPipelines.clear();
for (const auto &it : uniforms)
{
free(it.second.data);
if (it.second.textures != nullptr)
delete[] it.second.textures;
}
delete[] localUniformBufferData;
}} }}
void Shader::attach() void Shader::attach()