Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller][Compute] Guard subgroups with feature detection #40159

Merged
merged 3 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions impeller/fixtures/stroke.comp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ layout(binding = 0) buffer Polyline {
polyline;

layout(binding = 1) buffer VertexBuffer {
uint count;
vec2 position[];
}
vertex_buffer;
Expand All @@ -40,6 +41,8 @@ void main() {
return;
}

atomicAdd(vertex_buffer.count, 4);

vec2 offset = compute_offset(ident);
uint index = ident - 1;
vertex_buffer.position[index * 4 + 0] = polyline.data[ident - 1] + offset;
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/gles/context_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ ContextGLES::ContextGLES(std::unique_ptr<ProcTableGLES> gl,
.SetSupportsFramebufferFetch(false)
.SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt)
.SetDefaultStencilFormat(PixelFormat::kS8UInt)
.SetSupportsCompute(false, false)
.Build();
}

Expand Down
9 changes: 9 additions & 0 deletions impeller/renderer/backend/metal/context_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@
#endif

{
bool supports_subgroups = false;
// Refer to the "SIMD-scoped reduction operations" feature in the table
// below: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
if (@available(ios 13.0, tvos 13.0, macos 10.15, *)) {
supports_subgroups = [device supportsFamily:MTLGPUFamilyApple7] ||
[device supportsFamily:MTLGPUFamilyMac2];
}

device_capabilities_ =
DeviceCapabilitiesBuilder()
.SetHasThreadingRestrictions(false)
Expand All @@ -99,6 +107,7 @@
.SetSupportsFramebufferFetch(SupportsFramebufferFetch())
.SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt)
.SetDefaultStencilFormat(PixelFormat::kS8UInt)
.SetSupportsCompute(true, supports_subgroups)
.Build();
}

Expand Down
2 changes: 2 additions & 0 deletions impeller/renderer/backend/vulkan/context_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,8 @@ ContextVK::ContextVK(
.SetSupportsFramebufferFetch(false)
.SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt)
.SetDefaultStencilFormat(PixelFormat::kS8UInt)
// TODO(110622): detect this and enable.
.SetSupportsCompute(false, false)
.Build();
graphics_command_pool_ = std::move(graphics_command_pool.value);
descriptor_pool_ = std::move(descriptor_pool.value);
Expand Down
4 changes: 3 additions & 1 deletion impeller/renderer/compute_subgroup_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) {

auto context = GetContext();
ASSERT_TRUE(context);
ASSERT_TRUE(context->GetDeviceCapabilities().SupportsComputeSubgroups());

auto cmd_buffer = context->CreateCommandBuffer();
auto pass = cmd_buffer->CreateComputePass();
Expand Down Expand Up @@ -182,6 +183,7 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) {

auto* v = reinterpret_cast<SS::VertexBuffer<kCubicCount * 10 * 10 * 4>*>(
vertex_buffer->AsBufferView().contents);
EXPECT_EQ(v->count, golden_heart_vertices.size());
for (size_t i = 0; i < golden_heart_vertices.size(); i += 1) {
EXPECT_LT(std::abs(golden_heart_vertices[i].x - v->position[i].x), 1e-3);
EXPECT_LT(std::abs(golden_heart_vertices[i].y - v->position[i].y), 1e-3);
Expand All @@ -197,6 +199,7 @@ TEST_P(ComputeTest, QuadsToPolyline) {
using QS = QuadPolylineComputeShader;
auto context = GetContext();
ASSERT_TRUE(context);
ASSERT_TRUE(context->GetDeviceCapabilities().SupportsComputeSubgroups());

auto cmd_buffer = context->CreateCommandBuffer();
auto pass = cmd_buffer->CreateComputePass();
Expand Down Expand Up @@ -259,7 +262,6 @@ TEST_P(ComputeTest, QuadsToPolyline) {
EXPECT_LT(std::abs(p->data[i].x - golden_heart_points[i].x), 1e-3);
EXPECT_LT(std::abs(p->data[i].y - golden_heart_points[i].y), 1e-3);
}

latch.Signal();
}));

Expand Down
3 changes: 3 additions & 0 deletions impeller/renderer/compute_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ TEST_P(ComputeTest, CanCreateComputePass) {
using CS = SampleComputeShader;
auto context = GetContext();
ASSERT_TRUE(context);
ASSERT_TRUE(context->GetDeviceCapabilities().SupportsCompute());

using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
auto pipeline_desc =
SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
Expand Down Expand Up @@ -114,6 +116,7 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) {

auto context = GetContext();
ASSERT_TRUE(context);
ASSERT_TRUE(context->GetDeviceCapabilities().SupportsCompute());

auto pipeline_desc_1 =
Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
Expand Down
29 changes: 26 additions & 3 deletions impeller/renderer/device_capabilities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#include "impeller/renderer/device_capabilities.h"
#include "device_capabilities.h"

namespace impeller {

Expand All @@ -12,14 +13,18 @@ IDeviceCapabilities::IDeviceCapabilities(bool has_threading_restrictions,
bool supports_texture_to_texture_blits,
bool supports_framebuffer_fetch,
PixelFormat default_color_format,
PixelFormat default_stencil_format)
PixelFormat default_stencil_format,
bool supports_compute,
bool supports_compute_subgroups)
: has_threading_restrictions_(has_threading_restrictions),
supports_offscreen_msaa_(supports_offscreen_msaa),
supports_ssbo_(supports_ssbo),
supports_texture_to_texture_blits_(supports_texture_to_texture_blits),
supports_framebuffer_fetch_(supports_framebuffer_fetch),
default_color_format_(default_color_format),
default_stencil_format_(default_stencil_format) {}
default_stencil_format_(default_stencil_format),
supports_compute_(supports_compute),
supports_compute_subgroups_(supports_compute_subgroups) {}

IDeviceCapabilities::~IDeviceCapabilities() = default;

Expand Down Expand Up @@ -51,6 +56,14 @@ PixelFormat IDeviceCapabilities::GetDefaultStencilFormat() const {
return default_stencil_format_;
}

bool IDeviceCapabilities::SupportsCompute() const {
return supports_compute_;
}

bool IDeviceCapabilities::SupportsComputeSubgroups() const {
return supports_compute_subgroups_;
}

DeviceCapabilitiesBuilder::DeviceCapabilitiesBuilder() = default;

DeviceCapabilitiesBuilder::~DeviceCapabilitiesBuilder() = default;
Expand Down Expand Up @@ -97,6 +110,14 @@ DeviceCapabilitiesBuilder& DeviceCapabilitiesBuilder::SetDefaultStencilFormat(
return *this;
}

DeviceCapabilitiesBuilder& DeviceCapabilitiesBuilder::SetSupportsCompute(
bool value,
bool subgroups) {
supports_compute_ = value;
supports_compute_subgroups_ = subgroups;
return *this;
}

std::unique_ptr<IDeviceCapabilities> DeviceCapabilitiesBuilder::Build() {
FML_CHECK(default_color_format_.has_value())
<< "Default color format not set";
Expand All @@ -110,7 +131,9 @@ std::unique_ptr<IDeviceCapabilities> DeviceCapabilitiesBuilder::Build() {
supports_texture_to_texture_blits_, //
supports_framebuffer_fetch_, //
*default_color_format_, //
*default_stencil_format_ //
*default_stencil_format_, //
supports_compute_, //
supports_compute_subgroups_ //
);
return std::unique_ptr<IDeviceCapabilities>(capabilities);
}
Expand Down
13 changes: 12 additions & 1 deletion impeller/renderer/device_capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,19 @@ class IDeviceCapabilities {

PixelFormat GetDefaultStencilFormat() const;

bool SupportsCompute() const;
bool SupportsComputeSubgroups() const;

private:
IDeviceCapabilities(bool has_threading_restrictions,
bool supports_offscreen_msaa,
bool supports_ssbo,
bool supports_texture_to_texture_blits,
bool supports_framebuffer_fetch,
PixelFormat default_color_format,
PixelFormat default_stencil_format);
PixelFormat default_stencil_format,
bool supports_compute,
bool supports_compute_subgroups);

friend class DeviceCapabilitiesBuilder;

Expand All @@ -47,6 +52,8 @@ class IDeviceCapabilities {
bool supports_framebuffer_fetch_ = false;
PixelFormat default_color_format_;
PixelFormat default_stencil_format_;
bool supports_compute_ = false;
bool supports_compute_subgroups_ = false;

FML_DISALLOW_COPY_AND_ASSIGN(IDeviceCapabilities);
};
Expand All @@ -71,6 +78,8 @@ class DeviceCapabilitiesBuilder {

DeviceCapabilitiesBuilder& SetDefaultStencilFormat(PixelFormat value);

DeviceCapabilitiesBuilder& SetSupportsCompute(bool value, bool subgroups);

std::unique_ptr<IDeviceCapabilities> Build();

private:
Expand All @@ -79,6 +88,8 @@ class DeviceCapabilitiesBuilder {
bool supports_ssbo_ = false;
bool supports_texture_to_texture_blits_ = false;
bool supports_framebuffer_fetch_ = false;
bool supports_compute_ = false;
bool supports_compute_subgroups_ = false;
std::optional<PixelFormat> default_color_format_ = std::nullopt;
std::optional<PixelFormat> default_stencil_format_ = std::nullopt;

Expand Down