From 4b9c648c8b2ed09108033e926dd88342d71e5c01 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 24 Oct 2020 00:33:02 -0300 Subject: [PATCH] metal: work towards shader uniform implementation. Misc cleanup. --- src/modules/graphics/Graphics.h | 2 +- src/modules/graphics/metal/Buffer.mm | 1 + src/modules/graphics/metal/Graphics.h | 4 +- src/modules/graphics/metal/Graphics.mm | 251 ++++++++++++----------- src/modules/graphics/metal/Shader.h | 10 +- src/modules/graphics/metal/Shader.mm | 134 ++++++++++-- src/modules/graphics/opengl/Graphics.cpp | 6 +- src/modules/graphics/opengl/Graphics.h | 2 +- src/modules/graphics/opengl/OpenGL.cpp | 1 + src/modules/window/sdl/Window.cpp | 2 +- 10 files changed, 262 insertions(+), 151 deletions(-) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index c0eb1b697..541921104 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -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 diff --git a/src/modules/graphics/metal/Buffer.mm b/src/modules/graphics/metal/Buffer.mm index 0be88287b..440f00c17 100644 --- a/src/modules/graphics/metal/Buffer.mm +++ b/src/modules/graphics/metal/Buffer.mm @@ -95,6 +95,7 @@ Buffer::Buffer(love::graphics::Graphics *gfx, id device, const Settin Buffer::~Buffer() { @autoreleasepool { buffer = nil; + texture = nil; }} void *Buffer::map() diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 228fc6986..898936c52 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -49,7 +49,7 @@ public: love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector &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 cachedSamplers; std::unordered_map cachedDepthStencilStates; + std::atomic completeCommandBufferIndex; + }; // Graphics } // metal diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index 685a41c1f..3233fa514 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -112,6 +112,21 @@ static MTLStencilOperation getMTLStencilOperation(StencilAction action) return MTLStencilOperationKeep; } +static inline id getMTLTexture(love::graphics::Texture *tex) +{ + return tex ? (__bridge id)(void *) tex->getHandle() : nil; +} + +static inline id getMTLRenderTarget(love::graphics::Texture *tex) +{ + return tex ? (__bridge id)(void *) tex->getRenderTargetHandle() : nil; +} + +static inline id getMTLBuffer(love::graphics::Resource *res) +{ + return res ? (__bridge id)(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 Graphics::useCommandBuffer() { if (commandBuffer == nil) + { commandBuffer = [commandQueue commandBuffer]; + Graphics *pthis = this; + pthis->retain(); + [commandBuffer addCompletedHandler:^(id _Nonnull) { + pthis->completeCommandBufferIndex.fetch_add(1, std::memory_order_relaxed); + pthis->release(); + }]; + } + return commandBuffer; } @@ -361,21 +385,30 @@ id 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 defaultbuffer = (__bridge id)(void *)defaultAttributesBuffer->getHandle(); + id defaultbuffer = getMTLBuffer(defaultAttributesBuffer); [renderEncoder setVertexBuffer:defaultbuffer offset:0 atIndex:DEFAULT_VERTEX_BUFFER_BINDING]; dirtyRenderState = STATEBIT_ALL; @@ -622,37 +655,33 @@ void Graphics::applyShaderUniforms(id 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 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 buffer = (__bridge id)(void *)uniformBuffer->getHandle(); + id buffer = getMTLBuffer(uniformBuffer); int index = Shader::getUniformBufferBinding(); // TODO: bind shader textures/samplers @@ -679,6 +708,26 @@ void Graphics::applyShaderUniforms(id renderEncoder, lo uniformBufferOffset += alignUp(size, alignment); } +static void setVertexBuffers(id 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 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 encoder = useRenderEncoder(); @@ -690,29 +739,14 @@ void Graphics::draw(const DrawCommand &cmd) if (texture == nullptr) texture = defaultTextures[TEXTURE_2D]; - id mtltexture = (__bridge id)(void *) texture->getHandle(); + id 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 buffer = (__bridge id)(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 = (__bridge id)(void *) texture->getHandle(); + id 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 buffer = (__bridge id)(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)(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 = (__bridge id)(void *) texture->getHandle(); + id 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 buffer = (__bridge id)(void *)b.buffer->getHandle(); - [encoder setVertexBuffer:buffer offset:b.offset atIndex:i + VERTEX_BUFFER_BINDING_START]; - } - - i++; - allbits >>= 1; - } - - id ib = (__bridge id)(void *) quadIndexBuffer->getHandle(); + id 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)(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)(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. diff --git a/src/modules/graphics/metal/Shader.h b/src/modules/graphics/metal/Shader.h index c7f10e6c6..51c98acf7 100644 --- a/src/modules/graphics/metal/Shader.h +++ b/src/modules/graphics/metal/Shader.h @@ -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 attributes; diff --git a/src/modules/graphics/metal/Shader.mm b/src/modules/graphics/metal/Shader.mm index 260991604..733ff56bb 100644 --- a/src/modules/graphics/metal/Shader.mm +++ b/src/modules/graphics/metal/Shader.mm @@ -131,6 +131,7 @@ Shader::Shader(id 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 device, love::graphics::ShaderStage *vertex, love:: opt.validate = true; std::vector 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 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(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 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 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 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 Shader::getCachedRenderPipeline(const RenderPipelineKey &key) { auto it = cachedRenderPipelines.find(key); diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 801cce2e3..161893bc5 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -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(); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index fabe43a9b..96eebeedf 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -63,7 +63,7 @@ public: love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector &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; diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 2dfeb32c3..f87e00362 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -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; } diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index e24d8ae12..af63d5000 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -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