diff options
author | r.kuznetsov <r.kuznetsov@corp.mail.ru> | 2018-08-27 12:37:52 +0300 |
---|---|---|
committer | Aleksey Belousov <beloal@users.noreply.github.com> | 2018-09-25 12:33:08 +0300 |
commit | a81f1fc4d1f698a0f0aaaa1e7a29f41516b05d11 (patch) | |
tree | cf7c511247ca2ae4da08e2a11d2b22232846a3da /shaders | |
parent | 5cca83542d89b081d668bccca7bf14c5c8c165ad (diff) |
[drape][metal] Added states.
Diffstat (limited to 'shaders')
-rw-r--r-- | shaders/CMakeLists.txt | 12 | ||||
-rw-r--r-- | shaders/Metal/debug_rect.metal | 31 | ||||
-rw-r--r-- | shaders/Metal/screen_quad.metal | 38 | ||||
-rw-r--r-- | shaders/gl_program_params.cpp | 7 | ||||
-rw-r--r-- | shaders/gl_program_pool.cpp | 6 | ||||
-rw-r--r-- | shaders/metal_program_params.hpp | 26 | ||||
-rw-r--r-- | shaders/metal_program_params.mm | 47 | ||||
-rw-r--r-- | shaders/metal_program_pool.hpp | 29 | ||||
-rw-r--r-- | shaders/metal_program_pool.mm | 124 | ||||
-rw-r--r-- | shaders/program_manager.cpp | 63 | ||||
-rw-r--r-- | shaders/program_manager.hpp | 7 | ||||
-rw-r--r-- | shaders/program_manager_metal.mm | 16 | ||||
-rw-r--r-- | shaders/shaders_tests/gl_program_params_tests.cpp | 2 | ||||
-rw-r--r-- | shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp | 2 |
14 files changed, 378 insertions, 32 deletions
diff --git a/shaders/CMakeLists.txt b/shaders/CMakeLists.txt index 2c65193980..355651adb9 100644 --- a/shaders/CMakeLists.txt +++ b/shaders/CMakeLists.txt @@ -31,6 +31,18 @@ set( programs.hpp ) +if (PLATFORM_IPHONE) +append( + SRC + metal_program_params.hpp + metal_program_params.mm + metal_program_pool.hpp + metal_program_pool.mm + metal/debug_rect.metal + program_manager_metal.mm +) +endif() + add_library(${PROJECT_NAME} ${SRC}) set( diff --git a/shaders/Metal/debug_rect.metal b/shaders/Metal/debug_rect.metal new file mode 100644 index 0000000000..b795740622 --- /dev/null +++ b/shaders/Metal/debug_rect.metal @@ -0,0 +1,31 @@ +#include <metal_stdlib> +#include <simd/simd.h> +using namespace metal; + +typedef struct +{ + float2 a_position [[attribute(0)]]; +} Vertex_T; + +typedef struct +{ + float4 position [[position]]; +} Fragment_T; + +typedef struct +{ + float4 u_color; +} Uniforms_T; + +vertex Fragment_T vsDebugRect(const Vertex_T in [[stage_in]]) +{ + Fragment_T out; + out.position = float4(in.a_position, 0.0, 1.0); + return out; +} + +fragment float4 fsDebugRect(const Fragment_T in [[stage_in]], + constant Uniforms_T & uniforms [[buffer(0)]]) +{ + return uniforms.u_color; +} diff --git a/shaders/Metal/screen_quad.metal b/shaders/Metal/screen_quad.metal new file mode 100644 index 0000000000..c864387d6b --- /dev/null +++ b/shaders/Metal/screen_quad.metal @@ -0,0 +1,38 @@ +#include <metal_stdlib> +#include <simd/simd.h> +using namespace metal; + +typedef struct +{ + float2 a_position [[attribute(0)]]; + float2 a_texCoords [[attribute(1)]]; +} Vertex_T; + +typedef struct +{ + float4 position [[position]]; + float2 texCoords; +} Fragment_T; + +typedef struct +{ + float u_opacity; +} Uniforms_T; + +vertex Fragment_T vsScreenQuad(const Vertex_T in [[stage_in]]) +{ + Fragment_T out; + out.position = float4(in.a_position, 0.0, 1.0); + out.texCoords = in.a_texCoords; + return out; +} + +fragment float4 fsScreenQuad(const Fragment_T in [[stage_in]], + constant Uniforms_T & uniforms [[buffer(0)]], + texture2d<float> u_colorTex [[texture(0)]], + sampler u_colorTexSampler [[sampler(0)]]) +{ + float4 color = u_colorTex.sample(u_colorTexSampler, in.texCoords); + color.a *= uniforms.u_opacity; + return color; +} diff --git a/shaders/gl_program_params.cpp b/shaders/gl_program_params.cpp index 08bc3db140..a8109bdfc9 100644 --- a/shaders/gl_program_params.cpp +++ b/shaders/gl_program_params.cpp @@ -1,5 +1,6 @@ #include "shaders/gl_program_params.hpp" +#include "drape/gl_gpu_program.hpp" #include "drape/uniform_value.hpp" #include "base/assert.hpp" @@ -13,7 +14,7 @@ namespace struct UniformsGuard { template <typename ParamsType> - UniformsGuard(ref_ptr<dp::GpuProgram> program, ParamsType const &) + UniformsGuard(ref_ptr<dp::GLGpuProgram> program, ParamsType const &) : m_program(program) , m_paramsName(ParamsType::GetName()) { @@ -27,7 +28,7 @@ struct UniformsGuard CHECK_EQUAL(m_counter, uniformsCount, ("Not all numeric uniforms are set up", m_program->GetName(), m_paramsName)); } - ref_ptr<dp::GpuProgram> m_program; + ref_ptr<dp::GLGpuProgram> m_program; std::string const m_paramsName; uint32_t m_counter = 0; }; @@ -63,7 +64,7 @@ public: private: template<typename ParamType> - static bool Apply(ref_ptr<dp::GpuProgram> program, std::string const & name, ParamType const & p) + static bool Apply(ref_ptr<dp::GLGpuProgram> program, std::string const & name, ParamType const & p) { auto const location = program->GetUniformLocation(name); if (location < 0) diff --git a/shaders/gl_program_pool.cpp b/shaders/gl_program_pool.cpp index 7b985c81a9..80ac3cbbab 100644 --- a/shaders/gl_program_pool.cpp +++ b/shaders/gl_program_pool.cpp @@ -2,6 +2,9 @@ #include "shaders/program_params.hpp" #include "shaders/gl_shaders.hpp" +#include "drape/gl_gpu_program.hpp" +#include "drape/gl_functions.hpp" + namespace gpu { GLProgramPool::GLProgramPool(dp::ApiVersion apiVersion) @@ -21,6 +24,7 @@ GLProgramPool::GLProgramPool(dp::ApiVersion apiVersion) GLProgramPool::~GLProgramPool() { + GLFunctions::glUseProgram(0); ProgramParams::Destroy(); } @@ -33,7 +37,7 @@ drape_ptr<dp::GpuProgram> GLProgramPool::Get(Program program) dp::Shader::Type::FragmentShader); auto const name = DebugPrint(program); - return make_unique_dp<dp::GpuProgram>(name, vertexShader, fragmentShader); + return make_unique_dp<dp::GLGpuProgram>(name, vertexShader, fragmentShader); } void GLProgramPool::SetDefines(std::string const & defines) diff --git a/shaders/metal_program_params.hpp b/shaders/metal_program_params.hpp new file mode 100644 index 0000000000..f051ead1b3 --- /dev/null +++ b/shaders/metal_program_params.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "shaders/program_params.hpp" + +#include <cstdint> + +namespace gpu +{ +namespace metal +{ +class MetalProgramParamsSetter : public ProgramParamsSetter +{ +public: + void Apply(ref_ptr<dp::GpuProgram> program, MapProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, RouteProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, TrafficProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, TransitProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, GuiProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, ShapesProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, Arrow3dProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, DebugRectProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, ScreenQuadProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, SMAAProgramParams const & params) override; +}; +} // namespace metal +} // namespace gpu diff --git a/shaders/metal_program_params.mm b/shaders/metal_program_params.mm new file mode 100644 index 0000000000..c39b8b7247 --- /dev/null +++ b/shaders/metal_program_params.mm @@ -0,0 +1,47 @@ +#include "shaders/metal_program_params.hpp" + +namespace gpu +{ +namespace metal +{ +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, MapProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, RouteProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, TrafficProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, TransitProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, GuiProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, ShapesProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, Arrow3dProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, DebugRectProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, ScreenQuadProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, SMAAProgramParams const & params) +{ +} +} // namespace metal +} // namespace gpu diff --git a/shaders/metal_program_pool.hpp b/shaders/metal_program_pool.hpp new file mode 100644 index 0000000000..1c8ed6130d --- /dev/null +++ b/shaders/metal_program_pool.hpp @@ -0,0 +1,29 @@ +#pragma once +#import <MetalKit/MetalKit.h> + +#include "shaders/program_pool.hpp" + +#include "drape/pointers.hpp" + +#include <map> +#include <string> + +namespace gpu +{ +namespace metal +{ +class MetalProgramPool : public ProgramPool +{ +public: + explicit MetalProgramPool(id<MTLDevice> device); + ~MetalProgramPool() override; + + drape_ptr<dp::GpuProgram> Get(Program program) override; + +private: + id<MTLFunction> GetFunction(std::string const & name); + id<MTLLibrary> m_library; + std::map<std::string, id<MTLFunction>> m_functions; +}; +} // namespace metal +} // namespace gpu diff --git a/shaders/metal_program_pool.mm b/shaders/metal_program_pool.mm new file mode 100644 index 0000000000..bb1011e5a1 --- /dev/null +++ b/shaders/metal_program_pool.mm @@ -0,0 +1,124 @@ +#include "shaders/metal_program_pool.hpp" +#include "shaders/program_params.hpp" + +#include "drape/metal/metal_gpu_program.hpp" + +#include "base/assert.hpp" + +#include <utility> + +namespace gpu +{ +namespace metal +{ +namespace +{ +struct ProgramInfo +{ + std::string m_vertexShaderName; + std::string m_fragmentShaderName; + ProgramInfo(std::string && vertexShaderName, std::string fragmentShaderName) + : m_vertexShaderName(std::move(vertexShaderName)) + , m_fragmentShaderName(std::move(fragmentShaderName)) + {} +}; + +std::array<ProgramInfo, static_cast<size_t>(Program::ProgramsCount)> const kMetalProgramsInfo = {{ + ProgramInfo("", ""), // ColoredSymbol + ProgramInfo("", ""), // Texturing + ProgramInfo("", ""), // MaskedTexturing + ProgramInfo("", ""), // Bookmark + ProgramInfo("", ""), // BookmarkAnim + ProgramInfo("", ""), // TextOutlined + ProgramInfo("", ""), // Text + ProgramInfo("", ""), // TextFixed + ProgramInfo("", ""), // TextOutlinedGui + ProgramInfo("", ""), // Area + ProgramInfo("", ""), // AreaOutline + ProgramInfo("", ""), // Area3d + ProgramInfo("", ""), // Area3dOutline + ProgramInfo("", ""), // Line + ProgramInfo("", ""), // CapJoin + ProgramInfo("", ""), // TransitCircle + ProgramInfo("", ""), // DashedLine + ProgramInfo("", ""), // PathSymbol + ProgramInfo("", ""), // HatchingArea + ProgramInfo("", ""), // TexturingGui + ProgramInfo("", ""), // Ruler + ProgramInfo("", ""), // Accuracy + ProgramInfo("", ""), // MyPosition + ProgramInfo("", ""), // Transit + ProgramInfo("", ""), // TransitMarker + ProgramInfo("", ""), // Route + ProgramInfo("", ""), // RouteDash + ProgramInfo("", ""), // RouteArrow + ProgramInfo("", ""), // RouteMarker + ProgramInfo("", ""), // CirclePoint + ProgramInfo("vsDebugRect", "fsDebugRect"), // DebugRect + ProgramInfo("vsScreenQuad", "fsScreenQuad"), // ScreenQuad + ProgramInfo("", ""), // Arrow3d + ProgramInfo("", ""), // Arrow3dShadow + ProgramInfo("", ""), // Arrow3dOutline + ProgramInfo("", ""), // ColoredSymbolBillboard + ProgramInfo("", ""), // TexturingBillboard + ProgramInfo("", ""), // MaskedTexturingBillboard + ProgramInfo("", ""), // BookmarkBillboard + ProgramInfo("", ""), // BookmarkAnimBillboard + ProgramInfo("", ""), // TextOutlinedBillboard + ProgramInfo("", ""), // TextBillboard + ProgramInfo("", ""), // TextFixedBillboard + ProgramInfo("", ""), // Traffic + ProgramInfo("", ""), // TrafficLine + ProgramInfo("", ""), // TrafficCircle + ProgramInfo("", ""), // SmaaEdges + ProgramInfo("", ""), // SmaaBlendingWeight + ProgramInfo("", ""), // SmaaFinal +}}; +} // namespace + +MetalProgramPool::MetalProgramPool(id<MTLDevice> device) +{ + ProgramParams::Init(); + + NSString * libPath = [[NSBundle mainBundle] pathForResource:@"shaders_metal" ofType:@"metallib"]; + NSError * error; + m_library = [device newLibraryWithFile:libPath error:&error]; + if (error) + { + NSLog(@"%@", error); + CHECK(false, ("Shaders library creation error.")); + } + m_library.label = @"Shaders library"; +} + +MetalProgramPool::~MetalProgramPool() +{ + ProgramParams::Destroy(); +} + +drape_ptr<dp::GpuProgram> MetalProgramPool::Get(Program program) +{ + auto const & info = kMetalProgramsInfo[static_cast<size_t>(program)]; + CHECK(!info.m_vertexShaderName.empty(), ()); + CHECK(!info.m_fragmentShaderName.empty(), ()); + + auto const name = DebugPrint(program); + return make_unique_dp<dp::metal::MetalGpuProgram>(name, GetFunction(info.m_vertexShaderName), + GetFunction(info.m_fragmentShaderName)); +} + +id<MTLFunction> MetalProgramPool::GetFunction(std::string const & name) +{ + auto const it = m_functions.find(name); + if (it == m_functions.end()) + { + id<MTLFunction> f = [m_library newFunctionWithName:@(name.c_str())]; + CHECK(f != nil, ()); + f.label = [@"Function " stringByAppendingString:@(name.c_str())]; + m_functions.insert(std::make_pair(name, f)); + return f; + } + return it->second; +} +} // namespace metal +} // namespace gpu diff --git a/shaders/program_manager.cpp b/shaders/program_manager.cpp index b0f83289fc..faaaa86ef1 100644 --- a/shaders/program_manager.cpp +++ b/shaders/program_manager.cpp @@ -1,7 +1,7 @@ #include "shaders/program_manager.hpp" #include "shaders/gl_program_pool.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include "drape/support_manager.hpp" #include "base/logging.hpp" @@ -13,39 +13,52 @@ namespace gpu { -void ProgramManager::Init(dp::ApiVersion apiVersion) +void ProgramManager::Init(ref_ptr<dp::GraphicsContext> context) { + auto const apiVersion = context->GetApiVersion(); if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) { - std::string globalDefines; - - // This feature is not supported on some Android devices (especially on Android 4.x version). - // Since we can't predict on which devices it'll work fine, we have to turn off for all devices. -#if !defined(OMIM_OS_ANDROID) - if (GLFunctions::glGetInteger(gl_const::GLMaxVertexTextures) > 0) - { - LOG(LINFO, ("VTF enabled")); - globalDefines.append("#define ENABLE_VTF\n"); // VTF == Vertex Texture Fetch - } + InitForOpenGL(context); + } + else if (apiVersion == dp::ApiVersion::Metal) + { +#if defined(OMIM_OS_IPHONE) + InitForMetal(context); #endif - - if (dp::SupportManager::Instance().IsSamsungGoogleNexus()) - globalDefines.append("#define SAMSUNG_GOOGLE_NEXUS\n"); - - if (apiVersion == dp::ApiVersion::OpenGLES3) - globalDefines.append("#define GLES3\n"); - - m_pool = make_unique_dp<GLProgramPool>(apiVersion); - ref_ptr<GLProgramPool> pool = make_ref(m_pool); - pool->SetDefines(globalDefines); - - m_paramsSetter = make_unique_dp<GLProgramParamsSetter>(); } else { - CHECK(false, ("Unsupported API version")); + CHECK(false, ("Unsupported API version.")); } } + +void ProgramManager::InitForOpenGL(ref_ptr<dp::GraphicsContext> context) +{ + std::string globalDefines; + + // This feature is not supported on some Android devices (especially on Android 4.x version). + // Since we can't predict on which devices it'll work fine, we have to turn off for all devices. +#if !defined(OMIM_OS_ANDROID) + if (GLFunctions::glGetInteger(gl_const::GLMaxVertexTextures) > 0) + { + LOG(LINFO, ("VTF enabled")); + globalDefines.append("#define ENABLE_VTF\n"); // VTF == Vertex Texture Fetch + } +#endif + + if (dp::SupportManager::Instance().IsSamsungGoogleNexus()) + globalDefines.append("#define SAMSUNG_GOOGLE_NEXUS\n"); + + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES3) + globalDefines.append("#define GLES3\n"); + + m_pool = make_unique_dp<GLProgramPool>(apiVersion); + ref_ptr<GLProgramPool> pool = make_ref(m_pool); + pool->SetDefines(globalDefines); + + m_paramsSetter = make_unique_dp<GLProgramParamsSetter>(); +} ref_ptr<dp::GpuProgram> ProgramManager::GetProgram(Program program) { diff --git a/shaders/program_manager.hpp b/shaders/program_manager.hpp index e3209e6b44..f4b988496d 100644 --- a/shaders/program_manager.hpp +++ b/shaders/program_manager.hpp @@ -4,6 +4,7 @@ #include "shaders/program_params.hpp" #include "drape/drape_global.hpp" +#include "drape/graphics_context.hpp" #include "drape/gpu_program.hpp" #include "drape/pointers.hpp" @@ -19,12 +20,16 @@ class ProgramManager public: ProgramManager() = default; - void Init(dp::ApiVersion apiVersion); + void Init(ref_ptr<dp::GraphicsContext> context); ref_ptr<dp::GpuProgram> GetProgram(Program program); ref_ptr<ProgramParamsSetter> GetParamsSetter() const; private: + void InitForOpenGL(ref_ptr<dp::GraphicsContext> context); + // Definition of this method is in separate .mm-file. + void InitForMetal(ref_ptr<dp::GraphicsContext> context); + using Programs = std::array<drape_ptr<dp::GpuProgram>, static_cast<size_t>(Program::ProgramsCount)>; Programs m_programs; diff --git a/shaders/program_manager_metal.mm b/shaders/program_manager_metal.mm new file mode 100644 index 0000000000..43c3235d8c --- /dev/null +++ b/shaders/program_manager_metal.mm @@ -0,0 +1,16 @@ +#include "shaders/program_manager.hpp" +#include "shaders/metal_program_params.hpp" +#include "shaders/metal_program_pool.hpp" + +#include "drape/metal/metal_base_context.hpp" + +namespace gpu +{ +void ProgramManager::InitForMetal(ref_ptr<dp::GraphicsContext> context) +{ + ASSERT(dynamic_cast<dp::metal::MetalBaseContext *>(context.get()) != nullptr, ()); + ref_ptr<dp::metal::MetalBaseContext> metalContext = context; + m_pool = make_unique_dp<metal::MetalProgramPool>(metalContext->GetMetalDevice()); + m_paramsSetter = make_unique_dp<metal::MetalProgramParamsSetter>(); +} +} // namespace gpu diff --git a/shaders/shaders_tests/gl_program_params_tests.cpp b/shaders/shaders_tests/gl_program_params_tests.cpp index 25dd8e6006..ec5c1d9257 100644 --- a/shaders/shaders_tests/gl_program_params_tests.cpp +++ b/shaders/shaders_tests/gl_program_params_tests.cpp @@ -5,7 +5,7 @@ #include "shaders/gl_program_pool.hpp" #include "drape/drape_global.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include <functional> diff --git a/shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp b/shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp index b33cbba939..67c84e9fbc 100644 --- a/shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp +++ b/shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp @@ -4,7 +4,7 @@ #include "shaders/gl_program_pool.hpp" #include "drape/drape_global.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include <functional> |