From 200a245166339b06e0f6147be3150801b90f3f02 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 8 Mar 2023 11:04:47 -0800 Subject: [PATCH 1/2] Rendering --- impeller/fixtures/stroke.comp | 3 +++ impeller/renderer/compute_subgroup_unittests.cc | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/impeller/fixtures/stroke.comp b/impeller/fixtures/stroke.comp index 5bb16d76a1731..57d9555546d29 100644 --- a/impeller/fixtures/stroke.comp +++ b/impeller/fixtures/stroke.comp @@ -17,6 +17,7 @@ layout(binding = 0) buffer Polyline { polyline; layout(binding = 1) buffer VertexBuffer { + uint count; vec2 position[]; } vertex_buffer; @@ -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; diff --git a/impeller/renderer/compute_subgroup_unittests.cc b/impeller/renderer/compute_subgroup_unittests.cc index ff4ea32a2bc3e..2929a493ccee1 100644 --- a/impeller/renderer/compute_subgroup_unittests.cc +++ b/impeller/renderer/compute_subgroup_unittests.cc @@ -191,6 +191,12 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) { })); latch.Wait(); + + auto* v_buf = reinterpret_cast*>( + vertex_buffer->AsBufferView().contents); + FML_LOG(ERROR) << v_buf->count; + + OpenPlaygroundHere(); } TEST_P(ComputeTest, QuadsToPolyline) { @@ -259,7 +265,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(); })); From 3e0c47502673435a3c96721159d82d0e15632a65 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 8 Mar 2023 16:14:04 -0800 Subject: [PATCH 2/2] Feature detection --- .../renderer/backend/gles/context_gles.cc | 1 + .../renderer/backend/metal/context_mtl.mm | 9 ++++++ .../renderer/backend/vulkan/context_vk.cc | 2 ++ .../renderer/compute_subgroup_unittests.cc | 9 ++---- impeller/renderer/compute_unittests.cc | 3 ++ impeller/renderer/device_capabilities.cc | 29 +++++++++++++++++-- impeller/renderer/device_capabilities.h | 13 ++++++++- 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/impeller/renderer/backend/gles/context_gles.cc b/impeller/renderer/backend/gles/context_gles.cc index 99922ba7efaeb..674e911672627 100644 --- a/impeller/renderer/backend/gles/context_gles.cc +++ b/impeller/renderer/backend/gles/context_gles.cc @@ -80,6 +80,7 @@ ContextGLES::ContextGLES(std::unique_ptr gl, reactor_->GetProcTable().BlitFramebuffer.IsAvailable()) .SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt) .SetDefaultStencilFormat(PixelFormat::kS8UInt) + .SetSupportsCompute(false, false) .Build(); } diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index a601f099fd001..c8092a64ca0a7 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -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) @@ -98,6 +106,7 @@ .SetSupportsTextureToTextureBlits(true) .SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt) .SetDefaultStencilFormat(PixelFormat::kS8UInt) + .SetSupportsCompute(true, supports_subgroups) .Build(); } diff --git a/impeller/renderer/backend/vulkan/context_vk.cc b/impeller/renderer/backend/vulkan/context_vk.cc index 41594818f7b8f..7a6cd766ed431 100644 --- a/impeller/renderer/backend/vulkan/context_vk.cc +++ b/impeller/renderer/backend/vulkan/context_vk.cc @@ -556,6 +556,8 @@ ContextVK::ContextVK( .SetSupportsTextureToTextureBlits(true) .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); diff --git a/impeller/renderer/compute_subgroup_unittests.cc b/impeller/renderer/compute_subgroup_unittests.cc index 2929a493ccee1..5ebcb339ce466 100644 --- a/impeller/renderer/compute_subgroup_unittests.cc +++ b/impeller/renderer/compute_subgroup_unittests.cc @@ -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(); @@ -182,6 +183,7 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) { auto* v = reinterpret_cast*>( 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); @@ -191,18 +193,13 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) { })); latch.Wait(); - - auto* v_buf = reinterpret_cast*>( - vertex_buffer->AsBufferView().contents); - FML_LOG(ERROR) << v_buf->count; - - OpenPlaygroundHere(); } 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(); diff --git a/impeller/renderer/compute_unittests.cc b/impeller/renderer/compute_unittests.cc index ca8162d309293..cfa50e042d8e8 100644 --- a/impeller/renderer/compute_unittests.cc +++ b/impeller/renderer/compute_unittests.cc @@ -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; auto pipeline_desc = SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context); @@ -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); diff --git a/impeller/renderer/device_capabilities.cc b/impeller/renderer/device_capabilities.cc index 87653bb63beef..1e0325065af5d 100644 --- a/impeller/renderer/device_capabilities.cc +++ b/impeller/renderer/device_capabilities.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "impeller/renderer/device_capabilities.h" +#include "device_capabilities.h" namespace impeller { @@ -11,13 +12,17 @@ IDeviceCapabilities::IDeviceCapabilities(bool has_threading_restrictions, bool supports_ssbo, bool supports_texture_to_texture_blits, 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), 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; @@ -45,6 +50,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; @@ -85,6 +98,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 DeviceCapabilitiesBuilder::Build() { FML_CHECK(default_color_format_.has_value()) << "Default color format not set"; @@ -97,7 +118,9 @@ std::unique_ptr DeviceCapabilitiesBuilder::Build() { supports_ssbo_, // supports_texture_to_texture_blits_, // *default_color_format_, // - *default_stencil_format_ // + *default_stencil_format_, // + supports_compute_, // + supports_compute_subgroups_ // ); return std::unique_ptr(capabilities); } diff --git a/impeller/renderer/device_capabilities.h b/impeller/renderer/device_capabilities.h index 010281da37a4d..013e10a9123b6 100644 --- a/impeller/renderer/device_capabilities.h +++ b/impeller/renderer/device_capabilities.h @@ -27,13 +27,18 @@ 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, PixelFormat default_color_format, - PixelFormat default_stencil_format); + PixelFormat default_stencil_format, + bool supports_compute, + bool supports_compute_subgroups); friend class DeviceCapabilitiesBuilder; @@ -43,6 +48,8 @@ class IDeviceCapabilities { bool supports_texture_to_texture_blits_ = false; PixelFormat default_color_format_; PixelFormat default_stencil_format_; + bool supports_compute_ = false; + bool supports_compute_subgroups_ = false; FML_DISALLOW_COPY_AND_ASSIGN(IDeviceCapabilities); }; @@ -65,6 +72,8 @@ class DeviceCapabilitiesBuilder { DeviceCapabilitiesBuilder& SetDefaultStencilFormat(PixelFormat value); + DeviceCapabilitiesBuilder& SetSupportsCompute(bool value, bool subgroups); + std::unique_ptr Build(); private: @@ -72,6 +81,8 @@ class DeviceCapabilitiesBuilder { bool supports_offscreen_msaa_ = false; bool supports_ssbo_ = false; bool supports_texture_to_texture_blits_ = false; + bool supports_compute_ = false; + bool supports_compute_subgroups_ = false; std::optional default_color_format_ = std::nullopt; std::optional default_stencil_format_ = std::nullopt;