metal: work towards shader uniform implementation.

Misc cleanup.
This commit is contained in:
Alex Szpakowski
2020-10-24 00:33:02 -03:00
parent 5b4de2308d
commit 4b9c648c8b
10 changed files with 262 additions and 151 deletions
+1 -1
View File
@@ -472,7 +472,7 @@ public:
* @param width The viewport width.
* @param height The viewport height.
**/
virtual bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) = 0;
virtual bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth) = 0;
/**
* Un-sets the current graphics display mode (uninitializing objects if
+1
View File
@@ -95,6 +95,7 @@ Buffer::Buffer(love::graphics::Graphics *gfx, id<MTLDevice> device, const Settin
Buffer::~Buffer()
{ @autoreleasepool {
buffer = nil;
texture = nil;
}}
void *Buffer::map()
+3 -1
View File
@@ -49,7 +49,7 @@ public:
love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength) override;
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) override;
bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth) override;
void unSetMode() override;
void setActive(bool active) override;
@@ -195,6 +195,8 @@ private:
std::map<uint64, void *> cachedSamplers;
std::unordered_map<uint64, void *> cachedDepthStencilStates;
std::atomic<int64> completeCommandBufferIndex;
}; // Graphics
} // metal
+131 -120
View File
@@ -112,6 +112,21 @@ static MTLStencilOperation getMTLStencilOperation(StencilAction action)
return MTLStencilOperationKeep;
}
static inline id<MTLTexture> getMTLTexture(love::graphics::Texture *tex)
{
return tex ? (__bridge id<MTLTexture>)(void *) tex->getHandle() : nil;
}
static inline id<MTLTexture> getMTLRenderTarget(love::graphics::Texture *tex)
{
return tex ? (__bridge id<MTLTexture>)(void *) tex->getRenderTargetHandle() : nil;
}
static inline id<MTLBuffer> getMTLBuffer(love::graphics::Resource *res)
{
return res ? (__bridge id<MTLBuffer>)(void *) res->getHandle() : nil;
}
love::graphics::Graphics *createInstance()
{
love::graphics::Graphics *instance = nullptr;
@@ -190,7 +205,7 @@ Graphics::Graphics()
window->windowToDPICoords(&dpiW, &dpiH);
void *context = nullptr; // TODO
setMode(context, (int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), settings.stencil);
setMode(context, (int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), settings.stencil, settings.depth);
}
}
}}
@@ -257,18 +272,18 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh
}
}
bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil)
bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth)
{ @autoreleasepool {
this->width = width;
this->height = height;
this->metalLayer = (__bridge CAMetalLayer *) context;
this->windowHasStencil = windowhasstencil;
this->windowHasStencil = backbufferstencil;
metalLayer.device = device;
metalLayer.pixelFormat = isGammaCorrect() ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm;
// TODO: set to NO when we have pending screen captures
// This is set to NO when there are pending screen captures.
metalLayer.framebufferOnly = YES;
setViewportSize(width, height, pixelwidth, pixelheight);
@@ -338,8 +353,17 @@ void Graphics::setActive(bool enable)
id<MTLCommandBuffer> Graphics::useCommandBuffer()
{
if (commandBuffer == nil)
{
commandBuffer = [commandQueue commandBuffer];
Graphics *pthis = this;
pthis->retain();
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull) {
pthis->completeCommandBufferIndex.fetch_add(1, std::memory_order_relaxed);
pthis->release();
}];
}
return commandBuffer;
}
@@ -361,21 +385,30 @@ id<MTLRenderCommandEncoder> Graphics::useRenderEncoder()
{
submitBlitEncoder();
// Pass desc info for non-backbuffer render targets are set up in
// setRenderTagetsInternal.
const auto &rts = states.back().renderTargets;
if (rts.getFirstTarget().texture.get() != nullptr)
{
// TODO
}
else
if (rts.getFirstTarget().texture.get() == nullptr)
{
if (activeDrawable == nil)
{
// This is reset to YES after each frame.
// TODO: Does setting this reallocate memory?
if (!pendingScreenshotCallbacks.empty())
metalLayer.framebufferOnly = NO;
activeDrawable = [metalLayer nextDrawable];
}
passDesc.colorAttachments[0].texture = activeDrawable.texture;
passDesc.colorAttachments[0].level = 0;
passDesc.colorAttachments[0].slice = 0;
passDesc.colorAttachments[0].depthPlane = 0;
}
renderEncoder = [useCommandBuffer() renderCommandEncoderWithDescriptor:passDesc];
id<MTLBuffer> defaultbuffer = (__bridge id<MTLBuffer>)(void *)defaultAttributesBuffer->getHandle();
id<MTLBuffer> defaultbuffer = getMTLBuffer(defaultAttributesBuffer);
[renderEncoder setVertexBuffer:defaultbuffer offset:0 atIndex:DEFAULT_VERTEX_BUFFER_BINDING];
dirtyRenderState = STATEBIT_ALL;
@@ -622,37 +655,33 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
size_t alignment = 16;
#endif
// TODO: use the size of all uniforms
size_t size = sizeof(Shader::BuiltinUniformData);
size_t size = s->getLocalUniformBufferSize();
uint8 *bufferdata = s->getLocalUniformBufferData();
Shader::BuiltinUniformData data;
auto builtins = (Shader::BuiltinUniformData *) (bufferdata + s->getBuiltinUniformDataOffset());
data.transformMatrix = getTransform();
data.projectionMatrix = getProjection();
builtins->transformMatrix = getTransform();
builtins->projectionMatrix = getProjection();
// The normal matrix is the transpose of the inverse of the rotation portion
// (top-left 3x3) of the transform matrix.
{
Matrix3 normalmatrix = Matrix3(data.transformMatrix).transposedInverse();
Matrix3 normalmatrix = Matrix3(builtins->transformMatrix).transposedInverse();
const float *e = normalmatrix.getElements();
for (int i = 0; i < 3; i++)
{
data.normalMatrix[i].x = e[i * 3 + 0];
data.normalMatrix[i].y = e[i * 3 + 1];
data.normalMatrix[i].z = e[i * 3 + 2];
data.normalMatrix[i].w = 0.0f;
builtins->normalMatrix[i].x = e[i * 3 + 0];
builtins->normalMatrix[i].y = e[i * 3 + 1];
builtins->normalMatrix[i].z = e[i * 3 + 2];
builtins->normalMatrix[i].w = 0.0f;
}
}
// FIXME: should be active RT dimensions
data.screenSizeParams.x = getPixelWidth();
data.screenSizeParams.y = getPixelHeight();
builtins->screenSizeParams = Vector4(getPixelWidth(), getPixelHeight(), 1.0f, 0.0f);
data.screenSizeParams.z = 1.0f;
data.screenSizeParams.w = 0.0f;
data.constantColor = getColor();
gammaCorrectColor(data.constantColor);
builtins->constantColor = getColor();
gammaCorrectColor(builtins->constantColor);
if (uniformBuffer->getSize() < uniformBufferOffset + size)
{
@@ -666,9 +695,9 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
if (uniformBufferData.data == nullptr)
uniformBufferData = uniformBuffer->map(uniformBuffer->getSize());
memcpy(uniformBufferData.data + uniformBufferOffset, &data, sizeof(Shader::BuiltinUniformData));
memcpy(uniformBufferData.data + uniformBufferOffset, bufferdata, size);
id<MTLBuffer> buffer = (__bridge id<MTLBuffer>)(void *)uniformBuffer->getHandle();
id<MTLBuffer> buffer = getMTLBuffer(uniformBuffer);
int index = Shader::getUniformBufferBinding();
// TODO: bind shader textures/samplers
@@ -679,6 +708,26 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
uniformBufferOffset += alignUp(size, alignment);
}
static void setVertexBuffers(id<MTLRenderCommandEncoder> encoder, const BufferBindings *buffers)
{
uint32 allbits = buffers->useBits;
uint32 i = 0;
while (allbits)
{
uint32 bit = 1u << i;
if (buffers->useBits & bit)
{
auto b = buffers->info[i];
id<MTLBuffer> buffer = getMTLBuffer(b.buffer);
[encoder setVertexBuffer:buffer offset:b.offset atIndex:i + VERTEX_BUFFER_BINDING_START];
}
i++;
allbits >>= 1;
}
}
void Graphics::draw(const DrawCommand &cmd)
{ @autoreleasepool {
id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
@@ -690,29 +739,14 @@ void Graphics::draw(const DrawCommand &cmd)
if (texture == nullptr)
texture = defaultTextures[TEXTURE_2D];
id<MTLTexture> mtltexture = (__bridge id<MTLTexture>)(void *) texture->getHandle();
id<MTLTexture> mtltexture = getMTLTexture(texture);
[encoder setFragmentTexture:mtltexture atIndex:0];
[encoder setFragmentSamplerState:((Texture *)texture)->getMTLSampler() atIndex:0];
[encoder setCullMode:MTLCullModeNone];
uint32 allbits = cmd.buffers->useBits;
uint32 i = 0;
while (allbits)
{
uint32 bit = 1u << i;
if (cmd.buffers->useBits & bit)
{
auto b = cmd.buffers->info[i];
id<MTLBuffer> buffer = (__bridge id<MTLBuffer>)(void *)b.buffer->getHandle();
[encoder setVertexBuffer:buffer offset:b.offset atIndex:i + VERTEX_BUFFER_BINDING_START];
}
i++;
allbits >>= 1;
}
setVertexBuffers(encoder, cmd.buffers);
[encoder drawPrimitives:MTLPrimitiveTypeTriangle
vertexStart:cmd.vertexStart
@@ -731,36 +765,21 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
if (texture == nullptr)
texture = defaultTextures[TEXTURE_2D];
id<MTLTexture> mtltexture = (__bridge id<MTLTexture>)(void *) texture->getHandle();
id<MTLTexture> mtltexture = getMTLTexture(texture);
[encoder setFragmentTexture:mtltexture atIndex:0];
[encoder setFragmentSamplerState:((Texture *)texture)->getMTLSampler() atIndex:0];
[encoder setCullMode:MTLCullModeNone];
uint32 allbits = cmd.buffers->useBits;
uint32 i = 0;
while (allbits)
{
uint32 bit = 1u << i;
if (cmd.buffers->useBits & bit)
{
auto b = cmd.buffers->info[i];
id<MTLBuffer> buffer = (__bridge id<MTLBuffer>)(void *)b.buffer->getHandle();
[encoder setVertexBuffer:buffer offset:b.offset atIndex:i + VERTEX_BUFFER_BINDING_START];
}
i++;
allbits >>= 1;
}
setVertexBuffers(encoder, cmd.buffers);
auto indexType = cmd.indexType == INDEX_UINT32 ? MTLIndexTypeUInt32 : MTLIndexTypeUInt16;
[encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:cmd.indexCount
indexType:indexType
indexBuffer:(__bridge id<MTLBuffer>)(void*)cmd.indexBuffer->getHandle()
indexBuffer:getMTLBuffer(cmd.indexBuffer)
indexBufferOffset:cmd.indexBufferOffset
instanceCount:cmd.instanceCount];
}}
@@ -778,31 +797,16 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes &attribute
if (texture == nullptr)
texture = defaultTextures[TEXTURE_2D];
id<MTLTexture> mtltexture = (__bridge id<MTLTexture>)(void *) texture->getHandle();
id<MTLTexture> mtltexture = getMTLTexture(texture);
[encoder setFragmentTexture:mtltexture atIndex:0];
[encoder setFragmentSamplerState:((Texture *)texture)->getMTLSampler() atIndex:0];
[encoder setCullMode:MTLCullModeNone];
uint32 allbits = buffers.useBits;
uint32 i = 0;
while (allbits)
{
uint32 bit = 1u << i;
setVertexBuffers(encoder, &buffers);
if (buffers.useBits & bit)
{
auto b = buffers.info[i];
id<MTLBuffer> buffer = (__bridge id<MTLBuffer>)(void *)b.buffer->getHandle();
[encoder setVertexBuffer:buffer offset:b.offset atIndex:i + VERTEX_BUFFER_BINDING_START];
}
i++;
allbits >>= 1;
}
id<MTLBuffer> ib = (__bridge id<MTLBuffer>)(void *) quadIndexBuffer->getHandle();
id<MTLBuffer> ib = getMTLBuffer(quadIndexBuffer);
// TODO: support for iOS devices that don't support base vertex.
@@ -827,56 +831,60 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes &attribute
}
}}
void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBcanvas)
{ @autoreleasepool {
const DisplayState &state = states.back();
static inline void setAttachment(const Graphics::RenderTarget &rt, MTLRenderPassAttachmentDescriptor *desc)
{
bool isvolume = rt.texture->getTextureType() == TEXTURE_VOLUME;
desc.texture = getMTLRenderTarget(rt.texture);
desc.level = rt.mipmap;
desc.slice = isvolume ? 0 : rt.slice;
desc.depthPlane = isvolume ? rt.slice : 0;
// Default to load until clear or discard is called.
desc.loadAction = MTLLoadActionLoad;
desc.storeAction = MTLStoreActionStore;
desc.resolveTexture = nil;
if (rt.texture->getMSAA() > 1)
{
// TODO
desc.resolveTexture = getMTLTexture(rt.texture);
// TODO: This StoreAction is only supported sometimes.
desc.storeAction = MTLStoreActionStoreAndMultisampleResolve;
}
}
void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h, int /*pixelw*/, int /*pixelh*/, bool /*hasSRGBtexture*/)
{ @autoreleasepool {
endPass();
// Set up render pass descriptor for the next useRenderEncoder call.
// The backbuffer will be set up in useRenderEncoder rather than here.
for (size_t i = 0; i < rts.colors.size(); i++)
{
auto rt = rts.colors[i];
auto tex = rt.texture;
auto desc = passDesc.colorAttachments[i];
desc.texture = (__bridge id<MTLTexture>)(void*)tex->getRenderTargetHandle();
desc.level = rt.mipmap;
if (tex->getTextureType() == TEXTURE_VOLUME)
{
desc.slice = 0;
desc.depthPlane = rt.slice;
}
else
{
desc.slice = rt.slice;
desc.depthPlane = 0;
}
// Default to load until clear or discard is called.
desc.loadAction = MTLLoadActionLoad;
desc.storeAction = MTLStoreActionStore;
desc.resolveTexture = nil;
if (tex->getMSAA() > 1)
{
// TODO
desc.resolveTexture = (__bridge id<MTLTexture>)(void*)tex->getHandle();
// TODO: This StoreAction is only supported sometimes.
desc.storeAction = MTLStoreActionStoreAndMultisampleResolve;
}
setAttachment(rts.colors[i], desc);
passDesc.colorAttachments[i] = desc;
}
for (size_t i = rts.colors.size(); i < MAX_COLOR_RENDER_TARGETS; i++)
passDesc.colorAttachments[i] = nil;
// TODO: depth/stencil attachments
// TODO: projection matrix
// TODO: backbuffer
passDesc.depthAttachment = nil;
passDesc.stencilAttachment = nil;
if (rts.depthStencil.texture)
{
if (isPixelFormatDepth(rts.depthStencil.texture->getPixelFormat()))
setAttachment(rts.depthStencil, passDesc.depthAttachment);
if (isPixelFormatStencil(rts.depthStencil.texture->getPixelFormat()))
setAttachment(rts.depthStencil, passDesc.stencilAttachment);
}
projectionMatrix = Matrix4::ortho(0.0, (float) w, (float) h, 0.0, -10.0f, 10.0f);
dirtyRenderState = STATEBIT_ALL;
}}
@@ -1093,6 +1101,9 @@ void Graphics::present(void *screenshotCallbackData)
if (window != nullptr)
window->swapBuffers();
// This is set to NO when there are pending screen captures.
metalLayer.framebufferOnly = YES;
activeDrawable = nil;
// Reset the per-frame stat counts.
+6 -4
View File
@@ -76,10 +76,10 @@ public:
int getVertexAttributeIndex(const std::string &name) override;
const UniformInfo *getUniformInfo(const std::string &name) const override;
const UniformInfo *getUniformInfo(BuiltinUniform builtin) const override;
void updateUniform(const UniformInfo *info, int count) override {}
void sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count) override {}
void sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count) override {}
bool hasUniform(const std::string &name) const override { return false; }
void updateUniform(const UniformInfo *info, int count) override;
void sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count) override;
void sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count) override;
bool hasUniform(const std::string &name) const override;
ptrdiff_t getHandle() const override { return 0; }
void setVideoTextures(love::graphics::Texture *ytexture, love::graphics::Texture *cbtexture, love::graphics::Texture *crtexture) override {}
@@ -89,6 +89,7 @@ public:
uint8 *getLocalUniformBufferData() { return localUniformBufferData; }
size_t getLocalUniformBufferSize() const { return localUniformBufferSize; }
size_t getBuiltinUniformDataOffset() const { return builtinUniformDataOffset; }
private:
@@ -107,6 +108,7 @@ private:
uint8 *localUniformBufferData;
size_t localUniformBufferSize;
size_t builtinUniformDataOffset;
std::map<std::string, int> attributes;
+114 -20
View File
@@ -131,6 +131,7 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
, builtinUniformInfo()
, localUniformBufferData(nullptr)
, localUniformBufferSize(0)
, builtinUniformDataOffset(0)
{ @autoreleasepool {
using namespace glslang;
using namespace spirv_cross;
@@ -166,11 +167,7 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
opt.validate = true;
std::vector<unsigned int> spirv;
{
// timer::ScopedTimer("shader stage");
GlslangToSpv(*intermediate, spirv, &logger, &opt);
}
GlslangToSpv(*intermediate, spirv, &logger, &opt);
std::string msgs = logger.getAllMessages();
// printf("spirv length: %ld, messages:\n%s\n", spirv.size(), msgs.c_str());
@@ -203,28 +200,99 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
{
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);
continue;
}
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;
}
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)
{
auto it = uniforms.find(resource.name);
if (it != uniforms.end())
{
continue;
}
if (resource.name == "love_UniformsPerDrawBuffer")
{
msl.set_decoration(resource.id, spv::DecorationBinding, 0);
const SPIRType &type = msl.get_type(resource.base_type_id);
const auto &membertypes = type.member_types;
size_t size = msl.get_declared_struct_size(type);
if (localUniformBufferSize != 0)
{
if (localUniformBufferSize != size)
throw love::Exception("Local uniform buffer size mismatch");
continue;
}
localUniformBufferData = new uint8[size];
localUniformBufferSize = size;
memset(localUniformBufferData, 0, size);
for (size_t uindex = 0; uindex < membertypes.size(); uindex++)
{
const auto &membertype = msl.get_type(membertypes[uindex]);
size_t membersize = msl.get_declared_struct_member_size(type, uindex);
size_t offset = msl.type_struct_member_offset(type, uindex);
UniformInfo u = {};
u.name = msl.get_name(membertypes[uindex]);
u.dataSize = membersize;
u.count = std::max<size_t>(1, membertype.array.size());
BuiltinUniform builtin = BUILTIN_MAX_ENUM;
if (getConstant(u.name.c_str(), builtin))
{
if (builtin == BUILTIN_UNIFORMS_PER_DRAW)
builtinUniformDataOffset = offset;
}
switch (membertype.basetype)
{
case SPIRType::Int:
case SPIRType::UInt:
case SPIRType::Float:
u.data = localUniformBufferData + offset;
if (membertype.columns == 1)
{
if (membertype.basetype == SPIRType::Int)
u.baseType = UNIFORM_INT;
else if (membertype.basetype == SPIRType::UInt)
u.baseType = UNIFORM_UINT;
else
u.baseType = UNIFORM_FLOAT;
u.components = membertype.vecsize;
}
else
{
u.baseType = UNIFORM_MATRIX;
u.matrix.rows = membertype.vecsize;
u.matrix.columns = membertype.columns;
}
break;
case SPIRType::Struct:
// TODO
break;
default:
break;
}
}
}
}
@@ -247,10 +315,14 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
}
}
printf("ubos: %d, storage: %d, inputs: %d, outputs: %d, images: %d, samplers: %d, push: %d\n", resources.uniform_buffers.size(), resources.storage_buffers.size(), resources.stage_inputs.size(), resources.stage_outputs.size(), resources.storage_images.size(), resources.sampled_images.size(), resources.push_constant_buffers.size());
printf("// ubos: %ld, storage: %ld, inputs: %ld, outputs: %ld, images: %ld, samplers: %ld, push: %ld\n", resources.uniform_buffers.size(), resources.storage_buffers.size(), resources.stage_inputs.size(), resources.stage_outputs.size(), resources.storage_images.size(), resources.sampled_images.size(), resources.push_constant_buffers.size());
CompilerMSL::Options options;
options.set_msl_version(2, 1);
options.texture_buffer_native = true;
#ifdef LOVE_IOS
options.platform = CompilerMSL::Options::iOS;
#else
@@ -260,7 +332,7 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
msl.set_msl_options(options);
std::string source = msl.compile();
// printf("MSL SOURCE for stage %d:\n\n%s\n\n", i, source.c_str());
// printf("// MSL SOURCE for stage %d:\n\n%s\n\n", i, source.c_str());
NSString *nssource = [[NSString alloc] initWithBytes:source.c_str()
length:source.length()
@@ -280,6 +352,7 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
{
spv::StorageClass storage = msl.get_storage_class(var);
const std::string &name = msl.get_name(var);
printf("var: %s\n", name.c_str());
if (i == ShaderStage::STAGE_VERTEX && storage == spv::StorageClassInput)
attributes[name] = msl.get_decoration(var, spv::DecorationLocation);
@@ -338,6 +411,27 @@ const Shader::UniformInfo *Shader::getUniformInfo(BuiltinUniform builtin) const
return builtinUniformInfo[(int)builtin];
}
void Shader::updateUniform(const UniformInfo * /*info*/, int /*count*/)
{
// Nothing needed here, All uniform data will be memcpy'd to the main
// uniform buffer before drawing.
}
void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count)
{
// TODO
}
void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count)
{
// TODO
}
bool Shader::hasUniform(const std::string &name) const
{
return uniforms.find(name) != uniforms.end();
}
id<MTLRenderPipelineState> Shader::getCachedRenderPipeline(const RenderPipelineKey &key)
{
auto it = cachedRenderPipelines.find(key);
+3 -3
View File
@@ -129,7 +129,7 @@ Graphics::Graphics()
window->windowToDPICoords(&dpiW, &dpiH);
void *context = nullptr; // TODO
setMode(context, (int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), settings.stencil);
setMode(context, (int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), settings.stencil, settings.depth);
}
}
}
@@ -190,12 +190,12 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh
}
}
bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil)
bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int /*backbufferdepth*/)
{
this->width = width;
this->height = height;
this->windowHasStencil = windowhasstencil;
this->windowHasStencil = backbufferstencil;
// Okay, setup OpenGL.
gl.initContext();
+1 -1
View File
@@ -63,7 +63,7 @@ public:
love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength) override;
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) override;
bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth) override;
void unSetMode() override;
void setActive(bool active) override;
+1
View File
@@ -588,6 +588,7 @@ GLenum OpenGL::getGLBufferType(BufferType type)
case BUFFERTYPE_VERTEX: return GL_ARRAY_BUFFER;
case BUFFERTYPE_INDEX: return GL_ELEMENT_ARRAY_BUFFER;
case BUFFERTYPE_TEXEL: return GL_TEXTURE_BUFFER;
case BUFFERTYPE_UNIFORM: return GL_UNIFORM_BUFFER;
case BUFFERTYPE_MAX_ENUM: return GL_ZERO;
}
+1 -1
View File
@@ -603,7 +603,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
context = (void *) SDL_Metal_GetLayer(metalView);
#endif
graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil);
graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.depth);
}
#ifdef LOVE_ANDROID