mirror of
https://github.com/love2d/love.git
synced 2026-08-19 12:14:20 +02:00
metal: initial barebones texture reflection in shaders
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user