Wire up samplers.

This commit is contained in:
Chinmay Garde 2021-06-29 17:27:59 -07:00 committed by Dan Field
parent 135433a0d1
commit f86c10efca
13 changed files with 200 additions and 7 deletions

View File

@ -44,6 +44,8 @@ impeller_component("compositor") {
"renderer.mm",
"sampler.h",
"sampler.mm",
"sampler_descriptor.h",
"sampler_descriptor.mm",
"shader_function.h",
"shader_function.mm",
"shader_library.h",

View File

@ -14,6 +14,7 @@
namespace impeller {
class ShaderLibrary;
class SamplerLibrary;
class CommandBuffer;
class Allocator;
@ -39,6 +40,8 @@ class Context {
std::shared_ptr<ShaderLibrary> GetShaderLibrary() const;
std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const;
std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const;
std::shared_ptr<CommandBuffer> CreateRenderCommandBuffer() const;
@ -49,6 +52,7 @@ class Context {
id<MTLCommandQueue> transfer_queue_ = nullptr;
std::shared_ptr<ShaderLibrary> shader_library_;
std::shared_ptr<PipelineLibrary> pipeline_library_;
std::shared_ptr<SamplerLibrary> sampler_library_;
std::shared_ptr<Allocator> permanents_allocator_;
std::shared_ptr<Allocator> transients_allocator_;
bool is_valid_ = false;

View File

@ -8,6 +8,7 @@
#include "flutter/fml/paths.h"
#include "impeller/compositor/allocator.h"
#include "impeller/compositor/command_buffer.h"
#include "impeller/compositor/sampler_descriptor.h"
#include "impeller/compositor/shader_library.h"
namespace impeller {
@ -55,6 +56,12 @@ Context::Context(std::string shaders_directory)
std::shared_ptr<PipelineLibrary>(new PipelineLibrary(device_));
}
// Setup the sampler library.
{ //
sampler_library_ =
std::shared_ptr<SamplerLibrary>(new SamplerLibrary(device_));
}
{
transients_allocator_ = std::shared_ptr<Allocator>(
new Allocator(device_, "Impeller Transients Allocator"));
@ -86,6 +93,10 @@ std::shared_ptr<PipelineLibrary> Context::GetPipelineLibrary() const {
return pipeline_library_;
}
std::shared_ptr<SamplerLibrary> Context::GetSamplerLibrary() const {
return sampler_library_;
}
std::shared_ptr<CommandBuffer> Context::CreateRenderCommandBuffer() const {
if (!IsValid()) {
return nullptr;

View File

@ -66,6 +66,23 @@ enum class PrimitiveType {
// checks. Hence, they are not supported here.
};
enum class MinMagFilter {
/// Select nearest to the sample point. Most widely supported.
kNearest,
/// Select two points and linearly interpolate between them. Some formats may
/// not support this.
kLinear,
};
enum class SamplerAddressMode {
kClampToEdge,
kRepeat,
kMirror,
// More modes are almost always supported but they are usually behind
// extensions checks. The ones current in these structs are safe (always
// supported) defaults.
};
enum class ColorWriteMask : uint64_t {
kNone = 0,
kRed = 1 << 0,

View File

@ -215,6 +215,29 @@ constexpr StoreAction FromMTLStoreAction(MTLStoreAction action) {
return StoreAction::kDontCare;
}
constexpr MTLSamplerMinMagFilter ToMTLSamplerMinMagFilter(MinMagFilter filter) {
switch (filter) {
case MinMagFilter::kNearest:
return MTLSamplerMinMagFilterNearest;
case MinMagFilter::kLinear:
return MTLSamplerMinMagFilterLinear;
}
return MTLSamplerMinMagFilterNearest;
}
constexpr MTLSamplerAddressMode ToMTLSamplerAddressMode(
SamplerAddressMode mode) {
switch (mode) {
case SamplerAddressMode::kClampToEdge:
return MTLSamplerAddressModeClampToEdge;
case SamplerAddressMode::kRepeat:
return MTLSamplerAddressModeRepeat;
case SamplerAddressMode::kMirror:
return MTLSamplerAddressModeMirrorRepeat;
}
return MTLSamplerAddressModeClampToEdge;
}
constexpr MTLClearColor ToMTLClearColor(const Color& color) {
return MTLClearColorMake(color.red, color.green, color.blue, color.alpha);
}

View File

@ -32,7 +32,7 @@ class PipelineLibrary : public std::enable_shared_from_this<PipelineLibrary> {
std::shared_ptr<const Pipeline>,
ComparableHash<PipelineDescriptor>,
ComparableEqual<PipelineDescriptor>>;
id<MTLDevice> device_;
id<MTLDevice> device_ = nullptr;
Pipelines pipelines_;
PipelineLibrary(id<MTLDevice> device);

View File

@ -4,17 +4,27 @@
#pragma once
#include <Metal/Metal.h>
#include "flutter/fml/macros.h"
namespace impeller {
class SamplerLibrary;
class Sampler {
public:
Sampler();
bool IsValid() const;
~Sampler();
private:
friend SamplerLibrary;
id<MTLSamplerState> state_ = nullptr;
Sampler(id<MTLSamplerState> state);
FML_DISALLOW_COPY_AND_ASSIGN(Sampler);
};

View File

@ -6,8 +6,12 @@
namespace impeller {
Sampler::Sampler() = default;
Sampler::Sampler(id<MTLSamplerState> state) : state_(state) {}
Sampler::~Sampler() = default;
bool Sampler::IsValid() const {
return state_;
}
} // namespace impeller

View File

@ -0,0 +1,64 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <Metal/Metal.h>
#include <unordered_map>
#include "flutter/fml/macros.h"
#include "impeller/compositor/comparable.h"
#include "impeller/compositor/formats.h"
namespace impeller {
class Sampler;
class Context;
struct SamplerDescriptor final : public Comparable<SamplerDescriptor> {
MinMagFilter min_filter = MinMagFilter::kNearest;
MinMagFilter mag_filter = MinMagFilter::kNearest;
SamplerAddressMode width_address_mode = SamplerAddressMode::kClampToEdge;
SamplerAddressMode height_address_mode = SamplerAddressMode::kClampToEdge;
SamplerAddressMode depth_address_mode = SamplerAddressMode::kClampToEdge;
// Comparable<SamplerDescriptor>
std::size_t GetHash() const override {
return fml::HashCombine(min_filter, mag_filter, width_address_mode,
height_address_mode, depth_address_mode);
}
// Comparable<SamplerDescriptor>
bool IsEqual(const SamplerDescriptor& o) const override {
return min_filter == o.min_filter && mag_filter == o.mag_filter &&
width_address_mode == o.width_address_mode &&
height_address_mode == o.height_address_mode &&
depth_address_mode == o.depth_address_mode;
}
};
class SamplerLibrary {
public:
~SamplerLibrary();
std::shared_ptr<const Sampler> GetSampler(SamplerDescriptor descriptor);
private:
friend Context;
using Samplers = std::unordered_map<SamplerDescriptor,
std::shared_ptr<const Sampler>,
ComparableHash<SamplerDescriptor>,
ComparableEqual<SamplerDescriptor>>;
id<MTLDevice> device_ = nullptr;
Samplers samplers_;
SamplerLibrary(id<MTLDevice> device);
FML_DISALLOW_COPY_AND_ASSIGN(SamplerLibrary);
};
} // namespace impeller

View File

@ -0,0 +1,43 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/compositor/sampler_descriptor.h"
#include "impeller/compositor/formats_metal.h"
#include "impeller/compositor/sampler.h"
namespace impeller {
SamplerLibrary::SamplerLibrary(id<MTLDevice> device) : device_(device) {}
SamplerLibrary::~SamplerLibrary() = default;
std::shared_ptr<const Sampler> SamplerLibrary::GetSampler(
SamplerDescriptor descriptor) {
auto found = samplers_.find(descriptor);
if (found != samplers_.end()) {
return found->second;
}
if (!device_) {
return nullptr;
}
auto desc = [[MTLSamplerDescriptor alloc] init];
desc.minFilter = ToMTLSamplerMinMagFilter(descriptor.min_filter);
desc.magFilter = ToMTLSamplerMinMagFilter(descriptor.mag_filter);
desc.sAddressMode = MTLSamplerAddressMode(descriptor.width_address_mode);
desc.rAddressMode = MTLSamplerAddressMode(descriptor.depth_address_mode);
desc.tAddressMode = MTLSamplerAddressMode(descriptor.height_address_mode);
auto mtl_sampler = [device_ newSamplerStateWithDescriptor:desc];
if (!mtl_sampler) {
return nullptr;
}
auto sampler = std::shared_ptr<Sampler>(new Sampler(mtl_sampler));
if (!sampler->IsValid()) {
return nullptr;
}
samplers_[descriptor] = sampler;
return sampler;
}
} // namespace impeller

View File

@ -32,9 +32,13 @@ EntityRenderer::EntityRenderer(std::string shaders_directory)
VertexBufferBuilder<shader::BoxVertexInfo::PerVertexData> vertex_builder;
vertex_builder.SetLabel("Box");
vertex_builder.AddVertices({
{{0, 0, 0.0}, {Color::Red()}}, //
{{800, 0.0, 0.0}, {Color::Green()}}, //
{{0.0, 600, 0.0}, {Color::Blue()}}, //
{{100, 100, 0.0}, {Color::Red()}}, // 1
{{800, 100, 0.0}, {Color::Green()}}, // 2
{{800, 800, 0.0}, {Color::Blue()}}, // 3
{{100, 100, 0.0}, {Color::Cyan()}}, // 1
{{800, 800, 0.0}, {Color::White()}}, // 3
{{100, 800, 0.0}, {Color::Purple()}}, // 4
});
vertex_buffer_ =

View File

@ -3,9 +3,17 @@
// found in the LICENSE file.
in vec4 color;
in vec2 interpolated_texture_coordinates;
uniform sampler2D contents;
// uniform sampler2D texture_sampler2;
// uniform sampler2D texture_sampler3;
out vec4 frag_color;
void main() {
frag_color = color;
vec4 color1 = texture(contents, interpolated_texture_coordinates);
// vec4 color2 = texture(texture_sampler2, interpolated_texture_coordinates);
// vec4 color3 = texture(texture_sampler3, interpolated_texture_coordinates);
frag_color = color1;
}

View File

@ -8,10 +8,13 @@ uniform UniformBuffer {
in vec3 vertex_position;
in vec4 vertex_color;
in vec2 texture_coordinates;
out vec4 color;
out vec2 interpolated_texture_coordinates;
void main() {
gl_Position = uniforms.mvp * vec4(vertex_position, 1.0);
color = vertex_color;
interpolated_texture_coordinates = texture_coordinates;
}