aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--samples/CMakeLists.txt1
-rw-r--r--samples/config_helper_dawn.cc36
-rw-r--r--samples/dawn_device_metal.mm49
-rw-r--r--src/dawn/engine_dawn.cc78
-rw-r--r--src/dawn/engine_dawn.h2
5 files changed, 79 insertions, 87 deletions
diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt
index 29898e6..3831b8b 100644
--- a/samples/CMakeLists.txt
+++ b/samples/CMakeLists.txt
@@ -36,7 +36,6 @@ if (${Dawn_FOUND})
list(APPEND AMBER_EXTRA_LIBS Dawn::dawn_native Dawn::dawn)
if (APPLE)
add_definitions(-DAMBER_DAWN_METAL=1)
- set(AMBER_SOURCES ${AMBER_SOURCES} dawn_device_metal.mm)
find_library(METAL_LIB Metal)
list(APPEND AMBER_EXTRA_LIBS ${METAL_LIB})
else()
diff --git a/samples/config_helper_dawn.cc b/samples/config_helper_dawn.cc
index eeb66f3..32c4869 100644
--- a/samples/config_helper_dawn.cc
+++ b/samples/config_helper_dawn.cc
@@ -13,18 +13,12 @@
// limitations under the License.
#include "samples/config_helper_dawn.h"
-
#include <iostream>
#include "samples/dawn_device_metal.h"
-
namespace sample {
-
ConfigHelperDawn::ConfigHelperDawn() = default;
-
ConfigHelperDawn::~ConfigHelperDawn() = default;
-
-namespace {
-// Callback which prints a message from a Dawn device operation.
+namespace { // Callback which prints a message from a Dawn device operation.
void PrintDeviceError(const char* message, ::dawn::CallbackUserdata) {
std::cout << "Device error: " << message << std::endl;
}
@@ -39,22 +33,32 @@ amber::Result ConfigHelperDawn::CreateConfig(
bool,
bool,
std::unique_ptr<amber::EngineConfig>* config) {
-#if AMBER_DAWN_METAL
- auto r = dawn::CreateMetalDevice(&dawn_instance_, &dawn_device_);
- if (!r.IsSuccess())
- return r;
-#else
- return amber::Result("Can't make Dawn engine config");
-#endif
// Set procedure table and error callback.
- dawnProcTable backendProcs = dawn_native::GetProcs();
+ DawnProcTable backendProcs = dawn_native::GetProcs();
dawnSetProcs(&backendProcs);
- backendProcs.deviceSetErrorCallback(dawn_device_.Get(), PrintDeviceError, 0);
+ dawn_instance_.DiscoverDefaultAdapters();
+ for (dawn_native::Adapter& adapter : dawn_instance_.GetAdapters()) {
+#if AMBER_DAWN_METAL
+ ::dawn_native::BackendType backendType = ::dawn_native::BackendType::Metal;
+#else // assuming VULKAN
+ ::dawn_native::BackendType backendType = ::dawn_native::BackendType::Vulkan;
+#endif
+
+ if (adapter.GetBackendType() == backendType) {
+ dawn_device_ = ::dawn::Device::Acquire(adapter.CreateDevice());
+ }
+ }
+
+ if (!dawn_device_)
+ return amber::Result("could not find Vulkan or Metal backend for Dawn");
+
+ backendProcs.deviceSetErrorCallback(dawn_device_.Get(), PrintDeviceError, 0);
auto* dawn_config = new amber::DawnEngineConfig;
dawn_config->device = &dawn_device_;
config->reset(dawn_config);
+
return {};
}
diff --git a/samples/dawn_device_metal.mm b/samples/dawn_device_metal.mm
deleted file mode 100644
index bfbe852..0000000
--- a/samples/dawn_device_metal.mm
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 The Amber Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "dawn_device_metal.h"
-
-#include "amber/result.h"
-#include "dawn/dawncpp.h"
-#include "dawn_native/DawnNative.h"
-#include "dawn_native/MetalBackend.h"
-
-namespace sample {
-namespace dawn {
-
-amber::Result CreateMetalDevice(::dawn_native::Instance* dawn_instance_ptr,
- ::dawn::Device* device_ptr) {
- if (!dawn_instance_ptr) {
- return amber::Result(
- "::amber::dawn::CreateMetalDevice: invalid dawn instance parameter");
- }
- if (!device_ptr) {
- return amber::Result(
- "::amber::dawn::CreateMetalDevice: invalid device parameter");
- }
- *device_ptr = nullptr;
- dawn_instance_ptr->DiscoverDefaultAdapters();
- for (dawn_native::Adapter adapter : dawn_instance_ptr->GetAdapters()) {
- if (adapter.GetBackendType() == ::dawn_native::BackendType::Metal) {
- *device_ptr = ::dawn::Device::Acquire(adapter.CreateDevice());
- return {};
- }
- }
-
- return amber::Result(
- "::amber::dawn::CreateMetalDevice: Failed to create metal device");
-}
-
-} // namespace dawn
-} // namespace sample
diff --git a/src/dawn/engine_dawn.cc b/src/dawn/engine_dawn.cc
index bdd6b4b..39ce515 100644
--- a/src/dawn/engine_dawn.cc
+++ b/src/dawn/engine_dawn.cc
@@ -17,6 +17,7 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
+#include <cstring>
#include <iostream>
#include <utility>
#include <vector>
@@ -53,9 +54,9 @@ Result MakeFramebufferTexture(const ::dawn::Device& device,
descriptor.size.width = kFramebufferWidth;
descriptor.size.height = kFramebufferHeight;
descriptor.size.depth = 1;
- descriptor.arraySize = 1;
+ descriptor.arrayLayerCount = 1;
descriptor.format = format;
- descriptor.levelCount = 1;
+ descriptor.mipLevelCount = 1;
descriptor.sampleCount = 1;
descriptor.usage = ::dawn::TextureUsageBit::TransferSrc |
::dawn::TextureUsageBit::OutputAttachment;
@@ -117,6 +118,7 @@ Result MakeFramebufferBuffer(const ::dawn::Device& device,
struct MapResult {
Result result;
const void* data = nullptr;
+ int dataLength = 0;
};
// Handles the update from an asynchronous buffer map request, updating the
@@ -124,13 +126,15 @@ struct MapResult {
// On a successful mapping outcome, set the data pointer in the map result.
// Otherwise set the map result object to an error, and the data member is
// not changed.
-void HandleBufferMapCallback(dawnBufferMapAsyncStatus status,
+void HandleBufferMapCallback(DawnBufferMapAsyncStatus status,
const void* data,
- dawnCallbackUserdata userdata) {
+ uint32_t dataLength,
+ DawnCallbackUserdata userdata) {
MapResult& map_result = *reinterpret_cast<MapResult*>(userdata);
switch (status) {
case DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS:
map_result.data = data;
+ map_result.dataLength = dataLength;
break;
case DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR:
map_result.result = Result("Buffer map for reading failed: error");
@@ -150,12 +154,10 @@ void HandleBufferMapCallback(dawnBufferMapAsyncStatus status,
// status saved in the .result member and the host pointer to the mapped data
// in the |.data| member. Mapping a buffer can fail if the context is lost, for
// example. In the failure case, the .data member of the result will be null.
-MapResult MapBuffer(const ::dawn::Device& device,
- const ::dawn::Buffer& buf,
- uint32_t size) {
+MapResult MapBuffer(const ::dawn::Device& device, const ::dawn::Buffer& buf) {
MapResult map_result;
- buf.MapReadAsync(0, size, HandleBufferMapCallback,
- static_cast<dawnCallbackUserdata>(
+ buf.MapReadAsync(HandleBufferMapCallback,
+ static_cast<DawnCallbackUserdata>(
reinterpret_cast<uintptr_t>(&map_result)));
device.Tick();
// Wait until the callback has been processed. Use an exponential backoff
@@ -272,7 +274,7 @@ Result EngineDawn::DoClearDepth(const ClearDepthCommand* command) {
return {};
}
-Result EngineDawn::DoClear(const ClearCommand*) {
+Result EngineDawn::DoClear(const ClearCommand* command) {
Result result = CreateRenderObjectsIfNeeded();
if (!result.IsSuccess())
return result;
@@ -286,12 +288,48 @@ Result EngineDawn::DoClear(const ClearCommand*) {
color_attachment.loadOp = ::dawn::LoadOp::Clear;
color_attachment.storeOp = ::dawn::StoreOp::Store;
- ::dawn::RenderPassDescriptor rpd =
- device_->CreateRenderPassDescriptorBuilder()
- .SetColorAttachments(1, &color_attachment)
- .GetResult();
- command_buffer_builder_.BeginRenderPass(rpd).EndPass();
- return {};
+ ::dawn::RenderPassColorAttachmentDescriptor* rpca[] = {&color_attachment};
+ ::dawn::RenderPassDescriptor rpd;
+ rpd.colorAttachmentCount = 1;
+ rpd.colorAttachments = rpca;
+ rpd.depthStencilAttachment = nullptr;
+ ::dawn::RenderPassEncoder pass =
+ command_buffer_builder_.BeginRenderPass(&rpd);
+ pass.EndPass();
+
+ // Make sure we have a queue.
+ if (!queue_)
+ queue_ = device_->CreateQueue();
+
+ // Now run the commands.
+ ::dawn::Buffer& fb_buffer = render_pipeline_info_.fb_buffer;
+ auto command_buffer = command_buffer_builder_.Finish();
+
+ if (render_pipeline_info_.fb_data != nullptr) {
+ fb_buffer.Unmap();
+ render_pipeline_info_.fb_data = nullptr;
+ }
+
+ queue_.Submit(1, &command_buffer);
+
+ auto* pipeline = command->GetPipeline();
+ const std::vector<amber::Pipeline::BufferInfo>& out_color_attachment =
+ pipeline->GetColorAttachments();
+
+ // And any further commands start afresh.
+ DestroyCommandBufferBuilder();
+ MapResult map = MapBuffer(*device_, fb_buffer);
+
+ for (size_t i = 0; i < 1; ++i) {
+ auto& img = map;
+ auto& info = out_color_attachment[i];
+ auto* values = info.buffer->ValuePtr();
+ values->resize(info.buffer->GetSizeInBytes());
+ // assert map.size == info->buffer->GetSizeInBytes()
+ std::memcpy(values->data(), img.data, info.buffer->GetSizeInBytes());
+ }
+
+ return map.result;
}
Result EngineDawn::DoDrawRect(const DrawRectCommand*) {
@@ -337,7 +375,7 @@ Result EngineDawn::DoDrawRect(const DrawRectCommand*) {
queue_ = device_->CreateQueue();
// Now run the commands.
- auto command_buffer = command_buffer_builder_.GetResult();
+ auto command_buffer = command_buffer_builder_.Finish();
if (render_pipeline_info_.fb_data != nullptr) {
fb_buffer.Unmap();
@@ -349,7 +387,7 @@ Result EngineDawn::DoDrawRect(const DrawRectCommand*) {
// And any further commands start afresh.
DestroyCommandBufferBuilder();
- MapResult map = MapBuffer(*device_, fb_buffer, render_pipeline_info_.fb_size);
+ MapResult map = MapBuffer(*device_, fb_buffer);
render_pipeline_info_.fb_data = map.data;
return map.result;
}
@@ -385,14 +423,14 @@ Result EngineDawn::CreateCommandBufferBuilderIfNeeded() {
"EngineDawn: Can't create command buffer builder: device is not "
"initialized");
}
- command_buffer_builder_ = device_->CreateCommandBufferBuilder();
+ command_buffer_builder_ = device_->CreateCommandEncoder();
if (command_buffer_builder_)
return {};
return Result("EngineDawn: Can't create command buffer builder");
}
void EngineDawn::DestroyCommandBufferBuilder() {
- command_buffer_builder_ = ::dawn::CommandBufferBuilder();
+ command_buffer_builder_ = ::dawn::CommandEncoder();
}
Result EngineDawn::CreateRenderObjectsIfNeeded() {
diff --git a/src/dawn/engine_dawn.h b/src/dawn/engine_dawn.h
index a015d15..b92a66d 100644
--- a/src/dawn/engine_dawn.h
+++ b/src/dawn/engine_dawn.h
@@ -78,7 +78,7 @@ class EngineDawn : public Engine {
::dawn::Device* device_ = nullptr; // Borrowed from the engine config.
::dawn::Queue queue_;
- ::dawn::CommandBufferBuilder command_buffer_builder_;
+ ::dawn::CommandEncoder command_buffer_builder_;
std::unordered_map<ShaderType, ::dawn::ShaderModule, CastHash<ShaderType>>
module_for_type_;