diff --git a/libs/drape/metal/metal_base_context.mm b/libs/drape/metal/metal_base_context.mm index 25d4dee86..32bca956f 100644 --- a/libs/drape/metal/metal_base_context.mm +++ b/libs/drape/metal/metal_base_context.mm @@ -31,10 +31,10 @@ MetalBaseContext::MetalBaseContext(id device, m2::PointU const & scre m_renderPassDescriptor.stencilAttachment.loadAction = MTLLoadActionClear; m_renderPassDescriptor.stencilAttachment.storeAction = MTLStoreActionStore; m_renderPassDescriptor.stencilAttachment.clearStencil = 0; - + RecreateDepthTexture(screenSize); } - + void MetalBaseContext::RecreateDepthTexture(m2::PointU const & screenSize) { if (screenSize.x == 0 || screenSize.y == 0) @@ -42,7 +42,7 @@ void MetalBaseContext::RecreateDepthTexture(m2::PointU const & screenSize) m_depthTexture.reset(); return; } - + m_depthTexture = make_unique_dp(nullptr /* allocator */); HWTexture::Params params; params.m_width = screenSize.x; @@ -51,7 +51,7 @@ void MetalBaseContext::RecreateDepthTexture(m2::PointU const & screenSize) params.m_isRenderTarget = true; m_depthTexture->Create(make_ref(this), params, nullptr /* data */); } - + void MetalBaseContext::Init(dp::ApiVersion apiVersion) { CHECK(apiVersion == dp::ApiVersion::Metal, ()); @@ -62,7 +62,7 @@ ApiVersion MetalBaseContext::GetApiVersion() const { return dp::ApiVersion::Metal; } - + std::string MetalBaseContext::GetRendererName() const { return std::string([m_device.name UTF8String]); @@ -107,7 +107,7 @@ std::string MetalBaseContext::GetRendererVersion() const return s1.first > s2.first; }); } - + for (auto featureSet : features) { if ([m_device supportsFeatureSet:featureSet.first]) @@ -115,26 +115,26 @@ std::string MetalBaseContext::GetRendererVersion() const } return "Unknown"; } - + void MetalBaseContext::PushDebugLabel(std::string const & label) { if (m_currentCommandEncoder == nil) return; [m_currentCommandEncoder pushDebugGroup:@(label.c_str())]; } - + void MetalBaseContext::PopDebugLabel() { if (m_currentCommandEncoder == nil) return; [m_currentCommandEncoder popDebugGroup]; } - + void MetalBaseContext::Resize(int w, int h) { if (m_depthTexture && m_depthTexture->GetWidth() == w && m_depthTexture->GetHeight() == h) return; - + RecreateDepthTexture(m2::PointU(w, h)); } @@ -152,7 +152,7 @@ void MetalBaseContext::ApplyFramebuffer(std::string const & framebufferLabel) m_frameCommandBuffer = [m_commandQueue commandBuffer]; m_frameCommandBuffer.label = @"Frame command buffer"; } - + if (!m_currentFramebuffer) { // Use default(system) framebuffer and depth-stencil. @@ -164,11 +164,11 @@ void MetalBaseContext::ApplyFramebuffer(std::string const & framebufferLabel) else { ref_ptr framebuffer = m_currentFramebuffer; - + ASSERT(dynamic_cast(framebuffer->GetTexture()->GetHardwareTexture().get()) != nullptr, ()); ref_ptr colorAttachment = framebuffer->GetTexture()->GetHardwareTexture(); m_renderPassDescriptor.colorAttachments[0].texture = colorAttachment->GetTexture(); - + auto const depthStencilRef = framebuffer->GetDepthStencilRef(); if (depthStencilRef != nullptr) { @@ -186,12 +186,12 @@ void MetalBaseContext::ApplyFramebuffer(std::string const & framebufferLabel) m_renderPassDescriptor.stencilAttachment.texture = nil; } } - + CHECK(m_currentCommandEncoder == nil, ("Current command encoder was not finished.")); m_currentCommandEncoder = [m_frameCommandBuffer renderCommandEncoderWithDescriptor:m_renderPassDescriptor]; m_currentCommandEncoder.label = @(framebufferLabel.c_str()); [m_currentCommandEncoder pushDebugGroup:@(framebufferLabel.c_str())]; - + // Default rendering options. [m_currentCommandEncoder setFrontFacingWinding:MTLWindingClockwise]; [m_currentCommandEncoder setCullMode:MTLCullModeBack]; @@ -204,7 +204,7 @@ void MetalBaseContext::SetClearColor(dp::Color const & color) m_renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(color.GetRedF(), color.GetGreenF(), color.GetBlueF(), color.GetAlphaF()); } - + void MetalBaseContext::Clear(uint32_t clearBits, uint32_t storeBits) { if (m_currentCommandEncoder != nil) @@ -215,7 +215,7 @@ void MetalBaseContext::Clear(uint32_t clearBits, uint32_t storeBits) m_cleaner.ClearColor(make_ref(this), m_currentCommandEncoder); else if (clearBits & ClearBits::DepthBit) m_cleaner.ClearDepth(make_ref(this), m_currentCommandEncoder); - + if (clearBits & ClearBits::StencilBit) CHECK(false, ("Stencil clearing is not implemented")); } @@ -227,42 +227,41 @@ void MetalBaseContext::Clear(uint32_t clearBits, uint32_t storeBits) m_renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; else m_renderPassDescriptor.colorAttachments[0].loadAction = (storeBits & ClearBits::ColorBit) ? MTLLoadActionLoad : MTLLoadActionDontCare; - + if (clearBits & ClearBits::DepthBit) m_renderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear; else m_renderPassDescriptor.depthAttachment.loadAction = (storeBits & ClearBits::DepthBit) ? MTLLoadActionLoad : MTLLoadActionDontCare; - + if (clearBits & ClearBits::StencilBit) m_renderPassDescriptor.stencilAttachment.loadAction = MTLLoadActionClear; else m_renderPassDescriptor.stencilAttachment.loadAction = (storeBits & ClearBits::StencilBit) ? MTLLoadActionLoad : MTLLoadActionDontCare; - + // Apply storing mode. if (storeBits & ClearBits::ColorBit) m_renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; else m_renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionDontCare; - + if (storeBits & ClearBits::DepthBit) m_renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionStore; else m_renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionDontCare; - + if (storeBits & ClearBits::StencilBit) m_renderPassDescriptor.stencilAttachment.storeAction = MTLStoreActionStore; else m_renderPassDescriptor.stencilAttachment.storeAction = MTLStoreActionDontCare; } } - + void MetalBaseContext::SetViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) { id encoder = GetCommandEncoder(); - [encoder setViewport:(MTLViewport){ static_cast(x), static_cast(y), - static_cast(w), static_cast(h), - 0.0, 1.0 }]; - [encoder setScissorRect:(MTLScissorRect){ x, y, w, h }]; + [encoder setViewport:{static_cast(x), static_cast(y), static_cast(w), static_cast(h), + 0.0, 1.0}]; + [encoder setScissorRect:{x, y, w, h}]; } void MetalBaseContext::SetScissor(uint32_t x, uint32_t y, uint32_t w, uint32_t h) @@ -277,7 +276,7 @@ void MetalBaseContext::SetScissor(uint32_t x, uint32_t y, uint32_t w, uint32_t h if (x + w > rpWidth) w = rpWidth - x; if (y + h > rpHeight) h = rpHeight - y; - [encoder setScissorRect:(MTLScissorRect){ x, y, w, h }]; + [encoder setScissorRect:{x, y, w, h}]; } } @@ -314,12 +313,12 @@ void MetalBaseContext::SetCullingEnabled(bool enabled) id encoder = GetCommandEncoder(); [encoder setCullMode: (enabled ? MTLCullModeBack : MTLCullModeNone)]; } - + id MetalBaseContext::GetMetalDevice() const { return m_device; } - + id MetalBaseContext::GetCommandEncoder() const { CHECK(m_currentCommandEncoder != nil, ("Probably encoding commands were called before ApplyFramebuffer.")); @@ -331,41 +330,41 @@ id MetalBaseContext::GetCommandBuffer() const CHECK(m_frameCommandBuffer != nil, ("Probably encoding commands were called before ApplyFramebuffer.")); return m_frameCommandBuffer; } - + id MetalBaseContext::GetDepthStencilState() { return m_metalStates.GetDepthStencilState(m_device, m_currentDepthStencilKey); } - + id MetalBaseContext::GetPipelineState(ref_ptr program, bool blendingEnabled) { CHECK(m_currentCommandEncoder != nil, ("Probably encoding commands were called before ApplyFramebuffer.")); - + id colorTexture = m_renderPassDescriptor.colorAttachments[0].texture; // It can be nil in the case when Metal drawable is absent (e.g. finish rendering in background). if (colorTexture == nil) return nil; - + id depthTexture = m_renderPassDescriptor.depthAttachment.texture; MTLPixelFormat depthStencilFormat = (depthTexture != nil) ? depthTexture.pixelFormat : MTLPixelFormatInvalid; - + MetalStates::PipelineKey const key(program, colorTexture.pixelFormat, depthStencilFormat, blendingEnabled); return m_metalStates.GetPipelineState(m_device, key); } - + id MetalBaseContext::GetSamplerState(TextureFilter filter, TextureWrapping wrapSMode, TextureWrapping wrapTMode) { MetalStates::SamplerKey const key(filter, wrapSMode, wrapTMode); return m_metalStates.GetSamplerState(m_device, key); } - + bool MetalBaseContext::BeginRendering() { CHECK(m_currentCommandEncoder == nil, ("Current command encoder was not finished.")); return true; } - + void MetalBaseContext::EndRendering() { FinishCurrentEncoding(); @@ -376,27 +375,27 @@ void MetalBaseContext::Present() RequestFrameDrawable(); if (m_frameDrawable) [m_frameCommandBuffer presentDrawable:m_frameDrawable]; - + [m_frameCommandBuffer commit]; m_frameDrawable = nil; [m_frameCommandBuffer waitUntilCompleted]; m_frameCommandBuffer = nil; } - + void MetalBaseContext::RequestFrameDrawable() { if (m_frameDrawable != nil) return; - + CHECK(m_drawableRequest != nullptr, ()); m_frameDrawable = m_drawableRequest(); } - + void MetalBaseContext::ResetFrameDrawable() { if (m_frameDrawable == nil) return; - + m_frameDrawable = nil; RequestFrameDrawable(); } @@ -408,7 +407,7 @@ void MetalBaseContext::FinishCurrentEncoding() m_currentCommandEncoder = nil; m_lastPipelineState = nil; } - + void MetalBaseContext::SetSystemPrograms(drape_ptr && programClearColor, drape_ptr && programClearDepth, drape_ptr && programClearColorAndDepth) @@ -416,24 +415,24 @@ void MetalBaseContext::SetSystemPrograms(drape_ptr && programClearCo m_cleaner.Init(make_ref(this), std::move(programClearColor), std::move(programClearDepth), std::move(programClearColorAndDepth)); } - + void MetalBaseContext::ApplyPipelineState(id state) { m_lastPipelineState = state; if (state != nil) [GetCommandEncoder() setRenderPipelineState:state]; } - + bool MetalBaseContext::HasAppliedPipelineState() const { return m_lastPipelineState != nil; } - + void MetalBaseContext::ResetPipelineStatesCache() { m_metalStates.ResetPipelineStatesCache(); } - + void MetalBaseContext::DebugSynchronizeWithCPU() { FinishCurrentEncoding(); @@ -444,7 +443,7 @@ void MetalBaseContext::DebugSynchronizeWithCPU() m_frameCommandBuffer = nil; } -MTLRenderPassDescriptor * MetalBaseContext::GetRenderPassDescriptor() const +MTLRenderPassDescriptor * MetalBaseContext::GetRenderPassDescriptor() const { return m_renderPassDescriptor; } diff --git a/libs/shaders/metal_program_pool.mm b/libs/shaders/metal_program_pool.mm index 9926082ba..3803d93cd 100644 --- a/libs/shaders/metal_program_pool.mm +++ b/libs/shaders/metal_program_pool.mm @@ -21,7 +21,7 @@ struct ProgramInfo std::string const m_vertexShaderName; std::string const m_fragmentShaderName; Layout m_layout; - + // Layout is in the format { buffer0, buffer1, ..., bufferN }. // bufferX is a pair { start attribute index, end attribute index }. ProgramInfo(std::string && vertexShaderName, std::string && fragmentShaderName, @@ -39,7 +39,7 @@ struct ProgramInfo } } }; - + std::array(SystemProgram::SystemProgramsCount)> const kMetalSystemProgramsInfo = {{ ProgramInfo("vsCleaner", "fsClearColor", {{0, 0}}), // ClearColor ProgramInfo("vsCleaner", "fsClearDepth", {{0, 0}}), // ClearDepth @@ -117,7 +117,7 @@ MTLVertexFormat GetFormatByDataType(MTLDataType dataType) } return MTLVertexFormatInvalid; } - + uint32_t GetSizeByDataType(MTLDataType dataType) { switch (dataType) @@ -130,7 +130,7 @@ uint32_t GetSizeByDataType(MTLDataType dataType) } return 0; } - + void GetBindings(NSArray * arguments, int8_t & uniformsBindingIndex, dp::metal::MetalGpuProgram::TexturesBindingInfo & textureBindingInfo) { @@ -138,7 +138,7 @@ void GetBindings(NSArray * arguments, int8_t & uniformsBindingInd NSString * kUniformsName = @"uniforms"; // Sampler name must be constructed as concatenation of texture name and kSamplerSuffix. static std::string const kSamplerSuffix = "Sampler"; - + uniformsBindingIndex = dp::metal::MetalGpuProgram::kInvalidBindingIndex; for (MTLArgument * arg in arguments) @@ -163,7 +163,7 @@ void GetBindings(NSArray * arguments, int8_t & uniformsBindingInd } } } - + MTLVertexDescriptor * GetVertexDescriptor(id vertexShader, ProgramInfo::Layout const & layout) { MTLVertexDescriptor * vertexDesc = [[MTLVertexDescriptor alloc] init]; @@ -189,10 +189,10 @@ MTLVertexDescriptor * GetVertexDescriptor(id vertexShader, ProgramI sizes[bufferIndex] += sz; attrDesc.bufferIndex = bufferIndex; } - + for (auto const & s : sizes) vertexDesc.layouts[s.first].stride = s.second; - + return vertexDesc; } } // namespace @@ -204,19 +204,19 @@ std::string DebugPrint(SystemProgram p) case SystemProgram::ClearColor: return "ClearColor"; case SystemProgram::ClearDepth: return "ClearDepth"; case SystemProgram::ClearColorAndDepth: return "ClearColorAndDepth"; - + case SystemProgram::SystemProgramsCount: CHECK(false, ("Try to output SystemProgramsCount")); } CHECK(false, ("Unknown program")); return {}; } - + MetalProgramPool::MetalProgramPool(id device) : m_device(device) { ProgramParams::Init(); - + NSString * libPath = [[NSBundle mainBundle] pathForResource:@"shaders_metal" ofType:@"metallib"]; NSError * error = nil; m_library = [m_device newLibraryWithFile:libPath error:&error]; @@ -238,13 +238,13 @@ drape_ptr MetalProgramPool::GetSystemProgram(SystemProgram progr auto const & info = kMetalSystemProgramsInfo[static_cast(program)]; return Get(DebugPrint(program), info.m_vertexShaderName, info.m_fragmentShaderName, info.m_layout); } - + drape_ptr MetalProgramPool::Get(Program program) { auto const & info = kMetalProgramsInfo[static_cast(program)]; return Get(DebugPrint(program), info.m_vertexShaderName, info.m_fragmentShaderName, info.m_layout); } - + drape_ptr MetalProgramPool::Get(std::string const & programName, std::string const & vertexShaderName, std::string const & fragmentShaderName, @@ -252,7 +252,7 @@ drape_ptr MetalProgramPool::Get(std::string const & programName, { CHECK(!vertexShaderName.empty(), ()); CHECK(!fragmentShaderName.empty(), ()); - + id vertexShader = GetFunction(vertexShaderName); id fragmentShader = GetFunction(fragmentShaderName); MTLVertexDescriptor * vertexDesc = GetVertexDescriptor(vertexShader, layout); @@ -264,7 +264,7 @@ drape_ptr MetalProgramPool::Get(std::string const & programName, desc.vertexDescriptor = vertexDesc; desc.vertexFunction = vertexShader; desc.fragmentFunction = fragmentShader; - + NSError * error = nil; MTLRenderPipelineReflection * reflectionObj = nil; MTLPipelineOption option = MTLPipelineOptionBufferTypeInfo | MTLPipelineOptionArgumentInfo; @@ -277,22 +277,22 @@ drape_ptr MetalProgramPool::Get(std::string const & programName, NSLog(@"%@", error); CHECK(false, ("Failed to create reflection pipeline state.")); } - + int8_t vsUniformsBindingIndex = dp::metal::MetalGpuProgram::kInvalidBindingIndex; dp::metal::MetalGpuProgram::TexturesBindingInfo vsTextureBindingInfo; GetBindings(reflectionObj.vertexArguments, vsUniformsBindingIndex, vsTextureBindingInfo); - + int8_t fsUniformsBindingIndex = dp::metal::MetalGpuProgram::kInvalidBindingIndex; dp::metal::MetalGpuProgram::TexturesBindingInfo fsTextureBindingInfo; GetBindings(reflectionObj.fragmentArguments, fsUniformsBindingIndex, fsTextureBindingInfo); - + return make_unique_dp(programName, vertexShader, fragmentShader, vsUniformsBindingIndex, fsUniformsBindingIndex, std::move(vsTextureBindingInfo), std::move(fsTextureBindingInfo), vertexDesc); } - + id MetalProgramPool::GetFunction(std::string const & name) { auto const it = m_functions.find(name);