Metal setup merge (#1616)
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Alex Cristici <alex.cristici@gmail.com> Co-authored-by: mwilsnd <mwilsnd@gmail.com> Co-authored-by: Stefan Karschti <stefan.karschti@gmail.com> Co-authored-by: Bart Louwers <bart@emeel.net> Co-authored-by: Alex Cristici <alex@skoon.energy> Co-authored-by: Bart Louwers <bart.louwers@gmail.com> Co-authored-by: Wei Chen <alanchenboy@gmail.com> Co-authored-by: Siarhei Fedartsou <siarhei.fedartsou@gmail.com> Co-authored-by: tdcosta100 <tdcosta100@gmail.com>
This commit is contained in:
192
src/mbgl/shaders/mtl/shader_program.cpp
Normal file
192
src/mbgl/shaders/mtl/shader_program.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include <mbgl/shaders/mtl/shader_program.hpp>
|
||||
|
||||
#include <mbgl/gfx/render_pass.hpp>
|
||||
#include <mbgl/mtl/context.hpp>
|
||||
#include <mbgl/mtl/renderer_backend.hpp>
|
||||
#include <mbgl/mtl/renderable_resource.hpp>
|
||||
#include <mbgl/mtl/uniform_block.hpp>
|
||||
#include <mbgl/mtl/uniform_buffer.hpp>
|
||||
#include <mbgl/mtl/vertex_attribute.hpp>
|
||||
#include <mbgl/programs/program_parameters.hpp>
|
||||
#include <mbgl/shaders/shader_manifest.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <Metal/MTLRenderPass.hpp>
|
||||
#include <Metal/MTLRenderPipeline.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace mbgl {
|
||||
namespace mtl {
|
||||
|
||||
namespace {
|
||||
MTL::BlendOperation metalBlendOperation(const gfx::ColorBlendEquationType& colorBlend) {
|
||||
switch (colorBlend) {
|
||||
case gfx::ColorBlendEquationType::Add:
|
||||
return MTL::BlendOperationAdd;
|
||||
case gfx::ColorBlendEquationType::Subtract:
|
||||
return MTL::BlendOperationSubtract;
|
||||
case gfx::ColorBlendEquationType::ReverseSubtract:
|
||||
return MTL::BlendOperationReverseSubtract;
|
||||
}
|
||||
}
|
||||
|
||||
MTL::BlendFactor metalBlendFactor(const gfx::ColorBlendFactorType& colorFactor) {
|
||||
switch (colorFactor) {
|
||||
case gfx::ColorBlendFactorType::Zero:
|
||||
return MTL::BlendFactorZero;
|
||||
case gfx::ColorBlendFactorType::One:
|
||||
return MTL::BlendFactorOne;
|
||||
case gfx::ColorBlendFactorType::SrcColor:
|
||||
return MTL::BlendFactorSourceColor;
|
||||
case gfx::ColorBlendFactorType::OneMinusSrcColor:
|
||||
return MTL::BlendFactorOneMinusSourceColor;
|
||||
case gfx::ColorBlendFactorType::SrcAlpha:
|
||||
return MTL::BlendFactorSourceAlpha;
|
||||
case gfx::ColorBlendFactorType::OneMinusSrcAlpha:
|
||||
return MTL::BlendFactorOneMinusSourceAlpha;
|
||||
case gfx::ColorBlendFactorType::DstAlpha:
|
||||
return MTL::BlendFactorDestinationAlpha;
|
||||
case gfx::ColorBlendFactorType::OneMinusDstAlpha:
|
||||
return MTL::BlendFactorOneMinusDestinationAlpha;
|
||||
case gfx::ColorBlendFactorType::DstColor:
|
||||
return MTL::BlendFactorDestinationColor;
|
||||
case gfx::ColorBlendFactorType::OneMinusDstColor:
|
||||
return MTL::BlendFactorOneMinusDestinationColor;
|
||||
case gfx::ColorBlendFactorType::SrcAlphaSaturate:
|
||||
return MTL::BlendFactorSourceAlphaSaturated;
|
||||
case gfx::ColorBlendFactorType::ConstantColor:
|
||||
return MTL::BlendFactorBlendColor;
|
||||
case gfx::ColorBlendFactorType::OneMinusConstantColor:
|
||||
return MTL::BlendFactorOneMinusBlendColor;
|
||||
case gfx::ColorBlendFactorType::ConstantAlpha:
|
||||
return MTL::BlendFactorBlendAlpha;
|
||||
case gfx::ColorBlendFactorType::OneMinusConstantAlpha:
|
||||
return MTL::BlendFactorOneMinusBlendAlpha;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ShaderProgram::ShaderProgram(std::string name, RendererBackend& backend_, MTLFunctionPtr vert, MTLFunctionPtr frag)
|
||||
: ShaderProgramBase(),
|
||||
shaderName(std::move(name)),
|
||||
backend(backend_),
|
||||
vertexFunction(std::move(vert)),
|
||||
fragmentFunction(std::move(frag)) {}
|
||||
|
||||
MTLRenderPipelineStatePtr ShaderProgram::getRenderPipelineState(const gfx::RenderPassDescriptor& renderPassDescriptor,
|
||||
const MTLVertexDescriptorPtr& vertexDescriptor,
|
||||
const gfx::ColorMode& colorMode) const {
|
||||
auto pool = NS::TransferPtr(NS::AutoreleasePool::alloc()->init());
|
||||
|
||||
const auto& renderable = renderPassDescriptor.renderable;
|
||||
const auto& renderableResource = renderable.getResource<RenderableResource>();
|
||||
|
||||
auto colorFormat = MTL::PixelFormat::PixelFormatBGRA8Unorm;
|
||||
std::optional<MTL::PixelFormat> depthFormat = std::nullopt;
|
||||
std::optional<MTL::PixelFormat> stencilFormat = std::nullopt;
|
||||
if (const auto& rpd = renderableResource.getRenderPassDescriptor()) {
|
||||
if (auto* colorTarget = rpd->colorAttachments()->object(0)) {
|
||||
if (auto* tex = colorTarget->texture()) {
|
||||
colorFormat = tex->pixelFormat();
|
||||
}
|
||||
}
|
||||
if (auto* depthTarget = rpd->depthAttachment()) {
|
||||
if (auto* tex = depthTarget->texture()) {
|
||||
depthFormat = tex->pixelFormat();
|
||||
}
|
||||
}
|
||||
if (auto* stencilTarget = rpd->stencilAttachment()) {
|
||||
if (auto* tex = stencilTarget->texture()) {
|
||||
stencilFormat = tex->pixelFormat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto desc = NS::TransferPtr(MTL::RenderPipelineDescriptor::alloc()->init());
|
||||
desc->setLabel(NS::String::string(shaderName.data(), NS::UTF8StringEncoding));
|
||||
desc->setVertexFunction(vertexFunction.get());
|
||||
desc->setFragmentFunction(fragmentFunction.get());
|
||||
desc->setVertexDescriptor(vertexDescriptor.get());
|
||||
|
||||
if (auto* colorTarget = desc->colorAttachments()->object(0)) {
|
||||
const auto blendEnabled = !colorMode.blendFunction.is<gfx::ColorMode::Replace>();
|
||||
auto blendOperation = MTL::BlendOperationAdd;
|
||||
auto srcFactor = MTL::BlendFactorOne;
|
||||
auto destFactor = MTL::BlendFactorOne;
|
||||
|
||||
if (blendEnabled) {
|
||||
apply_visitor(
|
||||
[&](const auto& blendFunction) {
|
||||
blendOperation = metalBlendOperation(gfx::ColorBlendEquationType(blendFunction.equation));
|
||||
srcFactor = metalBlendFactor(blendFunction.srcFactor);
|
||||
destFactor = metalBlendFactor(blendFunction.dstFactor);
|
||||
},
|
||||
colorMode.blendFunction);
|
||||
}
|
||||
|
||||
colorTarget->setPixelFormat(colorFormat);
|
||||
colorTarget->setBlendingEnabled(blendEnabled);
|
||||
colorTarget->setRgbBlendOperation(blendOperation);
|
||||
colorTarget->setAlphaBlendOperation(blendOperation);
|
||||
colorTarget->setSourceRGBBlendFactor(srcFactor);
|
||||
colorTarget->setSourceAlphaBlendFactor(srcFactor);
|
||||
colorTarget->setDestinationRGBBlendFactor(destFactor);
|
||||
colorTarget->setDestinationAlphaBlendFactor(destFactor);
|
||||
}
|
||||
|
||||
if (depthFormat) {
|
||||
desc->setDepthAttachmentPixelFormat(*depthFormat);
|
||||
}
|
||||
|
||||
if (stencilFormat) {
|
||||
desc->setStencilAttachmentPixelFormat(*stencilFormat);
|
||||
}
|
||||
|
||||
NS::Error* error = nullptr;
|
||||
const auto& device = backend.getDevice();
|
||||
auto rps = NS::TransferPtr(device->newRenderPipelineState(desc.get(), &error));
|
||||
|
||||
if (!rps || error) {
|
||||
const auto errPtr = error ? error->localizedDescription()->utf8String() : nullptr;
|
||||
const auto errStr = (errPtr && errPtr[0]) ? ": "s + errPtr : std::string();
|
||||
Log::Error(Event::Shader, shaderName + " newRenderPipelineState failed" + errStr);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return rps;
|
||||
}
|
||||
|
||||
std::optional<uint32_t> ShaderProgram::getSamplerLocation(std::string_view name) const {
|
||||
std::size_t index = 0;
|
||||
for (const auto& bindingName : textureBindings) {
|
||||
if (bindingName == name) {
|
||||
return index;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void ShaderProgram::initAttribute(const shaders::AttributeInfo& info) {
|
||||
vertexAttributes.add(std::string(info.name), static_cast<int>(info.index), info.dataType, info.count);
|
||||
}
|
||||
|
||||
void ShaderProgram::initUniformBlock(const shaders::UniformBlockInfo& info) {
|
||||
if (const auto& block_ = uniformBlocks.add(info.name.data(), static_cast<int>(info.index), info.size)) {
|
||||
auto& block = static_cast<UniformBlock&>(*block_);
|
||||
block.setBindVertex(info.vertex);
|
||||
block.setBindFragment(info.fragment);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgram::initTexture(const shaders::TextureInfo& info) {
|
||||
textureBindings.resize(std::max(textureBindings.size(), info.index + 1));
|
||||
textureBindings[info.index] = info.name;
|
||||
}
|
||||
|
||||
} // namespace mtl
|
||||
} // namespace mbgl
|
||||
Reference in New Issue
Block a user