summaryrefslogtreecommitdiff
path: root/chromium/third_party/dawn
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-13 16:23:34 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-14 10:37:21 +0000
commit38a9a29f4f9436cace7f0e7abf9c586057df8a4e (patch)
treec4e8c458dc595bc0ddb435708fa2229edfd00bd4 /chromium/third_party/dawn
parente684a3455bcc29a6e3e66a004e352dea4e1141e7 (diff)
downloadqtwebengine-chromium-38a9a29f4f9436cace7f0e7abf9c586057df8a4e.tar.gz
BASELINE: Update Chromium to 73.0.3683.37
Change-Id: I08c9af2948b645f671e5d933aca1f7a90ea372f2 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/dawn')
-rw-r--r--chromium/third_party/dawn/BUILD.gn360
-rw-r--r--chromium/third_party/dawn/DEPS4
-rw-r--r--chromium/third_party/dawn/README.md1
-rw-r--r--chromium/third_party/dawn/build_overrides/shaderc.gni1
-rw-r--r--chromium/third_party/dawn/dawn.json491
-rw-r--r--chromium/third_party/dawn/dawn_wire.json80
-rw-r--r--chromium/third_party/dawn/examples/Animometer.cpp19
-rw-r--r--chromium/third_party/dawn/examples/CHelloTriangle.cpp93
-rw-r--r--chromium/third_party/dawn/examples/ComputeBoids.cpp45
-rw-r--r--chromium/third_party/dawn/examples/CppHelloTriangle.cpp39
-rw-r--r--chromium/third_party/dawn/examples/CubeReflection.cpp134
-rw-r--r--chromium/third_party/dawn/examples/SampleUtils.cpp23
-rw-r--r--chromium/third_party/dawn/examples/glTFViewer/glTFViewer.cpp58
-rw-r--r--chromium/third_party/dawn/generator/common.py149
-rw-r--r--chromium/third_party/dawn/generator/main.py213
-rw-r--r--chromium/third_party/dawn/generator/templates/api.h2
-rw-r--r--chromium/third_party/dawn/generator/templates/apicpp.h19
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_native/ProcTable.cpp8
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/TypeTraits.h35
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/WireClient.cpp691
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.cpp242
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.h139
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/WireServer.cpp557
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiObjects.h26
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiProcs.cpp135
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiProcs.h46
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/client/ClientHandlers.cpp81
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/client/ClientPrototypes.inl18
-rw-r--r--chromium/third_party/dawn/generator/templates/dawn_wire/client/Device.h73
-rw-r--r--chromium/third_party/dawn/generator/templates/mock_api.cpp17
-rw-r--r--chromium/third_party/dawn/generator/templates/mock_api.h16
-rw-r--r--chromium/third_party/dawn/generator/wire_cmd.py93
-rw-r--r--chromium/third_party/dawn/scripts/dawn_features.gni5
-rw-r--r--chromium/third_party/dawn/src/common/Compiler.h7
-rw-r--r--chromium/third_party/dawn/src/common/Constants.h4
-rw-r--r--chromium/third_party/dawn/src/common/Result.h6
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Adapter.cpp54
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Adapter.h51
-rw-r--r--chromium/third_party/dawn/src/dawn_native/BackendConnection.cpp36
-rw-r--r--chromium/third_party/dawn/src/dawn_native/BackendConnection.h50
-rw-r--r--chromium/third_party/dawn/src/dawn_native/BindGroup.cpp275
-rw-r--r--chromium/third_party/dawn/src/dawn_native/BindGroup.h45
-rw-r--r--chromium/third_party/dawn/src/dawn_native/BlendState.cpp98
-rw-r--r--chromium/third_party/dawn/src/dawn_native/BlendState.h67
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Buffer.cpp80
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Buffer.h35
-rw-r--r--chromium/third_party/dawn/src/dawn_native/CommandBuffer.cpp164
-rw-r--r--chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp12
-rw-r--r--chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.h4
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Commands.cpp20
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Commands.h36
-rw-r--r--chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.cpp7
-rw-r--r--chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.h2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp8
-rw-r--r--chromium/third_party/dawn/src/dawn_native/DawnNative.cpp56
-rw-r--r--chromium/third_party/dawn/src/dawn_native/DepthStencilState.cpp137
-rw-r--r--chromium/third_party/dawn/src/dawn_native/DepthStencilState.h85
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Device.cpp76
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Device.h45
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Error.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Error.h8
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Fence.cpp98
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Fence.h64
-rw-r--r--chromium/third_party/dawn/src/dawn_native/FenceSignalTracker.cpp43
-rw-r--r--chromium/third_party/dawn/src/dawn_native/FenceSignalTracker.h47
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Forward.h11
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Instance.cpp152
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Instance.h60
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Pipeline.cpp68
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Pipeline.h27
-rw-r--r--chromium/third_party/dawn/src/dawn_native/PipelineLayout.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp11
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Queue.cpp26
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Queue.h2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.cpp95
-rw-r--r--chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.h18
-rw-r--r--chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp47
-rw-r--r--chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h19
-rw-r--r--chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp302
-rw-r--r--chromium/third_party/dawn/src/dawn_native/RenderPipeline.h52
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Sampler.cpp12
-rw-r--r--chromium/third_party/dawn/src/dawn_native/SwapChain.cpp3
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Texture.cpp44
-rw-r--r--chromium/third_party/dawn/src/dawn_native/Texture.h5
-rw-r--r--chromium/third_party/dawn/src/dawn_native/ToBackend.h20
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.cpp48
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.h2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/BlendStateD3D12.cpp108
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.cpp28
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.h13
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/CommandAllocatorManager.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.cpp96
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.h15
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/D3D12Backend.cpp46
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/DepthStencilStateD3D12.cpp98
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/DepthStencilStateD3D12.h38
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.cpp95
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.h18
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/Forward.h8
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.cpp235
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.h4
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/ResourceAllocator.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.cpp29
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/ShaderModuleD3D12.cpp4
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.cpp107
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.h32
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.cpp25
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.h6
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/UtilsD3D12.cpp44
-rw-r--r--chromium/third_party/dawn/src/dawn_native/d3d12/UtilsD3D12.h (renamed from chromium/third_party/dawn/src/dawn_native/d3d12/BlendStateD3D12.h)21
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/BlendStateMTL.mm99
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.h5
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.mm3
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/CommandBufferMTL.mm80
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/DepthStencilStateMTL.mm120
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.h19
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.mm80
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/Forward.h8
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/MetalBackend.mm (renamed from chromium/third_party/dawn/src/dawn_native/metal/DepthStencilStateMTL.h)30
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.h7
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.mm234
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/SamplerMTL.mm19
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.mm66
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/UtilsMetal.h (renamed from chromium/third_party/dawn/src/dawn_native/metal/BlendStateMTL.h)18
-rw-r--r--chromium/third_party/dawn/src/dawn_native/metal/UtilsMetal.mm40
-rw-r--r--chromium/third_party/dawn/src/dawn_native/null/DeviceNull.cpp275
-rw-r--r--chromium/third_party/dawn/src/dawn_native/null/DeviceNull.h (renamed from chromium/third_party/dawn/src/dawn_native/null/NullBackend.h)53
-rw-r--r--chromium/third_party/dawn/src/dawn_native/null/NullBackend.cpp217
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.cpp86
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.h (renamed from chromium/third_party/dawn/src/dawn_native/opengl/DepthStencilStateGL.h)23
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/BlendStateGL.cpp96
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.cpp5
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.h5
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/CommandBufferGL.cpp72
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/DepthStencilStateGL.cpp116
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.cpp85
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.h29
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/Forward.h8
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/OpenGLBackend.cpp28
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/QueueGL.cpp4
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.cpp152
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.h3
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/SamplerGL.cpp30
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/UtilsGL.cpp44
-rw-r--r--chromium/third_party/dawn/src/dawn_native/opengl/UtilsGL.h (renamed from chromium/third_party/dawn/src/dawn_native/opengl/BlendStateGL.h)18
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.cpp13
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.h2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/BlendStateVk.cpp110
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.h2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/CommandBufferVk.cpp47
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/DepthStencilStateVk.cpp112
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.cpp256
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.h30
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/FencedDeleter.cpp28
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/Forward.h12
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/QueueVk.cpp2
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.cpp184
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.h3
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/SamplerVk.cpp26
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/UtilsVulkan.cpp44
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/UtilsVulkan.h (renamed from chromium/third_party/dawn/src/dawn_native/vulkan/BlendStateVk.h)24
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/VulkanBackend.cpp57
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/VulkanError.cpp73
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/VulkanError.h (renamed from chromium/third_party/dawn/src/dawn_native/vulkan/DepthStencilStateVk.h)29
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.cpp29
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.h8
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.cpp131
-rw-r--r--chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.h25
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/DawnWire.cpp29
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/WireCmd.h68
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/WireDeserializeAllocator.cpp60
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/WireDeserializeAllocator.h43
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/ApiObjects.h25
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/ApiProcs.cpp172
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/Buffer.cpp40
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/Buffer.h54
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/Client.cpp22
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/Client.h43
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/ClientHandlers.cpp172
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/Fence.cpp35
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/Fence.h42
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/ObjectAllocator.h103
-rw-r--r--chromium/third_party/dawn/src/dawn_wire/client/ObjectBase.h60
-rw-r--r--chromium/third_party/dawn/src/fuzzers/BUILD.gn13
-rw-r--r--chromium/third_party/dawn/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp25
-rw-r--r--chromium/third_party/dawn/src/include/dawn/dawn_export.h30
-rw-r--r--chromium/third_party/dawn/src/include/dawn_native/DawnNative.h74
-rw-r--r--chromium/third_party/dawn/src/include/dawn_native/MetalBackend.h5
-rw-r--r--chromium/third_party/dawn/src/include/dawn_native/NullBackend.h6
-rw-r--r--chromium/third_party/dawn/src/include/dawn_native/OpenGLBackend.h11
-rw-r--r--chromium/third_party/dawn/src/include/dawn_native/VulkanBackend.h3
-rw-r--r--chromium/third_party/dawn/src/include/dawn_native/dawn_native_export.h30
-rw-r--r--chromium/third_party/dawn/src/include/dawn_wire/dawn_wire_export.h30
-rw-r--r--chromium/third_party/dawn/src/utils/ComboRenderPipelineDescriptor.cpp95
-rw-r--r--chromium/third_party/dawn/src/utils/ComboRenderPipelineDescriptor.h45
-rw-r--r--chromium/third_party/dawn/src/utils/DawnHelpers.cpp76
-rw-r--r--chromium/third_party/dawn/src/utils/DawnHelpers.h43
-rw-r--r--chromium/third_party/dawn/src/utils/MetalBinding.mm16
-rw-r--r--chromium/third_party/dawn/src/utils/NullBinding.cpp26
-rw-r--r--chromium/third_party/dawn/src/utils/OpenGLBinding.cpp15
-rw-r--r--chromium/third_party/dawn/src/utils/SystemUtils.h5
-rw-r--r--chromium/third_party/dawn/src/utils/VulkanBinding.cpp34
-rw-r--r--chromium/third_party/dawn/third_party/BUILD.gn55
208 files changed, 7491 insertions, 5283 deletions
diff --git a/chromium/third_party/dawn/BUILD.gn b/chromium/third_party/dawn/BUILD.gn
index 1a4922ff975..ea12460c1cd 100644
--- a/chromium/third_party/dawn/BUILD.gn
+++ b/chromium/third_party/dawn/BUILD.gn
@@ -18,6 +18,14 @@ import("//build_overrides/build.gni")
import("//testing/test.gni")
+# Use Chromium's dcheck_always_on when available so that we respect it when
+# running tests on the GPU builders
+if (build_with_chromium) {
+ import("//build/config/dcheck_always_on.gni")
+} else {
+ dcheck_always_on = false
+}
+
###############################################################################
# Template to wrap the Dawn code generator
###############################################################################
@@ -46,6 +54,8 @@ template("dawn_generator") {
# target using templates in this directory.
generator_args = [
rebase_path("dawn.json", root_build_dir),
+ "--wire-json",
+ rebase_path("dawn_wire.json", root_build_dir),
"--template-dir",
rebase_path("generator/templates", root_build_dir),
"--targets",
@@ -125,35 +135,121 @@ template("dawn_generator") {
}
###############################################################################
+# Template to produce static and shared versions of Dawn's libraries
+###############################################################################
+
+# Template that produces static and shared versions of the same library.
+# - The shared version exports symbols and has dependent import the symbols
+# as libname.so with target name libname_shared
+# - The static library doesn't export symbols nor make dependents import them
+# - The libname target is an alias for libname_shared. This is mostly to keep
+# the GN convention that target_type(name) defines a "name" target.
+#
+# The DEFINE_PREFIX must be provided and must match the respective "_export.h"
+# file.
+#
+# Example usage:
+#
+# dawn_static_and_shared_library("my_library") {
+# // my_library_export.h must use the MY_LIBRARY_IMPLEMENTATION and
+# // MY_LIBRARY_SHARED_LIBRARY macros.
+# DEFINE_PREFIX = "MY_LIBRARY"
+#
+# sources = [...]
+# deps = [...]
+# configs = [...]
+# }
+#
+# executable("foo") {
+# deps = [ ":my_library_shared" ] // or :my_library for the same effect
+# }
+template("dawn_static_and_shared_library") {
+ # Copy the target_name in the local scope so it doesn't get shadowed in the
+ # definition of targets.
+ libname = target_name
+
+ # The config that will apply to dependents of the shared library so they know
+ # they should "import" the symbols
+ config("${libname}_shared_public_config") {
+ defines = [ "${invoker.DEFINE_PREFIX}_SHARED_LIBRARY" ]
+
+ # Executable needs an rpath to find our shared libraries on OSX and Linux
+ if (is_mac) {
+ ldflags = [
+ "-rpath",
+ "@executable_path/",
+ ]
+ }
+ if (is_linux) {
+ configs = [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
+ }
+ }
+
+ shared_library("${libname}_shared") {
+ output_name = libname
+
+ # Copy all variables except "configs", which has a default value
+ forward_variables_from(invoker, "*", [ "configs" ])
+ if (defined(invoker.configs)) {
+ configs += invoker.configs
+ }
+
+ # Tell dependents where to find this shared library
+ if (is_mac) {
+ ldflags = [
+ "-install_name",
+ "@rpath/${libname}.dylib",
+ ]
+ }
+
+ # Use the config that makes the ${DEFINE_PREFIX}_EXPORT macro do something
+ if (!defined(public_configs)) {
+ public_configs = []
+ }
+ public_configs += [ ":${libname}_shared_public_config" ]
+
+ # Tell sources of this library to export the symbols (and not import)
+ if (!defined(defines)) {
+ defines = []
+ }
+ defines += [ "${invoker.DEFINE_PREFIX}_IMPLEMENTATION" ]
+ }
+
+ static_library("${libname}_static") {
+ output_name = libname
+
+ complete_static_lib = dawn_complete_static_libs
+
+ # Copy all variables except "configs", which has a default value
+ forward_variables_from(invoker, "*", [ "configs" ])
+ if (defined(invoker.configs)) {
+ configs += invoker.configs
+ }
+ }
+
+ group(libname) {
+ public_deps = [
+ ":${libname}_shared",
+ ]
+ }
+}
+
+###############################################################################
# Common dawn libraries and configs
###############################################################################
-config("libdawn_public") {
+config("dawn_public") {
include_dirs = [
target_gen_dir,
"src/include",
]
}
-# Executable needs an rpath to find our shared libraries on OSX and Linux
-config("dawn_shared_library_public") {
- if (is_mac) {
- ldflags = [
- "-rpath",
- "@executable_path/",
- ]
- }
-
- if (is_linux) {
- configs = [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
- }
-}
-
config("dawn_internal") {
include_dirs = [ "src" ]
defines = []
- if (dawn_always_assert || is_debug) {
+ if (dawn_always_assert || dcheck_always_on || is_debug) {
defines += [ "DAWN_ENABLE_ASSERTS" ]
}
@@ -173,10 +269,7 @@ config("dawn_internal") {
defines += [ "DAWN_ENABLE_BACKEND_VULKAN" ]
}
- configs = [
- ":libdawn_public",
- ":dawn_shared_library_public",
- ]
+ configs = [ ":dawn_public" ]
# Only internal Dawn targets can use this config, this means only targets in
# this BUILD.gn file.
@@ -212,7 +305,7 @@ static_library("dawn_common") {
}
###############################################################################
-# Dawn headers and libdawn.so
+# Dawn headers
###############################################################################
dawn_generator("dawn_headers_gen") {
@@ -225,7 +318,7 @@ dawn_generator("dawn_headers_gen") {
}
source_set("dawn_headers") {
- public_configs = [ ":libdawn_public" ]
+ public_configs = [ ":dawn_public" ]
deps = [
":dawn_headers_gen",
]
@@ -238,6 +331,10 @@ source_set("dawn_headers") {
]
}
+###############################################################################
+# libdawn
+###############################################################################
+
dawn_generator("libdawn_gen") {
target = "libdawn"
outputs = [
@@ -246,11 +343,9 @@ dawn_generator("libdawn_gen") {
]
}
-config("libdawn_export") {
- defines = [ "DAWN_IMPLEMENTATION" ]
-}
+dawn_static_and_shared_library("libdawn") {
+ DEFINE_PREFIX = "DAWN"
-source_set("libdawn_sources") {
public_deps = [
":dawn_headers",
]
@@ -259,31 +354,10 @@ source_set("libdawn_sources") {
":libdawn_gen",
]
sources = get_target_outputs(":libdawn_gen")
-
- # Put the export config public so that dependents use the same declspec.
- public_configs = [ ":libdawn_export" ]
-}
-
-shared_library("libdawn") {
- public_deps = [
- ":dawn_headers",
- ]
-
- deps = [
- ":libdawn_sources",
- ]
-
- # Tell dependents where to find this shared library
- if (is_mac) {
- ldflags = [
- "-install_name",
- "@rpath/${target_name}.dylib",
- ]
- }
}
###############################################################################
-# libdawn_native.so
+# libdawn_native
###############################################################################
config("libdawn_native_internal") {
@@ -295,10 +369,6 @@ config("libdawn_native_internal") {
}
}
-config("libdawn_native_export") {
- defines = [ "DAWN_NATIVE_IMPLEMENTATION" ]
-}
-
dawn_generator("libdawn_native_utils_gen") {
target = "dawn_native_utils"
outputs = [
@@ -316,6 +386,7 @@ source_set("libdawn_native_headers") {
public_deps = [
":dawn_headers",
]
+ public_configs = [ ":dawn_public" ]
sources = [
"src/include/dawn_native/DawnNative.h",
"src/include/dawn_native/dawn_native_export.h",
@@ -331,32 +402,30 @@ source_set("libdawn_native_headers") {
}
# The meat of the compilation for libdawn_native so that we can cheaply have
-# shared_library / static_library / component versions of it.
+# shared_library / static_library versions of it. It compiles all the files
+# except those that define exported symbols.
source_set("libdawn_native_sources") {
deps = [
":dawn_common",
+ ":libdawn_native_headers",
":libdawn_native_utils_gen",
"${dawn_spirv_tools_dir}:spvtools_val",
"third_party:spirv_cross",
]
- public_deps = [
- ":libdawn_native_headers",
- ]
-
- # Put the export config public so that dependents use the same declspec.
- public_configs = [ ":libdawn_native_export" ]
configs += [ ":libdawn_native_internal" ]
libs = []
sources = get_target_outputs(":libdawn_native_utils_gen")
sources += [
+ "src/dawn_native/Adapter.cpp",
+ "src/dawn_native/Adapter.h",
+ "src/dawn_native/BackendConnection.cpp",
+ "src/dawn_native/BackendConnection.h",
"src/dawn_native/BindGroup.cpp",
"src/dawn_native/BindGroup.h",
"src/dawn_native/BindGroupLayout.cpp",
"src/dawn_native/BindGroupLayout.h",
- "src/dawn_native/BlendState.cpp",
- "src/dawn_native/BlendState.h",
"src/dawn_native/Buffer.cpp",
"src/dawn_native/Buffer.h",
"src/dawn_native/Builder.cpp",
@@ -373,18 +442,21 @@ source_set("libdawn_native_sources") {
"src/dawn_native/ComputePassEncoder.h",
"src/dawn_native/ComputePipeline.cpp",
"src/dawn_native/ComputePipeline.h",
- "src/dawn_native/DawnNative.cpp",
- "src/dawn_native/DepthStencilState.cpp",
- "src/dawn_native/DepthStencilState.h",
"src/dawn_native/Device.cpp",
"src/dawn_native/Device.h",
"src/dawn_native/Error.cpp",
"src/dawn_native/Error.h",
"src/dawn_native/ErrorData.cpp",
"src/dawn_native/ErrorData.h",
+ "src/dawn_native/Fence.cpp",
+ "src/dawn_native/Fence.h",
+ "src/dawn_native/FenceSignalTracker.cpp",
+ "src/dawn_native/FenceSignalTracker.h",
"src/dawn_native/Forward.h",
"src/dawn_native/InputState.cpp",
"src/dawn_native/InputState.h",
+ "src/dawn_native/Instance.cpp",
+ "src/dawn_native/Instance.h",
"src/dawn_native/ObjectBase.cpp",
"src/dawn_native/ObjectBase.h",
"src/dawn_native/PassResourceUsage.h",
@@ -425,8 +497,6 @@ source_set("libdawn_native_sources") {
"src/dawn_native/d3d12/BindGroupD3D12.h",
"src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp",
"src/dawn_native/d3d12/BindGroupLayoutD3D12.h",
- "src/dawn_native/d3d12/BlendStateD3D12.cpp",
- "src/dawn_native/d3d12/BlendStateD3D12.h",
"src/dawn_native/d3d12/BufferD3D12.cpp",
"src/dawn_native/d3d12/BufferD3D12.h",
"src/dawn_native/d3d12/CommandAllocatorManager.cpp",
@@ -435,8 +505,6 @@ source_set("libdawn_native_sources") {
"src/dawn_native/d3d12/CommandBufferD3D12.h",
"src/dawn_native/d3d12/ComputePipelineD3D12.cpp",
"src/dawn_native/d3d12/ComputePipelineD3D12.h",
- "src/dawn_native/d3d12/DepthStencilStateD3D12.cpp",
- "src/dawn_native/d3d12/DepthStencilStateD3D12.h",
"src/dawn_native/d3d12/DescriptorHeapAllocator.cpp",
"src/dawn_native/d3d12/DescriptorHeapAllocator.h",
"src/dawn_native/d3d12/DeviceD3D12.cpp",
@@ -470,6 +538,8 @@ source_set("libdawn_native_sources") {
"src/dawn_native/d3d12/TextureCopySplitter.h",
"src/dawn_native/d3d12/TextureD3D12.cpp",
"src/dawn_native/d3d12/TextureD3D12.h",
+ "src/dawn_native/d3d12/UtilsD3D12.cpp",
+ "src/dawn_native/d3d12/UtilsD3D12.h",
"src/dawn_native/d3d12/d3d12_platform.h",
]
}
@@ -481,16 +551,12 @@ source_set("libdawn_native_sources") {
"IOKit.framework",
]
sources += [
- "src/dawn_native/metal/BlendStateMTL.h",
- "src/dawn_native/metal/BlendStateMTL.mm",
"src/dawn_native/metal/BufferMTL.h",
"src/dawn_native/metal/BufferMTL.mm",
"src/dawn_native/metal/CommandBufferMTL.h",
"src/dawn_native/metal/CommandBufferMTL.mm",
"src/dawn_native/metal/ComputePipelineMTL.h",
"src/dawn_native/metal/ComputePipelineMTL.mm",
- "src/dawn_native/metal/DepthStencilStateMTL.h",
- "src/dawn_native/metal/DepthStencilStateMTL.mm",
"src/dawn_native/metal/DeviceMTL.h",
"src/dawn_native/metal/DeviceMTL.mm",
"src/dawn_native/metal/Forward.h",
@@ -512,29 +578,29 @@ source_set("libdawn_native_sources") {
"src/dawn_native/metal/SwapChainMTL.mm",
"src/dawn_native/metal/TextureMTL.h",
"src/dawn_native/metal/TextureMTL.mm",
+ "src/dawn_native/metal/UtilsMetal.h",
+ "src/dawn_native/metal/UtilsMetal.mm",
]
}
if (dawn_enable_null) {
sources += [
- "src/dawn_native/null/NullBackend.cpp",
- "src/dawn_native/null/NullBackend.h",
+ "src/dawn_native/null/DeviceNull.cpp",
+ "src/dawn_native/null/DeviceNull.h",
]
}
if (dawn_enable_opengl) {
deps += [ "third_party:glad" ]
sources += [
- "src/dawn_native/opengl/BlendStateGL.cpp",
- "src/dawn_native/opengl/BlendStateGL.h",
+ "src/dawn_native/opengl/BackendGL.cpp",
+ "src/dawn_native/opengl/BackendGL.h",
"src/dawn_native/opengl/BufferGL.cpp",
"src/dawn_native/opengl/BufferGL.h",
"src/dawn_native/opengl/CommandBufferGL.cpp",
"src/dawn_native/opengl/CommandBufferGL.h",
"src/dawn_native/opengl/ComputePipelineGL.cpp",
"src/dawn_native/opengl/ComputePipelineGL.h",
- "src/dawn_native/opengl/DepthStencilStateGL.cpp",
- "src/dawn_native/opengl/DepthStencilStateGL.h",
"src/dawn_native/opengl/DeviceGL.cpp",
"src/dawn_native/opengl/DeviceGL.h",
"src/dawn_native/opengl/Forward.h",
@@ -558,6 +624,8 @@ source_set("libdawn_native_sources") {
"src/dawn_native/opengl/SwapChainGL.h",
"src/dawn_native/opengl/TextureGL.cpp",
"src/dawn_native/opengl/TextureGL.h",
+ "src/dawn_native/opengl/UtilsGL.cpp",
+ "src/dawn_native/opengl/UtilsGL.h",
]
}
@@ -568,8 +636,6 @@ source_set("libdawn_native_sources") {
"src/dawn_native/vulkan/BindGroupLayoutVk.h",
"src/dawn_native/vulkan/BindGroupVk.cpp",
"src/dawn_native/vulkan/BindGroupVk.h",
- "src/dawn_native/vulkan/BlendStateVk.cpp",
- "src/dawn_native/vulkan/BlendStateVk.h",
"src/dawn_native/vulkan/BufferUploader.cpp",
"src/dawn_native/vulkan/BufferUploader.h",
"src/dawn_native/vulkan/BufferVk.cpp",
@@ -578,8 +644,6 @@ source_set("libdawn_native_sources") {
"src/dawn_native/vulkan/CommandBufferVk.h",
"src/dawn_native/vulkan/ComputePipelineVk.cpp",
"src/dawn_native/vulkan/ComputePipelineVk.h",
- "src/dawn_native/vulkan/DepthStencilStateVk.cpp",
- "src/dawn_native/vulkan/DepthStencilStateVk.h",
"src/dawn_native/vulkan/DeviceVk.cpp",
"src/dawn_native/vulkan/DeviceVk.h",
"src/dawn_native/vulkan/FencedDeleter.cpp",
@@ -609,6 +673,10 @@ source_set("libdawn_native_sources") {
"src/dawn_native/vulkan/SwapChainVk.h",
"src/dawn_native/vulkan/TextureVk.cpp",
"src/dawn_native/vulkan/TextureVk.h",
+ "src/dawn_native/vulkan/UtilsVulkan.cpp",
+ "src/dawn_native/vulkan/UtilsVulkan.h",
+ "src/dawn_native/vulkan/VulkanError.cpp",
+ "src/dawn_native/vulkan/VulkanError.h",
"src/dawn_native/vulkan/VulkanFunctions.cpp",
"src/dawn_native/vulkan/VulkanFunctions.h",
"src/dawn_native/vulkan/VulkanInfo.cpp",
@@ -617,29 +685,47 @@ source_set("libdawn_native_sources") {
}
}
-# The shared library for libdawn_native for use by samples, tests, etc.
-shared_library("libdawn_native") {
- deps = [
- ":libdawn_native_sources",
- ]
+# The static and shared libraries for libdawn_native. Most of the files are
+# already compiled in libdawn_native_sources, but we still need to compile
+# files defining exported symbols.
+dawn_static_and_shared_library("libdawn_native") {
+ DEFINE_PREFIX = "DAWN_NATIVE"
#Make headers publically visible
public_deps = [
":libdawn_native_headers",
]
- public_configs = [ ":libdawn_public" ]
- # Tell dependents where to find this shared library
- if (is_mac) {
- ldflags = [
- "-install_name",
- "@rpath/${target_name}.dylib",
- ]
+ deps = [
+ ":dawn_common",
+ ":libdawn_native_sources",
+ ]
+ sources = [
+ "src/dawn_native/DawnNative.cpp",
+ ]
+ configs = [ ":libdawn_native_internal" ]
+
+ if (dawn_enable_d3d12) {
+ sources += [ "src/dawn_native/d3d12/D3D12Backend.cpp" ]
+ }
+ if (dawn_enable_metal) {
+ sources += [ "src/dawn_native/metal/MetalBackend.mm" ]
+ }
+ if (dawn_enable_null) {
+ sources += [ "src/dawn_native/null/NullBackend.cpp" ]
+ }
+ if (dawn_enable_opengl) {
+ sources += [ "src/dawn_native/opengl/OpenGLBackend.cpp" ]
+ deps += [ "third_party:glad" ]
+ }
+ if (dawn_enable_vulkan) {
+ sources += [ "src/dawn_native/vulkan/VulkanBackend.cpp" ]
+ deps += [ "third_party:vulkan_headers" ]
}
}
###############################################################################
-# libdawn_wire.so
+# libdawn_wire
###############################################################################
# Public libdawn_wire headers so they can be publically visible for
@@ -648,65 +734,60 @@ source_set("libdawn_wire_headers") {
public_deps = [
":dawn_headers",
]
+ public_configs = [ ":dawn_public" ]
sources = [
"src/include/dawn_wire/Wire.h",
"src/include/dawn_wire/dawn_wire_export.h",
]
}
-config("libdawn_wire_export") {
- defines = [ "DAWN_WIRE_IMPLEMENTATION" ]
-}
-
dawn_generator("libdawn_wire_gen") {
target = "dawn_wire"
outputs = [
- "dawn_wire/WireServer.cpp",
+ "dawn_wire/TypeTraits_autogen.h",
"dawn_wire/WireCmd_autogen.h",
- "dawn_wire/WireClient.cpp",
"dawn_wire/WireCmd_autogen.cpp",
+ "dawn_wire/WireServer.cpp",
+ "dawn_wire/client/ApiObjects_autogen.h",
+ "dawn_wire/client/ApiProcs_autogen.cpp",
+ "dawn_wire/client/ApiProcs_autogen.h",
+ "dawn_wire/client/ClientHandlers_autogen.cpp",
+ "dawn_wire/client/ClientPrototypes_autogen.inl",
+ "dawn_wire/client/Device_autogen.h",
]
}
-source_set("libdawn_wire_sources") {
+dawn_static_and_shared_library("libdawn_wire") {
+ DEFINE_PREFIX = "DAWN_WIRE"
+
deps = [
":dawn_common",
":libdawn_wire_gen",
":libdawn_wire_headers",
]
- configs += [ ":dawn_internal" ]
+ configs = [ ":dawn_internal" ]
sources = get_target_outputs(":libdawn_wire_gen")
- sources += [ "src/dawn_wire/WireCmd.h" ]
-
- # Make headers publically visible
- public_deps = [
- ":libdawn_wire_headers",
- ]
- public_configs = [ ":libdawn_public" ]
-
- # Put the export config public so that dependents use the same declspec.
- public_configs += [ ":libdawn_wire_export" ]
-}
-
-shared_library("libdawn_wire") {
- deps = [
- ":libdawn_wire_sources",
+ sources += [
+ "src/dawn_wire/DawnWire.cpp",
+ "src/dawn_wire/WireDeserializeAllocator.cpp",
+ "src/dawn_wire/WireDeserializeAllocator.h",
+ "src/dawn_wire/client/ApiObjects.h",
+ "src/dawn_wire/client/ApiProcs.cpp",
+ "src/dawn_wire/client/Buffer.cpp",
+ "src/dawn_wire/client/Buffer.h",
+ "src/dawn_wire/client/Client.cpp",
+ "src/dawn_wire/client/Client.h",
+ "src/dawn_wire/client/ClientHandlers.cpp",
+ "src/dawn_wire/client/Fence.cpp",
+ "src/dawn_wire/client/Fence.h",
+ "src/dawn_wire/client/ObjectAllocator.h",
]
# Make headers publically visible
public_deps = [
":libdawn_wire_headers",
]
- public_configs = [ ":libdawn_public" ]
-
- # Tell dependents where to find this shared library
- if (is_mac) {
- ldflags = [
- "-install_name",
- "@rpath/${target_name}.dylib",
- ]
- }
}
###############################################################################
@@ -719,6 +800,8 @@ static_library("dawn_utils") {
sources = [
"src/utils/BackendBinding.cpp",
"src/utils/BackendBinding.h",
+ "src/utils/ComboRenderPipelineDescriptor.cpp",
+ "src/utils/ComboRenderPipelineDescriptor.h",
"src/utils/DawnHelpers.cpp",
"src/utils/DawnHelpers.h",
"src/utils/SystemUtils.cpp",
@@ -787,6 +870,7 @@ test("dawn_unittests") {
":dawn_headers",
":dawn_utils",
":libdawn",
+ ":libdawn_native",
":libdawn_native_sources",
":libdawn_wire",
":mock_dawn_gen",
@@ -813,19 +897,19 @@ test("dawn_unittests") {
"src/tests/unittests/ToBackendTests.cpp",
"src/tests/unittests/WireTests.cpp",
"src/tests/unittests/validation/BindGroupValidationTests.cpp",
- "src/tests/unittests/validation/BlendStateValidationTests.cpp",
"src/tests/unittests/validation/BufferValidationTests.cpp",
"src/tests/unittests/validation/CommandBufferValidationTests.cpp",
"src/tests/unittests/validation/ComputeValidationTests.cpp",
"src/tests/unittests/validation/CopyCommandsValidationTests.cpp",
- "src/tests/unittests/validation/DepthStencilStateValidationTests.cpp",
"src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp",
+ "src/tests/unittests/validation/FenceValidationTests.cpp",
"src/tests/unittests/validation/InputStateValidationTests.cpp",
"src/tests/unittests/validation/PushConstantsValidationTests.cpp",
"src/tests/unittests/validation/QueueSubmitValidationTests.cpp",
"src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp",
"src/tests/unittests/validation/RenderPipelineValidationTests.cpp",
"src/tests/unittests/validation/ShaderModuleValidationTests.cpp",
+ "src/tests/unittests/validation/TextureValidationTests.cpp",
"src/tests/unittests/validation/TextureViewValidationTests.cpp",
"src/tests/unittests/validation/ValidationTest.cpp",
"src/tests/unittests/validation/ValidationTest.h",
@@ -868,7 +952,8 @@ test("dawn_end2end_tests") {
"src/tests/end2end/ComputeCopyStorageBufferTests.cpp",
"src/tests/end2end/CopyTests.cpp",
"src/tests/end2end/DepthStencilStateTests.cpp",
- "src/tests/end2end/DrawElementsTests.cpp",
+ "src/tests/end2end/DrawIndexedTests.cpp",
+ "src/tests/end2end/FenceTests.cpp",
"src/tests/end2end/IndexFormatTests.cpp",
"src/tests/end2end/InputStateTests.cpp",
"src/tests/end2end/PrimitiveTopologyTests.cpp",
@@ -889,6 +974,21 @@ test("dawn_end2end_tests") {
}
}
+# Temporary groups to make a 5-way patch to fix crbug.com/913171
+group("dawn_unittests_temp_group") {
+ testonly = true
+ deps = [
+ ":dawn_unittests",
+ ]
+}
+
+group("dawn_end2end_tests_temp_group") {
+ testonly = true
+ deps = [
+ ":dawn_end2end_tests",
+ ]
+}
+
###############################################################################
# Dawn samples, only in standalone builds
###############################################################################
diff --git a/chromium/third_party/dawn/DEPS b/chromium/third_party/dawn/DEPS
index 69deb4a26f6..969f6f5ee19 100644
--- a/chromium/third_party/dawn/DEPS
+++ b/chromium/third_party/dawn/DEPS
@@ -12,7 +12,7 @@ vars = {
deps = {
# Dependencies required to use GN/Clang in standalone
'build': {
- 'url': '{chromium_git}/chromium/src/build@2fb6537bf59c9c9a736997b8bd888ca0ecf54322',
+ 'url': '{chromium_git}/chromium/src/build@e439f6082423106f1fe2afa7e22f8fd4c00691df',
'condition': 'dawn_standalone',
},
'buildtools': {
@@ -68,7 +68,7 @@ deps = {
'condition': 'dawn_standalone',
},
'third_party/shaderc': {
- 'url': '{chromium_git}/external/github.com/google/shaderc@909f0d3d31e7e7c8f39b40ba0e1dd7f99b749776',
+ 'url': '{chromium_git}/external/github.com/google/shaderc@ce7d92182b8cc9c72e99efb5fab1eae3c2084887',
'condition': 'dawn_standalone',
},
diff --git a/chromium/third_party/dawn/README.md b/chromium/third_party/dawn/README.md
index e9def8c4dd9..d262b403f63 100644
--- a/chromium/third_party/dawn/README.md
+++ b/chromium/third_party/dawn/README.md
@@ -68,6 +68,7 @@ Dawn doesn't have a formal coding style yet, except what's defined by our clang
Overall try to use the same style and convention as code around your change.
If you find issues with Dawn, please feel free to report them on the [bug tracker](https://bugs.chromium.org/p/dawn/issues/entry).
+For other discussions, please post to [Dawn's mailing list](https://groups.google.com/forum/#!members/dawn-graphics).
## License
diff --git a/chromium/third_party/dawn/build_overrides/shaderc.gni b/chromium/third_party/dawn/build_overrides/shaderc.gni
index df437e2abed..1cb6bd12f13 100644
--- a/chromium/third_party/dawn/build_overrides/shaderc.gni
+++ b/chromium/third_party/dawn/build_overrides/shaderc.gni
@@ -14,3 +14,4 @@
shaderc_glslang_dir = "//third_party/glslang"
shaderc_spirv_tools_dir = "//third_party/SPIRV-Tools"
+shaderc_spirv_cross_dir = "//third_party"
diff --git a/chromium/third_party/dawn/dawn.json b/chromium/third_party/dawn/dawn.json
index 0437b814506..271fd990c28 100644
--- a/chromium/third_party/dawn/dawn.json
+++ b/chromium/third_party/dawn/dawn.json
@@ -17,60 +17,47 @@
"address mode": {
"category": "enum",
"values": [
- {"value": 0, "name":"repeat"},
- {"value": 1, "name":"mirrored repeat"},
- {"value": 2, "name":"clamp to edge"}
+ {"value": 0, "name": "repeat"},
+ {"value": 1, "name": "mirrored repeat"},
+ {"value": 2, "name": "clamp to edge"},
+ {"value": 3, "name": "clamp to border color"}
+ ]
+ },
+ "attachment descriptor": {
+ "category": "structure",
+ "extensible": true,
+ "members": [
+ {"name": "format", "type": "texture format"}
]
},
"bind group": {
"category": "object"
},
- "bind group builder": {
- "category": "object",
- "methods": [
- {
- "name": "get result",
- "returns": "bind group"
- },
- {
- "name": "set layout",
- "args": [
- {"name": "layout", "type": "bind group layout"}
- ]
- },
- {
- "name": "set buffer views",
- "args": [
- {"name": "start", "type": "uint32_t"},
- {"name": "count", "type": "uint32_t"},
- {"name": "buffer views", "type": "buffer view", "annotation": "const*", "length": "count"}
- ]
- },
- {
- "name": "set samplers",
- "args": [
- {"name": "start", "type": "uint32_t"},
- {"name": "count", "type": "uint32_t"},
- {"name": "samplers", "type": "sampler", "annotation": "const*", "length": "count"}
- ]
- },
- {
- "name": "set texture views",
- "args": [
- {"name": "start", "type": "uint32_t"},
- {"name": "count", "type": "uint32_t"},
- {"name": "texture views", "type": "texture view", "annotation": "const*", "length": "count"}
- ]
- }
- ],
- "TODO": [
- "When resource are added, add methods for setting the content of the bind group"
+ "bind group binding": {
+ "category": "structure",
+ "extensible": false,
+ "members": [
+ {"name": "binding", "type": "uint32_t"},
+ {"name": "buffer", "type": "buffer", "optional": true},
+ {"name": "offset", "type": "uint32_t"},
+ {"name": "size", "type": "uint32_t"},
+ {"name": "sampler", "type": "sampler", "optional": true},
+ {"name": "texture view", "type": "texture view", "optional": true}
+ ]
+ },
+ "bind group descriptor": {
+ "category": "structure",
+ "extensible": true,
+ "members": [
+ {"name": "layout", "type": "bind group layout"},
+ {"name": "num bindings", "type": "uint32_t"},
+ {"name": "bindings", "type": "bind group binding", "annotation": "const*", "length": "num bindings"}
]
},
"bind group layout": {
"category": "object"
},
- "bind group binding": {
+ "bind group layout binding": {
"category": "structure",
"extensible": false,
"members": [
@@ -84,7 +71,7 @@
"extensible": true,
"members": [
{"name": "num bindings", "type": "uint32_t"},
- {"name": "bindings", "type": "bind group binding", "annotation": "const*", "length": "num bindings"}
+ {"name": "bindings", "type": "bind group layout binding", "annotation": "const*", "length": "num bindings"}
]
},
"binding type": {
@@ -133,45 +120,27 @@
{"value": 4, "name": "max"}
]
},
- "blend state": {
- "category": "object"
- },
- "blend state builder": {
- "category": "object",
- "methods": [
- {
- "name": "get result",
- "returns": "blend state"
- },
- {
- "name": "set blend enabled",
- "args": [
- {"name": "blend enabled", "type": "bool"}
- ]
- },
- {
- "name": "set alpha blend",
- "args": [
- {"name": "alpha blend", "type": "blend descriptor", "annotation": "const*"}
- ]
- },
- {
- "name": "set color blend",
- "args": [
- {"name": "color blend", "type": "blend descriptor", "annotation": "const*"}
- ]
- },
- {
- "name": "set color write mask",
- "args": [
- {"name": "color write mask", "type": "color write mask"}
- ]
- }
+ "blend state descriptor": {
+ "category": "structure",
+ "extensible": true,
+ "members": [
+ {"name": "blend enabled", "type": "bool"},
+ {"name": "alpha blend", "type": "blend descriptor"},
+ {"name": "color blend", "type": "blend descriptor"},
+ {"name": "color write mask", "type": "color write mask"}
]
},
"bool": {
"category": "native"
},
+ "border color": {
+ "category": "enum",
+ "values": [
+ {"value": 0, "name": "transparent black"},
+ {"value": 1, "name": "opaque black"},
+ {"value": 2, "name": "opaque white"}
+ ]
+ },
"builder error status": {
"category": "enum",
"values": [
@@ -188,10 +157,6 @@
"category": "object",
"methods": [
{
- "name": "create buffer view builder",
- "returns": "buffer view builder"
- },
- {
"name": "set sub data",
"args": [
{"name": "start", "type": "uint32_t"},
@@ -287,31 +252,21 @@
{"value": 128, "name": "storage"}
]
},
- "buffer view": {
- "category": "object"
- },
- "buffer view builder": {
- "category": "object",
- "methods": [
- {
- "name": "get result",
- "returns": "buffer view"
- },
- {
- "name": "set extent",
- "args": [
- {"name": "offset", "type": "uint32_t"},
- {"name": "size", "type": "uint32_t"}
- ]
- }
- ]
- },
"callback userdata": {
"category": "natively defined"
},
"char": {
"category": "native"
},
+ "color": {
+ "category": "structure",
+ "members": [
+ {"name": "r", "type": "float"},
+ {"name": "g", "type": "float"},
+ {"name": "b", "type": "float"},
+ {"name": "a", "type": "float"}
+ ]
+ },
"color write mask": {
"category": "bitmask",
"values": [
@@ -392,8 +347,7 @@
"category": "object",
"methods": [
{
- "name": "set compute pipeline",
- "TODO": "This is called setPipeline in the WebGPU IDL",
+ "name": "set pipeline",
"args": [
{"name": "pipeline", "type": "compute pipeline"}
]
@@ -448,8 +402,11 @@
"category": "object",
"methods": [
{
- "name": "create bind group builder",
- "returns": "bind group builder"
+ "name": "create bind group",
+ "returns": "bind group",
+ "args": [
+ {"name": "descriptor", "type": "bind group descriptor", "annotation": "const*"}
+ ]
},
{
"name": "create bind group layout",
@@ -459,10 +416,6 @@
]
},
{
- "name": "create blend state builder",
- "returns": "blend state builder"
- },
- {
"name": "create buffer",
"returns": "buffer",
"args": [
@@ -478,8 +431,11 @@
"returns": "command buffer builder"
},
{
- "name": "create depth stencil state builder",
- "returns": "depth stencil state builder"
+ "name": "create fence",
+ "returns": "fence",
+ "args": [
+ {"name": "descriptor", "type": "fence descriptor", "annotation": "const*"}
+ ]
},
{
"name": "create render pass descriptor builder",
@@ -497,8 +453,11 @@
]
},
{
- "name": "create render pipeline builder",
- "returns": "render pipeline builder"
+ "name": "create render pipeline",
+ "returns": "render pipeline",
+ "args": [
+ {"name": "descriptor", "type": "render pipeline descriptor", "annotation": "const*"}
+ ]
},
{
"name": "create pipeline layout",
@@ -548,45 +507,16 @@
}
]
},
- "depth stencil state": {
- "category": "object"
- },
- "depth stencil state builder": {
- "category": "object",
- "methods": [
- {
- "name": "get result",
- "returns": "depth stencil state"
- },
- {
- "name": "set depth compare function",
- "args": [
- {"name": "depth compare function", "type": "compare function"}
- ]
- },
- {
- "name": "set depth write enabled",
- "args" : [
- {"name": "enabled", "type": "bool"}
- ]
- },
- {
- "name": "set stencil function",
- "args": [
- {"name": "face", "type": "face"},
- {"name": "stencil compare function", "type": "compare function"},
- {"name": "stencil failure operation", "type": "stencil operation"},
- {"name": "depth failure operation", "type": "stencil operation"},
- {"name": "stencil pass operation", "type": "stencil operation"}
- ]
- },
- {
- "name": "set stencil mask",
- "args": [
- {"name": "read mask", "type": "uint32_t"},
- {"name": "write mask", "type": "uint32_t"}
- ]
- }
+ "depth stencil state descriptor": {
+ "category": "structure",
+ "extensible": true,
+ "members": [
+ {"name": "depth write enabled", "type": "bool"},
+ {"name": "depth compare", "type": "compare function"},
+ {"name": "front", "type": "stencil state face descriptor"},
+ {"name": "back", "type": "stencil state face descriptor"},
+ {"name": "stencil read mask", "type": "uint32_t"},
+ {"name": "stencil write mask", "type": "uint32_t"}
]
},
"device error callback": {
@@ -609,6 +539,42 @@
{"value": 3, "name": "both"}
]
},
+ "fence": {
+ "category": "object",
+ "methods": [
+ {
+ "name": "get completed value",
+ "returns": "uint64_t"
+ },
+ {
+ "name": "on completion",
+ "args": [
+ {"name": "value", "type": "uint64_t"},
+ {"name": "callback", "type": "fence on completion callback"},
+ {"name": "userdata", "type": "callback userdata"}
+ ]
+ }
+ ]
+ },
+ "fence on completion callback": {
+ "category": "natively defined"
+ },
+ "fence completion status": {
+ "category": "enum",
+ "values": [
+ {"value": 0, "name": "success"},
+ {"value": 1, "name": "error"},
+ {"value": 2, "name": "unknown"},
+ {"value": 3, "name": "context lost"}
+ ]
+ },
+ "fence descriptor": {
+ "category": "structure",
+ "extensible": true,
+ "members": [
+ {"name": "initial value", "type": "uint64_t"}
+ ]
+ },
"filter mode": {
"category": "enum",
"values": [
@@ -669,6 +635,12 @@
{"value": 1, "name": "load"}
]
},
+ "store op": {
+ "category": "enum",
+ "values": [
+ {"value": 0, "name": "store"}
+ ]
+ },
"origin 3D": {
"category": "structure",
"members": [
@@ -677,6 +649,16 @@
{"name": "z", "type": "uint32_t"}
]
},
+ "attachments state descriptor": {
+ "category": "structure",
+ "extensible": true,
+ "members": [
+ {"name": "num color attachments", "type": "uint32_t"},
+ {"name": "color attachments", "type": "attachment descriptor", "annotation": "const*const*", "length": "num color attachments"},
+ {"name": "has depth stencil attachment", "type": "bool"},
+ {"name": "depth stencil attachment", "type": "attachment descriptor", "annotation":"const*"}
+ ]
+ },
"pipeline layout": {
"category": "object"
},
@@ -688,6 +670,14 @@
{"name": "bind group layouts", "type": "bind group layout", "annotation": "const*", "length": "num bind group layouts"}
]
},
+ "pipeline stage descriptor": {
+ "category": "structure",
+ "extensible": true,
+ "members": [
+ {"name": "module", "type": "shader module"},
+ {"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen"}
+ ]
+ },
"primitive topology": {
"category": "enum",
"values": [
@@ -707,9 +697,41 @@
{"name": "num commands", "type": "uint32_t"},
{"name": "commands", "type": "command buffer", "annotation": "const*", "length": "num commands"}
]
+ },
+ {
+ "name": "signal",
+ "args": [
+ {"name": "fence", "type": "fence"},
+ {"name": "signal value", "type": "uint64_t"}
+ ]
}
]
},
+
+ "render pass color attachment descriptor": {
+ "category": "structure",
+ "members": [
+ {"name": "attachment", "type": "texture view"},
+ {"name": "resolve target", "type": "texture view", "optional": true},
+ {"name": "load op", "type": "load op"},
+ {"name": "store op", "type": "store op"},
+ {"name": "clear color", "type": "color"}
+ ]
+ },
+
+ "render pass depth stencil attachment descriptor": {
+ "category": "structure",
+ "members": [
+ {"name": "attachment", "type": "texture view"},
+ {"name": "depth load op", "type": "load op"},
+ {"name": "depth store op", "type": "store op"},
+ {"name": "clear depth", "type": "float"},
+ {"name": "stencil load op", "type": "load op"},
+ {"name": "stencil store op", "type": "store op"},
+ {"name": "clear stencil", "type": "uint32_t"}
+ ]
+ },
+
"render pass descriptor builder": {
"category": "object",
"methods": [
@@ -718,41 +740,20 @@
"returns": "render pass descriptor"
},
{
- "name": "set color attachment",
- "args": [
- {"name": "attachment slot", "type": "uint32_t"},
- {"name": "texture view", "type": "texture view"},
- {"name": "load op", "type": "load op"}
- ]
- },
- {
- "name": "set color attachment clear color",
- "TODO": "determine where to put these methods (probably BeginRenderPass?)",
+ "name": "set color attachments",
"args": [
- {"name": "attachment slot", "type": "uint32_t"},
- {"name": "clear r", "type": "float"},
- {"name": "clear g", "type": "float"},
- {"name": "clear b", "type": "float"},
- {"name": "clear a", "type": "float"}
+ {"name": "count", "type": "uint32_t"},
+ {"name": "color attachments", "type": "render pass color attachment descriptor", "annotation": "const*", "length": "count"}
]
},
{
"name": "set depth stencil attachment",
"args": [
- {"name": "texture view", "type": "texture view"},
- {"name": "depth load op", "type": "load op"},
- {"name": "stencil load op", "type": "load op"}
- ]
- },
- {
- "name": "set depth stencil attachment clear value",
- "TODO": "determine where to put these methods (probably BeginRenderPass?)",
- "args": [
- {"name": "clear depth", "type": "float"},
- {"name": "clear stencil", "type": "uint32_t"}
+ {"name": "depth stencil attachment", "type": "render pass depth stencil attachment descriptor", "annotation": "const*"}
]
}
- ]
+ ],
+ "TODO": "Remove this builder and use render pass descriptor directly"
},
"render pass descriptor": {
"category": "object"
@@ -761,8 +762,7 @@
"category": "object",
"methods": [
{
- "name": "set render pipeline",
- "TODO": "This is called setPipeline in the WebGPU IDL",
+ "name": "set pipeline",
"args": [
{"name": "pipeline", "type": "render pipeline"}
]
@@ -788,7 +788,7 @@
]
},
{
- "name": "draw arrays",
+ "name": "draw",
"args": [
{"name": "vertex count", "type": "uint32_t"},
{"name": "instance count", "type": "uint32_t"},
@@ -797,11 +797,12 @@
]
},
{
- "name": "draw elements",
+ "name": "draw indexed",
"args": [
{"name": "index count", "type": "uint32_t"},
{"name": "instance count", "type": "uint32_t"},
{"name": "first index", "type": "uint32_t"},
+ {"name": "base vertex", "type": "uint32_t"},
{"name": "first instance", "type": "uint32_t"}
]
},
@@ -854,73 +855,21 @@
"render pipeline": {
"category": "object"
},
- "render pipeline builder": {
- "category": "object",
- "methods": [
- {
- "name": "get result",
- "returns": "render pipeline"
- },
- {
- "name": "set color attachment format",
- "TODO": "Also need sample count",
- "args": [
- {"name": "attachment slot", "type": "uint32_t"},
- {"name": "format", "type": "texture format"}
- ]
- },
- {
- "name": "set depth stencil attachment format",
- "TODO": "Also need sample count",
- "args": [
- {"name": "format", "type": "texture format"}
- ]
- },
- {
- "name": "set color attachment blend state",
- "args": [
- {"name": "attachment slot", "type": "uint32_t"},
- {"name": "blend state", "type": "blend state"}
- ]
- },
- {
- "name": "set depth stencil state",
- "args": [
- {"name": "depth stencil state", "type": "depth stencil state"}
- ]
- },
- {
- "name": "set index format",
- "args": [
- {"name": "format", "type": "index format"}
- ]
- },
- {
- "name": "set input state",
- "args": [
- {"name": "input", "type": "input state"}
- ]
- },
- {
- "name": "set layout",
- "args": [
- {"name": "layout", "type": "pipeline layout"}
- ]
- },
- {
- "name": "set primitive topology",
- "args": [
- {"name": "primitive topology", "type": "primitive topology"}
- ]
- },
- {
- "name": "set stage",
- "args": [
- {"name": "stage", "type": "shader stage"},
- {"name": "module", "type": "shader module"},
- {"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen"}
- ]
- }
+ "render pipeline descriptor": {
+ "category": "structure",
+ "extensible": true,
+ "members": [
+ {"name": "layout", "type": "pipeline layout"},
+ {"name": "vertex stage", "type": "pipeline stage descriptor", "annotation": "const*"},
+ {"name": "fragment stage", "type": "pipeline stage descriptor", "annotation": "const*"},
+ {"name": "input state", "type": "input state"},
+ {"name": "index format", "type": "index format"},
+ {"name": "primitive topology", "type": "primitive topology"},
+ {"name": "attachments state", "type": "attachments state descriptor", "annotation": "const*"},
+ {"name": "sample count", "type": "uint32_t"},
+ {"name": "depth stencil state", "type": "depth stencil state descriptor", "annotation": "const*"},
+ {"name": "num blend states", "type": "uint32_t"},
+ {"name": "blend states", "type": "blend state descriptor", "annotation": "const*", "length": "num blend states"}
]
},
"sampler": {
@@ -930,12 +879,16 @@
"category": "structure",
"extensible": true,
"members": [
+ {"name": "address mode u", "type": "address mode"},
+ {"name": "address mode v", "type": "address mode"},
+ {"name": "address mode w", "type": "address mode"},
{"name": "mag filter", "type": "filter mode"},
{"name": "min filter", "type": "filter mode"},
{"name": "mipmap filter", "type": "filter mode"},
- {"name": "address mode u", "type": "address mode"},
- {"name": "address mode v", "type": "address mode"},
- {"name": "address mode w", "type": "address mode"}
+ {"name": "lod min clamp", "type": "float"},
+ {"name": "lod max clamp", "type": "float"},
+ {"name": "compare function", "type": "compare function"},
+ {"name": "border color", "type": "border color"}
]
},
"shader module": {
@@ -979,6 +932,16 @@
{"value": 7, "name": "decrement wrap"}
]
},
+ "stencil state face descriptor": {
+ "category": "structure",
+ "extensible": false,
+ "members": [
+ {"name": "compare", "type": "compare function"},
+ {"name": "stencil fail op", "type": "stencil operation"},
+ {"name": "depth fail op", "type": "stencil operation"},
+ {"name": "pass op", "type": "stencil operation"}
+ ]
+ },
"swap chain": {
"category": "object",
"methods": [
@@ -1049,8 +1012,7 @@
{"name": "texture", "type": "texture"},
{"name": "level", "type": "uint32_t"},
{"name": "slice", "type": "uint32_t"},
- {"name": "origin", "type": "origin 3D"},
- {"name": "aspect", "type": "texture aspect"}
+ {"name": "origin", "type": "origin 3D"}
]
},
"texture descriptor": {
@@ -1060,9 +1022,10 @@
{"name": "usage", "type": "texture usage bit"},
{"name": "dimension", "type": "texture dimension"},
{"name": "size", "type": "extent 3D"},
- {"name": "array layer", "type": "uint32_t"},
+ {"name": "array size", "type": "uint32_t"},
{"name": "format", "type": "texture format"},
- {"name": "level count", "type": "uint32_t"}
+ {"name": "level count", "type": "uint32_t"},
+ {"name": "sample count", "type": "uint32_t"}
]
},
"texture dimension": {
@@ -1143,6 +1106,18 @@
{"value": 11, "name": "unorm r8 g8"}
]
},
+ "ObjectType": {
+ "_comment": "Only used for the wire",
+ "category": "native"
+ },
+ "ObjectId": {
+ "_comment": "Only used for the wire",
+ "category": "native"
+ },
+ "ObjectHandle": {
+ "_comment": "Only used for the wire",
+ "category": "native"
+ },
"void": {
"category": "native"
},
diff --git a/chromium/third_party/dawn/dawn_wire.json b/chromium/third_party/dawn/dawn_wire.json
new file mode 100644
index 00000000000..eaa93b2d129
--- /dev/null
+++ b/chromium/third_party/dawn/dawn_wire.json
@@ -0,0 +1,80 @@
+{
+ "_comment": [
+ "Copyright 2019 The Dawn 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."
+ ],
+ "commands": {
+ "buffer map async": [
+ { "name": "buffer id", "type": "ObjectId" },
+ { "name": "request serial", "type": "uint32_t" },
+ { "name": "start", "type": "uint32_t" },
+ { "name": "size", "type": "uint32_t" },
+ { "name": "is write", "type": "bool" }
+ ],
+ "buffer update mapped data": [
+ { "name": "buffer id", "type": "ObjectId" },
+ { "name": "data length", "type": "uint32_t" },
+ { "name": "data", "type": "uint8_t", "annotation": "const*", "length": "data length" }
+ ],
+ "destroy object": [
+ { "name": "object type", "type": "ObjectType" },
+ { "name": "object id", "type": "ObjectId" }
+ ]
+ },
+ "return commands": {
+ "buffer map read async callback": [
+ { "name": "buffer", "type": "ObjectHandle" },
+ { "name": "request serial", "type": "uint32_t" },
+ { "name": "status", "type": "uint32_t" },
+ { "name": "data length", "type": "uint32_t" },
+ { "name": "data", "type": "uint8_t", "annotation": "const*", "length": "data length" }
+ ],
+ "buffer map write async callback": [
+ { "name": "buffer", "type": "ObjectHandle" },
+ { "name": "request serial", "type": "uint32_t" },
+ { "name": "status", "type": "uint32_t" }
+ ],
+ "device error callback": [
+ { "name": "message", "type": "char", "annotation": "const*", "length": "strlen" }
+ ],
+ "fence update completed value": [
+ { "name": "fence", "type": "ObjectHandle" },
+ { "name": "value", "type": "uint64_t" }
+ ]
+ },
+ "special items": {
+ "client_side_commands": [
+ "FenceGetCompletedValue"
+ ],
+ "client_proxied_commands": [
+ "BufferUnmap",
+ "DeviceCreateFence",
+ "QueueSignal"
+ ],
+ "client_special_objects": [
+ "Buffer",
+ "Device",
+ "Fence"
+ ],
+ "server_custom_pre_handler_commands": [
+ "BufferUnmap"
+ ],
+ "server_custom_post_handler_commands": [
+ "QueueSignal"
+ ],
+ "server_reverse_lookup_objects": [
+ "Fence"
+ ]
+ }
+}
diff --git a/chromium/third_party/dawn/examples/Animometer.cpp b/chromium/third_party/dawn/examples/Animometer.cpp
index 9e0eff9073a..30f42f1a56e 100644
--- a/chromium/third_party/dawn/examples/Animometer.cpp
+++ b/chromium/third_party/dawn/examples/Animometer.cpp
@@ -14,6 +14,7 @@
#include "SampleUtils.h"
+#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h"
@@ -109,12 +110,14 @@ void init() {
depthStencilView = CreateDefaultDepthStencilView(device);
- pipeline = device.CreateRenderPipelineBuilder()
- .SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
- .SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
- .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
- .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
- .GetResult();
+ utils::ComboRenderPipelineDescriptor descriptor(device);
+ descriptor.cVertexStage.module = vsModule;
+ descriptor.cFragmentStage.module = fsModule;
+ descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
+ descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
+ descriptor.cColorAttachments[0]->format = GetPreferredSwapChainTextureFormat();
+
+ pipeline = device.CreateRenderPipeline(&descriptor);
shaderData.resize(10000);
for (auto& data : shaderData) {
@@ -140,12 +143,12 @@ void frame() {
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
{
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass);
- pass.SetRenderPipeline(pipeline);
+ pass.SetPipeline(pipeline);
for (int k = 0; k < 10000; k++) {
shaderData[i].time = f / 60.0f;
pass.SetPushConstants(dawn::ShaderStageBit::Vertex, 0, 6, reinterpret_cast<uint32_t*>(&shaderData[i]));
- pass.DrawArrays(3, 1, 0, 0);
+ pass.Draw(3, 1, 0, 0);
i++;
}
diff --git a/chromium/third_party/dawn/examples/CHelloTriangle.cpp b/chromium/third_party/dawn/examples/CHelloTriangle.cpp
index 1d87073d16b..486f0d5dae9 100644
--- a/chromium/third_party/dawn/examples/CHelloTriangle.cpp
+++ b/chromium/third_party/dawn/examples/CHelloTriangle.cpp
@@ -56,12 +56,81 @@ void init() {
dawnShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fs).Release();
{
- dawnRenderPipelineBuilder builder = dawnDeviceCreateRenderPipelineBuilder(device);
- dawnRenderPipelineBuilderSetColorAttachmentFormat(builder, 0, swapChainFormat);
- dawnRenderPipelineBuilderSetStage(builder, DAWN_SHADER_STAGE_VERTEX, vsModule, "main");
- dawnRenderPipelineBuilderSetStage(builder, DAWN_SHADER_STAGE_FRAGMENT, fsModule, "main");
- pipeline = dawnRenderPipelineBuilderGetResult(builder);
- dawnRenderPipelineBuilderRelease(builder);
+ dawnRenderPipelineDescriptor descriptor;
+ descriptor.nextInChain = nullptr;
+
+ dawnPipelineStageDescriptor vertexStage;
+ vertexStage.nextInChain = nullptr;
+ vertexStage.module = vsModule;
+ vertexStage.entryPoint = "main";
+ descriptor.vertexStage = &vertexStage;
+
+ dawnPipelineStageDescriptor fragmentStage;
+ fragmentStage.nextInChain = nullptr;
+ fragmentStage.module = fsModule;
+ fragmentStage.entryPoint = "main";
+ descriptor.fragmentStage = &fragmentStage;
+
+ dawnAttachmentsStateDescriptor attachmentsState;
+ attachmentsState.nextInChain = nullptr;
+ attachmentsState.numColorAttachments = 1;
+ dawnAttachmentDescriptor colorAttachment = {nullptr, swapChainFormat};
+ dawnAttachmentDescriptor* colorAttachmentPtr[] = {&colorAttachment};
+ attachmentsState.colorAttachments = colorAttachmentPtr;
+ attachmentsState.hasDepthStencilAttachment = false;
+ // Even with hasDepthStencilAttachment = false, depthStencilAttachment must point to valid
+ // data because we don't have optional substructures yet.
+ attachmentsState.depthStencilAttachment = &colorAttachment;
+ descriptor.attachmentsState = &attachmentsState;
+
+ descriptor.sampleCount = 1;
+
+ descriptor.numBlendStates = 1;
+
+ dawnBlendDescriptor blendDescriptor;
+ blendDescriptor.operation = DAWN_BLEND_OPERATION_ADD;
+ blendDescriptor.srcFactor = DAWN_BLEND_FACTOR_ONE;
+ blendDescriptor.dstFactor = DAWN_BLEND_FACTOR_ONE;
+ dawnBlendStateDescriptor blendStateDescriptor;
+ blendStateDescriptor.nextInChain = nullptr;
+ blendStateDescriptor.blendEnabled = false;
+ blendStateDescriptor.alphaBlend = blendDescriptor;
+ blendStateDescriptor.colorBlend = blendDescriptor;
+ blendStateDescriptor.colorWriteMask = DAWN_COLOR_WRITE_MASK_ALL;
+ descriptor.blendStates = &blendStateDescriptor;
+
+ dawnPipelineLayoutDescriptor pl;
+ pl.nextInChain = nullptr;
+ pl.numBindGroupLayouts = 0;
+ pl.bindGroupLayouts = nullptr;
+ descriptor.layout = dawnDeviceCreatePipelineLayout(device, &pl);
+
+ dawnInputStateBuilder inputStateBuilder = dawnDeviceCreateInputStateBuilder(device);
+ descriptor.inputState = dawnInputStateBuilderGetResult(inputStateBuilder);
+ dawnInputStateBuilderRelease(inputStateBuilder);
+
+ descriptor.indexFormat = DAWN_INDEX_FORMAT_UINT32;
+ descriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+ dawnStencilStateFaceDescriptor stencilFace;
+ stencilFace.compare = DAWN_COMPARE_FUNCTION_ALWAYS;
+ stencilFace.stencilFailOp = DAWN_STENCIL_OPERATION_KEEP;
+ stencilFace.depthFailOp = DAWN_STENCIL_OPERATION_KEEP;
+ stencilFace.passOp = DAWN_STENCIL_OPERATION_KEEP;
+
+ dawnDepthStencilStateDescriptor depthStencilState;
+ depthStencilState.nextInChain = nullptr;
+ depthStencilState.depthWriteEnabled = false;
+ depthStencilState.depthCompare = DAWN_COMPARE_FUNCTION_ALWAYS;
+ depthStencilState.back = stencilFace;
+ depthStencilState.front = stencilFace;
+ depthStencilState.stencilReadMask = 0xff;
+ depthStencilState.stencilWriteMask = 0xff;
+ descriptor.depthStencilState = &depthStencilState;
+
+ pipeline = dawnDeviceCreateRenderPipeline(device, &descriptor);
+
+ dawnInputStateRelease(descriptor.inputState);
}
dawnShaderModuleRelease(vsModule);
@@ -77,7 +146,13 @@ void frame() {
dawnRenderPassDescriptor renderpassInfo;
{
dawnRenderPassDescriptorBuilder builder = dawnDeviceCreateRenderPassDescriptorBuilder(device);
- dawnRenderPassDescriptorBuilderSetColorAttachment(builder, 0, backbufferView, DAWN_LOAD_OP_CLEAR);
+ dawnRenderPassColorAttachmentDescriptor colorAttachment;
+ colorAttachment.attachment = backbufferView;
+ colorAttachment.resolveTarget = nullptr;
+ colorAttachment.clearColor = { 0.0f, 0.0f, 0.0f, 0.0f };
+ colorAttachment.loadOp = DAWN_LOAD_OP_CLEAR;
+ colorAttachment.storeOp = DAWN_STORE_OP_STORE;
+ dawnRenderPassDescriptorBuilderSetColorAttachments(builder, 1, &colorAttachment);
renderpassInfo = dawnRenderPassDescriptorBuilderGetResult(builder);
dawnRenderPassDescriptorBuilderRelease(builder);
}
@@ -86,8 +161,8 @@ void frame() {
dawnCommandBufferBuilder builder = dawnDeviceCreateCommandBufferBuilder(device);
dawnRenderPassEncoder pass = dawnCommandBufferBuilderBeginRenderPass(builder, renderpassInfo);
- dawnRenderPassEncoderSetRenderPipeline(pass, pipeline);
- dawnRenderPassEncoderDrawArrays(pass, 3, 1, 0, 0);
+ dawnRenderPassEncoderSetPipeline(pass, pipeline);
+ dawnRenderPassEncoderDraw(pass, 3, 1, 0, 0);
dawnRenderPassEncoderEndPass(pass);
dawnRenderPassEncoderRelease(pass);
diff --git a/chromium/third_party/dawn/examples/ComputeBoids.cpp b/chromium/third_party/dawn/examples/ComputeBoids.cpp
index 869f95f4b28..ce5668c960a 100644
--- a/chromium/third_party/dawn/examples/ComputeBoids.cpp
+++ b/chromium/third_party/dawn/examples/ComputeBoids.cpp
@@ -14,6 +14,7 @@
#include "SampleUtils.h"
+#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h"
@@ -123,13 +124,15 @@ void initRender() {
depthStencilView = CreateDefaultDepthStencilView(device);
- renderPipeline = device.CreateRenderPipelineBuilder()
- .SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
- .SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
- .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
- .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
- .SetInputState(inputState)
- .GetResult();
+ utils::ComboRenderPipelineDescriptor descriptor(device);
+ descriptor.cVertexStage.module = vsModule;
+ descriptor.cFragmentStage.module = fsModule;
+ descriptor.inputState = inputState;
+ descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
+ descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
+ descriptor.cColorAttachments[0]->format = GetPreferredSwapChainTextureFormat();
+
+ renderPipeline = device.CreateRenderPipeline(&descriptor);
}
void initSim() {
@@ -237,24 +240,12 @@ void initSim() {
csDesc.layout = pl;
updatePipeline = device.CreateComputePipeline(&csDesc);
- dawn::BufferView updateParamsView = updateParams.CreateBufferViewBuilder()
- .SetExtent(0, sizeof(SimParams))
- .GetResult();
-
- std::array<dawn::BufferView, 2> views;
- for (uint32_t i = 0; i < 2; ++i) {
- views[i] = particleBuffers[i].CreateBufferViewBuilder()
- .SetExtent(0, kNumParticles * sizeof(Particle))
- .GetResult();
- }
-
for (uint32_t i = 0; i < 2; ++i) {
- updateBGs[i] = device.CreateBindGroupBuilder()
- .SetLayout(bgl)
- .SetBufferViews(0, 1, &updateParamsView)
- .SetBufferViews(1, 1, &views[i])
- .SetBufferViews(2, 1, &views[(i + 1) % 2])
- .GetResult();
+ updateBGs[i] = utils::MakeBindGroup(device, bgl, {
+ {0, updateParams, 0, sizeof(SimParams)},
+ {1, particleBuffers[i], 0, kNumParticles * sizeof(Particle)},
+ {2, particleBuffers[(i + 1) % 2], 0, kNumParticles * sizeof(Particle)},
+ });
}
}
@@ -265,7 +256,7 @@ dawn::CommandBuffer createCommandBuffer(const dawn::RenderPassDescriptor& render
{
dawn::ComputePassEncoder pass = builder.BeginComputePass();
- pass.SetComputePipeline(updatePipeline);
+ pass.SetPipeline(updatePipeline);
pass.SetBindGroup(0, updateBGs[i]);
pass.Dispatch(kNumParticles, 1, 1);
pass.EndPass();
@@ -273,10 +264,10 @@ dawn::CommandBuffer createCommandBuffer(const dawn::RenderPassDescriptor& render
{
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass);
- pass.SetRenderPipeline(renderPipeline);
+ pass.SetPipeline(renderPipeline);
pass.SetVertexBuffers(0, 1, &bufferDst, zeroOffsets);
pass.SetVertexBuffers(1, 1, &modelBuffer, zeroOffsets);
- pass.DrawArrays(3, kNumParticles, 0, 0);
+ pass.Draw(3, kNumParticles, 0, 0);
pass.EndPass();
}
diff --git a/chromium/third_party/dawn/examples/CppHelloTriangle.cpp b/chromium/third_party/dawn/examples/CppHelloTriangle.cpp
index de60b2e654e..7aca392ce9b 100644
--- a/chromium/third_party/dawn/examples/CppHelloTriangle.cpp
+++ b/chromium/third_party/dawn/examples/CppHelloTriangle.cpp
@@ -14,6 +14,7 @@
#include "SampleUtils.h"
+#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h"
@@ -53,7 +54,8 @@ void initTextures() {
descriptor.size.width = 1024;
descriptor.size.height = 1024;
descriptor.size.depth = 1;
- descriptor.arrayLayer = 1;
+ descriptor.arraySize = 1;
+ descriptor.sampleCount = 1;
descriptor.format = dawn::TextureFormat::R8G8B8A8Unorm;
descriptor.levelCount = 1;
descriptor.usage = dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled;
@@ -70,8 +72,7 @@ void initTextures() {
dawn::Buffer stagingBuffer = utils::CreateBufferFromData(device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::TransferSrc);
dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);
- dawn::TextureCopyView textureCopyView =
- utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color);
+ dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});
dawn::Extent3D copySize = {1024, 1024, 1};
dawn::CommandBuffer copy =
device.CreateCommandBufferBuilder()
@@ -125,23 +126,23 @@ void init() {
depthStencilView = CreateDefaultDepthStencilView(device);
- pipeline = device.CreateRenderPipelineBuilder()
- .SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
- .SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
- .SetLayout(pl)
- .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
- .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
- .SetIndexFormat(dawn::IndexFormat::Uint32)
- .SetInputState(inputState)
- .GetResult();
+ utils::ComboRenderPipelineDescriptor descriptor(device);
+ descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
+ descriptor.cVertexStage.module = vsModule;
+ descriptor.cFragmentStage.module = fsModule;
+ descriptor.inputState = inputState;
+ descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
+ descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
+ descriptor.cColorAttachments[0]->format = GetPreferredSwapChainTextureFormat();
+
+ pipeline = device.CreateRenderPipeline(&descriptor);
dawn::TextureView view = texture.CreateDefaultTextureView();
- bindGroup = device.CreateBindGroupBuilder()
- .SetLayout(bgl)
- .SetSamplers(0, 1, &sampler)
- .SetTextureViews(1, 1, &view)
- .GetResult();
+ bindGroup = utils::MakeBindGroup(device, bgl, {
+ {0, sampler},
+ {1, view}
+ });
}
struct {uint32_t a; float b;} s;
@@ -158,11 +159,11 @@ void frame() {
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
{
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass);
- pass.SetRenderPipeline(pipeline);
+ pass.SetPipeline(pipeline);
pass.SetBindGroup(0, bindGroup);
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
pass.SetIndexBuffer(indexBuffer, 0);
- pass.DrawElements(3, 1, 0, 0);
+ pass.DrawIndexed(3, 1, 0, 0, 0);
pass.EndPass();
}
diff --git a/chromium/third_party/dawn/examples/CubeReflection.cpp b/chromium/third_party/dawn/examples/CubeReflection.cpp
index 5a5f658822e..7266539b5e1 100644
--- a/chromium/third_party/dawn/examples/CubeReflection.cpp
+++ b/chromium/third_party/dawn/examples/CubeReflection.cpp
@@ -14,6 +14,7 @@
#include "SampleUtils.h"
+#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h"
@@ -180,80 +181,61 @@ void init() {
transform = glm::translate(transform, glm::vec3(0.f, -2.f, 0.f));
transformBuffer[1] = utils::CreateBufferFromData(device, &transform, sizeof(glm::mat4), dawn::BufferUsageBit::Uniform);
- dawn::BufferView cameraBufferView = cameraBuffer.CreateBufferViewBuilder()
- .SetExtent(0, sizeof(CameraData))
- .GetResult();
+ bindGroup[0] = utils::MakeBindGroup(device, bgl, {
+ {0, cameraBuffer, 0, sizeof(CameraData)},
+ {1, transformBuffer[0], 0, sizeof(glm::mat4)}
+ });
- dawn::BufferView transformBufferView[2] = {
- transformBuffer[0].CreateBufferViewBuilder()
- .SetExtent(0, sizeof(glm::mat4))
- .GetResult(),
- transformBuffer[1].CreateBufferViewBuilder()
- .SetExtent(0, sizeof(glm::mat4))
- .GetResult(),
- };
-
- bindGroup[0] = device.CreateBindGroupBuilder()
- .SetLayout(bgl)
- .SetBufferViews(0, 1, &cameraBufferView)
- .SetBufferViews(1, 1, &transformBufferView[0])
- .GetResult();
-
- bindGroup[1] = device.CreateBindGroupBuilder()
- .SetLayout(bgl)
- .SetBufferViews(0, 1, &cameraBufferView)
- .SetBufferViews(1, 1, &transformBufferView[1])
- .GetResult();
+ bindGroup[1] = utils::MakeBindGroup(device, bgl, {
+ {0, cameraBuffer, 0, sizeof(CameraData)},
+ {1, transformBuffer[1], 0, sizeof(glm::mat4)}
+ });
depthStencilView = CreateDefaultDepthStencilView(device);
- auto depthStencilState = device.CreateDepthStencilStateBuilder()
- .SetDepthCompareFunction(dawn::CompareFunction::Less)
- .SetDepthWriteEnabled(true)
- .GetResult();
-
- pipeline = device.CreateRenderPipelineBuilder()
- .SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
- .SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
- .SetLayout(pl)
- .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
- .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
- .SetIndexFormat(dawn::IndexFormat::Uint32)
- .SetInputState(inputState)
- .SetDepthStencilState(depthStencilState)
- .GetResult();
-
- auto planeStencilState = device.CreateDepthStencilStateBuilder()
- .SetDepthCompareFunction(dawn::CompareFunction::Less)
- .SetDepthWriteEnabled(false)
- .SetStencilFunction(dawn::Face::Both, dawn::CompareFunction::Always, dawn::StencilOperation::Keep, dawn::StencilOperation::Keep, dawn::StencilOperation::Replace)
- .GetResult();
-
- planePipeline = device.CreateRenderPipelineBuilder()
- .SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
- .SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
- .SetLayout(pl)
- .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
- .SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
- .SetInputState(inputState)
- .SetDepthStencilState(planeStencilState)
- .GetResult();
-
- auto reflectionStencilState = device.CreateDepthStencilStateBuilder()
- .SetDepthCompareFunction(dawn::CompareFunction::Less)
- .SetDepthWriteEnabled(true)
- .SetStencilFunction(dawn::Face::Both, dawn::CompareFunction::Equal, dawn::StencilOperation::Keep, dawn::StencilOperation::Keep, dawn::StencilOperation::Replace)
- .GetResult();
-
- reflectionPipeline = device.CreateRenderPipelineBuilder()
- .SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
- .SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
- .SetLayout(pl)
- .SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
- .SetStage(dawn::ShaderStage::Fragment, fsReflectionModule, "main")
- .SetInputState(inputState)
- .SetDepthStencilState(reflectionStencilState)
- .GetResult();
+ utils::ComboRenderPipelineDescriptor descriptor(device);
+ descriptor.layout = pl;
+ descriptor.cVertexStage.module = vsModule;
+ descriptor.cFragmentStage.module = fsModule;
+ descriptor.inputState = inputState;
+ descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
+ descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
+ descriptor.cColorAttachments[0]->format = GetPreferredSwapChainTextureFormat();
+ descriptor.cDepthStencilState.depthWriteEnabled = true;
+ descriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Less;
+
+ pipeline = device.CreateRenderPipeline(&descriptor);
+
+ utils::ComboRenderPipelineDescriptor pDescriptor(device);
+ pDescriptor.layout = pl;
+ pDescriptor.cVertexStage.module = vsModule;
+ pDescriptor.cFragmentStage.module = fsModule;
+ pDescriptor.inputState = inputState;
+ pDescriptor.cAttachmentsState.hasDepthStencilAttachment = true;
+ pDescriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
+ pDescriptor.cColorAttachments[0]->format = GetPreferredSwapChainTextureFormat();
+ pDescriptor.cDepthStencilState.front.passOp = dawn::StencilOperation::Replace;
+ pDescriptor.cDepthStencilState.back.passOp = dawn::StencilOperation::Replace;
+ pDescriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Less;
+
+ planePipeline = device.CreateRenderPipeline(&pDescriptor);
+
+ utils::ComboRenderPipelineDescriptor rfDescriptor(device);
+ rfDescriptor.layout = pl;
+ rfDescriptor.cVertexStage.module = vsModule;
+ rfDescriptor.cFragmentStage.module = fsReflectionModule;
+ rfDescriptor.inputState = inputState;
+ rfDescriptor.cAttachmentsState.hasDepthStencilAttachment = true;
+ rfDescriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
+ rfDescriptor.cColorAttachments[0]->format = GetPreferredSwapChainTextureFormat();
+ pDescriptor.cDepthStencilState.front.compare = dawn::CompareFunction::Equal;
+ pDescriptor.cDepthStencilState.back.compare = dawn::CompareFunction::Equal;
+ pDescriptor.cDepthStencilState.front.passOp = dawn::StencilOperation::Replace;
+ pDescriptor.cDepthStencilState.back.passOp = dawn::StencilOperation::Replace;
+ rfDescriptor.cDepthStencilState.depthWriteEnabled = true;
+ rfDescriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Less;
+
+ reflectionPipeline = device.CreateRenderPipeline(&rfDescriptor);
cameraData.proj = glm::perspective(glm::radians(45.0f), 1.f, 1.0f, 100.0f);
}
@@ -280,22 +262,22 @@ void frame() {
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
{
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass);
- pass.SetRenderPipeline(pipeline);
+ pass.SetPipeline(pipeline);
pass.SetBindGroup(0, bindGroup[0]);
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
pass.SetIndexBuffer(indexBuffer, 0);
- pass.DrawElements(36, 1, 0, 0);
+ pass.DrawIndexed(36, 1, 0, 0, 0);
pass.SetStencilReference(0x1);
- pass.SetRenderPipeline(planePipeline);
+ pass.SetPipeline(planePipeline);
pass.SetBindGroup(0, bindGroup[0]);
pass.SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets);
- pass.DrawElements(6, 1, 0, 0);
+ pass.DrawIndexed(6, 1, 0, 0, 0);
- pass.SetRenderPipeline(reflectionPipeline);
+ pass.SetPipeline(reflectionPipeline);
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
pass.SetBindGroup(0, bindGroup[1]);
- pass.DrawElements(36, 1, 0, 0);
+ pass.DrawIndexed(36, 1, 0, 0, 0);
pass.EndPass();
}
diff --git a/chromium/third_party/dawn/examples/SampleUtils.cpp b/chromium/third_party/dawn/examples/SampleUtils.cpp
index 0c01964a1ae..99e151928dd 100644
--- a/chromium/third_party/dawn/examples/SampleUtils.cpp
+++ b/chromium/third_party/dawn/examples/SampleUtils.cpp
@@ -141,7 +141,8 @@ dawn::TextureView CreateDefaultDepthStencilView(const dawn::Device& device) {
descriptor.size.width = 640;
descriptor.size.height = 480;
descriptor.size.depth = 1;
- descriptor.arrayLayer = 1;
+ descriptor.arraySize = 1;
+ descriptor.sampleCount = 1;
descriptor.format = dawn::TextureFormat::D32FloatS8Uint;
descriptor.levelCount = 1;
descriptor.usage = dawn::TextureUsageBit::OutputAttachment;
@@ -156,9 +157,25 @@ void GetNextRenderPassDescriptor(const dawn::Device& device,
dawn::RenderPassDescriptor* info) {
*backbuffer = swapchain.GetNextTexture();
auto backbufferView = backbuffer->CreateDefaultTextureView();
+ dawn::RenderPassColorAttachmentDescriptor colorAttachment;
+ colorAttachment.attachment = backbufferView;
+ colorAttachment.resolveTarget = nullptr;
+ colorAttachment.clearColor = { 0.0f, 0.0f, 0.0f, 0.0f };
+ colorAttachment.loadOp = dawn::LoadOp::Clear;
+ colorAttachment.storeOp = dawn::StoreOp::Store;
+
+ dawn::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
+ depthStencilAttachment.attachment = depthStencilView;
+ depthStencilAttachment.depthLoadOp = dawn::LoadOp::Clear;
+ depthStencilAttachment.stencilLoadOp = dawn::LoadOp::Clear;
+ depthStencilAttachment.clearDepth = 1.0f;
+ depthStencilAttachment.clearStencil = 0;
+ depthStencilAttachment.depthStoreOp = dawn::StoreOp::Store;
+ depthStencilAttachment.stencilStoreOp = dawn::StoreOp::Store;
+
*info = device.CreateRenderPassDescriptorBuilder()
- .SetColorAttachment(0, backbufferView, dawn::LoadOp::Clear)
- .SetDepthStencilAttachment(depthStencilView, dawn::LoadOp::Clear, dawn::LoadOp::Clear)
+ .SetColorAttachments(1, &colorAttachment)
+ .SetDepthStencilAttachment(&depthStencilAttachment)
.GetResult();
}
diff --git a/chromium/third_party/dawn/examples/glTFViewer/glTFViewer.cpp b/chromium/third_party/dawn/examples/glTFViewer/glTFViewer.cpp
index 873a2461c9f..acefd2a4b06 100644
--- a/chromium/third_party/dawn/examples/glTFViewer/glTFViewer.cpp
+++ b/chromium/third_party/dawn/examples/glTFViewer/glTFViewer.cpp
@@ -23,6 +23,7 @@
#include "common/Assert.h"
#include "common/Math.h"
#include "common/Constants.h"
+#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h"
@@ -281,36 +282,38 @@ namespace {
dawn::BindingType::SampledTexture},
});
- auto depthStencilState = device.CreateDepthStencilStateBuilder()
- .SetDepthCompareFunction(dawn::CompareFunction::Less)
- .SetDepthWriteEnabled(true)
- .GetResult();
-
auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
- auto pipeline = device.CreateRenderPipelineBuilder()
- .SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
- .SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
- .SetLayout(pipelineLayout)
- .SetStage(dawn::ShaderStage::Vertex, oVSModule, "main")
- .SetStage(dawn::ShaderStage::Fragment, oFSModule, "main")
- .SetIndexFormat(dawn::IndexFormat::Uint16)
- .SetInputState(inputState)
- .SetDepthStencilState(depthStencilState)
- .GetResult();
-
- auto bindGroupBuilder = device.CreateBindGroupBuilder();
- bindGroupBuilder.SetLayout(bindGroupLayout);
+
+ utils::ComboRenderPipelineDescriptor descriptor(device);
+ descriptor.layout = pipelineLayout;
+ descriptor.cVertexStage.module = oVSModule;
+ descriptor.cFragmentStage.module = oFSModule;
+ descriptor.inputState = inputState;
+ descriptor.indexFormat = dawn::IndexFormat::Uint16;
+ descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
+ descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
+ descriptor.cColorAttachments[0]->format = GetPreferredSwapChainTextureFormat();
+ descriptor.cDepthStencilState.depthWriteEnabled = true;
+ descriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Less;
+
+ dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
+
+ dawn::BindGroup bindGroup;
if (hasTexture) {
const auto& textureView = textures[iTextureID];
const auto& iSamplerID = scene.textures[iTextureID].sampler;
- bindGroupBuilder.SetSamplers(0, 1, &samplers[iSamplerID]);
- bindGroupBuilder.SetTextureViews(1, 1, &textureView);
+ bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {
+ {0, samplers[iSamplerID]},
+ {1, textureView}
+ });
+ } else {
+ bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {});
}
MaterialInfo material = {
- pipeline.Get(),
- bindGroupBuilder.GetResult(),
+ pipeline,
+ bindGroup,
std::map<uint32_t, std::string>(),
};
materials[key] = std::move(material);
@@ -387,7 +390,8 @@ namespace {
descriptor.size.width = iImage.width;
descriptor.size.height = iImage.height;
descriptor.size.depth = 1;
- descriptor.arrayLayer = 1;
+ descriptor.arraySize = 1;
+ descriptor.sampleCount = 1;
descriptor.format = format;
descriptor.levelCount = 1;
descriptor.usage = dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled;
@@ -436,7 +440,7 @@ namespace {
dawn::BufferCopyView bufferCopyView =
utils::CreateBufferCopyView(staging, 0, rowPitch, 0);
dawn::TextureCopyView textureCopyView =
- utils::CreateTextureCopyView(oTexture, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color);
+ utils::CreateTextureCopyView(oTexture, 0, 0, {0, 0, 0});
dawn::Extent3D copySize = {iImage.width, iImage.height, 1};
auto cmdbuf = device.CreateCommandBufferBuilder()
.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize)
@@ -489,7 +493,7 @@ namespace {
}
}
const MaterialInfo& material = getMaterial(iPrim.material, strides[0], strides[1], strides[2]);
- pass.SetRenderPipeline(material.pipeline);
+ pass.SetPipeline(material.pipeline);
pass.SetBindGroup(0, material.bindGroup0);
pass.SetPushConstants(dawn::ShaderStageBit::Vertex,
0, sizeof(u_transform_block) / sizeof(uint32_t),
@@ -528,10 +532,10 @@ namespace {
}
const auto& oIndicesBuffer = buffers.at(iIndices.bufferView);
pass.SetIndexBuffer(oIndicesBuffer, static_cast<uint32_t>(iIndices.byteOffset));
- pass.DrawElements(static_cast<uint32_t>(iIndices.count), 1, 0, 0);
+ pass.DrawIndexed(static_cast<uint32_t>(iIndices.count), 1, 0, 0, 0);
} else {
// DrawArrays
- pass.DrawArrays(vertexCount, 1, 0, 0);
+ pass.Draw(vertexCount, 1, 0, 0);
}
}
}
diff --git a/chromium/third_party/dawn/generator/common.py b/chromium/third_party/dawn/generator/common.py
new file mode 100644
index 00000000000..977dee96229
--- /dev/null
+++ b/chromium/third_party/dawn/generator/common.py
@@ -0,0 +1,149 @@
+# Copyright 2017 The Dawn 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.
+
+from collections import namedtuple
+
+class Name:
+ def __init__(self, name, native=False):
+ self.native = native
+ if native:
+ self.chunks = [name]
+ else:
+ self.chunks = name.split(' ')
+
+ def CamelChunk(self, chunk):
+ return chunk[0].upper() + chunk[1:]
+
+ def canonical_case(self):
+ return (' '.join(self.chunks)).lower()
+
+ def concatcase(self):
+ return ''.join(self.chunks)
+
+ def camelCase(self):
+ return self.chunks[0] + ''.join([self.CamelChunk(chunk) for chunk in self.chunks[1:]])
+
+ def CamelCase(self):
+ return ''.join([self.CamelChunk(chunk) for chunk in self.chunks])
+
+ def SNAKE_CASE(self):
+ return '_'.join([chunk.upper() for chunk in self.chunks])
+
+ def snake_case(self):
+ return '_'.join(self.chunks)
+
+class Type:
+ def __init__(self, name, json_data, native=False):
+ self.json_data = json_data
+ self.dict_name = name
+ self.name = Name(name, native=native)
+ self.category = json_data['category']
+ self.is_builder = self.name.canonical_case().endswith(" builder")
+
+EnumValue = namedtuple('EnumValue', ['name', 'value'])
+class EnumType(Type):
+ def __init__(self, name, json_data):
+ Type.__init__(self, name, json_data)
+ self.values = [EnumValue(Name(m['name']), m['value']) for m in self.json_data['values']]
+
+BitmaskValue = namedtuple('BitmaskValue', ['name', 'value'])
+class BitmaskType(Type):
+ def __init__(self, name, json_data):
+ Type.__init__(self, name, json_data)
+ self.values = [BitmaskValue(Name(m['name']), m['value']) for m in self.json_data['values']]
+ self.full_mask = 0
+ for value in self.values:
+ self.full_mask = self.full_mask | value.value
+
+class NativeType(Type):
+ def __init__(self, name, json_data):
+ Type.__init__(self, name, json_data, native=True)
+
+class NativelyDefined(Type):
+ def __init__(self, name, json_data):
+ Type.__init__(self, name, json_data)
+
+# Methods and structures are both "records", so record members correspond to
+# method arguments or structure members.
+class RecordMember:
+ def __init__(self, name, typ, annotation, optional, is_return_value):
+ self.name = name
+ self.type = typ
+ self.annotation = annotation
+ self.length = None
+ self.optional = optional
+ self.is_return_value = is_return_value
+
+Method = namedtuple('Method', ['name', 'return_type', 'arguments'])
+class ObjectType(Type):
+ def __init__(self, name, json_data):
+ Type.__init__(self, name, json_data)
+ self.methods = []
+ self.native_methods = []
+ self.built_type = None
+
+class Record:
+ def __init__(self, name):
+ self.name = Name(name)
+ self.members = []
+ self.has_dawn_object = False
+
+ def update_metadata(self):
+ def has_dawn_object(member):
+ if isinstance(member.type, ObjectType):
+ return True
+ elif isinstance(member.type, StructureType):
+ return member.type.has_dawn_object
+ else:
+ return False
+
+ self.has_dawn_object = any(has_dawn_object(member) for member in self.members)
+
+class StructureType(Record, Type):
+ def __init__(self, name, json_data):
+ Record.__init__(self, name)
+ Type.__init__(self, name, json_data)
+ self.extensible = json_data.get("extensible", False)
+
+class Command(Record):
+ def __init__(self, name, members=None):
+ Record.__init__(self, name)
+ self.members = members or []
+ self.derived_object = None
+ self.derived_method = None
+
+def linked_record_members(json_data, types):
+ members = []
+ members_by_name = {}
+ for m in json_data:
+ member = RecordMember(Name(m['name']), types[m['type']],
+ m.get('annotation', 'value'), m.get('optional', False),
+ m.get('is_return_value', False))
+ members.append(member)
+ members_by_name[member.name.canonical_case()] = member
+
+ for (member, m) in zip(members, json_data):
+ if member.annotation != 'value':
+ if not 'length' in m:
+ if member.type.category == 'structure':
+ member.length = "constant"
+ member.constant_length = 1
+ else:
+ assert(False)
+ elif m['length'] == 'strlen':
+ member.length = 'strlen'
+ else:
+ member.length = members_by_name[m['length']]
+
+ return members
diff --git a/chromium/third_party/dawn/generator/main.py b/chromium/third_party/dawn/generator/main.py
index e58daac59ee..53e3068ce03 100644
--- a/chromium/third_party/dawn/generator/main.py
+++ b/chromium/third_party/dawn/generator/main.py
@@ -17,96 +17,9 @@
# COMMON
############################################################
from collections import namedtuple
-
-class Name:
- def __init__(self, name, native=False):
- self.native = native
- if native:
- self.chunks = [name]
- else:
- self.chunks = name.split(' ')
-
- def CamelChunk(self, chunk):
- return chunk[0].upper() + chunk[1:]
-
- def canonical_case(self):
- return (' '.join(self.chunks)).lower()
-
- def concatcase(self):
- return ''.join(self.chunks)
-
- def camelCase(self):
- return self.chunks[0] + ''.join([self.CamelChunk(chunk) for chunk in self.chunks[1:]])
-
- def CamelCase(self):
- return ''.join([self.CamelChunk(chunk) for chunk in self.chunks])
-
- def SNAKE_CASE(self):
- return '_'.join([chunk.upper() for chunk in self.chunks])
-
- def snake_case(self):
- return '_'.join(self.chunks)
-
-class Type:
- def __init__(self, name, record, native=False):
- self.record = record
- self.dict_name = name
- self.name = Name(name, native=native)
- self.category = record['category']
- self.is_builder = self.name.canonical_case().endswith(" builder")
-
-EnumValue = namedtuple('EnumValue', ['name', 'value'])
-class EnumType(Type):
- def __init__(self, name, record):
- Type.__init__(self, name, record)
- self.values = [EnumValue(Name(m['name']), m['value']) for m in self.record['values']]
-
-BitmaskValue = namedtuple('BitmaskValue', ['name', 'value'])
-class BitmaskType(Type):
- def __init__(self, name, record):
- Type.__init__(self, name, record)
- self.values = [BitmaskValue(Name(m['name']), m['value']) for m in self.record['values']]
- self.full_mask = 0
- for value in self.values:
- self.full_mask = self.full_mask | value.value
-
-class NativeType(Type):
- def __init__(self, name, record):
- Type.__init__(self, name, record, native=True)
-
-class NativelyDefined(Type):
- def __init__(self, name, record):
- Type.__init__(self, name, record)
-
-class MethodArgument:
- def __init__(self, name, typ, annotation, optional):
- self.name = name
- self.type = typ
- self.annotation = annotation
- self.length = None
- self.optional = optional
-
-Method = namedtuple('Method', ['name', 'return_type', 'arguments'])
-class ObjectType(Type):
- def __init__(self, name, record):
- Type.__init__(self, name, record)
- self.methods = []
- self.native_methods = []
- self.built_type = None
-
-class StructureMember:
- def __init__(self, name, typ, annotation, optional):
- self.name = name
- self.type = typ
- self.annotation = annotation
- self.length = None
- self.optional = optional
-
-class StructureType(Type):
- def __init__(self, name, record):
- Type.__init__(self, name, record)
- self.extensible = record.get("extensible", False)
- self.members = []
+from common import Name
+import common
+import wire_cmd
############################################################
# PARSE
@@ -118,31 +31,11 @@ def is_native_method(method):
any([arg.type.category == "natively defined" for arg in method.arguments])
def link_object(obj, types):
- def make_method(record):
- arguments = []
- arguments_by_name = {}
- for a in record.get('args', []):
- arg = MethodArgument(Name(a['name']), types[a['type']],
- a.get('annotation', 'value'), a.get('optional', False))
- arguments.append(arg)
- arguments_by_name[arg.name.canonical_case()] = arg
-
- for (arg, a) in zip(arguments, record.get('args', [])):
- if arg.annotation != 'value':
- if not 'length' in a:
- if arg.type.category == 'structure':
- arg.length = "constant"
- arg.constant_length = 1
- else:
- assert(False)
- elif a['length'] == 'strlen':
- arg.length = 'strlen'
- else:
- arg.length = arguments_by_name[a['length']]
-
- return Method(Name(record['name']), types[record.get('returns', 'void')], arguments)
-
- methods = [make_method(m) for m in obj.record.get('methods', [])]
+ def make_method(json_data):
+ arguments = common.linked_record_members(json_data.get('args', []), types)
+ return common.Method(Name(json_data['name']), types[json_data.get('returns', 'void')], arguments)
+
+ methods = [make_method(m) for m in obj.json_data.get('methods', [])]
obj.methods = [method for method in methods if not is_native_method(method)]
obj.native_methods = [method for method in methods if is_native_method(method)]
@@ -155,25 +48,7 @@ def link_object(obj, types):
assert(obj.built_type != None)
def link_structure(struct, types):
- def make_member(m):
- return StructureMember(Name(m['name']), types[m['type']],
- m.get('annotation', 'value'), m.get('optional', False))
-
- members = []
- members_by_name = {}
- for m in struct.record['members']:
- member = make_member(m)
- members.append(member)
- members_by_name[member.name.canonical_case()] = member
- struct.members = members
-
- for (member, m) in zip(members, struct.record['members']):
- # TODO(kainino@chromium.org): More robust pointer/length handling?
- if 'length' in m:
- if m['length'] == 'strlen':
- member.length = 'strlen'
- else:
- member.length = members_by_name[m['length']]
+ struct.members = common.linked_record_members(struct.json_data['members'], types)
# Sort structures so that if struct A has struct B as a member, then B is listed before A
# This is a form of topological sort where we try to keep the order reasonably similar to the
@@ -193,7 +68,7 @@ def topo_sort_structure(structs):
max_dependent_depth = 0
for member in struct.members:
- if member.type.category == 'structure' and member.annotation == 'value':
+ if member.type.category == 'structure':
max_dependent_depth = max(max_dependent_depth, compute_depth(member.type) + 1)
struct.subdag_depth = max_dependent_depth
@@ -213,12 +88,12 @@ def topo_sort_structure(structs):
def parse_json(json):
category_to_parser = {
- 'bitmask': BitmaskType,
- 'enum': EnumType,
- 'native': NativeType,
- 'natively defined': NativelyDefined,
- 'object': ObjectType,
- 'structure': StructureType,
+ 'bitmask': common.BitmaskType,
+ 'enum': common.EnumType,
+ 'native': common.NativeType,
+ 'natively defined': common.NativelyDefined,
+ 'object': common.ObjectType,
+ 'structure': common.StructureType,
}
types = {}
@@ -227,11 +102,11 @@ def parse_json(json):
for name in category_to_parser.keys():
by_category[name] = []
- for (name, record) in json.items():
+ for (name, json_data) in json.items():
if name[0] == '_':
continue
- category = record['category']
- parsed = category_to_parser[category](name, record)
+ category = json_data['category']
+ parsed = category_to_parser[category](name, json_data)
by_category[category].append(parsed)
types[name] = parsed
@@ -246,6 +121,9 @@ def parse_json(json):
by_category['structure'] = topo_sort_structure(by_category['structure'])
+ for struct in by_category['structure']:
+ struct.update_metadata()
+
return {
'types': types,
'by_category': by_category
@@ -363,10 +241,10 @@ def as_cppType(name):
def decorate(name, typ, arg):
if arg.annotation == 'value':
return typ + ' ' + name
- elif arg.annotation == '*':
- return typ + '* ' + name
elif arg.annotation == 'const*':
return typ + ' const * ' + name
+ elif arg.annotation == 'const*const*':
+ return 'const ' + typ + '* const * ' + name
else:
assert(False)
@@ -413,18 +291,18 @@ def cpp_native_methods(types, typ):
methods = typ.methods + typ.native_methods
if typ.is_builder:
- methods.append(Method(Name('set error callback'), types['void'], [
- MethodArgument(Name('callback'), types['builder error callback'], 'value', False),
- MethodArgument(Name('userdata1'), types['callback userdata'], 'value', False),
- MethodArgument(Name('userdata2'), types['callback userdata'], 'value', False),
+ methods.append(common.Method(Name('set error callback'), types['void'], [
+ common.RecordMember(Name('callback'), types['builder error callback'], 'value', False, False),
+ common.RecordMember(Name('userdata1'), types['callback userdata'], 'value', False, False),
+ common.RecordMember(Name('userdata2'), types['callback userdata'], 'value', False, False),
]))
return methods
def c_native_methods(types, typ):
return cpp_native_methods(types, typ) + [
- Method(Name('reference'), types['void'], []),
- Method(Name('release'), types['void'], []),
+ common.Method(Name('reference'), types['void'], []),
+ common.Method(Name('release'), types['void'], []),
]
def js_native_methods(types, typ):
@@ -433,7 +311,7 @@ def js_native_methods(types, typ):
def debug(text):
print(text)
-def get_renders_for_targets(api_params, targets):
+def get_renders_for_targets(api_params, wire_json, targets):
base_params = {
'enumerate': enumerate,
'format': format,
@@ -492,18 +370,27 @@ def get_renders_for_targets(api_params, targets):
renders.append(FileRender('dawn_native/ProcTable.cpp', 'dawn_native/ProcTable.cpp', frontend_params))
if 'dawn_wire' in targets:
+ additional_params = wire_cmd.compute_wire_params(api_params, wire_json)
+
wire_params = [
base_params,
api_params,
c_params,
{
'as_wireType': lambda typ: typ.name.CamelCase() + '*' if typ.category == 'object' else as_cppType(typ.name)
- }
+ },
+ additional_params
]
+ renders.append(FileRender('dawn_wire/TypeTraits.h', 'dawn_wire/TypeTraits_autogen.h', wire_params))
renders.append(FileRender('dawn_wire/WireCmd.h', 'dawn_wire/WireCmd_autogen.h', wire_params))
renders.append(FileRender('dawn_wire/WireCmd.cpp', 'dawn_wire/WireCmd_autogen.cpp', wire_params))
- renders.append(FileRender('dawn_wire/WireClient.cpp', 'dawn_wire/WireClient.cpp', wire_params))
renders.append(FileRender('dawn_wire/WireServer.cpp', 'dawn_wire/WireServer.cpp', wire_params))
+ renders.append(FileRender('dawn_wire/client/ApiObjects.h', 'dawn_wire/client/ApiObjects_autogen.h', wire_params))
+ renders.append(FileRender('dawn_wire/client/ApiProcs.cpp', 'dawn_wire/client/ApiProcs_autogen.cpp', wire_params))
+ renders.append(FileRender('dawn_wire/client/ApiProcs.h', 'dawn_wire/client/ApiProcs_autogen.h', wire_params))
+ renders.append(FileRender('dawn_wire/client/ClientHandlers.cpp', 'dawn_wire/client/ClientHandlers_autogen.cpp', wire_params))
+ renders.append(FileRender('dawn_wire/client/ClientPrototypes.inl', 'dawn_wire/client/ClientPrototypes_autogen.inl', wire_params))
+ renders.append(FileRender('dawn_wire/client/Device.h', 'dawn_wire/client/Device_autogen.h', wire_params))
return renders
@@ -527,6 +414,7 @@ def main():
formatter_class = argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument('json', metavar='DAWN_JSON', nargs=1, type=str, help ='The DAWN JSON definition to use.')
+ parser.add_argument('--wire-json', default=None, type=str, help='The DAWN WIRE JSON definition to use.')
parser.add_argument('-t', '--template-dir', default='templates', type=str, help='Directory with template files.')
parser.add_argument('-T', '--targets', required=True, type=str, help='Comma-separated subset of targets to output. Available targets: ' + ', '.join(allowed_targets))
parser.add_argument(kExtraPythonPath, default=None, type=str, help='Additional python path to set before loading Jinja2')
@@ -542,7 +430,17 @@ def main():
api_params = parse_json(loaded_json)
targets = args.targets.split(',')
- renders = get_renders_for_targets(api_params, targets)
+ dependencies = [
+ os.path.join(os.path.abspath(os.path.dirname(__file__)), "common.py")
+ ]
+
+ loaded_wire_json = None
+ if args.wire_json:
+ with open(args.wire_json) as f:
+ loaded_wire_json = json.loads(f.read())
+ dependencies.append(args.wire_json)
+
+ renders = get_renders_for_targets(api_params, loaded_wire_json, targets)
# The caller wants to assert that the outputs are what it expects.
# Load the file and compare with our renders.
@@ -564,8 +462,9 @@ def main():
if args.output_json_tarball != None:
output_to_json(outputs, args.output_json_tarball)
- dependencies = [args.template_dir + os.path.sep + render.template for render in renders]
+ dependencies += [args.template_dir + os.path.sep + render.template for render in renders]
dependencies.append(args.json[0])
+ dependencies.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "wire_cmd.py"))
output_depfile(args.depfile, args.output_json_tarball, dependencies)
if __name__ == '__main__':
diff --git a/chromium/third_party/dawn/generator/templates/api.h b/chromium/third_party/dawn/generator/templates/api.h
index 0b8a19a3041..d4aedd72067 100644
--- a/chromium/third_party/dawn/generator/templates/api.h
+++ b/chromium/third_party/dawn/generator/templates/api.h
@@ -53,6 +53,8 @@ typedef void (*dawnDeviceErrorCallback)(const char* message, dawnCallbackUserdat
typedef void (*dawnBuilderErrorCallback)(dawnBuilderErrorStatus status, const char* message, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2);
typedef void (*dawnBufferMapReadCallback)(dawnBufferMapAsyncStatus status, const void* data, dawnCallbackUserdata userdata);
typedef void (*dawnBufferMapWriteCallback)(dawnBufferMapAsyncStatus status, void* data, dawnCallbackUserdata userdata);
+typedef void (*dawnFenceOnCompletionCallback)(dawnFenceCompletionStatus status,
+ dawnCallbackUserdata userdata);
#ifdef __cplusplus
extern "C" {
diff --git a/chromium/third_party/dawn/generator/templates/apicpp.h b/chromium/third_party/dawn/generator/templates/apicpp.h
index af142b04c02..133ec5c264c 100644
--- a/chromium/third_party/dawn/generator/templates/apicpp.h
+++ b/chromium/third_party/dawn/generator/templates/apicpp.h
@@ -97,6 +97,15 @@ namespace dawn {
return static_cast<Derived&>(*this);
}
+ ObjectBase(std::nullptr_t) {}
+ Derived& operator=(std::nullptr_t) {
+ if (mHandle != nullptr) {
+ Derived::DawnRelease(mHandle);
+ mHandle = nullptr;
+ }
+ return static_cast<Derived&>(*this);
+ }
+
explicit operator bool() const {
return mHandle != nullptr;
}
@@ -121,9 +130,9 @@ namespace dawn {
{% macro render_cpp_method_declaration(type, method) %}
{% set CppType = as_cppType(type.name) %}
{% if method.return_type.name.concatcase() == "void" and type.is_builder -%}
- {{CppType}} const&
+ DAWN_EXPORT {{CppType}} const&
{%- else -%}
- {{as_cppType(method.return_type.name)}}
+ DAWN_EXPORT {{as_cppType(method.return_type.name)}}
{%- endif -%}
{{" "}}{{method.name.CamelCase()}}(
{%- for arg in method.arguments -%}
@@ -140,7 +149,7 @@ namespace dawn {
{% for type in by_category["object"] %}
{% set CppType = as_cppType(type.name) %}
{% set CType = as_cType(type.name) %}
- class DAWN_EXPORT {{CppType}} : public ObjectBase<{{CppType}}, {{CType}}> {
+ class {{CppType}} : public ObjectBase<{{CppType}}, {{CType}}> {
public:
using ObjectBase::ObjectBase;
using ObjectBase::operator=;
@@ -151,8 +160,8 @@ namespace dawn {
private:
friend ObjectBase<{{CppType}}, {{CType}}>;
- static void DawnReference({{CType}} handle);
- static void DawnRelease({{CType}} handle);
+ static DAWN_EXPORT void DawnReference({{CType}} handle);
+ static DAWN_EXPORT void DawnRelease({{CType}} handle);
};
{% endfor %}
diff --git a/chromium/third_party/dawn/generator/templates/dawn_native/ProcTable.cpp b/chromium/third_party/dawn/generator/templates/dawn_native/ProcTable.cpp
index 21c29269f8a..089159b6def 100644
--- a/chromium/third_party/dawn/generator/templates/dawn_native/ProcTable.cpp
+++ b/chromium/third_party/dawn/generator/templates/dawn_native/ProcTable.cpp
@@ -20,7 +20,7 @@
#include "dawn_native/ValidationUtils_autogen.h"
{% for type in by_category["object"] %}
- {% if not type.is_builder and type.name.canonical_case() not in ["buffer view", "texture view"] %}
+ {% if not type.is_builder and type.name.canonical_case() not in ["texture view"] %}
#include "dawn_native/{{type.name.CamelCase()}}.h"
{% endif %}
{% endfor %}
@@ -159,7 +159,11 @@ namespace dawn_native {
{%- endfor -%}
);
{% if method.return_type.name.canonical_case() != "void" %}
- return reinterpret_cast<{{as_cType(method.return_type.name)}}>(result);
+ {% if method.return_type.category == "object" %}
+ return reinterpret_cast<{{as_cType(method.return_type.name)}}>(result);
+ {% else %}
+ return result;
+ {% endif %}
{% endif %}
}
{% endfor %}
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/TypeTraits.h b/chromium/third_party/dawn/generator/templates/dawn_wire/TypeTraits.h
new file mode 100644
index 00000000000..26a91eeff2e
--- /dev/null
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/TypeTraits.h
@@ -0,0 +1,35 @@
+//* Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_TYPETRAITS_AUTOGEN_H_
+#define DAWNWIRE_TYPETRAITS_AUTOGEN_H_
+
+#include <dawn/dawn.h>
+
+//* This file can be removed when WebGPU error handling is implemented
+namespace dawn_wire {
+ template <typename T>
+ struct IsBuilderType {
+ static constexpr bool value = false;
+ };
+
+ {% for type in by_category["object"] if type.is_builder %}
+ template<>
+ struct IsBuilderType<{{as_cType(type.name)}}> {
+ static constexpr bool value = true;
+ };
+ {% endfor %}
+}
+
+#endif // DAWNWIRE_TYPETRAITS_AUTOGEN_H_
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/WireClient.cpp b/chromium/third_party/dawn/generator/templates/dawn_wire/WireClient.cpp
deleted file mode 100644
index 117cfad5dcc..00000000000
--- a/chromium/third_party/dawn/generator/templates/dawn_wire/WireClient.cpp
+++ /dev/null
@@ -1,691 +0,0 @@
-//* Copyright 2017 The Dawn 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_wire/Wire.h"
-#include "dawn_wire/WireCmd.h"
-
-#include "common/Assert.h"
-
-#include <cstring>
-#include <cstdlib>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace dawn_wire {
-
- //* Client side implementation of the API, will serialize everything to memory to send to the server side.
- namespace client {
-
- class Device;
-
- struct BuilderCallbackData {
- bool Call(dawnBuilderErrorStatus status, const char* message) {
- if (canCall && callback != nullptr) {
- canCall = true;
- callback(status, message, userdata1, userdata2);
- return true;
- }
-
- return false;
- }
-
- //* For help with development, prints all builder errors by default.
- dawnBuilderErrorCallback callback = nullptr;
- dawnCallbackUserdata userdata1 = 0;
- dawnCallbackUserdata userdata2 = 0;
- bool canCall = true;
- };
-
- //* All non-Device objects of the client side have:
- //* - A pointer to the device to get where to serialize commands
- //* - The external reference count
- //* - An ID that is used to refer to this object when talking with the server side
- struct ObjectBase {
- ObjectBase(Device* device, uint32_t refcount, uint32_t id)
- :device(device), refcount(refcount), id(id) {
- }
-
- Device* device;
- uint32_t refcount;
- uint32_t id;
-
- BuilderCallbackData builderCallback;
- };
-
- {% set special_objects = [
- "device",
- "buffer",
- ] %}
- {% for type in by_category["object"] if not type.name.canonical_case() in special_objects %}
- struct {{type.name.CamelCase()}} : ObjectBase {
- using ObjectBase::ObjectBase;
- };
- {% endfor %}
-
- struct Buffer : ObjectBase {
- using ObjectBase::ObjectBase;
-
- ~Buffer() {
- //* Callbacks need to be fired in all cases, as they can handle freeing resources
- //* so we call them with "Unknown" status.
- ClearMapRequests(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN);
-
- if (mappedData) {
- free(mappedData);
- }
- }
-
- void ClearMapRequests(dawnBufferMapAsyncStatus status) {
- for (auto& it : requests) {
- if (it.second.isWrite) {
- it.second.writeCallback(status, nullptr, it.second.userdata);
- } else {
- it.second.readCallback(status, nullptr, it.second.userdata);
- }
- }
- requests.clear();
- }
-
- //* We want to defer all the validation to the server, which means we could have multiple
- //* map request in flight at a single time and need to track them separately.
- //* On well-behaved applications, only one request should exist at a single time.
- struct MapRequestData {
- dawnBufferMapReadCallback readCallback = nullptr;
- dawnBufferMapWriteCallback writeCallback = nullptr;
- dawnCallbackUserdata userdata = 0;
- uint32_t size = 0;
- bool isWrite = false;
- };
- std::map<uint32_t, MapRequestData> requests;
- uint32_t requestSerial = 0;
-
- //* Only one mapped pointer can be active at a time because Unmap clears all the in-flight requests.
- void* mappedData = nullptr;
- size_t mappedDataSize = 0;
- bool isWriteMapped = false;
- };
-
- //* TODO(cwallez@chromium.org): Do something with objects before they are destroyed ?
- //* - Call still uncalled builder callbacks
- template<typename T>
- class ObjectAllocator {
- public:
- struct ObjectAndSerial {
- ObjectAndSerial(std::unique_ptr<T> object, uint32_t serial)
- : object(std::move(object)), serial(serial) {
- }
- std::unique_ptr<T> object;
- uint32_t serial;
- };
-
- ObjectAllocator(Device* device) : mDevice(device) {
- // ID 0 is nullptr
- mObjects.emplace_back(nullptr, 0);
- }
-
- ObjectAndSerial* New() {
- uint32_t id = GetNewId();
- T* result = new T(mDevice, 1, id);
- auto object = std::unique_ptr<T>(result);
-
- if (id >= mObjects.size()) {
- ASSERT(id == mObjects.size());
- mObjects.emplace_back(std::move(object), 0);
- } else {
- ASSERT(mObjects[id].object == nullptr);
- //* TODO(cwallez@chromium.org): investigate if overflows could cause bad things to happen
- mObjects[id].serial++;
- mObjects[id].object = std::move(object);
- }
-
- return &mObjects[id];
- }
- void Free(T* obj) {
- FreeId(obj->id);
- mObjects[obj->id].object = nullptr;
- }
-
- T* GetObject(uint32_t id) {
- if (id >= mObjects.size()) {
- return nullptr;
- }
- return mObjects[id].object.get();
- }
-
- uint32_t GetSerial(uint32_t id) {
- if (id >= mObjects.size()) {
- return 0;
- }
- return mObjects[id].serial;
- }
-
- private:
- uint32_t GetNewId() {
- if (mFreeIds.empty()) {
- return mCurrentId ++;
- }
- uint32_t id = mFreeIds.back();
- mFreeIds.pop_back();
- return id;
- }
- void FreeId(uint32_t id) {
- mFreeIds.push_back(id);
- }
-
- // 0 is an ID reserved to represent nullptr
- uint32_t mCurrentId = 1;
- std::vector<uint32_t> mFreeIds;
- std::vector<ObjectAndSerial> mObjects;
- Device* mDevice;
- };
-
- //* The client wire uses the global Dawn device to store its global data such as the serializer
- //* and the object id allocators.
- class Device : public ObjectBase, public ObjectIdProvider {
- public:
- Device(CommandSerializer* serializer)
- : ObjectBase(this, 1, 1),
- {% for type in by_category["object"] if not type.name.canonical_case() == "device" %}
- {{type.name.camelCase()}}(this),
- {% endfor %}
- mSerializer(serializer) {
- }
-
- void* GetCmdSpace(size_t size) {
- return mSerializer->GetCmdSpace(size);
- }
-
- {% for type in by_category["object"] if not type.name.canonical_case() == "device" %}
- ObjectAllocator<{{type.name.CamelCase()}}> {{type.name.camelCase()}};
- {% endfor %}
-
- // Implementation of the ObjectIdProvider interface
- {% for type in by_category["object"] %}
- ObjectId GetId({{as_cType(type.name)}} object) const final {
- return reinterpret_cast<{{as_wireType(type)}}>(object)->id;
- }
- ObjectId GetOptionalId({{as_cType(type.name)}} object) const final {
- if (object == nullptr) {
- return 0;
- }
- return GetId(object);
- }
- {% endfor %}
-
- void HandleError(const char* message) {
- if (errorCallback) {
- errorCallback(message, errorUserdata);
- }
- }
-
- dawnDeviceErrorCallback errorCallback = nullptr;
- dawnCallbackUserdata errorUserdata;
-
- private:
- CommandSerializer* mSerializer = nullptr;
- };
-
- //* Implementation of the client API functions.
- {% for type in by_category["object"] %}
- {% set Type = type.name.CamelCase() %}
- {% set cType = as_cType(type.name) %}
-
- {% for method in type.methods %}
- {% set Suffix = as_MethodSuffix(type.name, method.name) %}
-
- {{as_cType(method.return_type.name)}} Client{{Suffix}}(
- {{-cType}} cSelf
- {%- for arg in method.arguments -%}
- , {{as_annotated_cType(arg)}}
- {%- endfor -%}
- ) {
- auto self = reinterpret_cast<{{as_wireType(type)}}>(cSelf);
- Device* device = self->device;
- {{Suffix}}Cmd cmd;
-
- //* Create the structure going on the wire on the stack and fill it with the value
- //* arguments so it can compute its size.
- cmd.self = cSelf;
-
- //* For object creation, store the object ID the client will use for the result.
- {% if method.return_type.category == "object" %}
- auto* allocation = self->device->{{method.return_type.name.camelCase()}}.New();
-
- {% if type.is_builder %}
- //* We are in GetResult, so the callback that should be called is the
- //* currently set one. Copy it over to the created object and prevent the
- //* builder from calling the callback on destruction.
- allocation->object->builderCallback = self->builderCallback;
- self->builderCallback.canCall = false;
- {% endif %}
-
- cmd.resultId = allocation->object->id;
- cmd.resultSerial = allocation->serial;
- {% endif %}
-
- {% for arg in method.arguments %}
- cmd.{{as_varName(arg.name)}} = {{as_varName(arg.name)}};
- {% endfor %}
-
- //* Allocate space to send the command and copy the value args over.
- size_t requiredSize = cmd.GetRequiredSize();
- char* allocatedBuffer = static_cast<char*>(device->GetCmdSpace(requiredSize));
- cmd.Serialize(allocatedBuffer, *device);
-
- {% if method.return_type.category == "object" %}
- return reinterpret_cast<{{as_cType(method.return_type.name)}}>(allocation->object.get());
- {% endif %}
- }
- {% endfor %}
-
- {% if type.is_builder %}
- void Client{{as_MethodSuffix(type.name, Name("set error callback"))}}({{cType}} cSelf,
- dawnBuilderErrorCallback callback,
- dawnCallbackUserdata userdata1,
- dawnCallbackUserdata userdata2) {
- {{Type}}* self = reinterpret_cast<{{Type}}*>(cSelf);
- self->builderCallback.callback = callback;
- self->builderCallback.userdata1 = userdata1;
- self->builderCallback.userdata2 = userdata2;
- }
- {% endif %}
-
- {% if not type.name.canonical_case() == "device" %}
- //* When an object's refcount reaches 0, notify the server side of it and delete it.
- void Client{{as_MethodSuffix(type.name, Name("release"))}}({{cType}} cObj) {
- {{Type}}* obj = reinterpret_cast<{{Type}}*>(cObj);
- obj->refcount --;
-
- if (obj->refcount > 0) {
- return;
- }
-
- obj->builderCallback.Call(DAWN_BUILDER_ERROR_STATUS_UNKNOWN, "Unknown");
-
- {{as_MethodSuffix(type.name, Name("destroy"))}}Cmd cmd;
- cmd.objectId = obj->id;
-
- auto allocCmd = static_cast<decltype(cmd)*>(obj->device->GetCmdSpace(sizeof(cmd)));
- *allocCmd = cmd;
-
- obj->device->{{type.name.camelCase()}}.Free(obj);
- }
-
- void Client{{as_MethodSuffix(type.name, Name("reference"))}}({{cType}} cObj) {
- {{Type}}* obj = reinterpret_cast<{{Type}}*>(cObj);
- obj->refcount ++;
- }
- {% endif %}
- {% endfor %}
-
- void ClientBufferMapReadAsync(dawnBuffer cBuffer, uint32_t start, uint32_t size, dawnBufferMapReadCallback callback, dawnCallbackUserdata userdata) {
- Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
-
- uint32_t serial = buffer->requestSerial++;
- ASSERT(buffer->requests.find(serial) == buffer->requests.end());
-
- Buffer::MapRequestData request;
- request.readCallback = callback;
- request.userdata = userdata;
- request.size = size;
- request.isWrite = false;
- buffer->requests[serial] = request;
-
- BufferMapAsyncCmd cmd;
- cmd.bufferId = buffer->id;
- cmd.requestSerial = serial;
- cmd.start = start;
- cmd.size = size;
- cmd.isWrite = false;
-
- auto allocCmd = static_cast<decltype(cmd)*>(buffer->device->GetCmdSpace(sizeof(cmd)));
- *allocCmd = cmd;
- }
-
- void ClientBufferMapWriteAsync(dawnBuffer cBuffer, uint32_t start, uint32_t size, dawnBufferMapWriteCallback callback, dawnCallbackUserdata userdata) {
- Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
-
- uint32_t serial = buffer->requestSerial++;
- ASSERT(buffer->requests.find(serial) == buffer->requests.end());
-
- Buffer::MapRequestData request;
- request.writeCallback = callback;
- request.userdata = userdata;
- request.size = size;
- request.isWrite = true;
- buffer->requests[serial] = request;
-
- BufferMapAsyncCmd cmd;
- cmd.bufferId = buffer->id;
- cmd.requestSerial = serial;
- cmd.start = start;
- cmd.size = size;
- cmd.isWrite = true;
-
- auto allocCmd = static_cast<decltype(cmd)*>(buffer->device->GetCmdSpace(sizeof(cmd)));
- *allocCmd = cmd;
- }
-
- void ProxyClientBufferUnmap(dawnBuffer cBuffer) {
- Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
-
- //* Invalidate the local pointer, and cancel all other in-flight requests that would turn into
- //* errors anyway (you can't double map). This prevents race when the following happens, where
- //* the application code would have unmapped a buffer but still receive a callback:
- //* - Client -> Server: MapRequest1, Unmap, MapRequest2
- //* - Server -> Client: Result of MapRequest1
- //* - Unmap locally on the client
- //* - Server -> Client: Result of MapRequest2
- if (buffer->mappedData) {
-
- // If the buffer was mapped for writing, send the update to the data to the server
- if (buffer->isWriteMapped) {
- BufferUpdateMappedDataCmd cmd;
- cmd.bufferId = buffer->id;
- cmd.dataLength = static_cast<uint32_t>(buffer->mappedDataSize);
-
- auto allocCmd = static_cast<decltype(cmd)*>(buffer->device->GetCmdSpace(sizeof(cmd)));
- *allocCmd = cmd;
-
- void* dataAlloc = buffer->device->GetCmdSpace(cmd.dataLength);
- memcpy(dataAlloc, buffer->mappedData, cmd.dataLength);
- }
-
- free(buffer->mappedData);
- buffer->mappedData = nullptr;
- }
- buffer->ClearMapRequests(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN);
-
- ClientBufferUnmap(cBuffer);
- }
-
- void ClientDeviceReference(dawnDevice) {
- }
-
- void ClientDeviceRelease(dawnDevice) {
- }
-
- void ClientDeviceSetErrorCallback(dawnDevice cSelf, dawnDeviceErrorCallback callback, dawnCallbackUserdata userdata) {
- Device* self = reinterpret_cast<Device*>(cSelf);
- self->errorCallback = callback;
- self->errorUserdata = userdata;
- }
-
- // Some commands don't have a custom wire format, but need to be handled manually to update
- // some client-side state tracking. For these we have two functions:
- // - An autogenerated Client{{suffix}} method that sends the command on the wire
- // - A manual ProxyClient{{suffix}} method that will be inserted in the proctable instead of
- // the autogenerated one, and that will have to call Client{{suffix}}
- {% set proxied_commands = ["BufferUnmap"] %}
-
- dawnProcTable GetProcs() {
- dawnProcTable table;
- {% for type in by_category["object"] %}
- {% for method in native_methods(type) %}
- {% set suffix = as_MethodSuffix(type.name, method.name) %}
- {% if suffix in proxied_commands %}
- table.{{as_varName(type.name, method.name)}} = ProxyClient{{suffix}};
- {% else %}
- table.{{as_varName(type.name, method.name)}} = Client{{suffix}};
- {% endif %}
- {% endfor %}
- {% endfor %}
- return table;
- }
-
- class Client : public CommandHandler {
- public:
- Client(Device* device) : mDevice(device) {
- }
-
- const char* HandleCommands(const char* commands, size_t size) override {
- while (size >= sizeof(ReturnWireCmd)) {
- ReturnWireCmd cmdId = *reinterpret_cast<const ReturnWireCmd*>(commands);
-
- bool success = false;
- switch (cmdId) {
- case ReturnWireCmd::DeviceErrorCallback:
- success = HandleDeviceErrorCallbackCmd(&commands, &size);
- break;
- {% for type in by_category["object"] if type.is_builder %}
- case ReturnWireCmd::{{type.name.CamelCase()}}ErrorCallback:
- success = Handle{{type.name.CamelCase()}}ErrorCallbackCmd(&commands, &size);
- break;
- {% endfor %}
- case ReturnWireCmd::BufferMapReadAsyncCallback:
- success = HandleBufferMapReadAsyncCallback(&commands, &size);
- break;
- case ReturnWireCmd::BufferMapWriteAsyncCallback:
- success = HandleBufferMapWriteAsyncCallback(&commands, &size);
- break;
- default:
- success = false;
- }
-
- if (!success) {
- return nullptr;
- }
- }
-
- if (size != 0) {
- return nullptr;
- }
-
- return commands;
- }
-
- private:
- Device* mDevice = nullptr;
-
- //* Helper function for the getting of the command data in command handlers.
- //* Checks there is enough data left, updates the buffer / size and returns
- //* the command (or nullptr for an error).
- template <typename T>
- static const T* GetData(const char** buffer, size_t* size, size_t count) {
- // TODO(cwallez@chromium.org): Check for overflow
- size_t totalSize = count * sizeof(T);
- if (*size < totalSize) {
- return nullptr;
- }
-
- const T* data = reinterpret_cast<const T*>(*buffer);
-
- *buffer += totalSize;
- *size -= totalSize;
-
- return data;
- }
- template <typename T>
- static const T* GetCommand(const char** commands, size_t* size) {
- return GetData<T>(commands, size, 1);
- }
-
- bool HandleDeviceErrorCallbackCmd(const char** commands, size_t* size) {
- const auto* cmd = GetCommand<ReturnDeviceErrorCallbackCmd>(commands, size);
- if (cmd == nullptr) {
- return false;
- }
-
- const char* message = GetData<char>(commands, size, cmd->messageStrlen + 1);
- if (message == nullptr || message[cmd->messageStrlen] != '\0') {
- return false;
- }
-
- mDevice->HandleError(message);
-
- return true;
- }
-
- {% for type in by_category["object"] if type.is_builder %}
- {% set Type = type.name.CamelCase() %}
- bool Handle{{Type}}ErrorCallbackCmd(const char** commands, size_t* size) {
- const auto* cmd = GetCommand<Return{{Type}}ErrorCallbackCmd>(commands, size);
- if (cmd == nullptr) {
- return false;
- }
-
- const char* message = GetData<char>(commands, size, cmd->messageStrlen + 1);
- if (message == nullptr || message[cmd->messageStrlen] != '\0') {
- return false;
- }
-
- auto* builtObject = mDevice->{{type.built_type.name.camelCase()}}.GetObject(cmd->builtObjectId);
- uint32_t objectSerial = mDevice->{{type.built_type.name.camelCase()}}.GetSerial(cmd->builtObjectId);
-
- //* The object might have been deleted or a new object created with the same ID.
- if (builtObject == nullptr || objectSerial != cmd->builtObjectSerial) {
- return true;
- }
-
- bool called = builtObject->builderCallback.Call(static_cast<dawnBuilderErrorStatus>(cmd->status), message);
-
- // Unhandled builder errors are forwarded to the device
- if (!called && cmd->status != DAWN_BUILDER_ERROR_STATUS_SUCCESS && cmd->status != DAWN_BUILDER_ERROR_STATUS_UNKNOWN) {
- mDevice->HandleError(("Unhandled builder error: " + std::string(message)).c_str());
- }
-
- return true;
- }
- {% endfor %}
-
- bool HandleBufferMapReadAsyncCallback(const char** commands, size_t* size) {
- const auto* cmd = GetCommand<ReturnBufferMapReadAsyncCallbackCmd>(commands, size);
- if (cmd == nullptr) {
- return false;
- }
-
- //* Unconditionnally get the data from the buffer so that the correct amount of data is
- //* consumed from the buffer, even when we ignore the command and early out.
- const char* requestData = nullptr;
- if (cmd->status == DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS) {
- requestData = GetData<char>(commands, size, cmd->dataLength);
- if (requestData == nullptr) {
- return false;
- }
- }
-
- auto* buffer = mDevice->buffer.GetObject(cmd->bufferId);
- uint32_t bufferSerial = mDevice->buffer.GetSerial(cmd->bufferId);
-
- //* The buffer might have been deleted or recreated so this isn't an error.
- if (buffer == nullptr || bufferSerial != cmd->bufferSerial) {
- return true;
- }
-
- //* The requests can have been deleted via an Unmap so this isn't an error.
- auto requestIt = buffer->requests.find(cmd->requestSerial);
- if (requestIt == buffer->requests.end()) {
- return true;
- }
-
- //* It is an error for the server to call the read callback when we asked for a map write
- if (requestIt->second.isWrite) {
- return false;
- }
-
- auto request = requestIt->second;
- //* Delete the request before calling the callback otherwise the callback could be fired a
- //* second time. If, for example, buffer.Unmap() is called inside the callback.
- buffer->requests.erase(requestIt);
-
- //* On success, we copy the data locally because the IPC buffer isn't valid outside of this function
- if (cmd->status == DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS) {
- //* The server didn't send the right amount of data, this is an error and could cause
- //* the application to crash if we did call the callback.
- if (request.size != cmd->dataLength) {
- return false;
- }
-
- ASSERT(requestData != nullptr);
-
- if (buffer->mappedData != nullptr) {
- return false;
- }
-
- buffer->isWriteMapped = false;
- buffer->mappedDataSize = request.size;
- buffer->mappedData = malloc(request.size);
- memcpy(buffer->mappedData, requestData, request.size);
-
- request.readCallback(static_cast<dawnBufferMapAsyncStatus>(cmd->status), buffer->mappedData, request.userdata);
- } else {
- request.readCallback(static_cast<dawnBufferMapAsyncStatus>(cmd->status), nullptr, request.userdata);
- }
-
- return true;
- }
-
- bool HandleBufferMapWriteAsyncCallback(const char** commands, size_t* size) {
- const auto* cmd = GetCommand<ReturnBufferMapWriteAsyncCallbackCmd>(commands, size);
- if (cmd == nullptr) {
- return false;
- }
-
- auto* buffer = mDevice->buffer.GetObject(cmd->bufferId);
- uint32_t bufferSerial = mDevice->buffer.GetSerial(cmd->bufferId);
-
- //* The buffer might have been deleted or recreated so this isn't an error.
- if (buffer == nullptr || bufferSerial != cmd->bufferSerial) {
- return true;
- }
-
- //* The requests can have been deleted via an Unmap so this isn't an error.
- auto requestIt = buffer->requests.find(cmd->requestSerial);
- if (requestIt == buffer->requests.end()) {
- return true;
- }
-
- //* It is an error for the server to call the write callback when we asked for a map read
- if (!requestIt->second.isWrite) {
- return false;
- }
-
- auto request = requestIt->second;
- //* Delete the request before calling the callback otherwise the callback could be fired a second time. If, for example, buffer.Unmap() is called inside the callback.
- buffer->requests.erase(requestIt);
-
- //* On success, we copy the data locally because the IPC buffer isn't valid outside of this function
- if (cmd->status == DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS) {
- if (buffer->mappedData != nullptr) {
- return false;
- }
-
- buffer->isWriteMapped = true;
- buffer->mappedDataSize = request.size;
- buffer->mappedData = malloc(request.size);
- memset(buffer->mappedData, 0, request.size);
-
- request.writeCallback(static_cast<dawnBufferMapAsyncStatus>(cmd->status), buffer->mappedData, request.userdata);
- } else {
- request.writeCallback(static_cast<dawnBufferMapAsyncStatus>(cmd->status), nullptr, request.userdata);
- }
-
- return true;
- }
- };
-
- }
-
- CommandHandler* NewClientDevice(dawnProcTable* procs, dawnDevice* device, CommandSerializer* serializer) {
- auto clientDevice = new client::Device(serializer);
-
- *device = reinterpret_cast<dawnDeviceImpl*>(clientDevice);
- *procs = client::GetProcs();
-
- return new client::Client(clientDevice);
- }
-
-} // namespace dawn_wire
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.cpp b/chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.cpp
index ceb828f123d..75ac7f4a22a 100644
--- a/chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.cpp
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.cpp
@@ -12,11 +12,12 @@
//* See the License for the specific language governing permissions and
//* limitations under the License.
-#include "dawn_wire/WireCmd.h"
+#include "dawn_wire/WireCmd_autogen.h"
#include "common/Assert.h"
#include <cstring>
+#include <limits>
//* Helper macros so that the main [de]serialization functions can be written in a generic manner.
@@ -48,10 +49,15 @@
//* Outputs the serialization code to put `in` in `out`
{% macro serialize_member(member, in, out) %}
{%- if member.type.category == "object" -%}
- {% set Optional = "Optional" if member.optional else "" %}
+ {%- set Optional = "Optional" if member.optional else "" -%}
{{out}} = provider.Get{{Optional}}Id({{in}});
{% elif member.type.category == "structure"%}
- {{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer, provider);
+ {%- set Provider = ", provider" if member.type.has_dawn_object else "" -%}
+ {% if member.annotation == "const*const*" %}
+ {{as_cType(member.type.name)}}Serialize(*{{in}}, &{{out}}, buffer{{Provider}});
+ {% else %}
+ {{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}});
+ {% endif %}
{%- else -%}
{{out}} = {{in}};
{%- endif -%}
@@ -60,42 +66,34 @@
//* Outputs the deserialization code to put `in` in `out`
{% macro deserialize_member(member, in, out) %}
{%- if member.type.category == "object" -%}
- {% set Optional = "Optional" if member.optional else "" %}
+ {%- set Optional = "Optional" if member.optional else "" -%}
DESERIALIZE_TRY(resolver.Get{{Optional}}FromId({{in}}, &{{out}}));
- {% elif member.type.category == "structure"%}
- DESERIALIZE_TRY({{as_cType(member.type.name)}}Deserialize(&{{out}}, &{{in}}, buffer, size, allocator, resolver));
+ {%- elif member.type.category == "structure" -%}
+ DESERIALIZE_TRY({{as_cType(member.type.name)}}Deserialize(&{{out}}, &{{in}}, buffer, size, allocator
+ {%- if member.type.has_dawn_object -%}
+ , resolver
+ {%- endif -%}
+ ));
{%- else -%}
{{out}} = {{in}};
{%- endif -%}
{% endmacro %}
//* The main [de]serialization macro
-
//* Methods are very similar to structures that have one member corresponding to each arguments.
//* This macro takes advantage of the similarity to output [de]serialization code for a record
//* that is either a structure or a method, with some special cases for each.
-{% macro write_serialization_methods(name, members, as_method=None, as_struct=None, is_return_command=False) %}
+{% macro write_record_serialization_helpers(record, name, members, is_cmd=False, is_method=False, is_return_command=False) %}
{% set Return = "Return" if is_return_command else "" %}
- {% set is_method = as_method != None %}
- {% set is_struct = as_struct != None %}
+ {% set Cmd = "Cmd" if is_cmd else "" %}
//* Structure for the wire format of each of the records. Members that are values
//* are embedded directly in the structure. Other members are assumed to be in the
//* memory directly following the structure in the buffer.
- struct {{name}}Transfer {
- {% if is_method %}
+ struct {{Return}}{{name}}Transfer {
+ {% if is_cmd %}
//* Start the transfer structure with the command ID, so that casting to WireCmd gives the ID.
{{Return}}WireCmd commandId;
-
- //* Methods always have an implicit "self" argument.
- ObjectId self;
-
- //* Methods that return objects need to declare to the server which ID will be used for the
- //* return value.
- {% if as_method.return_type.category == "object" %}
- ObjectId resultId;
- ObjectSerial resultSerial;
- {% endif %}
{% endif %}
//* Value types are directly in the command, objects being replaced with their IDs.
@@ -110,7 +108,7 @@
};
//* Returns the required transfer size for `record` in addition to the transfer structure.
- size_t {{name}}GetExtraRequiredSize(const {{name}}& record) {
+ DAWN_DECLARE_UNUSED size_t {{Return}}{{name}}GetExtraRequiredSize(const {{Return}}{{name}}{{Cmd}}& record) {
DAWN_UNUSED(record);
size_t result = 0;
@@ -129,7 +127,11 @@
//* Structures might contain more pointers so we need to add their extra size as well.
{% if member.type.category == "structure" %}
for (size_t i = 0; i < memberLength; ++i) {
- result += {{as_cType(member.type.name)}}GetExtraRequiredSize(record.{{as_varName(member.name)}}[i]);
+ {% if member.annotation == "const*const*" %}
+ result += {{as_cType(member.type.name)}}GetExtraRequiredSize(*record.{{as_varName(member.name)}}[i]);
+ {% else %}
+ result += {{as_cType(member.type.name)}}GetExtraRequiredSize(record.{{as_varName(member.name)}}[i]);
+ {% endif %}
}
{% endif %}
}
@@ -139,24 +141,21 @@
}
// GetExtraRequiredSize isn't used for structures that are value members of other structures
// because we assume they cannot contain pointers themselves.
- DAWN_UNUSED_FUNC({{name}}GetExtraRequiredSize);
+ DAWN_UNUSED_FUNC({{Return}}{{name}}GetExtraRequiredSize);
//* Serializes `record` into `transfer`, using `buffer` to get more space for pointed-to data
//* and `provider` to serialize objects.
- void {{name}}Serialize(const {{name}}& record, {{name}}Transfer* transfer,
- char* buffer, const ObjectIdProvider& provider) {
- DAWN_UNUSED(provider);
+ void {{Return}}{{name}}Serialize(const {{Return}}{{name}}{{Cmd}}& record, {{Return}}{{name}}Transfer* transfer,
+ char** buffer
+ {%- if record.has_dawn_object -%}
+ , const ObjectIdProvider& provider
+ {%- endif -%}
+ ) {
DAWN_UNUSED(buffer);
//* Handle special transfer members of methods.
- {% if is_method %}
- {% if as_method.return_type.category == "object" %}
- transfer->resultId = record.resultId;
- transfer->resultSerial = record.resultSerial;
- {% endif %}
-
+ {% if is_cmd %}
transfer->commandId = {{Return}}WireCmd::{{name}};
- transfer->self = provider.GetId(record.self);
{% endif %}
//* Value types are directly in the transfer record, objects being replaced with their IDs.
@@ -170,8 +169,8 @@
{% set memberName = as_varName(member.name) %}
transfer->{{memberName}}Strlen = std::strlen(record.{{memberName}});
- memcpy(buffer, record.{{memberName}}, transfer->{{memberName}}Strlen);
- buffer += transfer->{{memberName}}Strlen;
+ memcpy(*buffer, record.{{memberName}}, transfer->{{memberName}}Strlen);
+ *buffer += transfer->{{memberName}}Strlen;
{% endfor %}
//* Allocate space and write the non-value arguments in it.
@@ -179,9 +178,9 @@
{% set memberName = as_varName(member.name) %}
{
size_t memberLength = {{member_length(member, "record.")}};
- auto memberBuffer = reinterpret_cast<{{member_transfer_type(member)}}*>(buffer);
+ auto memberBuffer = reinterpret_cast<{{member_transfer_type(member)}}*>(*buffer);
- buffer += memberLength * {{member_transfer_sizeof(member)}};
+ *buffer += memberLength * {{member_transfer_sizeof(member)}};
for (size_t i = 0; i < memberLength; ++i) {
{{serialize_member(member, "record." + memberName + "[i]", "memberBuffer[i]" )}}
}
@@ -192,30 +191,56 @@
//* Deserializes `transfer` into `record` getting more serialized data from `buffer` and `size`
//* if needed, using `allocator` to store pointed-to values and `resolver` to translate object
//* Ids to actual objects.
- DeserializeResult {{name}}Deserialize({{name}}* record, const {{name}}Transfer* transfer,
- const char** buffer, size_t* size, DeserializeAllocator* allocator, const ObjectIdResolver& resolver) {
+ DeserializeResult {{Return}}{{name}}Deserialize({{Return}}{{name}}{{Cmd}}* record, const {{Return}}{{name}}Transfer* transfer,
+ const char** buffer, size_t* size, DeserializeAllocator* allocator
+ {%- if record.has_dawn_object -%}
+ , const ObjectIdResolver& resolver
+ {%- endif -%}
+ ) {
DAWN_UNUSED(allocator);
- DAWN_UNUSED(resolver);
DAWN_UNUSED(buffer);
DAWN_UNUSED(size);
- //* Handle special transfer members for methods
- {% if is_method %}
- {% if as_method.return_type.category == "object" %}
- record->resultId = transfer->resultId;
- record->resultSerial = transfer->resultSerial;
- {% endif %}
-
+ {% if is_cmd %}
ASSERT(transfer->commandId == {{Return}}WireCmd::{{name}});
+ {% endif %}
+ //* First assign result ObjectHandles:
+ //* Deserialize guarantees they are filled even if there is an ID for an error object
+ //* for the Maybe monad mechanism.
+ //* TODO(enga): This won't need to be done first once we have "WebGPU error handling".
+ {% set return_handles = members
+ |selectattr("is_return_value")
+ |selectattr("annotation", "equalto", "value")
+ |selectattr("type.dict_name", "equalto", "ObjectHandle")
+ |list %}
+
+ //* Strip return_handles so we don't deserialize it again
+ {% set members = members|reject("in", return_handles)|list %}
+
+ {% for member in return_handles %}
+ {% set memberName = as_varName(member.name) %}
+ {{deserialize_member(member, "transfer->" + memberName, "record->" + memberName)}}
+ {% endfor %}
+
+ //* Handle special transfer members for methods
+ {% if is_method %}
+ //* First assign selfId:
+ //* Deserialize guarantees they are filled even if there is an ID for an error object
+ //* for the Maybe monad mechanism.
+ //* TODO(enga): This won't need to be done first once we have "WebGPU error handling".
+ //* We can also remove is_method
record->selfId = transfer->self;
//* This conversion is done after the copying of result* and selfId: Deserialize
//* guarantees they are filled even if there is an ID for an error object for the
//* Maybe monad mechanism.
DESERIALIZE_TRY(resolver.GetFromId(record->selfId, &record->self));
+ //* Strip self so we don't deserialize it again
+ {% set members = members|rejectattr("name.chunks", "equalto", ["self"])|list %}
+
//* The object resolver returns a success even if the object is null because the
- //* frontend is reponsible to validate that (null objects sometimes have special
+ //* frontend is responsible to validate that (null objects sometimes have special
//* meanings). However it is never valid to call a method on a null object so we
//* can error out in that case.
if (record->self == nullptr) {
@@ -223,7 +248,7 @@
}
{% endif %}
- {% if is_struct and as_struct.extensible %}
+ {% if record.extensible %}
record->nextInChain = nullptr;
{% endif %}
@@ -259,7 +284,16 @@
{{as_cType(member.type.name)}}* copiedMembers = nullptr;
DESERIALIZE_TRY(GetSpace(allocator, memberLength, &copiedMembers));
- record->{{memberName}} = copiedMembers;
+ {% if member.annotation == "const*const*" %}
+ {{as_cType(member.type.name)}}** pointerArray = nullptr;
+ DESERIALIZE_TRY(GetSpace(allocator, memberLength, &pointerArray));
+ for (size_t i = 0; i < memberLength; ++i) {
+ pointerArray[i] = &copiedMembers[i];
+ }
+ record->{{memberName}} = pointerArray;
+ {% else %}
+ record->{{memberName}} = copiedMembers;
+ {% endif %}
for (size_t i = 0; i < memberLength; ++i) {
{{deserialize_member(member, "memberBuffer[i]", "copiedMembers[i]")}}
@@ -271,6 +305,47 @@
}
{% endmacro %}
+{% macro write_command_serialization_methods(command, is_return) %}
+ {% set Return = "Return" if is_return else "" %}
+ {% set Name = Return + command.name.CamelCase() %}
+ {% set Cmd = Name + "Cmd" %}
+
+ size_t {{Cmd}}::GetRequiredSize() const {
+ size_t size = sizeof({{Name}}Transfer) + {{Name}}GetExtraRequiredSize(*this);
+ return size;
+ }
+
+ void {{Cmd}}::Serialize(char* buffer
+ {%- if command.has_dawn_object -%}
+ , const ObjectIdProvider& objectIdProvider
+ {%- endif -%}
+ ) const {
+ auto transfer = reinterpret_cast<{{Name}}Transfer*>(buffer);
+ buffer += sizeof({{Name}}Transfer);
+
+ {{Name}}Serialize(*this, transfer, &buffer
+ {%- if command.has_dawn_object -%}
+ , objectIdProvider
+ {%- endif -%}
+ );
+ }
+
+ DeserializeResult {{Cmd}}::Deserialize(const char** buffer, size_t* size, DeserializeAllocator* allocator
+ {%- if command.has_dawn_object -%}
+ , const ObjectIdResolver& resolver
+ {%- endif -%}
+ ) {
+ const {{Name}}Transfer* transfer = nullptr;
+ DESERIALIZE_TRY(GetPtrFromBuffer(buffer, size, 1, &transfer));
+
+ return {{Name}}Deserialize(this, transfer, buffer, size, allocator
+ {%- if command.has_dawn_object -%}
+ , resolver
+ {%- endif -%}
+ );
+ }
+{% endmacro %}
+
namespace dawn_wire {
// Macro to simplify error handling, similar to DAWN_TRY but for DeserializeResult.
@@ -288,7 +363,11 @@ namespace dawn_wire {
// Returns FatalError if not enough memory was available
template <typename T>
DeserializeResult GetPtrFromBuffer(const char** buffer, size_t* size, size_t count, const T** data) {
- // TODO(cwallez@chromium.org): For robustness we would need to handle overflows here.
+ constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T);
+ if (count > kMaxCountWithoutOverflows) {
+ return DeserializeResult::FatalError;
+ }
+
size_t totalSize = sizeof(T) * count;
if (totalSize > *size) {
return DeserializeResult::FatalError;
@@ -305,7 +384,11 @@ namespace dawn_wire {
// Return FatalError if the allocator couldn't allocate the memory.
template <typename T>
DeserializeResult GetSpace(DeserializeAllocator* allocator, size_t count, T** out) {
- // TODO(cwallez@chromium.org): For robustness we would need to handle overflows here.
+ constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T);
+ if (count > kMaxCountWithoutOverflows) {
+ return DeserializeResult::FatalError;
+ }
+
size_t totalSize = sizeof(T) * count;
*out = static_cast<T*>(allocator->GetSpace(totalSize));
if (*out == nullptr) {
@@ -315,46 +398,35 @@ namespace dawn_wire {
return DeserializeResult::Success;
}
- //* Output structure [de]serialization first because it is used by methods.
+ //* Output structure [de]serialization first because it is used by commands.
{% for type in by_category["structure"] %}
{% set name = as_cType(type.name) %}
- {{write_serialization_methods(name, type.members, as_struct=type)}}
+ {{write_record_serialization_helpers(type, name, type.members,
+ is_cmd=False)}}
{% endfor %}
- // * Output [de]serialization helpers for methods
- {% for type in by_category["object"] %}
- {% for method in type.methods %}
- {% set name = as_MethodSuffix(type.name, method.name) %}
+ //* Output [de]serialization helpers for commands
+ {% for command in cmd_records["command"] %}
+ {% set name = command.name.CamelCase() %}
+ {{write_record_serialization_helpers(command, name, command.members,
+ is_cmd=True, is_method=command.derived_method != None)}}
+ {% endfor %}
- using {{name}} = {{name}}Cmd;
- {{write_serialization_methods(name, method.arguments, as_method=method)}}
- {% endfor %}
+ //* Output [de]serialization helpers for return commands
+ {% for command in cmd_records["return command"] %}
+ {% set name = command.name.CamelCase() %}
+ {{write_record_serialization_helpers(command, name, command.members,
+ is_cmd=True, is_method=command.derived_method != None,
+ is_return_command=True)}}
{% endfor %}
} // anonymous namespace
- {% for type in by_category["object"] %}
- {% for method in type.methods %}
- {% set name = as_MethodSuffix(type.name, method.name) %}
- {% set Cmd = name + "Cmd" %}
-
- size_t {{Cmd}}::GetRequiredSize() const {
- return sizeof({{name}}Transfer) + {{name}}GetExtraRequiredSize(*this);
- }
-
- void {{Cmd}}::Serialize(char* buffer, const ObjectIdProvider& objectIdProvider) const {
- auto transfer = reinterpret_cast<{{name}}Transfer*>(buffer);
- buffer += sizeof({{name}}Transfer);
-
- {{name}}Serialize(*this, transfer, buffer, objectIdProvider);
- }
-
- DeserializeResult {{Cmd}}::Deserialize(const char** buffer, size_t* size, DeserializeAllocator* allocator, const ObjectIdResolver& resolver) {
- const {{name}}Transfer* transfer = nullptr;
- DESERIALIZE_TRY(GetPtrFromBuffer(buffer, size, 1, &transfer));
+ {% for command in cmd_records["command"] %}
+ {{ write_command_serialization_methods(command, False) }}
+ {% endfor %}
- return {{name}}Deserialize(this, transfer, buffer, size, allocator, resolver);
- }
- {% endfor %}
+ {% for command in cmd_records["return command"] %}
+ {{ write_command_serialization_methods(command, True) }}
{% endfor %}
} // namespace dawn_wire
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.h b/chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.h
index 2d5300872d3..d92de2ce686 100644
--- a/chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.h
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/WireCmd.h
@@ -15,10 +15,16 @@
#ifndef DAWNWIRE_WIRECMD_AUTOGEN_H_
#define DAWNWIRE_WIRECMD_AUTOGEN_H_
+#include <dawn/dawn.h>
+
namespace dawn_wire {
using ObjectId = uint32_t;
using ObjectSerial = uint32_t;
+ struct ObjectHandle {
+ ObjectId id;
+ ObjectSerial serial;
+ };
enum class DeserializeResult {
Success,
@@ -53,93 +59,76 @@ namespace dawn_wire {
{% endfor %}
};
- //* Enum used as a prefix to each command on the wire format.
- enum class WireCmd : uint32_t {
+ enum class ObjectType : uint32_t {
{% for type in by_category["object"] %}
- {% for method in type.methods %}
- {{as_MethodSuffix(type.name, method.name)}},
- {% endfor %}
- {{as_MethodSuffix(type.name, Name("destroy"))}},
+ {{type.name.CamelCase()}},
{% endfor %}
- BufferMapAsync,
- BufferUpdateMappedDataCmd,
};
- {% for type in by_category["object"] %}
- {% for method in type.methods %}
- {% set Suffix = as_MethodSuffix(type.name, method.name) %}
- {% set Cmd = Suffix + "Cmd" %}
-
- //* These are "structure" version of the list of arguments to the different Dawn methods.
- //* They provide helpers to serialize/deserialize to/from a buffer.
- struct {{Cmd}} {
- //* From a filled structure, compute how much size will be used in the serialization buffer.
- size_t GetRequiredSize() const;
-
- //* Serialize the structure and everything it points to into serializeBuffer which must be
- //* big enough to contain all the data (as queried from GetRequiredSize).
- void Serialize(char* serializeBuffer, const ObjectIdProvider& objectIdProvider) const;
-
- //* Deserializes the structure from a buffer, consuming a maximum of *size bytes. When this
- //* function returns, buffer and size will be updated by the number of bytes consumed to
- //* deserialize the structure. Structures containing pointers will use allocator to get
- //* scratch space to deserialize the pointed-to data.
- //* Deserialize returns:
- //* - Success if everything went well (yay!)
- //* - FatalError is something bad happened (buffer too small for example)
- //* - ErrorObject if one if the deserialized object is an error value, for the implementation
- //* of the Maybe monad.
- //* If the return value is not FatalError, selfId, resultId and resultSerial (if present) are
- //* filled.
- DeserializeResult Deserialize(const char** buffer, size_t* size, DeserializeAllocator* allocator, const ObjectIdResolver& resolver);
-
- {{as_cType(type.name)}} self;
-
- //* Command handlers want to know the object ID in addition to the backing object.
- //* Doesn't need to be filled before Serialize, or GetRequiredSize.
- ObjectId selfId;
-
- //* Commands creating objects say which ID the created object will be referred as.
- {% if method.return_type.category == "object" %}
- ObjectId resultId;
- ObjectSerial resultSerial;
- {% endif %}
-
- {% for arg in method.arguments %}
- {{as_annotated_cType(arg)}};
- {% endfor %}
- };
+ //* Enum used as a prefix to each command on the wire format.
+ enum class WireCmd : uint32_t {
+ {% for command in cmd_records["command"] %}
+ {{command.name.CamelCase()}},
{% endfor %}
-
- //* The command structure used when sending that an ID is destroyed.
- {% set Suffix = as_MethodSuffix(type.name, Name("destroy")) %}
- struct {{Suffix}}Cmd {
- WireCmd commandId = WireCmd::{{Suffix}};
- ObjectId objectId;
- };
-
- {% endfor %}
+ };
//* Enum used as a prefix to each command on the return wire format.
enum class ReturnWireCmd : uint32_t {
- DeviceErrorCallback,
- {% for type in by_category["object"] if type.is_builder %}
- {{type.name.CamelCase()}}ErrorCallback,
+ {% for command in cmd_records["return command"] %}
+ {{command.name.CamelCase()}},
{% endfor %}
- BufferMapReadAsyncCallback,
- BufferMapWriteAsyncCallback,
};
- //* Command for the server calling a builder status callback.
- {% for type in by_category["object"] if type.is_builder %}
- struct Return{{type.name.CamelCase()}}ErrorCallbackCmd {
- ReturnWireCmd commandId = ReturnWireCmd::{{type.name.CamelCase()}}ErrorCallback;
+{% macro write_command_struct(command, is_return_command) %}
+ {% set Return = "Return" if is_return_command else "" %}
+ {% set Cmd = command.name.CamelCase() + "Cmd" %}
+ struct {{Return}}{{Cmd}} {
+ //* From a filled structure, compute how much size will be used in the serialization buffer.
+ size_t GetRequiredSize() const;
+
+ //* Serialize the structure and everything it points to into serializeBuffer which must be
+ //* big enough to contain all the data (as queried from GetRequiredSize).
+ void Serialize(char* serializeBuffer
+ {%- if command.has_dawn_object -%}
+ , const ObjectIdProvider& objectIdProvider
+ {%- endif -%}
+ ) const;
+
+ //* Deserializes the structure from a buffer, consuming a maximum of *size bytes. When this
+ //* function returns, buffer and size will be updated by the number of bytes consumed to
+ //* deserialize the structure. Structures containing pointers will use allocator to get
+ //* scratch space to deserialize the pointed-to data.
+ //* Deserialize returns:
+ //* - Success if everything went well (yay!)
+ //* - FatalError is something bad happened (buffer too small for example)
+ //* - ErrorObject if one if the deserialized object is an error value, for the implementation
+ //* of the Maybe monad.
+ //* If the return value is not FatalError, selfId, resultId and resultSerial (if present) are
+ //* filled.
+ DeserializeResult Deserialize(const char** buffer, size_t* size, DeserializeAllocator* allocator
+ {%- if command.has_dawn_object -%}
+ , const ObjectIdResolver& resolver
+ {%- endif -%}
+ );
+
+ {% if command.derived_method %}
+ //* Command handlers want to know the object ID in addition to the backing object.
+ //* Doesn't need to be filled before Serialize, or GetRequiredSize.
+ ObjectId selfId;
+ {% endif %}
+
+ {% for member in command.members %}
+ {{as_annotated_cType(member)}};
+ {% endfor %}
+ };
+{% endmacro %}
+
+ {% for command in cmd_records["command"] %}
+ {{write_command_struct(command, False)}}
+ {% endfor %}
- ObjectId builtObjectId;
- ObjectSerial builtObjectSerial;
- uint32_t status;
- size_t messageStrlen;
- };
+ {% for command in cmd_records["return command"] %}
+ {{write_command_struct(command, True)}}
{% endfor %}
} // namespace dawn_wire
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/WireServer.cpp b/chromium/third_party/dawn/generator/templates/dawn_wire/WireServer.cpp
index ebc341760bd..7997f4f0449 100644
--- a/chromium/third_party/dawn/generator/templates/dawn_wire/WireServer.cpp
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/WireServer.cpp
@@ -12,14 +12,18 @@
//* See the License for the specific language governing permissions and
//* limitations under the License.
+#include "dawn_wire/TypeTraits_autogen.h"
#include "dawn_wire/Wire.h"
-#include "dawn_wire/WireCmd.h"
+#include "dawn_wire/WireCmd_autogen.h"
+#include "dawn_wire/WireDeserializeAllocator.h"
#include "common/Assert.h"
#include <algorithm>
#include <cstdlib>
#include <cstring>
+#include <map>
+#include <memory>
#include <vector>
namespace dawn_wire {
@@ -29,25 +33,24 @@ namespace dawn_wire {
struct MapUserdata {
Server* server;
- uint32_t bufferId;
- uint32_t bufferSerial;
+ ObjectHandle buffer;
uint32_t requestSerial;
uint32_t size;
bool isWrite;
};
- //* Stores what the backend knows about the type.
- template<typename T>
+ struct FenceCompletionUserdata {
+ Server* server;
+ ObjectHandle fence;
+ uint64_t value;
+ };
+
+ template <typename T>
struct ObjectDataBase {
//* The backend-provided handle and serial to this object.
T handle;
uint32_t serial = 0;
- //* Built object ID and serial, needed to send to the client along with builder error callbacks
- //* TODO(cwallez@chromium.org) only have this for builder T
- uint32_t builtObjectId = 0;
- uint32_t builtObjectSerial = 0;
-
//* Used by the error-propagation mechanism to know if this object is an error.
//* TODO(cwallez@chromium.org): this is doubling the memory usage of
//* std::vector<ObjectDataBase> consider making it a special marker value in handle instead.
@@ -55,8 +58,21 @@ namespace dawn_wire {
//* Whether this object has been allocated, used by the KnownObjects queries
//* TODO(cwallez@chromium.org): make this an internal bit vector in KnownObjects.
bool allocated;
+ };
+
+ //* Stores what the backend knows about the type.
+ template<typename T, bool IsBuilder = IsBuilderType<T>::value>
+ struct ObjectData : public ObjectDataBase<T> {
+ };
+
- //* TODO(cwallez@chromium.org): this is only useful for buffers
+ template <typename T>
+ struct ObjectData<T, true> : public ObjectDataBase<T> {
+ ObjectHandle builtObject = ObjectHandle{0, 0};
+ };
+
+ template <>
+ struct ObjectData<dawnBuffer, false> : public ObjectDataBase<dawnBuffer> {
void* mappedData = nullptr;
size_t mappedDataSize = 0;
};
@@ -65,7 +81,7 @@ namespace dawn_wire {
template<typename T>
class KnownObjects {
public:
- using Data = ObjectDataBase<T>;
+ using Data = ObjectData<T>;
KnownObjects() {
//* Pre-allocate ID 0 to refer to the null handle.
@@ -137,71 +153,64 @@ namespace dawn_wire {
mKnown[id].allocated = false;
}
+ std::vector<T> AcquireAllHandles() {
+ std::vector<T> objects;
+ for (Data& data : mKnown) {
+ if (data.allocated && data.handle != nullptr) {
+ objects.push_back(data.handle);
+ data.valid = false;
+ data.allocated = false;
+ data.handle = nullptr;
+ }
+ }
+
+ return objects;
+ }
+
private:
std::vector<Data> mKnown;
};
- void ForwardDeviceErrorToServer(const char* message, dawnCallbackUserdata userdata);
-
- {% for type in by_category["object"] if type.is_builder%}
- void Forward{{type.name.CamelCase()}}ToClient(dawnBuilderErrorStatus status, const char* message, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2);
- {% endfor %}
-
- void ForwardBufferMapReadAsync(dawnBufferMapAsyncStatus status, const void* ptr, dawnCallbackUserdata userdata);
- void ForwardBufferMapWriteAsync(dawnBufferMapAsyncStatus status, void* ptr, dawnCallbackUserdata userdata);
+ // ObjectIds are lost in deserialization. Store the ids of deserialized
+ // objects here so they can be used in command handlers. This is useful
+ // for creating ReturnWireCmds which contain client ids
+ template <typename T>
+ class ObjectIdLookupTable {
+ public:
+ void Store(T key, ObjectId id) {
+ mTable[key] = id;
+ }
- // A really really simple implementation of the DeserializeAllocator. It's main feature
- // is that it has some inline storage so as to avoid allocations for the majority of
- // commands.
- class ServerAllocator : public DeserializeAllocator {
- public:
- ServerAllocator() {
- Reset();
+ // Return the cached ObjectId, or 0 (null handle)
+ ObjectId Get(T key) const {
+ const auto it = mTable.find(key);
+ if (it != mTable.end()) {
+ return it->second;
}
+ return 0;
+ }
- ~ServerAllocator() {
- Reset();
+ void Remove(T key) {
+ auto it = mTable.find(key);
+ if (it != mTable.end()) {
+ mTable.erase(it);
}
+ }
- void* GetSpace(size_t size) override {
- // Return space in the current buffer if possible first.
- if (mRemainingSize >= size) {
- char* buffer = mCurrentBuffer;
- mCurrentBuffer += size;
- mRemainingSize -= size;
- return buffer;
- }
-
- // Otherwise allocate a new buffer and try again.
- size_t allocationSize = std::max(size, size_t(2048));
- char* allocation = static_cast<char*>(malloc(allocationSize));
- if (allocation == nullptr) {
- return nullptr;
- }
-
- mAllocations.push_back(allocation);
- mCurrentBuffer = allocation;
- mRemainingSize = allocationSize;
- return GetSpace(size);
- }
+ private:
+ std::map<T, ObjectId> mTable;
+ };
- void Reset() {
- for (auto allocation : mAllocations) {
- free(allocation);
- }
- mAllocations.clear();
+ void ForwardDeviceErrorToServer(const char* message, dawnCallbackUserdata userdata);
- // The initial buffer is the inline buffer so that some allocations can be skipped
- mCurrentBuffer = mStaticBuffer;
- mRemainingSize = sizeof(mStaticBuffer);
- }
+ {% for type in by_category["object"] if type.is_builder%}
+ void Forward{{type.name.CamelCase()}}ToClient(dawnBuilderErrorStatus status, const char* message, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2);
+ {% endfor %}
- private:
- size_t mRemainingSize = 0;
- char* mCurrentBuffer = nullptr;
- char mStaticBuffer[2048];
- std::vector<char*> mAllocations;
- };
+ void ForwardBufferMapReadAsync(dawnBufferMapAsyncStatus status, const void* ptr, dawnCallbackUserdata userdata);
+ void ForwardBufferMapWriteAsync(dawnBufferMapAsyncStatus status, void* ptr, dawnCallbackUserdata userdata);
+ void ForwardFenceCompletedValue(dawnFenceCompletionStatus status,
+ dawnCallbackUserdata userdata);
class Server : public CommandHandler, public ObjectIdResolver {
public:
@@ -216,15 +225,25 @@ namespace dawn_wire {
procs.deviceSetErrorCallback(device, ForwardDeviceErrorToServer, userdata);
}
+ ~Server() override {
+ //* Free all objects when the server is destroyed
+ {% for type in by_category["object"] if type.name.canonical_case() != "device" %}
+ {
+ std::vector<{{as_cType(type.name)}}> handles = mKnown{{type.name.CamelCase()}}.AcquireAllHandles();
+ for ({{as_cType(type.name)}} handle : handles) {
+ mProcs.{{as_varName(type.name, Name("release"))}}(handle);
+ }
+ }
+ {% endfor %}
+ }
+
void OnDeviceError(const char* message) {
ReturnDeviceErrorCallbackCmd cmd;
- cmd.messageStrlen = std::strlen(message);
+ cmd.message = message;
- auto allocCmd = static_cast<ReturnDeviceErrorCallbackCmd*>(GetCmdSpace(sizeof(cmd)));
- *allocCmd = cmd;
-
- char* messageAlloc = static_cast<char*>(GetCmdSpace(cmd.messageStrlen + 1));
- strcpy(messageAlloc, message);
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
}
{% for type in by_category["object"] if type.is_builder%}
@@ -243,62 +262,79 @@ namespace dawn_wire {
if (status != DAWN_BUILDER_ERROR_STATUS_UNKNOWN) {
//* Unknown is the only status that can be returned without a call to GetResult
//* so we are guaranteed to have created an object.
- ASSERT(builder->builtObjectId != 0);
+ ASSERT(builder->builtObject.id != 0);
Return{{Type}}ErrorCallbackCmd cmd;
- cmd.builtObjectId = builder->builtObjectId;
- cmd.builtObjectSerial = builder->builtObjectSerial;
+ cmd.builtObject = builder->builtObject;
cmd.status = status;
- cmd.messageStrlen = std::strlen(message);
+ cmd.message = message;
- auto allocCmd = static_cast<Return{{Type}}ErrorCallbackCmd*>(GetCmdSpace(sizeof(cmd)));
- *allocCmd = cmd;
- char* messageAlloc = static_cast<char*>(GetCmdSpace(strlen(message) + 1));
- strcpy(messageAlloc, message);
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
}
}
{% endfor %}
- void OnMapReadAsyncCallback(dawnBufferMapAsyncStatus status, const void* ptr, MapUserdata* data) {
+ void OnMapReadAsyncCallback(dawnBufferMapAsyncStatus status, const void* ptr, MapUserdata* userdata) {
+ std::unique_ptr<MapUserdata> data(userdata);
+
+ // Skip sending the callback if the buffer has already been destroyed.
+ auto* bufferData = mKnownBuffer.Get(data->buffer.id);
+ if (bufferData == nullptr || bufferData->serial != data->buffer.serial) {
+ return;
+ }
+
ReturnBufferMapReadAsyncCallbackCmd cmd;
- cmd.bufferId = data->bufferId;
- cmd.bufferSerial = data->bufferSerial;
+ cmd.buffer = data->buffer;
cmd.requestSerial = data->requestSerial;
cmd.status = status;
cmd.dataLength = 0;
-
- auto allocCmd = static_cast<ReturnBufferMapReadAsyncCallbackCmd*>(GetCmdSpace(sizeof(cmd)));
- *allocCmd = cmd;
+ cmd.data = reinterpret_cast<const uint8_t*>(ptr);
if (status == DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS) {
- allocCmd->dataLength = data->size;
-
- void* dataAlloc = GetCmdSpace(data->size);
- memcpy(dataAlloc, ptr, data->size);
+ cmd.dataLength = data->size;
}
- delete data;
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
}
- void OnMapWriteAsyncCallback(dawnBufferMapAsyncStatus status, void* ptr, MapUserdata* data) {
+ void OnMapWriteAsyncCallback(dawnBufferMapAsyncStatus status, void* ptr, MapUserdata* userdata) {
+ std::unique_ptr<MapUserdata> data(userdata);
+
+ // Skip sending the callback if the buffer has already been destroyed.
+ auto* bufferData = mKnownBuffer.Get(data->buffer.id);
+ if (bufferData == nullptr || bufferData->serial != data->buffer.serial) {
+ return;
+ }
+
ReturnBufferMapWriteAsyncCallbackCmd cmd;
- cmd.bufferId = data->bufferId;
- cmd.bufferSerial = data->bufferSerial;
+ cmd.buffer = data->buffer;
cmd.requestSerial = data->requestSerial;
cmd.status = status;
- auto allocCmd = static_cast<ReturnBufferMapWriteAsyncCallbackCmd*>(GetCmdSpace(sizeof(cmd)));
- *allocCmd = cmd;
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
if (status == DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS) {
- auto* selfData = mKnownBuffer.Get(data->bufferId);
- ASSERT(selfData != nullptr);
-
- selfData->mappedData = ptr;
- selfData->mappedDataSize = data->size;
+ bufferData->mappedData = ptr;
+ bufferData->mappedDataSize = data->size;
}
+ }
- delete data;
+ void OnFenceCompletedValueUpdated(FenceCompletionUserdata* userdata) {
+ std::unique_ptr<FenceCompletionUserdata> data(userdata);
+
+ ReturnFenceUpdateCompletedValueCmd cmd;
+ cmd.fence = data->fence;
+ cmd.value = data->value;
+
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
}
const char* HandleCommands(const char* commands, size_t size) override {
@@ -309,25 +345,11 @@ namespace dawn_wire {
bool success = false;
switch (cmdId) {
- {% for type in by_category["object"] %}
- {% for method in type.methods %}
- {% set Suffix = as_MethodSuffix(type.name, method.name) %}
- case WireCmd::{{Suffix}}:
- success = Handle{{Suffix}}(&commands, &size);
- break;
- {% endfor %}
- {% set Suffix = as_MethodSuffix(type.name, Name("destroy")) %}
- case WireCmd::{{Suffix}}:
- success = Handle{{Suffix}}(&commands, &size);
+ {% for command in cmd_records["command"] %}
+ case WireCmd::{{command.name.CamelCase()}}:
+ success = Handle{{command.name.CamelCase()}}(&commands, &size);
break;
{% endfor %}
- case WireCmd::BufferMapAsync:
- success = HandleBufferMapAsync(&commands, &size);
- break;
- case WireCmd::BufferUpdateMappedDataCmd:
- success = HandleBufferUpdateMappedData(&commands, &size);
- break;
-
default:
success = false;
}
@@ -349,7 +371,7 @@ namespace dawn_wire {
dawnProcTable mProcs;
CommandSerializer* mSerializer = nullptr;
- ServerAllocator mAllocator;
+ WireDeserializeAllocator mAllocator;
void* GetCmdSpace(size_t size) {
return mSerializer->GetCmdSpace(size);
@@ -386,30 +408,9 @@ namespace dawn_wire {
KnownObjects<{{as_cType(type.name)}}> mKnown{{type.name.CamelCase()}};
{% endfor %}
- //* Helper function for the getting of the command data in command handlers.
- //* Checks there is enough data left, updates the buffer / size and returns
- //* the command (or nullptr for an error).
- template <typename T>
- static const T* GetData(const char** buffer, size_t* size, size_t count) {
- // TODO(cwallez@chromium.org): Check for overflow
- size_t totalSize = count * sizeof(T);
- if (*size < totalSize) {
- return nullptr;
- }
-
- const T* data = reinterpret_cast<const T*>(*buffer);
-
- *buffer += totalSize;
- *size -= totalSize;
-
- return data;
- }
- template <typename T>
- static const T* GetCommand(const char** commands, size_t* size) {
- return GetData<T>(commands, size, 1);
- }
-
- {% set custom_pre_handler_commands = ["BufferUnmap"] %}
+ {% for type in by_category["object"] if type.name.CamelCase() in server_reverse_lookup_objects %}
+ ObjectIdLookupTable<{{as_cType(type.name)}}> m{{type.name.CamelCase()}}IdTable;
+ {% endfor %}
bool PreHandleBufferUnmap(const BufferUnmapCmd& cmd) {
auto* selfData = mKnownBuffer.Get(cmd.selfId);
@@ -420,131 +421,136 @@ namespace dawn_wire {
return true;
}
+ bool PostHandleQueueSignal(const QueueSignalCmd& cmd) {
+ if (cmd.fence == nullptr) {
+ return false;
+ }
+ ObjectId fenceId = mFenceIdTable.Get(cmd.fence);
+ ASSERT(fenceId != 0);
+ auto* fence = mKnownFence.Get(fenceId);
+ ASSERT(fence != nullptr);
+
+ auto* data = new FenceCompletionUserdata;
+ data->server = this;
+ data->fence = ObjectHandle{fenceId, fence->serial};
+ data->value = cmd.signalValue;
+
+ auto userdata = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(data));
+ mProcs.fenceOnCompletion(cmd.fence, cmd.signalValue, ForwardFenceCompletedValue, userdata);
+ return true;
+ }
+
//* Implementation of the command handlers
{% for type in by_category["object"] %}
{% for method in type.methods %}
{% set Suffix = as_MethodSuffix(type.name, method.name) %}
+ {% if Suffix not in client_side_commands %}
+ //* The generic command handlers
- //* The generic command handlers
+ bool Handle{{Suffix}}(const char** commands, size_t* size) {
+ {{Suffix}}Cmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator, *this);
- bool Handle{{Suffix}}(const char** commands, size_t* size) {
- {{Suffix}}Cmd cmd;
- DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator, *this);
-
- if (deserializeResult == DeserializeResult::FatalError) {
- return false;
- }
-
- {% if Suffix in custom_pre_handler_commands %}
- if (!PreHandle{{Suffix}}(cmd)) {
+ if (deserializeResult == DeserializeResult::FatalError) {
return false;
}
- {% endif %}
-
- //* Unpack 'self'
- auto* selfData = mKnown{{type.name.CamelCase()}}.Get(cmd.selfId);
- ASSERT(selfData != nullptr);
-
- //* In all cases allocate the object data as it will be refered-to by the client.
- {% set return_type = method.return_type %}
- {% set returns = return_type.name.canonical_case() != "void" %}
- {% if returns %}
- {% set Type = method.return_type.name.CamelCase() %}
- auto* resultData = mKnown{{Type}}.Allocate(cmd.resultId);
- if (resultData == nullptr) {
- return false;
- }
- resultData->serial = cmd.resultSerial;
- {% if type.is_builder %}
- selfData->builtObjectId = cmd.resultId;
- selfData->builtObjectSerial = cmd.resultSerial;
- {% endif %}
- {% endif %}
-
- //* After the data is allocated, apply the argument error propagation mechanism
- if (deserializeResult == DeserializeResult::ErrorObject) {
- {% if type.is_builder %}
- selfData->valid = false;
- //* If we are in GetResult, fake an error callback
- {% if returns %}
- On{{type.name.CamelCase()}}Error(DAWN_BUILDER_ERROR_STATUS_ERROR, "Maybe monad", cmd.selfId, selfData->serial);
- {% endif %}
+ {% if Suffix in server_custom_pre_handler_commands %}
+ if (!PreHandle{{Suffix}}(cmd)) {
+ return false;
+ }
{% endif %}
- return true;
- }
- {% if returns %}
- auto result ={{" "}}
- {%- endif %}
- mProcs.{{as_varName(type.name, method.name)}}(cmd.self
- {%- for arg in method.arguments -%}
- , cmd.{{as_varName(arg.name)}}
- {%- endfor -%}
- );
-
- {% if returns %}
- resultData->handle = result;
- resultData->valid = result != nullptr;
-
- //* builders remember the ID of the object they built so that they can send it
- //* in the callback to the client.
- {% if return_type.is_builder %}
- if (result != nullptr) {
- uint64_t userdata1 = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this));
- uint64_t userdata2 = (uint64_t(resultData->serial) << uint64_t(32)) + cmd.resultId;
- mProcs.{{as_varName(return_type.name, Name("set error callback"))}}(result, Forward{{return_type.name.CamelCase()}}ToClient, userdata1, userdata2);
+ //* Unpack 'self'
+ auto* selfData = mKnown{{type.name.CamelCase()}}.Get(cmd.selfId);
+ ASSERT(selfData != nullptr);
+
+ //* In all cases allocate the object data as it will be refered-to by the client.
+ {% set return_type = method.return_type %}
+ {% set returns = return_type.name.canonical_case() != "void" %}
+ {% if returns %}
+ {% set Type = method.return_type.name.CamelCase() %}
+ auto* resultData = mKnown{{Type}}.Allocate(cmd.result.id);
+ if (resultData == nullptr) {
+ return false;
}
- {% endif %}
- {% endif %}
+ resultData->serial = cmd.result.serial;
- return true;
- }
- {% endfor %}
+ {% if type.is_builder %}
+ selfData->builtObject = cmd.result;
+ {% endif %}
+ {% endif %}
- //* Handlers for the destruction of objects: clients do the tracking of the
- //* reference / release and only send destroy on refcount = 0.
- {% set Suffix = as_MethodSuffix(type.name, Name("destroy")) %}
- bool Handle{{Suffix}}(const char** commands, size_t* size) {
- const auto* cmd = GetCommand<{{Suffix}}Cmd>(commands, size);
- if (cmd == nullptr) {
- return false;
- }
+ //* After the data is allocated, apply the argument error propagation mechanism
+ if (deserializeResult == DeserializeResult::ErrorObject) {
+ {% if type.is_builder %}
+ selfData->valid = false;
+ //* If we are in GetResult, fake an error callback
+ {% if returns %}
+ On{{type.name.CamelCase()}}Error(DAWN_BUILDER_ERROR_STATUS_ERROR, "Maybe monad", cmd.selfId, selfData->serial);
+ {% endif %}
+ {% endif %}
+ return true;
+ }
- ObjectId objectId = cmd->objectId;
+ {% if returns %}
+ auto result ={{" "}}
+ {%- endif %}
+ mProcs.{{as_varName(type.name, method.name)}}(cmd.self
+ {%- for arg in method.arguments -%}
+ , cmd.{{as_varName(arg.name)}}
+ {%- endfor -%}
+ );
+
+ {% if Suffix in server_custom_post_handler_commands %}
+ if (!PostHandle{{Suffix}}(cmd)) {
+ return false;
+ }
+ {% endif %}
- //* ID 0 are reserved for nullptr and cannot be destroyed.
- if (objectId == 0) {
- return false;
- }
+ {% if returns %}
+ resultData->handle = result;
+ resultData->valid = result != nullptr;
- auto* data = mKnown{{type.name.CamelCase()}}.Get(objectId);
- if (data == nullptr) {
- return false;
- }
+ {% if return_type.name.CamelCase() in server_reverse_lookup_objects %}
+ //* For created objects, store a mapping from them back to their client IDs
+ if (result) {
+ m{{return_type.name.CamelCase()}}IdTable.Store(result, cmd.result.id);
+ }
+ {% endif %}
- if (data->valid) {
- mProcs.{{as_varName(type.name, Name("release"))}}(data->handle);
- }
+ //* builders remember the ID of the object they built so that they can send it
+ //* in the callback to the client.
+ {% if return_type.is_builder %}
+ if (result != nullptr) {
+ uint64_t userdata1 = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this));
+ uint64_t userdata2 = (uint64_t(resultData->serial) << uint64_t(32)) + cmd.result.id;
+ mProcs.{{as_varName(return_type.name, Name("set error callback"))}}(result, Forward{{return_type.name.CamelCase()}}ToClient, userdata1, userdata2);
+ }
+ {% endif %}
+ {% endif %}
- mKnown{{type.name.CamelCase()}}.Free(objectId);
- return true;
- }
+ return true;
+ }
+ {% endif %}
+ {% endfor %}
{% endfor %}
bool HandleBufferMapAsync(const char** commands, size_t* size) {
//* These requests are just forwarded to the buffer, with userdata containing what the client
//* will require in the return command.
- const auto* cmd = GetCommand<BufferMapAsyncCmd>(commands, size);
- if (cmd == nullptr) {
+ BufferMapAsyncCmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
+
+ if (deserializeResult == DeserializeResult::FatalError) {
return false;
}
- ObjectId bufferId = cmd->bufferId;
- uint32_t requestSerial = cmd->requestSerial;
- uint32_t requestSize = cmd->size;
- uint32_t requestStart = cmd->start;
- bool isWrite = cmd->isWrite;
+ ObjectId bufferId = cmd.bufferId;
+ uint32_t requestSerial = cmd.requestSerial;
+ uint32_t requestSize = cmd.size;
+ uint32_t requestStart = cmd.start;
+ bool isWrite = cmd.isWrite;
//* The null object isn't valid as `self`
if (bufferId == 0) {
@@ -558,8 +564,7 @@ namespace dawn_wire {
auto* data = new MapUserdata;
data->server = this;
- data->bufferId = bufferId;
- data->bufferSerial = buffer->serial;
+ data->buffer = ObjectHandle{bufferId, buffer->serial};
data->requestSerial = requestSerial;
data->size = requestSize;
data->isWrite = isWrite;
@@ -586,13 +591,15 @@ namespace dawn_wire {
}
bool HandleBufferUpdateMappedData(const char** commands, size_t* size) {
- const auto* cmd = GetCommand<BufferUpdateMappedDataCmd>(commands, size);
- if (cmd == nullptr) {
+ BufferUpdateMappedDataCmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
+
+ if (deserializeResult == DeserializeResult::FatalError) {
return false;
}
- ObjectId bufferId = cmd->bufferId;
- size_t dataLength = cmd->dataLength;
+ ObjectId bufferId = cmd.bufferId;
+ size_t dataLength = cmd.dataLength;
//* The null object isn't valid as `self`
if (bufferId == 0) {
@@ -605,14 +612,55 @@ namespace dawn_wire {
return false;
}
- const char* data = GetData<char>(commands, size, dataLength);
- if (data == nullptr) {
+ DAWN_ASSERT(cmd.data != nullptr);
+
+ memcpy(buffer->mappedData, cmd.data, dataLength);
+
+ return true;
+ }
+
+ bool HandleDestroyObject(const char** commands, size_t* size) {
+ DestroyObjectCmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
+
+ if (deserializeResult == DeserializeResult::FatalError) {
return false;
}
- memcpy(buffer->mappedData, data, dataLength);
+ ObjectId objectId = cmd.objectId;
+ //* ID 0 are reserved for nullptr and cannot be destroyed.
+ if (objectId == 0) {
+ return false;
+ }
- return true;
+ switch (cmd.objectType) {
+ {% for type in by_category["object"] %}
+ {% set ObjectType = type.name.CamelCase() %}
+ case ObjectType::{{ObjectType}}: {
+ {% if ObjectType == "Device" %}
+ //* Freeing the device has to be done out of band.
+ return false;
+ {% else %}
+ auto* data = mKnown{{type.name.CamelCase()}}.Get(objectId);
+ if (data == nullptr) {
+ return false;
+ }
+ {% if type.name.CamelCase() in server_reverse_lookup_objects %}
+ m{{type.name.CamelCase()}}IdTable.Remove(data->handle);
+ {% endif %}
+
+ if (data->handle != nullptr) {
+ mProcs.{{as_varName(type.name, Name("release"))}}(data->handle);
+ }
+
+ mKnown{{type.name.CamelCase()}}.Free(objectId);
+ return true;
+ {% endif %}
+ }
+ {% endfor %}
+ default:
+ UNREACHABLE();
+ }
}
};
@@ -639,6 +687,13 @@ namespace dawn_wire {
auto data = reinterpret_cast<MapUserdata*>(static_cast<uintptr_t>(userdata));
data->server->OnMapWriteAsyncCallback(status, ptr, data);
}
+
+ void ForwardFenceCompletedValue(dawnFenceCompletionStatus status, dawnCallbackUserdata userdata) {
+ auto data = reinterpret_cast<FenceCompletionUserdata*>(static_cast<uintptr_t>(userdata));
+ if (status == DAWN_FENCE_COMPLETION_STATUS_SUCCESS) {
+ data->server->OnFenceCompletedValueUpdated(data);
+ }
+ }
}
CommandHandler* NewServerCommandHandler(dawnDevice device, const dawnProcTable& procs, CommandSerializer* serializer) {
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiObjects.h b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiObjects.h
new file mode 100644
index 00000000000..5c2ae3f613c
--- /dev/null
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiObjects.h
@@ -0,0 +1,26 @@
+//* Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_APIOBJECTS_AUTOGEN_H_
+#define DAWNWIRE_CLIENT_APIOBJECTS_AUTOGEN_H_
+
+namespace dawn_wire { namespace client {
+ {% for type in by_category["object"] if not type.name.CamelCase() in client_special_objects %}
+ struct {{type.name.CamelCase()}} : ObjectBase {
+ using ObjectBase::ObjectBase;
+ };
+ {% endfor %}
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_APIOBJECTS_AUTOGEN_H_
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiProcs.cpp b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiProcs.cpp
new file mode 100644
index 00000000000..9544e93dd9a
--- /dev/null
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiProcs.cpp
@@ -0,0 +1,135 @@
+//* Copyright 2019 The Dawn 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_wire/client/ApiObjects.h"
+#include "dawn_wire/client/ApiProcs_autogen.h"
+#include "dawn_wire/client/Client.h"
+#include "dawn_wire/client/Device_autogen.h"
+
+namespace dawn_wire { namespace client {
+ //* Implementation of the client API functions.
+ {% for type in by_category["object"] %}
+ {% set Type = type.name.CamelCase() %}
+ {% set cType = as_cType(type.name) %}
+
+ {% for method in type.methods %}
+ {% set Suffix = as_MethodSuffix(type.name, method.name) %}
+ {% if Suffix not in client_side_commands %}
+ {{as_cType(method.return_type.name)}} Client{{Suffix}}(
+ {{-cType}} cSelf
+ {%- for arg in method.arguments -%}
+ , {{as_annotated_cType(arg)}}
+ {%- endfor -%}
+ ) {
+ auto self = reinterpret_cast<{{as_wireType(type)}}>(cSelf);
+ Device* device = self->device;
+ {{Suffix}}Cmd cmd;
+
+ //* Create the structure going on the wire on the stack and fill it with the value
+ //* arguments so it can compute its size.
+ cmd.self = cSelf;
+
+ //* For object creation, store the object ID the client will use for the result.
+ {% if method.return_type.category == "object" %}
+ auto* allocation = self->device->{{method.return_type.name.camelCase()}}.New();
+
+ {% if type.is_builder %}
+ //* We are in GetResult, so the callback that should be called is the
+ //* currently set one. Copy it over to the created object and prevent the
+ //* builder from calling the callback on destruction.
+ allocation->object->builderCallback = self->builderCallback;
+ self->builderCallback.canCall = false;
+ {% endif %}
+
+ cmd.result = ObjectHandle{allocation->object->id, allocation->serial};
+ {% endif %}
+
+ {% for arg in method.arguments %}
+ cmd.{{as_varName(arg.name)}} = {{as_varName(arg.name)}};
+ {% endfor %}
+
+ //* Allocate space to send the command and copy the value args over.
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(device->GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer, *device);
+
+ {% if method.return_type.category == "object" %}
+ return reinterpret_cast<{{as_cType(method.return_type.name)}}>(allocation->object.get());
+ {% endif %}
+ }
+ {% endif %}
+ {% endfor %}
+
+ {% if type.is_builder %}
+ void Client{{as_MethodSuffix(type.name, Name("set error callback"))}}({{cType}} cSelf,
+ dawnBuilderErrorCallback callback,
+ dawnCallbackUserdata userdata1,
+ dawnCallbackUserdata userdata2) {
+ {{Type}}* self = reinterpret_cast<{{Type}}*>(cSelf);
+ self->builderCallback.callback = callback;
+ self->builderCallback.userdata1 = userdata1;
+ self->builderCallback.userdata2 = userdata2;
+ }
+ {% endif %}
+
+ {% if not type.name.canonical_case() == "device" %}
+ //* When an object's refcount reaches 0, notify the server side of it and delete it.
+ void Client{{as_MethodSuffix(type.name, Name("release"))}}({{cType}} cObj) {
+ {{Type}}* obj = reinterpret_cast<{{Type}}*>(cObj);
+ obj->refcount --;
+
+ if (obj->refcount > 0) {
+ return;
+ }
+
+ obj->builderCallback.Call(DAWN_BUILDER_ERROR_STATUS_UNKNOWN, "Unknown");
+
+ DestroyObjectCmd cmd;
+ cmd.objectType = ObjectType::{{type.name.CamelCase()}};
+ cmd.objectId = obj->id;
+
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(obj->device->GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
+
+ obj->device->{{type.name.camelCase()}}.Free(obj);
+ }
+
+ void Client{{as_MethodSuffix(type.name, Name("reference"))}}({{cType}} cObj) {
+ {{Type}}* obj = reinterpret_cast<{{Type}}*>(cObj);
+ obj->refcount ++;
+ }
+ {% endif %}
+ {% endfor %}
+
+ //* Some commands don't have a custom wire format, but need to be handled manually to update
+ //* some client-side state tracking. For these we have two functions:
+ //* - An autogenerated Client{{suffix}} method that sends the command on the wire
+ //* - A manual ProxyClient{{suffix}} method that will be inserted in the proctable instead of
+ //* the autogenerated one, and that will have to call Client{{suffix}}
+ dawnProcTable GetProcs() {
+ dawnProcTable table;
+ {% for type in by_category["object"] %}
+ {% for method in native_methods(type) %}
+ {% set suffix = as_MethodSuffix(type.name, method.name) %}
+ {% if suffix in client_proxied_commands %}
+ table.{{as_varName(type.name, method.name)}} = ProxyClient{{suffix}};
+ {% else %}
+ table.{{as_varName(type.name, method.name)}} = Client{{suffix}};
+ {% endif %}
+ {% endfor %}
+ {% endfor %}
+ return table;
+ }
+}} // namespace dawn_wire::client
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiProcs.h b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiProcs.h
new file mode 100644
index 00000000000..91489f2d71d
--- /dev/null
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ApiProcs.h
@@ -0,0 +1,46 @@
+//* Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_APIPROCS_AUTOGEN_H_
+#define DAWNWIRE_CLIENT_APIPROCS_AUTOGEN_H_
+
+#include <dawn/dawn.h>
+
+namespace dawn_wire { namespace client {
+
+ //* Dawn API
+ {% for type in by_category["object"] %}
+ {% set cType = as_cType(type.name) %}
+ {% for method in native_methods(type) %}
+ {% set Suffix = as_MethodSuffix(type.name, method.name) %}
+ {% if Suffix in client_proxied_commands %}
+ {{as_cType(method.return_type.name)}} ProxyClient{{Suffix}}(
+ {{-cType}} cSelf
+ {%- for arg in method.arguments -%}
+ , {{as_annotated_cType(arg)}}
+ {%- endfor -%}
+ );
+ {% endif %}
+ {{as_cType(method.return_type.name)}} Client{{Suffix}}(
+ {{-cType}} cSelf
+ {%- for arg in method.arguments -%}
+ , {{as_annotated_cType(arg)}}
+ {%- endfor -%}
+ );
+ {% endfor %}
+ {% endfor %}
+
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_APIPROCS_AUTOGEN_H_
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/client/ClientHandlers.cpp b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ClientHandlers.cpp
new file mode 100644
index 00000000000..31a80810516
--- /dev/null
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ClientHandlers.cpp
@@ -0,0 +1,81 @@
+//* Copyright 2019 The Dawn 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 "common/Assert.h"
+#include "dawn_wire/client/Client.h"
+#include "dawn_wire/client/Device_autogen.h"
+
+#include <string>
+
+namespace dawn_wire { namespace client {
+ {% for type in by_category["object"] if type.is_builder %}
+ {% set Type = type.name.CamelCase() %}
+ bool Client::Handle{{Type}}ErrorCallback(const char** commands, size_t* size) {
+ Return{{Type}}ErrorCallbackCmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
+
+ if (deserializeResult == DeserializeResult::FatalError) {
+ return false;
+ }
+
+ DAWN_ASSERT(cmd.message != nullptr);
+
+ auto* builtObject = mDevice->{{type.built_type.name.camelCase()}}.GetObject(cmd.builtObject.id);
+ uint32_t objectSerial = mDevice->{{type.built_type.name.camelCase()}}.GetSerial(cmd.builtObject.id);
+
+ //* The object might have been deleted or a new object created with the same ID.
+ if (builtObject == nullptr || objectSerial != cmd.builtObject.serial) {
+ return true;
+ }
+
+ bool called = builtObject->builderCallback.Call(static_cast<dawnBuilderErrorStatus>(cmd.status), cmd.message);
+
+ // Unhandled builder errors are forwarded to the device
+ if (!called && cmd.status != DAWN_BUILDER_ERROR_STATUS_SUCCESS && cmd.status != DAWN_BUILDER_ERROR_STATUS_UNKNOWN) {
+ mDevice->HandleError(("Unhandled builder error: " + std::string(cmd.message)).c_str());
+ }
+
+ return true;
+ }
+ {% endfor %}
+
+ const char* Client::HandleCommands(const char* commands, size_t size) {
+ while (size >= sizeof(ReturnWireCmd)) {
+ ReturnWireCmd cmdId = *reinterpret_cast<const ReturnWireCmd*>(commands);
+
+ bool success = false;
+ switch (cmdId) {
+ {% for command in cmd_records["return command"] %}
+ {% set Suffix = command.name.CamelCase() %}
+ case ReturnWireCmd::{{Suffix}}:
+ success = Handle{{Suffix}}(&commands, &size);
+ break;
+ {% endfor %}
+ default:
+ success = false;
+ }
+
+ if (!success) {
+ return nullptr;
+ }
+ mAllocator.Reset();
+ }
+
+ if (size != 0) {
+ return nullptr;
+ }
+
+ return commands;
+ }
+}} // namespace dawn_wire::client
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/client/ClientPrototypes.inl b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ClientPrototypes.inl
new file mode 100644
index 00000000000..5d64d85ce83
--- /dev/null
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/client/ClientPrototypes.inl
@@ -0,0 +1,18 @@
+//* Copyright 2019 The Dawn 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.
+
+//* Return command handlers
+{% for command in cmd_records["return command"] %}
+ bool Handle{{command.name.CamelCase()}}(const char** commands, size_t* size);
+{% endfor %}
diff --git a/chromium/third_party/dawn/generator/templates/dawn_wire/client/Device.h b/chromium/third_party/dawn/generator/templates/dawn_wire/client/Device.h
new file mode 100644
index 00000000000..796383a3aae
--- /dev/null
+++ b/chromium/third_party/dawn/generator/templates/dawn_wire/client/Device.h
@@ -0,0 +1,73 @@
+//* Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_DEVICE_AUTOGEN_H_
+#define DAWNWIRE_CLIENT_DEVICE_AUTOGEN_H_
+
+#include <dawn/dawn.h>
+
+#include "dawn_wire/Wire.h"
+#include "dawn_wire/WireCmd_autogen.h"
+#include "dawn_wire/client/ApiObjects.h"
+#include "dawn_wire/client/ObjectAllocator.h"
+
+namespace dawn_wire { namespace client {
+ //* The client wire uses the global Dawn device to store its global data such as the serializer
+ //* and the object id allocators.
+ class Device : public ObjectBase, public ObjectIdProvider {
+ public:
+ Device(CommandSerializer* serializer)
+ : ObjectBase(this, 1, 1),
+ {% for type in by_category["object"] if not type.name.canonical_case() == "device" %}
+ {{type.name.camelCase()}}(this),
+ {% endfor %}
+ mSerializer(serializer) {
+ }
+
+ void* GetCmdSpace(size_t size) {
+ return mSerializer->GetCmdSpace(size);
+ }
+
+ {% for type in by_category["object"] if not type.name.canonical_case() == "device" %}
+ ObjectAllocator<{{type.name.CamelCase()}}> {{type.name.camelCase()}};
+ {% endfor %}
+
+ // Implementation of the ObjectIdProvider interface
+ {% for type in by_category["object"] %}
+ ObjectId GetId({{as_cType(type.name)}} object) const final {
+ return reinterpret_cast<{{as_wireType(type)}}>(object)->id;
+ }
+ ObjectId GetOptionalId({{as_cType(type.name)}} object) const final {
+ if (object == nullptr) {
+ return 0;
+ }
+ return GetId(object);
+ }
+ {% endfor %}
+
+ void HandleError(const char* message) {
+ if (errorCallback) {
+ errorCallback(message, errorUserdata);
+ }
+ }
+
+ dawnDeviceErrorCallback errorCallback = nullptr;
+ dawnCallbackUserdata errorUserdata;
+
+ private:
+ CommandSerializer* mSerializer = nullptr;
+ };
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_DEVICE_AUTOGEN_H_
diff --git a/chromium/third_party/dawn/generator/templates/mock_api.cpp b/chromium/third_party/dawn/generator/templates/mock_api.cpp
index 3c39d71357a..447bd9fc581 100644
--- a/chromium/third_party/dawn/generator/templates/mock_api.cpp
+++ b/chromium/third_party/dawn/generator/templates/mock_api.cpp
@@ -72,6 +72,17 @@ void ProcTableAsClass::BufferMapWriteAsync(dawnBuffer self, uint32_t start, uint
OnBufferMapWriteAsyncCallback(self, start, size, callback, userdata);
}
+void ProcTableAsClass::FenceOnCompletion(dawnFence self,
+ uint64_t value,
+ dawnFenceOnCompletionCallback callback,
+ dawnCallbackUserdata userdata) {
+ auto object = reinterpret_cast<ProcTableAsClass::Object*>(self);
+ object->fenceOnCompletionCallback = callback;
+ object->userdata1 = userdata;
+
+ OnFenceOnCompletionCallback(self, value, callback, userdata);
+}
+
void ProcTableAsClass::CallDeviceErrorCallback(dawnDevice device, const char* message) {
auto object = reinterpret_cast<ProcTableAsClass::Object*>(device);
object->deviceErrorCallback(message, object->userdata1);
@@ -90,6 +101,12 @@ void ProcTableAsClass::CallMapWriteCallback(dawnBuffer buffer, dawnBufferMapAsyn
object->mapWriteCallback(status, data, object->userdata1);
}
+void ProcTableAsClass::CallFenceOnCompletionCallback(dawnFence fence,
+ dawnFenceCompletionStatus status) {
+ auto object = reinterpret_cast<ProcTableAsClass::Object*>(fence);
+ object->fenceOnCompletionCallback(status, object->userdata1);
+}
+
{% for type in by_category["object"] if type.is_builder %}
void ProcTableAsClass::{{as_MethodSuffix(type.name, Name("set error callback"))}}({{as_cType(type.name)}} self, dawnBuilderErrorCallback callback, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2) {
auto object = reinterpret_cast<ProcTableAsClass::Object*>(self);
diff --git a/chromium/third_party/dawn/generator/templates/mock_api.h b/chromium/third_party/dawn/generator/templates/mock_api.h
index b82a22afa3e..da3c60e70cf 100644
--- a/chromium/third_party/dawn/generator/templates/mock_api.h
+++ b/chromium/third_party/dawn/generator/templates/mock_api.h
@@ -59,19 +59,27 @@ class ProcTableAsClass {
void DeviceSetErrorCallback(dawnDevice self, dawnDeviceErrorCallback callback, dawnCallbackUserdata userdata);
void BufferMapReadAsync(dawnBuffer self, uint32_t start, uint32_t size, dawnBufferMapReadCallback callback, dawnCallbackUserdata userdata);
void BufferMapWriteAsync(dawnBuffer self, uint32_t start, uint32_t size, dawnBufferMapWriteCallback callback, dawnCallbackUserdata userdata);
-
+ void FenceOnCompletion(dawnFence self,
+ uint64_t value,
+ dawnFenceOnCompletionCallback callback,
+ dawnCallbackUserdata userdata);
// Special cased mockable methods
virtual void OnDeviceSetErrorCallback(dawnDevice device, dawnDeviceErrorCallback callback, dawnCallbackUserdata userdata) = 0;
virtual void OnBuilderSetErrorCallback(dawnBufferBuilder builder, dawnBuilderErrorCallback callback, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2) = 0;
virtual void OnBufferMapReadAsyncCallback(dawnBuffer buffer, uint32_t start, uint32_t size, dawnBufferMapReadCallback callback, dawnCallbackUserdata userdata) = 0;
virtual void OnBufferMapWriteAsyncCallback(dawnBuffer buffer, uint32_t start, uint32_t size, dawnBufferMapWriteCallback callback, dawnCallbackUserdata userdata) = 0;
+ virtual void OnFenceOnCompletionCallback(dawnFence fence,
+ uint64_t value,
+ dawnFenceOnCompletionCallback callback,
+ dawnCallbackUserdata userdata) = 0;
// Calls the stored callbacks
void CallDeviceErrorCallback(dawnDevice device, const char* message);
void CallBuilderErrorCallback(void* builder , dawnBuilderErrorStatus status, const char* message);
void CallMapReadCallback(dawnBuffer buffer, dawnBufferMapAsyncStatus status, const void* data);
void CallMapWriteCallback(dawnBuffer buffer, dawnBufferMapAsyncStatus status, void* data);
+ void CallFenceOnCompletionCallback(dawnFence fence, dawnFenceCompletionStatus status);
struct Object {
ProcTableAsClass* procs = nullptr;
@@ -79,6 +87,7 @@ class ProcTableAsClass {
dawnBuilderErrorCallback builderErrorCallback = nullptr;
dawnBufferMapReadCallback mapReadCallback = nullptr;
dawnBufferMapWriteCallback mapWriteCallback = nullptr;
+ dawnFenceOnCompletionCallback fenceOnCompletionCallback = nullptr;
dawnCallbackUserdata userdata1 = 0;
dawnCallbackUserdata userdata2 = 0;
};
@@ -112,6 +121,11 @@ class MockProcTable : public ProcTableAsClass {
MOCK_METHOD4(OnBuilderSetErrorCallback, void(dawnBufferBuilder builder, dawnBuilderErrorCallback callback, dawnCallbackUserdata userdata1, dawnCallbackUserdata userdata2));
MOCK_METHOD5(OnBufferMapReadAsyncCallback, void(dawnBuffer buffer, uint32_t start, uint32_t size, dawnBufferMapReadCallback callback, dawnCallbackUserdata userdata));
MOCK_METHOD5(OnBufferMapWriteAsyncCallback, void(dawnBuffer buffer, uint32_t start, uint32_t size, dawnBufferMapWriteCallback callback, dawnCallbackUserdata userdata));
+ MOCK_METHOD4(OnFenceOnCompletionCallback,
+ void(dawnFence fence,
+ uint64_t value,
+ dawnFenceOnCompletionCallback callback,
+ dawnCallbackUserdata userdata));
};
#endif // MOCK_DAWN_H
diff --git a/chromium/third_party/dawn/generator/wire_cmd.py b/chromium/third_party/dawn/generator/wire_cmd.py
new file mode 100644
index 00000000000..73669ca7d8c
--- /dev/null
+++ b/chromium/third_party/dawn/generator/wire_cmd.py
@@ -0,0 +1,93 @@
+# Copyright 2019 The Dawn 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.
+
+from collections import namedtuple
+from common import Name
+import common
+
+def concat_names(*names):
+ return ' '.join([name.canonical_case() for name in names])
+
+# Create wire commands from api methods
+def compute_wire_params(api_params, wire_json):
+ wire_params = api_params.copy()
+ types = wire_params['types']
+
+ commands = []
+ return_commands = []
+
+ object_result_member = common.RecordMember(Name('result'), types['ObjectHandle'], 'value', False, True)
+
+ string_message_member = common.RecordMember(Name('message'), types['char'], 'const*', False, False)
+ string_message_member.length = 'strlen'
+
+ built_object_member = common.RecordMember(Name('built object'), types['ObjectHandle'], 'value', False, False)
+
+ callback_status_member = common.RecordMember(Name('status'), types['uint32_t'], 'value', False, False)
+
+ # Generate commands from object methods
+ for api_object in wire_params['by_category']['object']:
+ for method in api_object.methods:
+ if method.return_type.category != 'object' and method.return_type.name.canonical_case() != 'void':
+ # No other return types supported
+ continue
+
+ # Create object method commands by prepending "self"
+ members = [common.RecordMember(Name('self'), types[api_object.dict_name], 'value', False, False)]
+
+ members += method.arguments
+
+ # Client->Server commands that return an object return the result object handle
+ if method.return_type.category == 'object':
+ members.append(object_result_member)
+
+ command_name = concat_names(api_object.name, method.name)
+ command = common.Command(command_name, members)
+
+ command.derived_object = api_object
+ command.derived_method = method
+ commands.append(command)
+
+ # Create builder return ErrorCallback commands
+ # This can be removed when WebGPU error handling is implemented
+ if api_object.is_builder:
+ command_name = concat_names(api_object.name, Name('error callback'))
+
+ command = common.Command(command_name, [
+ built_object_member,
+ callback_status_member,
+ string_message_member,
+ ])
+ command.derived_object = api_object
+ return_commands.append(command)
+
+ for (name, json_data) in wire_json['commands'].items():
+ commands.append(common.Command(name, common.linked_record_members(json_data, types)))
+
+ for (name, json_data) in wire_json['return commands'].items():
+ return_commands.append(common.Command(name, common.linked_record_members(json_data, types)))
+
+ wire_params['cmd_records'] = {
+ 'command': commands,
+ 'return command': return_commands
+ }
+
+ for commands in wire_params['cmd_records'].values():
+ for command in commands:
+ command.update_metadata()
+ commands.sort(key=lambda c: c.name.canonical_case())
+
+ wire_params.update(wire_json.get('special items', {}))
+
+ return wire_params
diff --git a/chromium/third_party/dawn/scripts/dawn_features.gni b/chromium/third_party/dawn/scripts/dawn_features.gni
index 031cdb1739b..d86f2189cb2 100644
--- a/chromium/third_party/dawn/scripts/dawn_features.gni
+++ b/chromium/third_party/dawn/scripts/dawn_features.gni
@@ -16,6 +16,11 @@ declare_args() {
# Enable Dawn's ASSERTs even in release builds
dawn_always_assert = false
+ # Should the Dawn static libraries be fully linked vs. GN's default of
+ # treating them as source sets. This is useful for people using Dawn
+ # standalone to produce static libraries to use in their projects.
+ dawn_complete_static_libs = false
+
# Enables the compilation of Dawn's D3D12 backend
dawn_enable_d3d12 = is_win
diff --git a/chromium/third_party/dawn/src/common/Compiler.h b/chromium/third_party/dawn/src/common/Compiler.h
index 72a8c60c1b6..06b38ab5b90 100644
--- a/chromium/third_party/dawn/src/common/Compiler.h
+++ b/chromium/third_party/dawn/src/common/Compiler.h
@@ -24,6 +24,9 @@
// (resp. false) to help it generate code that leads to better branch prediction.
// - DAWN_UNUSED(EXPR): Prevents unused variable/expression warnings on EXPR.
// - DAWN_UNUSED_FUNC(FUNC): Prevents unused function warnings on FUNC.
+// - DAWN_DECLARE_UNUSED: Prevents unused function warnings a subsequent declaration.
+// Both DAWN_UNUSED_FUNC and DAWN_DECLARE_UNUSED may be necessary, e.g. to suppress clang's
+// unneeded-internal-declaration warning.
// Clang and GCC, check for __clang__ too to catch clang-cl masquarading as MSVC
#if defined(__GNUC__) || defined(__clang__)
@@ -57,6 +60,8 @@
# define DAWN_NO_DISCARD [[nodiscard]]
# endif
+# define DAWN_DECLARE_UNUSED __attribute__((unused))
+
// MSVC
#elif defined(_MSC_VER)
# define DAWN_COMPILER_MSVC
@@ -71,6 +76,8 @@ extern void __cdecl __debugbreak(void);
# define DAWN_NO_DISCARD [[nodiscard]]
# endif
+# define DAWN_DECLARE_UNUSED
+
#else
# error "Unsupported compiler"
#endif
diff --git a/chromium/third_party/dawn/src/common/Constants.h b/chromium/third_party/dawn/src/common/Constants.h
index 869cb13654a..238d0c2e078 100644
--- a/chromium/third_party/dawn/src/common/Constants.h
+++ b/chromium/third_party/dawn/src/common/Constants.h
@@ -27,4 +27,8 @@ static constexpr uint32_t kNumStages = 3;
static constexpr uint32_t kMaxColorAttachments = 4u;
static constexpr uint32_t kTextureRowPitchAlignment = 256u;
+// Non spec defined constants.
+static constexpr float kLodMin = 0.0;
+static constexpr float kLodMax = 1000.0;
+
#endif // COMMON_CONSTANTS_H_
diff --git a/chromium/third_party/dawn/src/common/Result.h b/chromium/third_party/dawn/src/common/Result.h
index b5bf5e57827..b4824fe62f4 100644
--- a/chromium/third_party/dawn/src/common/Result.h
+++ b/chromium/third_party/dawn/src/common/Result.h
@@ -282,11 +282,11 @@ E* Result<T*, E*>::GetErrorFromPayload(intptr_t payload) {
// Implementation of Result<T, E>
template <typename T, typename E>
-Result<T, E>::Result(T&& success) : mType(Success), mSuccess(success) {
+Result<T, E>::Result(T&& success) : mType(Success), mSuccess(std::move(success)) {
}
template <typename T, typename E>
-Result<T, E>::Result(E&& error) : mType(Error), mError(error) {
+Result<T, E>::Result(E&& error) : mType(Error), mError(std::move(error)) {
}
template <typename T, typename E>
@@ -296,7 +296,7 @@ Result<T, E>::~Result() {
template <typename T, typename E>
Result<T, E>::Result(Result<T, E>&& other)
- : mType(other.mType), mError(std::move(other.mError)), mSuccess(other.mSuccess) {
+ : mType(other.mType), mError(std::move(other.mError)), mSuccess(std::move(other.mSuccess)) {
other.mType = Acquired;
}
template <typename T, typename E>
diff --git a/chromium/third_party/dawn/src/dawn_native/Adapter.cpp b/chromium/third_party/dawn/src/dawn_native/Adapter.cpp
new file mode 100644
index 00000000000..137a1c7e70a
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/Adapter.cpp
@@ -0,0 +1,54 @@
+// Copyright 2018 The Dawn 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_native/Adapter.h"
+
+#include "dawn_native/Instance.h"
+
+namespace dawn_native {
+
+ AdapterBase::AdapterBase(InstanceBase* instance, BackendType backend)
+ : mInstance(instance), mBackend(backend) {
+ }
+
+ BackendType AdapterBase::GetBackendType() const {
+ return mBackend;
+ }
+
+ const PCIInfo& AdapterBase::GetPCIInfo() const {
+ return mPCIInfo;
+ }
+
+ InstanceBase* AdapterBase::GetInstance() const {
+ return mInstance;
+ }
+
+ DeviceBase* AdapterBase::CreateDevice() {
+ DeviceBase* result = nullptr;
+
+ if (mInstance->ConsumedError(CreateDeviceInternal(&result))) {
+ return nullptr;
+ }
+
+ return result;
+ }
+
+ MaybeError AdapterBase::CreateDeviceInternal(DeviceBase** result) {
+ // TODO(cwallez@chromium.org): This will eventually have validation that the device
+ // descriptor is valid and is a subset what's allowed on this adapter.
+ DAWN_TRY_ASSIGN(*result, CreateDeviceImpl());
+ return {};
+ }
+
+} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/Adapter.h b/chromium/third_party/dawn/src/dawn_native/Adapter.h
new file mode 100644
index 00000000000..bb15e70a92c
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/Adapter.h
@@ -0,0 +1,51 @@
+// Copyright 2018 The Dawn 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.
+
+#ifndef DAWNNATIVE_ADAPTER_H_
+#define DAWNNATIVE_ADAPTER_H_
+
+#include "dawn_native/DawnNative.h"
+
+#include "dawn_native/Error.h"
+
+namespace dawn_native {
+
+ class DeviceBase;
+
+ class AdapterBase {
+ public:
+ AdapterBase(InstanceBase* instance, BackendType backend);
+ virtual ~AdapterBase() = default;
+
+ BackendType GetBackendType() const;
+ const PCIInfo& GetPCIInfo() const;
+ InstanceBase* GetInstance() const;
+
+ DeviceBase* CreateDevice();
+
+ protected:
+ PCIInfo mPCIInfo = {};
+
+ private:
+ virtual ResultOrError<DeviceBase*> CreateDeviceImpl() = 0;
+
+ MaybeError CreateDeviceInternal(DeviceBase** result);
+
+ InstanceBase* mInstance = nullptr;
+ BackendType mBackend;
+ };
+
+} // namespace dawn_native
+
+#endif // DAWNNATIVE_ADAPTER_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/BackendConnection.cpp b/chromium/third_party/dawn/src/dawn_native/BackendConnection.cpp
new file mode 100644
index 00000000000..5a9d4b169f1
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/BackendConnection.cpp
@@ -0,0 +1,36 @@
+// Copyright 2018 The Dawn 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_native/BackendConnection.h"
+
+namespace dawn_native {
+
+ BackendConnection::BackendConnection(InstanceBase* instance, BackendType type)
+ : mInstance(instance), mType(type) {
+ }
+
+ BackendType BackendConnection::GetType() const {
+ return mType;
+ }
+
+ InstanceBase* BackendConnection::GetInstance() const {
+ return mInstance;
+ }
+
+ ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> BackendConnection::DiscoverAdapters(
+ const AdapterDiscoveryOptionsBase* options) {
+ return DAWN_VALIDATION_ERROR("DiscoverAdapters not implemented for this backend.");
+ }
+
+} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/BackendConnection.h b/chromium/third_party/dawn/src/dawn_native/BackendConnection.h
new file mode 100644
index 00000000000..e0e56994eca
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/BackendConnection.h
@@ -0,0 +1,50 @@
+// Copyright 2018 The Dawn 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.
+
+#ifndef DAWNNATIVE_BACKENDCONNECTION_H_
+#define DAWNNATIVE_BACKENDCONNECTION_H_
+
+#include "dawn_native/Adapter.h"
+#include "dawn_native/DawnNative.h"
+
+#include <memory>
+
+namespace dawn_native {
+
+ // An common interface for all backends. Mostly used to create adapters for a particular
+ // backend.
+ class BackendConnection {
+ public:
+ BackendConnection(InstanceBase* instance, BackendType type);
+ virtual ~BackendConnection() = default;
+
+ BackendType GetType() const;
+ InstanceBase* GetInstance() const;
+
+ // Returns all the adapters for the system that can be created by the backend, without extra
+ // options (such as debug adapters, custom driver libraries, etc.)
+ virtual std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() = 0;
+
+ // Returns new adapters created with the backend-specific options.
+ virtual ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
+ const AdapterDiscoveryOptionsBase* options);
+
+ private:
+ InstanceBase* mInstance = nullptr;
+ BackendType mType;
+ };
+
+} // namespace dawn_native
+
+#endif // DAWNNATIVE_BACKENDCONNECTION_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/BindGroup.cpp b/chromium/third_party/dawn/src/dawn_native/BindGroup.cpp
index 637b4b2fa40..5a5a1778f7f 100644
--- a/chromium/third_party/dawn/src/dawn_native/BindGroup.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/BindGroup.cpp
@@ -19,191 +19,190 @@
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/Buffer.h"
#include "dawn_native/Device.h"
+#include "dawn_native/Sampler.h"
#include "dawn_native/Texture.h"
namespace dawn_native {
- // BindGroup
+ namespace {
- BindGroupBase::BindGroupBase(BindGroupBuilder* builder)
- : ObjectBase(builder->GetDevice()),
- mLayout(std::move(builder->mLayout)),
- mBindings(std::move(builder->mBindings)) {
- }
+ // Helper functions to perform binding-type specific validation
- const BindGroupLayoutBase* BindGroupBase::GetLayout() const {
- return mLayout.Get();
- }
+ MaybeError ValidateBufferBinding(const BindGroupBinding& binding,
+ dawn::BufferUsageBit requiredUsage) {
+ if (binding.buffer == nullptr || binding.sampler != nullptr ||
+ binding.textureView != nullptr) {
+ return DAWN_VALIDATION_ERROR("expected buffer binding");
+ }
- BufferViewBase* BindGroupBase::GetBindingAsBufferView(size_t binding) {
- ASSERT(binding < kMaxBindingsPerGroup);
- ASSERT(mLayout->GetBindingInfo().mask[binding]);
- ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::UniformBuffer ||
- mLayout->GetBindingInfo().types[binding] == dawn::BindingType::StorageBuffer);
- return reinterpret_cast<BufferViewBase*>(mBindings[binding].Get());
- }
+ uint32_t bufferSize = binding.buffer->GetSize();
+ if (binding.size > bufferSize) {
+ return DAWN_VALIDATION_ERROR("Buffer binding size larger than the buffer");
+ }
- SamplerBase* BindGroupBase::GetBindingAsSampler(size_t binding) {
- ASSERT(binding < kMaxBindingsPerGroup);
- ASSERT(mLayout->GetBindingInfo().mask[binding]);
- ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::Sampler);
- return reinterpret_cast<SamplerBase*>(mBindings[binding].Get());
- }
+ // Note that no overflow can happen because we already checked that
+ // bufferSize >= binding.size
+ if (binding.offset > bufferSize - binding.size) {
+ return DAWN_VALIDATION_ERROR("Buffer binding doesn't fit in the buffer");
+ }
- TextureViewBase* BindGroupBase::GetBindingAsTextureView(size_t binding) {
- ASSERT(binding < kMaxBindingsPerGroup);
- ASSERT(mLayout->GetBindingInfo().mask[binding]);
- ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::SampledTexture);
- return reinterpret_cast<TextureViewBase*>(mBindings[binding].Get());
- }
+ if (!IsAligned(binding.offset, 256)) {
+ return DAWN_VALIDATION_ERROR(
+ "Buffer offset for bind group needs to be 256-byte aligned");
+ }
- // BindGroupBuilder
+ if (!(binding.buffer->GetUsage() & requiredUsage)) {
+ return DAWN_VALIDATION_ERROR("buffer binding usage mismatch");
+ }
- enum BindGroupSetProperties {
- BINDGROUP_PROPERTY_LAYOUT = 0x1,
- };
+ return {};
+ }
- BindGroupBuilder::BindGroupBuilder(DeviceBase* device) : Builder(device) {
- }
+ MaybeError ValidateTextureBinding(const BindGroupBinding& binding,
+ dawn::TextureUsageBit requiredUsage) {
+ if (binding.textureView == nullptr || binding.sampler != nullptr ||
+ binding.buffer != nullptr) {
+ return DAWN_VALIDATION_ERROR("expected texture binding");
+ }
- BindGroupBase* BindGroupBuilder::GetResultImpl() {
- constexpr int allProperties = BINDGROUP_PROPERTY_LAYOUT;
- if ((mPropertiesSet & allProperties) != allProperties) {
- HandleError("Bindgroup missing properties");
- return nullptr;
+ if (!(binding.textureView->GetTexture()->GetUsage() & requiredUsage)) {
+ return DAWN_VALIDATION_ERROR("texture binding usage mismatch");
+ }
+
+ return {};
}
- if (mSetMask != mLayout->GetBindingInfo().mask) {
- HandleError("Bindgroup missing bindings");
- return nullptr;
+ MaybeError ValidateSamplerBinding(const BindGroupBinding& binding) {
+ if (binding.sampler == nullptr || binding.textureView != nullptr ||
+ binding.buffer != nullptr) {
+ return DAWN_VALIDATION_ERROR("expected sampler binding");
+ }
+ return {};
}
- return GetDevice()->CreateBindGroup(this);
- }
+ } // anonymous namespace
- void BindGroupBuilder::SetLayout(BindGroupLayoutBase* layout) {
- if ((mPropertiesSet & BINDGROUP_PROPERTY_LAYOUT) != 0) {
- HandleError("Bindgroup layout property set multiple times");
- return;
+ MaybeError ValidateBindGroupDescriptor(DeviceBase*, const BindGroupDescriptor* descriptor) {
+ if (descriptor->nextInChain != nullptr) {
+ return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
}
- mLayout = layout;
- mPropertiesSet |= BINDGROUP_PROPERTY_LAYOUT;
- }
+ if (descriptor->layout == nullptr) {
+ return DAWN_VALIDATION_ERROR("layout cannot be null");
+ }
- void BindGroupBuilder::SetBufferViews(uint32_t start,
- uint32_t count,
- BufferViewBase* const* bufferViews) {
- if (!SetBindingsValidationBase(start, count)) {
- return;
+ const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo =
+ descriptor->layout->GetBindingInfo();
+
+ if (descriptor->numBindings != layoutInfo.mask.count()) {
+ return DAWN_VALIDATION_ERROR("numBindings mismatch");
}
- const auto& layoutInfo = mLayout->GetBindingInfo();
- for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
- dawn::BufferUsageBit requiredBit = dawn::BufferUsageBit::None;
- switch (layoutInfo.types[i]) {
- case dawn::BindingType::UniformBuffer:
- requiredBit = dawn::BufferUsageBit::Uniform;
- break;
+ std::bitset<kMaxBindingsPerGroup> bindingsSet;
+ for (uint32_t i = 0; i < descriptor->numBindings; ++i) {
+ const BindGroupBinding& binding = descriptor->bindings[i];
+ uint32_t bindingIndex = binding.binding;
- case dawn::BindingType::StorageBuffer:
- requiredBit = dawn::BufferUsageBit::Storage;
- break;
+ // Check that we can set this binding.
+ if (bindingIndex >= kMaxBindingsPerGroup) {
+ return DAWN_VALIDATION_ERROR("binding index too high");
+ }
- case dawn::BindingType::Sampler:
- case dawn::BindingType::SampledTexture:
- HandleError("Setting buffer for a wrong binding type");
- return;
+ if (!layoutInfo.mask[bindingIndex]) {
+ return DAWN_VALIDATION_ERROR("setting non-existent binding");
}
- if (!(bufferViews[j]->GetBuffer()->GetUsage() & requiredBit)) {
- HandleError("Buffer needs to allow the correct usage bit");
- return;
+ if (bindingsSet[bindingIndex]) {
+ return DAWN_VALIDATION_ERROR("binding set twice");
}
+ bindingsSet.set(bindingIndex);
- if (!IsAligned(bufferViews[j]->GetOffset(), 256)) {
- HandleError("Buffer view offset for bind group needs to be 256-byte aligned");
- return;
+ // Perform binding-type specific validation.
+ switch (layoutInfo.types[bindingIndex]) {
+ case dawn::BindingType::UniformBuffer:
+ DAWN_TRY(ValidateBufferBinding(binding, dawn::BufferUsageBit::Uniform));
+ break;
+ case dawn::BindingType::StorageBuffer:
+ DAWN_TRY(ValidateBufferBinding(binding, dawn::BufferUsageBit::Storage));
+ break;
+ case dawn::BindingType::SampledTexture:
+ DAWN_TRY(ValidateTextureBinding(binding, dawn::TextureUsageBit::Sampled));
+ break;
+ case dawn::BindingType::Sampler:
+ DAWN_TRY(ValidateSamplerBinding(binding));
+ break;
}
}
- SetBindingsBase(start, count, reinterpret_cast<ObjectBase* const*>(bufferViews));
+ // This should always be true because
+ // - numBindings has to match between the bind group and its layout.
+ // - Each binding must be set at most once
+ //
+ // We don't validate the equality because it wouldn't be possible to cover it with a test.
+ ASSERT(bindingsSet == layoutInfo.mask);
+
+ return {};
}
- void BindGroupBuilder::SetSamplers(uint32_t start,
- uint32_t count,
- SamplerBase* const* samplers) {
- if (!SetBindingsValidationBase(start, count)) {
- return;
- }
+ // BindGroup
- const auto& layoutInfo = mLayout->GetBindingInfo();
- for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
- if (layoutInfo.types[i] != dawn::BindingType::Sampler) {
- HandleError("Setting binding for a wrong layout binding type");
- return;
- }
- }
+ BindGroupBase::BindGroupBase(DeviceBase* device, const BindGroupDescriptor* descriptor)
+ : ObjectBase(device), mLayout(descriptor->layout) {
+ for (uint32_t i = 0; i < descriptor->numBindings; ++i) {
+ const BindGroupBinding& binding = descriptor->bindings[i];
- SetBindingsBase(start, count, reinterpret_cast<ObjectBase* const*>(samplers));
- }
+ uint32_t bindingIndex = binding.binding;
+ ASSERT(bindingIndex < kMaxBindingsPerGroup);
- void BindGroupBuilder::SetTextureViews(uint32_t start,
- uint32_t count,
- TextureViewBase* const* textureViews) {
- if (!SetBindingsValidationBase(start, count)) {
- return;
- }
+ // Only a single binding type should be set, so once we found it we can skip to the
+ // next loop iteration.
- const auto& layoutInfo = mLayout->GetBindingInfo();
- for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
- if (layoutInfo.types[i] != dawn::BindingType::SampledTexture) {
- HandleError("Setting binding for a wrong layout binding type");
- return;
+ if (binding.buffer != nullptr) {
+ ASSERT(mBindings[bindingIndex].Get() == nullptr);
+ mBindings[bindingIndex] = binding.buffer;
+ mOffsets[bindingIndex] = binding.offset;
+ mSizes[bindingIndex] = binding.size;
+ continue;
}
- if (!(textureViews[j]->GetTexture()->GetUsage() & dawn::TextureUsageBit::Sampled)) {
- HandleError("Texture needs to allow the sampled usage bit");
- return;
+ if (binding.textureView != nullptr) {
+ ASSERT(mBindings[bindingIndex].Get() == nullptr);
+ mBindings[bindingIndex] = binding.textureView;
+ continue;
}
- }
- SetBindingsBase(start, count, reinterpret_cast<ObjectBase* const*>(textureViews));
- }
-
- void BindGroupBuilder::SetBindingsBase(uint32_t start,
- uint32_t count,
- ObjectBase* const* objects) {
- for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
- mSetMask.set(i);
- mBindings[i] = objects[j];
+ if (binding.sampler != nullptr) {
+ ASSERT(mBindings[bindingIndex].Get() == nullptr);
+ mBindings[bindingIndex] = binding.sampler;
+ continue;
+ }
}
}
- bool BindGroupBuilder::SetBindingsValidationBase(uint32_t start, uint32_t count) {
- if (start + count > kMaxBindingsPerGroup) {
- HandleError("Setting bindings type over maximum number of bindings");
- return false;
- }
-
- if ((mPropertiesSet & BINDGROUP_PROPERTY_LAYOUT) == 0) {
- HandleError("Bindgroup layout must be set before views");
- return false;
- }
+ const BindGroupLayoutBase* BindGroupBase::GetLayout() const {
+ return mLayout.Get();
+ }
- const auto& layoutInfo = mLayout->GetBindingInfo();
- for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
- if (mSetMask[i]) {
- HandleError("Setting already set binding");
- return false;
- }
+ BufferBinding BindGroupBase::GetBindingAsBufferBinding(size_t binding) {
+ ASSERT(binding < kMaxBindingsPerGroup);
+ ASSERT(mLayout->GetBindingInfo().mask[binding]);
+ ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::UniformBuffer ||
+ mLayout->GetBindingInfo().types[binding] == dawn::BindingType::StorageBuffer);
+ BufferBase* buffer = reinterpret_cast<BufferBase*>(mBindings[binding].Get());
+ return {buffer, mOffsets[binding], mSizes[binding]};
+ }
- if (!layoutInfo.mask[i]) {
- HandleError("Setting binding that isn't present in the layout");
- return false;
- }
- }
+ SamplerBase* BindGroupBase::GetBindingAsSampler(size_t binding) {
+ ASSERT(binding < kMaxBindingsPerGroup);
+ ASSERT(mLayout->GetBindingInfo().mask[binding]);
+ ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::Sampler);
+ return reinterpret_cast<SamplerBase*>(mBindings[binding].Get());
+ }
- return true;
+ TextureViewBase* BindGroupBase::GetBindingAsTextureView(size_t binding) {
+ ASSERT(binding < kMaxBindingsPerGroup);
+ ASSERT(mLayout->GetBindingInfo().mask[binding]);
+ ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::SampledTexture);
+ return reinterpret_cast<TextureViewBase*>(mBindings[binding].Get());
}
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/BindGroup.h b/chromium/third_party/dawn/src/dawn_native/BindGroup.h
index 115b8256ddf..050747b1070 100644
--- a/chromium/third_party/dawn/src/dawn_native/BindGroup.h
+++ b/chromium/third_party/dawn/src/dawn_native/BindGroup.h
@@ -17,54 +17,41 @@
#include "common/Constants.h"
#include "dawn_native/BindGroupLayout.h"
-#include "dawn_native/Builder.h"
+#include "dawn_native/Error.h"
#include "dawn_native/Forward.h"
#include "dawn_native/ObjectBase.h"
#include "dawn_native/dawn_platform.h"
#include <array>
-#include <bitset>
namespace dawn_native {
- class BindGroupBase : public ObjectBase {
- public:
- BindGroupBase(BindGroupBuilder* builder);
+ class DeviceBase;
- const BindGroupLayoutBase* GetLayout() const;
- BufferViewBase* GetBindingAsBufferView(size_t binding);
- SamplerBase* GetBindingAsSampler(size_t binding);
- TextureViewBase* GetBindingAsTextureView(size_t binding);
+ MaybeError ValidateBindGroupDescriptor(DeviceBase* device,
+ const BindGroupDescriptor* descriptor);
- private:
- Ref<BindGroupLayoutBase> mLayout;
- std::array<Ref<ObjectBase>, kMaxBindingsPerGroup> mBindings;
+ struct BufferBinding {
+ BufferBase* buffer;
+ uint32_t offset;
+ uint32_t size;
};
- class BindGroupBuilder : public Builder<BindGroupBase> {
+ class BindGroupBase : public ObjectBase {
public:
- BindGroupBuilder(DeviceBase* device);
-
- // Dawn API
- void SetLayout(BindGroupLayoutBase* layout);
+ BindGroupBase(DeviceBase* device, const BindGroupDescriptor* descriptor);
- void SetBufferViews(uint32_t start, uint32_t count, BufferViewBase* const* bufferViews);
- void SetSamplers(uint32_t start, uint32_t count, SamplerBase* const* samplers);
- void SetTextureViews(uint32_t start, uint32_t count, TextureViewBase* const* textureViews);
+ const BindGroupLayoutBase* GetLayout() const;
+ BufferBinding GetBindingAsBufferBinding(size_t binding);
+ SamplerBase* GetBindingAsSampler(size_t binding);
+ TextureViewBase* GetBindingAsTextureView(size_t binding);
private:
- friend class BindGroupBase;
-
- BindGroupBase* GetResultImpl() override;
- void SetBindingsBase(uint32_t start, uint32_t count, ObjectBase* const* objects);
- bool SetBindingsValidationBase(uint32_t start, uint32_t count);
-
- std::bitset<kMaxBindingsPerGroup> mSetMask;
- int mPropertiesSet = 0;
-
Ref<BindGroupLayoutBase> mLayout;
std::array<Ref<ObjectBase>, kMaxBindingsPerGroup> mBindings;
+ std::array<uint32_t, kMaxBindingsPerGroup> mOffsets;
+ std::array<uint32_t, kMaxBindingsPerGroup> mSizes;
};
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/BlendState.cpp b/chromium/third_party/dawn/src/dawn_native/BlendState.cpp
deleted file mode 100644
index 2cf042d23bc..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/BlendState.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2017 The Dawn 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_native/BlendState.h"
-
-#include "dawn_native/Device.h"
-
-namespace dawn_native {
-
- // BlendStateBase
-
- BlendStateBase::BlendStateBase(BlendStateBuilder* builder)
- : ObjectBase(builder->GetDevice()), mBlendInfo(builder->mBlendInfo) {
- }
-
- const BlendStateBase::BlendInfo& BlendStateBase::GetBlendInfo() const {
- return mBlendInfo;
- }
-
- // BlendStateBuilder
-
- enum BlendStateSetProperties {
- BLEND_STATE_PROPERTY_BLEND_ENABLED = 0x1,
- BLEND_STATE_PROPERTY_ALPHA_BLEND = 0x2,
- BLEND_STATE_PROPERTY_COLOR_BLEND = 0x4,
- BLEND_STATE_PROPERTY_COLOR_WRITE_MASK = 0x08,
- };
-
- BlendStateBuilder::BlendStateBuilder(DeviceBase* device) : Builder(device) {
- }
-
- BlendStateBase* BlendStateBuilder::GetResultImpl() {
- return GetDevice()->CreateBlendState(this);
- }
-
- void BlendStateBuilder::SetBlendEnabled(bool blendEnabled) {
- if ((mPropertiesSet & BLEND_STATE_PROPERTY_BLEND_ENABLED) != 0) {
- HandleError("Blend enabled property set multiple times");
- return;
- }
-
- mPropertiesSet |= BLEND_STATE_PROPERTY_BLEND_ENABLED;
-
- mBlendInfo.blendEnabled = blendEnabled;
- }
-
- void BlendStateBuilder::SetAlphaBlend(const BlendDescriptor* alphaBlend) {
- if ((mPropertiesSet & BLEND_STATE_PROPERTY_ALPHA_BLEND) != 0) {
- HandleError("Alpha blend property set multiple times");
- return;
- }
-
- mPropertiesSet |= BLEND_STATE_PROPERTY_ALPHA_BLEND;
-
- // TODO(yunchao.he@intel.com): validate the enum values in
- // ValidateBlendStateDescriptor when it is added.
- mBlendInfo.alphaBlend.operation = alphaBlend->operation;
- mBlendInfo.alphaBlend.srcFactor = alphaBlend->srcFactor;
- mBlendInfo.alphaBlend.dstFactor = alphaBlend->dstFactor;
- }
-
- void BlendStateBuilder::SetColorBlend(const BlendDescriptor* colorBlend) {
- if ((mPropertiesSet & BLEND_STATE_PROPERTY_COLOR_BLEND) != 0) {
- HandleError("Color blend property set multiple times");
- return;
- }
-
- mPropertiesSet |= BLEND_STATE_PROPERTY_COLOR_BLEND;
-
- // TODO(yunchao.he@intel.com): validate the enum values in
- // ValidateBlendStateDescriptor when it is added.
- mBlendInfo.colorBlend.operation = colorBlend->operation;
- mBlendInfo.colorBlend.srcFactor = colorBlend->srcFactor;
- mBlendInfo.colorBlend.dstFactor = colorBlend->dstFactor;
- }
-
- void BlendStateBuilder::SetColorWriteMask(dawn::ColorWriteMask colorWriteMask) {
- if ((mPropertiesSet & BLEND_STATE_PROPERTY_COLOR_WRITE_MASK) != 0) {
- HandleError("Color write mask property set multiple times");
- return;
- }
-
- mPropertiesSet |= BLEND_STATE_PROPERTY_COLOR_WRITE_MASK;
-
- mBlendInfo.colorWriteMask = colorWriteMask;
- }
-} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/BlendState.h b/chromium/third_party/dawn/src/dawn_native/BlendState.h
deleted file mode 100644
index 72e8821b549..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/BlendState.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017 The Dawn 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.
-
-#ifndef DAWNNATIVE_BLENDSTATE_H_
-#define DAWNNATIVE_BLENDSTATE_H_
-
-#include "dawn_native/Builder.h"
-#include "dawn_native/Forward.h"
-#include "dawn_native/ObjectBase.h"
-
-#include "dawn_native/dawn_platform.h"
-
-namespace dawn_native {
-
- class BlendStateBase : public ObjectBase {
- public:
- BlendStateBase(BlendStateBuilder* builder);
-
- struct BlendInfo {
- bool blendEnabled = false;
- BlendDescriptor alphaBlend = {dawn::BlendOperation::Add, dawn::BlendFactor::One,
- dawn::BlendFactor::Zero};
- BlendDescriptor colorBlend = {dawn::BlendOperation::Add, dawn::BlendFactor::One,
- dawn::BlendFactor::Zero};
- dawn::ColorWriteMask colorWriteMask = dawn::ColorWriteMask::All;
- };
-
- const BlendInfo& GetBlendInfo() const;
-
- private:
- BlendInfo mBlendInfo;
- };
-
- class BlendStateBuilder : public Builder<BlendStateBase> {
- public:
- BlendStateBuilder(DeviceBase* device);
-
- // Dawn API
- void SetBlendEnabled(bool blendEnabled);
- void SetAlphaBlend(const BlendDescriptor* alphaBlend);
- void SetColorBlend(const BlendDescriptor* colorBlend);
- void SetColorWriteMask(dawn::ColorWriteMask colorWriteMask);
-
- private:
- friend class BlendStateBase;
-
- BlendStateBase* GetResultImpl() override;
-
- int mPropertiesSet = 0;
-
- BlendStateBase::BlendInfo mBlendInfo;
- };
-
-} // namespace dawn_native
-
-#endif // DAWNNATIVE_BLENDSTATE_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/Buffer.cpp b/chromium/third_party/dawn/src/dawn_native/Buffer.cpp
index e073491144c..887356775a6 100644
--- a/chromium/third_party/dawn/src/dawn_native/Buffer.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/Buffer.cpp
@@ -60,10 +60,6 @@ namespace dawn_native {
}
}
- BufferViewBuilder* BufferBase::CreateBufferViewBuilder() {
- return new BufferViewBuilder(GetDevice(), this);
- }
-
uint32_t BufferBase::GetSize() const {
return mSize;
}
@@ -170,8 +166,12 @@ namespace dawn_native {
}
MaybeError BufferBase::ValidateSetSubData(uint32_t start, uint32_t count) const {
- // TODO(cwallez@chromium.org): check for overflows.
- if (start + count > GetSize()) {
+ if (count > GetSize()) {
+ return DAWN_VALIDATION_ERROR("Buffer subdata with too much data");
+ }
+
+ // Note that no overflow can happen because we already checked for GetSize() >= count
+ if (start > GetSize() - count) {
return DAWN_VALIDATION_ERROR("Buffer subdata out of range");
}
@@ -185,9 +185,13 @@ namespace dawn_native {
MaybeError BufferBase::ValidateMap(uint32_t start,
uint32_t size,
dawn::BufferUsageBit requiredUsage) const {
- // TODO(cwallez@chromium.org): check for overflows.
- if (start + size > GetSize()) {
- return DAWN_VALIDATION_ERROR("Buffer map read out of range");
+ if (size > GetSize()) {
+ return DAWN_VALIDATION_ERROR("Buffer mapping with too big a region");
+ }
+
+ // Note that no overflow can happen because we already checked for GetSize() >= size
+ if (start > GetSize() - size) {
+ return DAWN_VALIDATION_ERROR("Buffer mapping out of range");
}
if (mIsMapped) {
@@ -209,62 +213,4 @@ namespace dawn_native {
return {};
}
- // BufferViewBase
-
- BufferViewBase::BufferViewBase(BufferViewBuilder* builder)
- : ObjectBase(builder->GetDevice()),
- mBuffer(std::move(builder->mBuffer)),
- mSize(builder->mSize),
- mOffset(builder->mOffset) {
- }
-
- BufferBase* BufferViewBase::GetBuffer() {
- return mBuffer.Get();
- }
-
- uint32_t BufferViewBase::GetSize() const {
- return mSize;
- }
-
- uint32_t BufferViewBase::GetOffset() const {
- return mOffset;
- }
-
- // BufferViewBuilder
-
- enum BufferViewSetProperties {
- BUFFER_VIEW_PROPERTY_EXTENT = 0x1,
- };
-
- BufferViewBuilder::BufferViewBuilder(DeviceBase* device, BufferBase* buffer)
- : Builder(device), mBuffer(buffer) {
- }
-
- BufferViewBase* BufferViewBuilder::GetResultImpl() {
- constexpr int allProperties = BUFFER_VIEW_PROPERTY_EXTENT;
- if ((mPropertiesSet & allProperties) != allProperties) {
- HandleError("Buffer view missing properties");
- return nullptr;
- }
-
- return GetDevice()->CreateBufferView(this);
- }
-
- void BufferViewBuilder::SetExtent(uint32_t offset, uint32_t size) {
- if ((mPropertiesSet & BUFFER_VIEW_PROPERTY_EXTENT) != 0) {
- HandleError("Buffer view extent property set multiple times");
- return;
- }
-
- uint64_t viewEnd = static_cast<uint64_t>(offset) + static_cast<uint64_t>(size);
- if (viewEnd > static_cast<uint64_t>(mBuffer->GetSize())) {
- HandleError("Buffer view end is OOB");
- return;
- }
-
- mOffset = offset;
- mSize = size;
- mPropertiesSet |= BUFFER_VIEW_PROPERTY_EXTENT;
- }
-
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/Buffer.h b/chromium/third_party/dawn/src/dawn_native/Buffer.h
index ce10ea5b619..9a3fa2cc46a 100644
--- a/chromium/third_party/dawn/src/dawn_native/Buffer.h
+++ b/chromium/third_party/dawn/src/dawn_native/Buffer.h
@@ -45,7 +45,6 @@ namespace dawn_native {
MaybeError ValidateCanUseInSubmitNow() const;
// Dawn API
- BufferViewBuilder* CreateBufferViewBuilder();
void SetSubData(uint32_t start, uint32_t count, const uint8_t* data);
void MapReadAsync(uint32_t start,
uint32_t size,
@@ -86,40 +85,8 @@ namespace dawn_native {
bool mIsMapped = false;
};
- class BufferViewBase : public ObjectBase {
- public:
- BufferViewBase(BufferViewBuilder* builder);
-
- BufferBase* GetBuffer();
- uint32_t GetSize() const;
- uint32_t GetOffset() const;
-
- private:
- Ref<BufferBase> mBuffer;
- uint32_t mSize;
- uint32_t mOffset;
- };
-
- class BufferViewBuilder : public Builder<BufferViewBase> {
- public:
- BufferViewBuilder(DeviceBase* device, BufferBase* buffer);
-
- // Dawn API
- void SetExtent(uint32_t offset, uint32_t size);
-
- private:
- friend class BufferViewBase;
-
- BufferViewBase* GetResultImpl() override;
-
- Ref<BufferBase> mBuffer;
- uint32_t mOffset = 0;
- uint32_t mSize = 0;
- int mPropertiesSet = 0;
- };
-
// This builder class is kept around purely for testing but should not be used.
- class BufferBuilder : public Builder<BufferViewBase> {
+ class BufferBuilder : public Builder<BufferBase> {
public:
BufferBuilder(DeviceBase* device) : Builder(device) {
UNREACHABLE();
diff --git a/chromium/third_party/dawn/src/dawn_native/CommandBuffer.cpp b/chromium/third_party/dawn/src/dawn_native/CommandBuffer.cpp
index 8ddcc15b5c0..97b5678b889 100644
--- a/chromium/third_party/dawn/src/dawn_native/CommandBuffer.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/CommandBuffer.cpp
@@ -35,29 +35,30 @@ namespace dawn_native {
namespace {
- MaybeError ValidateCopyLocationFitsInTexture(const TextureCopyLocation& location) {
- const TextureBase* texture = location.texture.Get();
- if (location.level >= texture->GetNumMipLevels()) {
+ MaybeError ValidateCopySizeFitsInTexture(const TextureCopy& textureCopy,
+ const Extent3D& copySize) {
+ const TextureBase* texture = textureCopy.texture.Get();
+ if (textureCopy.level >= texture->GetNumMipLevels()) {
return DAWN_VALIDATION_ERROR("Copy mip-level out of range");
}
- if (location.slice >= texture->GetArrayLayers()) {
+ if (textureCopy.slice >= texture->GetArrayLayers()) {
return DAWN_VALIDATION_ERROR("Copy array-layer out of range");
}
// All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid
// overflows.
- uint64_t level = location.level;
- if (uint64_t(location.x) + uint64_t(location.width) >
+ uint64_t level = textureCopy.level;
+ if (uint64_t(textureCopy.origin.x) + uint64_t(copySize.width) >
(static_cast<uint64_t>(texture->GetSize().width) >> level) ||
- uint64_t(location.y) + uint64_t(location.height) >
+ uint64_t(textureCopy.origin.y) + uint64_t(copySize.height) >
(static_cast<uint64_t>(texture->GetSize().height) >> level)) {
return DAWN_VALIDATION_ERROR("Copy would touch outside of the texture");
}
// TODO(cwallez@chromium.org): Check the depth bound differently for 2D arrays and 3D
// textures
- if (location.z != 0 || location.depth != 1) {
+ if (textureCopy.origin.z != 0 || copySize.depth != 1) {
return DAWN_VALIDATION_ERROR("No support for z != 0 and depth != 1 for now");
}
@@ -69,31 +70,42 @@ namespace dawn_native {
return offset <= bufferSize && (size <= (bufferSize - offset));
}
- MaybeError ValidateCopySizeFitsInBuffer(const BufferCopyLocation& location,
- uint32_t dataSize) {
- if (!FitsInBuffer(location.buffer.Get(), location.offset, dataSize)) {
+ MaybeError ValidateCopySizeFitsInBuffer(const BufferCopy& bufferCopy, uint32_t dataSize) {
+ if (!FitsInBuffer(bufferCopy.buffer.Get(), bufferCopy.offset, dataSize)) {
return DAWN_VALIDATION_ERROR("Copy would overflow the buffer");
}
return {};
}
- MaybeError ValidateTexelBufferOffset(TextureBase* texture,
- const BufferCopyLocation& location) {
+ MaybeError ValidateTexelBufferOffset(TextureBase* texture, const BufferCopy& bufferCopy) {
uint32_t texelSize =
static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat()));
- if (location.offset % texelSize != 0) {
+ if (bufferCopy.offset % texelSize != 0) {
return DAWN_VALIDATION_ERROR("Buffer offset must be a multiple of the texel size");
}
return {};
}
- MaybeError ComputeTextureCopyBufferSize(const TextureCopyLocation& location,
+ MaybeError ValidateImageHeight(uint32_t imageHeight, uint32_t copyHeight) {
+ if (imageHeight < copyHeight) {
+ return DAWN_VALIDATION_ERROR("Image height must not be less than the copy height.");
+ }
+
+ return {};
+ }
+
+ MaybeError ComputeTextureCopyBufferSize(const Extent3D& copySize,
uint32_t rowPitch,
+ uint32_t imageHeight,
uint32_t* bufferSize) {
+ DAWN_TRY(ValidateImageHeight(imageHeight, copySize.height));
+
// TODO(cwallez@chromium.org): check for overflows
- *bufferSize = (rowPitch * (location.height - 1) + location.width) * location.depth;
+ uint32_t slicePitch = rowPitch * imageHeight;
+ uint32_t sliceSize = rowPitch * (copySize.height - 1) + copySize.width;
+ *bufferSize = (slicePitch * (copySize.depth - 1)) + sliceSize;
return {};
}
@@ -103,13 +115,15 @@ namespace dawn_native {
return texelSize * width;
}
- MaybeError ValidateRowPitch(const TextureCopyLocation& location, uint32_t rowPitch) {
+ MaybeError ValidateRowPitch(dawn::TextureFormat format,
+ const Extent3D& copySize,
+ uint32_t rowPitch) {
if (rowPitch % kTextureRowPitchAlignment != 0) {
return DAWN_VALIDATION_ERROR("Row pitch must be a multiple of 256");
}
- uint32_t texelSize = TextureFormatPixelSize(location.texture.Get()->GetFormat());
- if (rowPitch < location.width * texelSize) {
+ uint32_t texelSize = TextureFormatPixelSize(format);
+ if (rowPitch < copySize.width * texelSize) {
return DAWN_VALIDATION_ERROR(
"Row pitch must not be less than the number of bytes per row");
}
@@ -254,12 +268,12 @@ namespace dawn_native {
switch (type) {
case dawn::BindingType::UniformBuffer: {
- BufferBase* buffer = group->GetBindingAsBufferView(i)->GetBuffer();
+ BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer;
tracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Uniform);
} break;
case dawn::BindingType::StorageBuffer: {
- BufferBase* buffer = group->GetBindingAsBufferView(i)->GetBuffer();
+ BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer;
tracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Storage);
} break;
@@ -350,6 +364,10 @@ namespace dawn_native {
// Implementation of the command buffer validation that can be precomputed before submit
MaybeError CommandBufferBuilder::ValidateGetResult() {
+ if (mEncodingState != EncodingState::TopLevel) {
+ return DAWN_VALIDATION_ERROR("Command buffer recording ended mid-pass");
+ }
+
MoveToIterator();
mIterator.Reset();
@@ -385,11 +403,14 @@ namespace dawn_native {
CopyBufferToTextureCmd* copy = mIterator.NextCommand<CopyBufferToTextureCmd>();
uint32_t bufferCopySize = 0;
- DAWN_TRY(ValidateRowPitch(copy->destination, copy->rowPitch));
- DAWN_TRY(ComputeTextureCopyBufferSize(copy->destination, copy->rowPitch,
+ DAWN_TRY(ValidateRowPitch(copy->destination.texture->GetFormat(),
+ copy->copySize, copy->source.rowPitch));
+
+ DAWN_TRY(ComputeTextureCopyBufferSize(copy->copySize, copy->source.rowPitch,
+ copy->source.imageHeight,
&bufferCopySize));
- DAWN_TRY(ValidateCopyLocationFitsInTexture(copy->destination));
+ DAWN_TRY(ValidateCopySizeFitsInTexture(copy->destination, copy->copySize));
DAWN_TRY(ValidateCopySizeFitsInBuffer(copy->source, bufferCopySize));
DAWN_TRY(
ValidateTexelBufferOffset(copy->destination.texture.Get(), copy->source));
@@ -407,11 +428,13 @@ namespace dawn_native {
CopyTextureToBufferCmd* copy = mIterator.NextCommand<CopyTextureToBufferCmd>();
uint32_t bufferCopySize = 0;
- DAWN_TRY(ValidateRowPitch(copy->source, copy->rowPitch));
- DAWN_TRY(ComputeTextureCopyBufferSize(copy->source, copy->rowPitch,
- &bufferCopySize));
+ DAWN_TRY(ValidateRowPitch(copy->source.texture->GetFormat(), copy->copySize,
+ copy->destination.rowPitch));
+ DAWN_TRY(ComputeTextureCopyBufferSize(
+ copy->copySize, copy->destination.rowPitch, copy->destination.imageHeight,
+ &bufferCopySize));
- DAWN_TRY(ValidateCopyLocationFitsInTexture(copy->source));
+ DAWN_TRY(ValidateCopySizeFitsInTexture(copy->source, copy->copySize));
DAWN_TRY(ValidateCopySizeFitsInBuffer(copy->destination, bufferCopySize));
DAWN_TRY(
ValidateTexelBufferOffset(copy->source.texture.Get(), copy->destination));
@@ -483,6 +506,7 @@ namespace dawn_native {
}
}
+ UNREACHABLE();
return DAWN_VALIDATION_ERROR("Unfinished compute pass");
}
@@ -512,14 +536,14 @@ namespace dawn_native {
return {};
} break;
- case Command::DrawArrays: {
- mIterator.NextCommand<DrawArraysCmd>();
- DAWN_TRY(persistentState.ValidateCanDrawArrays());
+ case Command::Draw: {
+ mIterator.NextCommand<DrawCmd>();
+ DAWN_TRY(persistentState.ValidateCanDraw());
} break;
- case Command::DrawElements: {
- mIterator.NextCommand<DrawElementsCmd>();
- DAWN_TRY(persistentState.ValidateCanDrawElements());
+ case Command::DrawIndexed: {
+ mIterator.NextCommand<DrawIndexedCmd>();
+ DAWN_TRY(persistentState.ValidateCanDrawIndexed());
} break;
case Command::SetRenderPipeline: {
@@ -590,6 +614,7 @@ namespace dawn_native {
}
}
+ UNREACHABLE();
return DAWN_VALIDATION_ERROR("Unfinished render pass");
}
@@ -618,6 +643,11 @@ namespace dawn_native {
return nullptr;
}
+ if (info == nullptr) {
+ HandleError("RenderPassDescriptor cannot be null");
+ return nullptr;
+ }
+
BeginRenderPassCmd* cmd = mAllocator.Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
new (cmd) BeginRenderPassCmd;
cmd->info = info;
@@ -635,6 +665,16 @@ namespace dawn_native {
return;
}
+ if (source == nullptr) {
+ HandleError("Source cannot be null");
+ return;
+ }
+
+ if (destination == nullptr) {
+ HandleError("Destination cannot be null");
+ return;
+ }
+
CopyBufferToBufferCmd* copy =
mAllocator.Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
new (copy) CopyBufferToBufferCmd;
@@ -651,24 +691,36 @@ namespace dawn_native {
if (ConsumedError(ValidateCanRecordTopLevelCommands())) {
return;
}
+
+ if (source->buffer == nullptr) {
+ HandleError("Buffer cannot be null");
+ return;
+ }
+
+ if (destination->texture == nullptr) {
+ HandleError("Texture cannot be null");
+ return;
+ }
+
CopyBufferToTextureCmd* copy =
mAllocator.Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
new (copy) CopyBufferToTextureCmd;
copy->source.buffer = source->buffer;
copy->source.offset = source->offset;
copy->destination.texture = destination->texture;
- copy->destination.x = destination->origin.x;
- copy->destination.y = destination->origin.y;
- copy->destination.z = destination->origin.z;
- copy->destination.width = copySize->width;
- copy->destination.height = copySize->height;
- copy->destination.depth = copySize->depth;
+ copy->destination.origin = destination->origin;
+ copy->copySize = *copySize;
copy->destination.level = destination->level;
copy->destination.slice = destination->slice;
if (source->rowPitch == 0) {
- copy->rowPitch = ComputeDefaultRowPitch(destination->texture, copySize->width);
+ copy->source.rowPitch = ComputeDefaultRowPitch(destination->texture, copySize->width);
+ } else {
+ copy->source.rowPitch = source->rowPitch;
+ }
+ if (source->imageHeight == 0) {
+ copy->source.imageHeight = copySize->height;
} else {
- copy->rowPitch = source->rowPitch;
+ copy->source.imageHeight = source->imageHeight;
}
}
@@ -678,24 +730,36 @@ namespace dawn_native {
if (ConsumedError(ValidateCanRecordTopLevelCommands())) {
return;
}
+
+ if (source->texture == nullptr) {
+ HandleError("Texture cannot be null");
+ return;
+ }
+
+ if (destination->buffer == nullptr) {
+ HandleError("Buffer cannot be null");
+ return;
+ }
+
CopyTextureToBufferCmd* copy =
mAllocator.Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
new (copy) CopyTextureToBufferCmd;
copy->source.texture = source->texture;
- copy->source.x = source->origin.x;
- copy->source.y = source->origin.y;
- copy->source.z = source->origin.z;
- copy->source.width = copySize->width;
- copy->source.height = copySize->height;
- copy->source.depth = copySize->depth;
+ copy->source.origin = source->origin;
+ copy->copySize = *copySize;
copy->source.level = source->level;
copy->source.slice = source->slice;
copy->destination.buffer = destination->buffer;
copy->destination.offset = destination->offset;
if (destination->rowPitch == 0) {
- copy->rowPitch = ComputeDefaultRowPitch(source->texture, copySize->width);
+ copy->destination.rowPitch = ComputeDefaultRowPitch(source->texture, copySize->width);
+ } else {
+ copy->destination.rowPitch = destination->rowPitch;
+ }
+ if (destination->imageHeight == 0) {
+ copy->destination.imageHeight = copySize->height;
} else {
- copy->rowPitch = destination->rowPitch;
+ copy->destination.imageHeight = destination->imageHeight;
}
}
diff --git a/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp b/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp
index 44799ac1091..9a7fdd988e3 100644
--- a/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp
@@ -38,11 +38,11 @@ namespace dawn_native {
static constexpr CommandBufferStateTracker::ValidationAspects kDispatchAspects =
1 << VALIDATION_ASPECT_PIPELINE | 1 << VALIDATION_ASPECT_BIND_GROUPS;
- static constexpr CommandBufferStateTracker::ValidationAspects kDrawArraysAspects =
+ static constexpr CommandBufferStateTracker::ValidationAspects kDrawAspects =
1 << VALIDATION_ASPECT_PIPELINE | 1 << VALIDATION_ASPECT_BIND_GROUPS |
1 << VALIDATION_ASPECT_VERTEX_BUFFERS;
- static constexpr CommandBufferStateTracker::ValidationAspects kDrawElementsAspects =
+ static constexpr CommandBufferStateTracker::ValidationAspects kDrawIndexedAspects =
1 << VALIDATION_ASPECT_PIPELINE | 1 << VALIDATION_ASPECT_BIND_GROUPS |
1 << VALIDATION_ASPECT_VERTEX_BUFFERS | 1 << VALIDATION_ASPECT_INDEX_BUFFER;
@@ -53,12 +53,12 @@ namespace dawn_native {
return ValidateOperation(kDispatchAspects);
}
- MaybeError CommandBufferStateTracker::ValidateCanDrawArrays() {
- return ValidateOperation(kDrawArraysAspects);
+ MaybeError CommandBufferStateTracker::ValidateCanDraw() {
+ return ValidateOperation(kDrawAspects);
}
- MaybeError CommandBufferStateTracker::ValidateCanDrawElements() {
- return ValidateOperation(kDrawElementsAspects);
+ MaybeError CommandBufferStateTracker::ValidateCanDrawIndexed() {
+ return ValidateOperation(kDrawIndexedAspects);
}
MaybeError CommandBufferStateTracker::ValidateOperation(ValidationAspects requiredAspects) {
diff --git a/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.h b/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.h
index 9dd1edbac6d..2419dede9d6 100644
--- a/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.h
+++ b/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.h
@@ -29,8 +29,8 @@ namespace dawn_native {
public:
// Non-state-modifying validation functions
MaybeError ValidateCanDispatch();
- MaybeError ValidateCanDrawArrays();
- MaybeError ValidateCanDrawElements();
+ MaybeError ValidateCanDraw();
+ MaybeError ValidateCanDrawIndexed();
// State-modifying methods
void SetComputePipeline(ComputePipelineBase* pipeline);
diff --git a/chromium/third_party/dawn/src/dawn_native/Commands.cpp b/chromium/third_party/dawn/src/dawn_native/Commands.cpp
index 455675a5b6e..6443fc8abc5 100644
--- a/chromium/third_party/dawn/src/dawn_native/Commands.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/Commands.cpp
@@ -53,13 +53,13 @@ namespace dawn_native {
DispatchCmd* dispatch = commands->NextCommand<DispatchCmd>();
dispatch->~DispatchCmd();
} break;
- case Command::DrawArrays: {
- DrawArraysCmd* draw = commands->NextCommand<DrawArraysCmd>();
- draw->~DrawArraysCmd();
+ case Command::Draw: {
+ DrawCmd* draw = commands->NextCommand<DrawCmd>();
+ draw->~DrawCmd();
} break;
- case Command::DrawElements: {
- DrawElementsCmd* draw = commands->NextCommand<DrawElementsCmd>();
- draw->~DrawElementsCmd();
+ case Command::DrawIndexed: {
+ DrawIndexedCmd* draw = commands->NextCommand<DrawIndexedCmd>();
+ draw->~DrawIndexedCmd();
} break;
case Command::EndComputePass: {
EndComputePassCmd* cmd = commands->NextCommand<EndComputePassCmd>();
@@ -142,12 +142,12 @@ namespace dawn_native {
commands->NextCommand<DispatchCmd>();
break;
- case Command::DrawArrays:
- commands->NextCommand<DrawArraysCmd>();
+ case Command::Draw:
+ commands->NextCommand<DrawCmd>();
break;
- case Command::DrawElements:
- commands->NextCommand<DrawElementsCmd>();
+ case Command::DrawIndexed:
+ commands->NextCommand<DrawIndexedCmd>();
break;
case Command::EndComputePass:
diff --git a/chromium/third_party/dawn/src/dawn_native/Commands.h b/chromium/third_party/dawn/src/dawn_native/Commands.h
index e4598ad6a89..37b2297714e 100644
--- a/chromium/third_party/dawn/src/dawn_native/Commands.h
+++ b/chromium/third_party/dawn/src/dawn_native/Commands.h
@@ -33,8 +33,8 @@ namespace dawn_native {
CopyBufferToTexture,
CopyTextureToBuffer,
Dispatch,
- DrawArrays,
- DrawElements,
+ Draw,
+ DrawIndexed,
EndComputePass,
EndRenderPass,
SetComputePipeline,
@@ -54,35 +54,36 @@ namespace dawn_native {
Ref<RenderPassDescriptorBase> info;
};
- struct BufferCopyLocation {
+ struct BufferCopy {
Ref<BufferBase> buffer;
- uint32_t offset;
+ uint32_t offset; // Bytes
+ uint32_t rowPitch; // Bytes
+ uint32_t imageHeight; // Texels
};
- struct TextureCopyLocation {
+ struct TextureCopy {
Ref<TextureBase> texture;
- uint32_t x, y, z;
- uint32_t width, height, depth;
uint32_t level;
uint32_t slice;
+ Origin3D origin; // Texels
};
struct CopyBufferToBufferCmd {
- BufferCopyLocation source;
- BufferCopyLocation destination;
+ BufferCopy source;
+ BufferCopy destination;
uint32_t size;
};
struct CopyBufferToTextureCmd {
- BufferCopyLocation source;
- TextureCopyLocation destination;
- uint32_t rowPitch;
+ BufferCopy source;
+ TextureCopy destination;
+ Extent3D copySize; // Texels
};
struct CopyTextureToBufferCmd {
- TextureCopyLocation source;
- BufferCopyLocation destination;
- uint32_t rowPitch;
+ TextureCopy source;
+ BufferCopy destination;
+ Extent3D copySize; // Texels
};
struct DispatchCmd {
@@ -91,17 +92,18 @@ namespace dawn_native {
uint32_t z;
};
- struct DrawArraysCmd {
+ struct DrawCmd {
uint32_t vertexCount;
uint32_t instanceCount;
uint32_t firstVertex;
uint32_t firstInstance;
};
- struct DrawElementsCmd {
+ struct DrawIndexedCmd {
uint32_t indexCount;
uint32_t instanceCount;
uint32_t firstIndex;
+ uint32_t baseVertex;
uint32_t firstInstance;
};
diff --git a/chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.cpp b/chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.cpp
index 77774db3d5d..bc2510c1ba2 100644
--- a/chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.cpp
@@ -38,11 +38,16 @@ namespace dawn_native {
dispatch->z = z;
}
- void ComputePassEncoderBase::SetComputePipeline(ComputePipelineBase* pipeline) {
+ void ComputePassEncoderBase::SetPipeline(ComputePipelineBase* pipeline) {
if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) {
return;
}
+ if (pipeline == nullptr) {
+ mTopLevelBuilder->HandleError("Pipeline cannot be null");
+ return;
+ }
+
SetComputePipelineCmd* cmd =
mAllocator->Allocate<SetComputePipelineCmd>(Command::SetComputePipeline);
new (cmd) SetComputePipelineCmd;
diff --git a/chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.h b/chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.h
index 79c8f63c044..7de4c76ad7e 100644
--- a/chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.h
+++ b/chromium/third_party/dawn/src/dawn_native/ComputePassEncoder.h
@@ -31,7 +31,7 @@ namespace dawn_native {
CommandAllocator* allocator);
void Dispatch(uint32_t x, uint32_t y, uint32_t z);
- void SetComputePipeline(ComputePipelineBase* pipeline);
+ void SetPipeline(ComputePipelineBase* pipeline);
};
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp b/chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp
index 6e961f19f0d..fb7c8618e8f 100644
--- a/chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp
@@ -24,6 +24,14 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
}
+ if (descriptor->module == nullptr) {
+ return DAWN_VALIDATION_ERROR("module cannot be null");
+ }
+
+ if (descriptor->layout == nullptr) {
+ return DAWN_VALIDATION_ERROR("layout cannot be null");
+ }
+
if (descriptor->entryPoint != std::string("main")) {
return DAWN_VALIDATION_ERROR("Currently the entry point has to be main()");
}
diff --git a/chromium/third_party/dawn/src/dawn_native/DawnNative.cpp b/chromium/third_party/dawn/src/dawn_native/DawnNative.cpp
index f1dd1aa423a..d10e8cb1f67 100644
--- a/chromium/third_party/dawn/src/dawn_native/DawnNative.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/DawnNative.cpp
@@ -14,6 +14,7 @@
#include "dawn_native/DawnNative.h"
#include "dawn_native/Device.h"
+#include "dawn_native/Instance.h"
// Contains the entry-points into dawn_native
@@ -30,4 +31,59 @@ namespace dawn_native {
return deviceBase->GetPCIInfo();
}
+ // Adapter
+
+ Adapter::Adapter() = default;
+
+ Adapter::Adapter(AdapterBase* impl) : mImpl(impl) {
+ }
+
+ Adapter::~Adapter() {
+ mImpl = nullptr;
+ }
+
+ BackendType Adapter::GetBackendType() const {
+ return mImpl->GetBackendType();
+ }
+
+ const PCIInfo& Adapter::GetPCIInfo() const {
+ return mImpl->GetPCIInfo();
+ }
+
+ dawnDevice Adapter::CreateDevice() {
+ return reinterpret_cast<dawnDevice>(mImpl->CreateDevice());
+ }
+
+ // AdapterDiscoverOptionsBase
+
+ AdapterDiscoveryOptionsBase::AdapterDiscoveryOptionsBase(BackendType type) : backendType(type) {
+ }
+
+ // Instance
+
+ Instance::Instance() : mImpl(new InstanceBase()) {
+ }
+
+ Instance::~Instance() {
+ delete mImpl;
+ mImpl = nullptr;
+ }
+
+ void Instance::DiscoverDefaultAdapters() {
+ mImpl->DiscoverDefaultAdapters();
+ }
+
+ bool Instance::DiscoverAdapters(const AdapterDiscoveryOptionsBase* options) {
+ return mImpl->DiscoverAdapters(options);
+ }
+
+ std::vector<Adapter> Instance::GetAdapters() const {
+ // Adapters are owned by mImpl so it is safe to return non RAII pointers to them
+ std::vector<Adapter> adapters;
+ for (const std::unique_ptr<AdapterBase>& adapter : mImpl->GetAdapters()) {
+ adapters.push_back({adapter.get()});
+ }
+ return adapters;
+ }
+
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/DepthStencilState.cpp b/chromium/third_party/dawn/src/dawn_native/DepthStencilState.cpp
deleted file mode 100644
index 9405cfab955..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/DepthStencilState.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2017 The Dawn 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_native/DepthStencilState.h"
-
-#include "dawn_native/Device.h"
-
-namespace dawn_native {
-
- // DepthStencilStateBase
-
- DepthStencilStateBase::DepthStencilStateBase(DepthStencilStateBuilder* builder)
- : ObjectBase(builder->GetDevice()),
- mDepthInfo(builder->mDepthInfo),
- mStencilInfo(builder->mStencilInfo) {
- }
-
- bool DepthStencilStateBase::StencilTestEnabled() const {
- return mStencilInfo.back.compareFunction != dawn::CompareFunction::Always ||
- mStencilInfo.back.stencilFail != dawn::StencilOperation::Keep ||
- mStencilInfo.back.depthFail != dawn::StencilOperation::Keep ||
- mStencilInfo.back.depthStencilPass != dawn::StencilOperation::Keep ||
- mStencilInfo.front.compareFunction != dawn::CompareFunction::Always ||
- mStencilInfo.front.stencilFail != dawn::StencilOperation::Keep ||
- mStencilInfo.front.depthFail != dawn::StencilOperation::Keep ||
- mStencilInfo.front.depthStencilPass != dawn::StencilOperation::Keep;
- }
-
- const DepthStencilStateBase::DepthInfo& DepthStencilStateBase::GetDepth() const {
- return mDepthInfo;
- }
-
- const DepthStencilStateBase::StencilInfo& DepthStencilStateBase::GetStencil() const {
- return mStencilInfo;
- }
-
- // DepthStencilStateBuilder
-
- enum DepthStencilStateSetProperties {
- DEPTH_STENCIL_STATE_PROPERTY_DEPTH_COMPARE_FUNCTION = 0x1,
- DEPTH_STENCIL_STATE_PROPERTY_DEPTH_WRITE_ENABLED = 0x2,
- DEPTH_STENCIL_STATE_PROPERTY_STENCIL_BACK_FUNCTION = 0x4,
- DEPTH_STENCIL_STATE_PROPERTY_STENCIL_FRONT_FUNCTION = 0x08,
- DEPTH_STENCIL_STATE_PROPERTY_STENCIL_MASK = 0x10,
- };
-
- DepthStencilStateBuilder::DepthStencilStateBuilder(DeviceBase* device) : Builder(device) {
- }
-
- DepthStencilStateBase* DepthStencilStateBuilder::GetResultImpl() {
- return GetDevice()->CreateDepthStencilState(this);
- }
-
- void DepthStencilStateBuilder::SetDepthCompareFunction(
- dawn::CompareFunction depthCompareFunction) {
- if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_DEPTH_COMPARE_FUNCTION) != 0) {
- HandleError("Depth compare property set multiple times");
- return;
- }
-
- mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_DEPTH_COMPARE_FUNCTION;
-
- mDepthInfo.compareFunction = depthCompareFunction;
- }
-
- void DepthStencilStateBuilder::SetDepthWriteEnabled(bool enabled) {
- if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_DEPTH_WRITE_ENABLED) != 0) {
- HandleError("Depth write enabled property set multiple times");
- return;
- }
-
- mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_DEPTH_WRITE_ENABLED;
-
- mDepthInfo.depthWriteEnabled = enabled;
- }
-
- void DepthStencilStateBuilder::SetStencilFunction(dawn::Face face,
- dawn::CompareFunction stencilCompareFunction,
- dawn::StencilOperation stencilFail,
- dawn::StencilOperation depthFail,
- dawn::StencilOperation depthStencilPass) {
- if (face == dawn::Face::None) {
- HandleError("Can't set stencil function of None face");
- return;
- }
-
- if (face & dawn::Face::Back) {
- if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_STENCIL_BACK_FUNCTION) != 0) {
- HandleError("Stencil back function property set multiple times");
- return;
- }
-
- mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_STENCIL_BACK_FUNCTION;
-
- mStencilInfo.back.compareFunction = stencilCompareFunction;
- mStencilInfo.back.stencilFail = stencilFail;
- mStencilInfo.back.depthFail = depthFail;
- mStencilInfo.back.depthStencilPass = depthStencilPass;
- }
- if (face & dawn::Face::Front) {
- if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_STENCIL_FRONT_FUNCTION) != 0) {
- HandleError("Stencil front function property set multiple times");
- return;
- }
-
- mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_STENCIL_FRONT_FUNCTION;
-
- mStencilInfo.front.compareFunction = stencilCompareFunction;
- mStencilInfo.front.stencilFail = stencilFail;
- mStencilInfo.front.depthFail = depthFail;
- mStencilInfo.front.depthStencilPass = depthStencilPass;
- }
- }
-
- void DepthStencilStateBuilder::SetStencilMask(uint32_t readMask, uint32_t writeMask) {
- if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_STENCIL_MASK) != 0) {
- HandleError("Stencilmask property set multiple times");
- return;
- }
-
- mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_STENCIL_MASK;
- mStencilInfo.readMask = readMask;
- mStencilInfo.writeMask = writeMask;
- }
-
-} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/DepthStencilState.h b/chromium/third_party/dawn/src/dawn_native/DepthStencilState.h
deleted file mode 100644
index 87a8952b79e..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/DepthStencilState.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2017 The Dawn 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.
-
-#ifndef DAWNNATIVE_DEPTHSTENCILSTATE_H_
-#define DAWNNATIVE_DEPTHSTENCILSTATE_H_
-
-#include "dawn_native/Builder.h"
-#include "dawn_native/Forward.h"
-#include "dawn_native/ObjectBase.h"
-
-#include "dawn_native/dawn_platform.h"
-
-namespace dawn_native {
-
- class DepthStencilStateBase : public ObjectBase {
- public:
- DepthStencilStateBase(DepthStencilStateBuilder* builder);
-
- struct DepthInfo {
- dawn::CompareFunction compareFunction = dawn::CompareFunction::Always;
- bool depthWriteEnabled = false;
- };
-
- struct StencilFaceInfo {
- dawn::CompareFunction compareFunction = dawn::CompareFunction::Always;
- dawn::StencilOperation stencilFail = dawn::StencilOperation::Keep;
- dawn::StencilOperation depthFail = dawn::StencilOperation::Keep;
- dawn::StencilOperation depthStencilPass = dawn::StencilOperation::Keep;
- };
-
- struct StencilInfo {
- StencilFaceInfo back;
- StencilFaceInfo front;
- uint32_t readMask = 0xff;
- uint32_t writeMask = 0xff;
- };
-
- bool StencilTestEnabled() const;
- const DepthInfo& GetDepth() const;
- const StencilInfo& GetStencil() const;
-
- private:
- DepthInfo mDepthInfo;
- StencilInfo mStencilInfo;
- };
-
- class DepthStencilStateBuilder : public Builder<DepthStencilStateBase> {
- public:
- DepthStencilStateBuilder(DeviceBase* device);
-
- // Dawn API
- void SetDepthCompareFunction(dawn::CompareFunction depthCompareFunction);
- void SetDepthWriteEnabled(bool enabled);
- void SetStencilFunction(dawn::Face face,
- dawn::CompareFunction stencilCompareFunction,
- dawn::StencilOperation stencilFail,
- dawn::StencilOperation depthFail,
- dawn::StencilOperation depthStencilPass);
- void SetStencilMask(uint32_t readMask, uint32_t writeMask);
-
- private:
- friend class DepthStencilStateBase;
-
- DepthStencilStateBase* GetResultImpl() override;
-
- int mPropertiesSet = 0;
-
- DepthStencilStateBase::DepthInfo mDepthInfo;
- DepthStencilStateBase::StencilInfo mStencilInfo;
- };
-
-} // namespace dawn_native
-
-#endif // DAWNNATIVE_DEPTHSTENCILSTATE_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/Device.cpp b/chromium/third_party/dawn/src/dawn_native/Device.cpp
index f2581cd03f6..c5f69932994 100644
--- a/chromium/third_party/dawn/src/dawn_native/Device.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/Device.cpp
@@ -14,14 +14,15 @@
#include "dawn_native/Device.h"
+#include "dawn_native/Adapter.h"
#include "dawn_native/BindGroup.h"
#include "dawn_native/BindGroupLayout.h"
-#include "dawn_native/BlendState.h"
#include "dawn_native/Buffer.h"
#include "dawn_native/CommandBuffer.h"
#include "dawn_native/ComputePipeline.h"
-#include "dawn_native/DepthStencilState.h"
#include "dawn_native/ErrorData.h"
+#include "dawn_native/Fence.h"
+#include "dawn_native/FenceSignalTracker.h"
#include "dawn_native/InputState.h"
#include "dawn_native/PipelineLayout.h"
#include "dawn_native/Queue.h"
@@ -49,8 +50,9 @@ namespace dawn_native {
// DeviceBase
- DeviceBase::DeviceBase() {
+ DeviceBase::DeviceBase(AdapterBase* adapter) : mAdapter(adapter) {
mCaches = std::make_unique<DeviceBase::Caches>();
+ mFenceSignalTracker = std::make_unique<FenceSignalTracker>(this);
}
DeviceBase::~DeviceBase() {
@@ -72,6 +74,10 @@ namespace dawn_native {
return this;
}
+ FenceSignalTracker* DeviceBase::GetFenceSignalTracker() const {
+ return mFenceSignalTracker.get();
+ }
+
ResultOrError<BindGroupLayoutBase*> DeviceBase::GetOrCreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor) {
BindGroupLayoutBase blueprint(this, descriptor, true);
@@ -92,10 +98,21 @@ namespace dawn_native {
mCaches->bindGroupLayouts.erase(obj);
}
+ const PCIInfo& DeviceBase::GetPCIInfo() const {
+ ASSERT(mAdapter != nullptr);
+ return mAdapter->GetPCIInfo();
+ }
+
// Object creation API methods
- BindGroupBuilder* DeviceBase::CreateBindGroupBuilder() {
- return new BindGroupBuilder(this);
+ BindGroupBase* DeviceBase::CreateBindGroup(const BindGroupDescriptor* descriptor) {
+ BindGroupBase* result = nullptr;
+
+ if (ConsumedError(CreateBindGroupInternal(&result, descriptor))) {
+ return nullptr;
+ }
+
+ return result;
}
BindGroupLayoutBase* DeviceBase::CreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor) {
@@ -107,9 +124,6 @@ namespace dawn_native {
return result;
}
- BlendStateBuilder* DeviceBase::CreateBlendStateBuilder() {
- return new BlendStateBuilder(this);
- }
BufferBase* DeviceBase::CreateBuffer(const BufferDescriptor* descriptor) {
BufferBase* result = nullptr;
@@ -132,8 +146,14 @@ namespace dawn_native {
return result;
}
- DepthStencilStateBuilder* DeviceBase::CreateDepthStencilStateBuilder() {
- return new DepthStencilStateBuilder(this);
+ FenceBase* DeviceBase::CreateFence(const FenceDescriptor* descriptor) {
+ FenceBase* result = nullptr;
+
+ if (ConsumedError(CreateFenceInternal(&result, descriptor))) {
+ return nullptr;
+ }
+
+ return result;
}
InputStateBuilder* DeviceBase::CreateInputStateBuilder() {
return new InputStateBuilder(this);
@@ -160,9 +180,6 @@ namespace dawn_native {
RenderPassDescriptorBuilder* DeviceBase::CreateRenderPassDescriptorBuilder() {
return new RenderPassDescriptorBuilder(this);
}
- RenderPipelineBuilder* DeviceBase::CreateRenderPipelineBuilder() {
- return new RenderPipelineBuilder(this);
- }
SamplerBase* DeviceBase::CreateSampler(const SamplerDescriptor* descriptor) {
SamplerBase* result = nullptr;
@@ -172,6 +189,16 @@ namespace dawn_native {
return result;
}
+ RenderPipelineBase* DeviceBase::CreateRenderPipeline(
+ const RenderPipelineDescriptor* descriptor) {
+ RenderPipelineBase* result = nullptr;
+
+ if (ConsumedError(CreateRenderPipelineInternal(&result, descriptor))) {
+ return nullptr;
+ }
+
+ return result;
+ }
ShaderModuleBase* DeviceBase::CreateShaderModule(const ShaderModuleDescriptor* descriptor) {
ShaderModuleBase* result = nullptr;
@@ -206,6 +233,7 @@ namespace dawn_native {
void DeviceBase::Tick() {
TickImpl();
+ mFenceSignalTracker->Tick(GetCompletedCommandSerial());
}
void DeviceBase::Reference() {
@@ -223,6 +251,13 @@ namespace dawn_native {
// Implementation details of object creation
+ MaybeError DeviceBase::CreateBindGroupInternal(BindGroupBase** result,
+ const BindGroupDescriptor* descriptor) {
+ DAWN_TRY(ValidateBindGroupDescriptor(this, descriptor));
+ DAWN_TRY_ASSIGN(*result, CreateBindGroupImpl(descriptor));
+ return {};
+ }
+
MaybeError DeviceBase::CreateBindGroupLayoutInternal(
BindGroupLayoutBase** result,
const BindGroupLayoutDescriptor* descriptor) {
@@ -246,6 +281,13 @@ namespace dawn_native {
return {};
}
+ MaybeError DeviceBase::CreateFenceInternal(FenceBase** result,
+ const FenceDescriptor* descriptor) {
+ DAWN_TRY(ValidateFenceDescriptor(this, descriptor));
+ *result = new FenceBase(this, descriptor);
+ return {};
+ }
+
MaybeError DeviceBase::CreatePipelineLayoutInternal(
PipelineLayoutBase** result,
const PipelineLayoutDescriptor* descriptor) {
@@ -259,6 +301,14 @@ namespace dawn_native {
return {};
}
+ MaybeError DeviceBase::CreateRenderPipelineInternal(
+ RenderPipelineBase** result,
+ const RenderPipelineDescriptor* descriptor) {
+ DAWN_TRY(ValidateRenderPipelineDescriptor(this, descriptor));
+ DAWN_TRY_ASSIGN(*result, CreateRenderPipelineImpl(descriptor));
+ return {};
+ }
+
MaybeError DeviceBase::CreateSamplerInternal(SamplerBase** result,
const SamplerDescriptor* descriptor) {
DAWN_TRY(ValidateSamplerDescriptor(this, descriptor));
diff --git a/chromium/third_party/dawn/src/dawn_native/Device.h b/chromium/third_party/dawn/src/dawn_native/Device.h
index 59c027212ab..82e2cf86298 100644
--- a/chromium/third_party/dawn/src/dawn_native/Device.h
+++ b/chromium/third_party/dawn/src/dawn_native/Device.h
@@ -12,9 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_DEVICEBASE_H_
-#define DAWNNATIVE_DEVICEBASE_H_
+#ifndef DAWNNATIVE_DEVICE_H_
+#define DAWNNATIVE_DEVICE_H_
+#include "common/Serial.h"
#include "dawn_native/Error.h"
#include "dawn_native/Forward.h"
#include "dawn_native/ObjectBase.h"
@@ -28,9 +29,12 @@ namespace dawn_native {
using ErrorCallback = void (*)(const char* errorMessage, void* userData);
+ class AdapterBase;
+ class FenceSignalTracker;
+
class DeviceBase {
public:
- DeviceBase();
+ DeviceBase(AdapterBase* adapter);
virtual ~DeviceBase();
void HandleError(const char* message);
@@ -46,18 +50,16 @@ namespace dawn_native {
// Used by autogenerated code, returns itself
DeviceBase* GetDevice();
- virtual BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) = 0;
- virtual BlendStateBase* CreateBlendState(BlendStateBuilder* builder) = 0;
- virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0;
+ FenceSignalTracker* GetFenceSignalTracker() const;
+
virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0;
- virtual DepthStencilStateBase* CreateDepthStencilState(
- DepthStencilStateBuilder* builder) = 0;
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
virtual RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) = 0;
- virtual RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) = 0;
virtual SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) = 0;
+ virtual Serial GetCompletedCommandSerial() const = 0;
+ virtual Serial GetLastSubmittedCommandSerial() const = 0;
virtual void TickImpl() = 0;
// Many Dawn objects are completely immutable once created which means that if two
@@ -79,18 +81,17 @@ namespace dawn_native {
void UncacheBindGroupLayout(BindGroupLayoutBase* obj);
// Dawn API
- BindGroupBuilder* CreateBindGroupBuilder();
+ BindGroupBase* CreateBindGroup(const BindGroupDescriptor* descriptor);
BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
- BlendStateBuilder* CreateBlendStateBuilder();
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
CommandBufferBuilder* CreateCommandBufferBuilder();
ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor);
- DepthStencilStateBuilder* CreateDepthStencilStateBuilder();
+ FenceBase* CreateFence(const FenceDescriptor* descriptor);
InputStateBuilder* CreateInputStateBuilder();
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
QueueBase* CreateQueue();
RenderPassDescriptorBuilder* CreateRenderPassDescriptorBuilder();
- RenderPipelineBuilder* CreateRenderPipelineBuilder();
+ RenderPipelineBase* CreateRenderPipeline(const RenderPipelineDescriptor* descriptor);
SamplerBase* CreateSampler(const SamplerDescriptor* descriptor);
ShaderModuleBase* CreateShaderModule(const ShaderModuleDescriptor* descriptor);
SwapChainBuilder* CreateSwapChainBuilder();
@@ -99,6 +100,7 @@ namespace dawn_native {
const TextureViewDescriptor* descriptor);
void Tick();
+
void SetErrorCallback(dawn::DeviceErrorCallback callback, dawn::CallbackUserdata userdata);
void Reference();
void Release();
@@ -107,9 +109,11 @@ namespace dawn_native {
return nullptr;
}
- virtual const PCIInfo& GetPCIInfo() const = 0;
+ virtual const PCIInfo& GetPCIInfo() const;
private:
+ virtual ResultOrError<BindGroupBase*> CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) = 0;
virtual ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) = 0;
virtual ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) = 0;
@@ -118,6 +122,8 @@ namespace dawn_native {
virtual ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) = 0;
virtual ResultOrError<QueueBase*> CreateQueueImpl() = 0;
+ virtual ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) = 0;
virtual ResultOrError<SamplerBase*> CreateSamplerImpl(
const SamplerDescriptor* descriptor) = 0;
virtual ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
@@ -128,14 +134,19 @@ namespace dawn_native {
TextureBase* texture,
const TextureViewDescriptor* descriptor) = 0;
+ MaybeError CreateBindGroupInternal(BindGroupBase** result,
+ const BindGroupDescriptor* descriptor);
MaybeError CreateBindGroupLayoutInternal(BindGroupLayoutBase** result,
const BindGroupLayoutDescriptor* descriptor);
MaybeError CreateBufferInternal(BufferBase** result, const BufferDescriptor* descriptor);
MaybeError CreateComputePipelineInternal(ComputePipelineBase** result,
const ComputePipelineDescriptor* descriptor);
+ MaybeError CreateFenceInternal(FenceBase** result, const FenceDescriptor* descriptor);
MaybeError CreatePipelineLayoutInternal(PipelineLayoutBase** result,
const PipelineLayoutDescriptor* descriptor);
MaybeError CreateQueueInternal(QueueBase** result);
+ MaybeError CreateRenderPipelineInternal(RenderPipelineBase** result,
+ const RenderPipelineDescriptor* descriptor);
MaybeError CreateSamplerInternal(SamplerBase** result, const SamplerDescriptor* descriptor);
MaybeError CreateShaderModuleInternal(ShaderModuleBase** result,
const ShaderModuleDescriptor* descriptor);
@@ -146,11 +157,15 @@ namespace dawn_native {
void ConsumeError(ErrorData* error);
+ AdapterBase* mAdapter = nullptr;
+
// The object caches aren't exposed in the header as they would require a lot of
// additional includes.
struct Caches;
std::unique_ptr<Caches> mCaches;
+ std::unique_ptr<FenceSignalTracker> mFenceSignalTracker;
+
dawn::DeviceErrorCallback mErrorCallback = nullptr;
dawn::CallbackUserdata mErrorUserdata = 0;
uint32_t mRefCount = 1;
@@ -158,4 +173,4 @@ namespace dawn_native {
} // namespace dawn_native
-#endif // DAWNNATIVE_DEVICEBASE_H_
+#endif // DAWNNATIVE_DEVICE_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/Error.cpp b/chromium/third_party/dawn/src/dawn_native/Error.cpp
index 9467c3a0395..2e09931574e 100644
--- a/chromium/third_party/dawn/src/dawn_native/Error.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/Error.cpp
@@ -19,7 +19,7 @@
namespace dawn_native {
ErrorData* MakeError(ErrorType type,
- const char* message,
+ std::string message,
const char* file,
const char* function,
int line) {
diff --git a/chromium/third_party/dawn/src/dawn_native/Error.h b/chromium/third_party/dawn/src/dawn_native/Error.h
index 7f202f70590..f76e6382e97 100644
--- a/chromium/third_party/dawn/src/dawn_native/Error.h
+++ b/chromium/third_party/dawn/src/dawn_native/Error.h
@@ -17,6 +17,8 @@
#include "common/Result.h"
+#include <string>
+
namespace dawn_native {
// This is the content of an error value for MaybeError or ResultOrError, split off to its own
@@ -59,7 +61,7 @@ namespace dawn_native {
if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) { \
ErrorData* error = DAWN_LOCAL_VAR.AcquireError(); \
AppendBacktrace(error, __FILE__, __func__, __LINE__); \
- return {error}; \
+ return {std::move(error)}; \
} \
} \
for (;;) \
@@ -73,7 +75,7 @@ namespace dawn_native {
if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) { \
ErrorData* error = DAWN_LOCAL_VAR.AcquireError(); \
AppendBacktrace(error, __FILE__, __func__, __LINE__); \
- return {error}; \
+ return {std::move(error)}; \
} \
VAR = DAWN_LOCAL_VAR.AcquireSuccess(); \
} \
@@ -85,7 +87,7 @@ namespace dawn_native {
// Implementation detail of DAWN_MAKE_ERROR
ErrorData* MakeError(ErrorType type,
- const char* message,
+ std::string message,
const char* file,
const char* function,
int line);
diff --git a/chromium/third_party/dawn/src/dawn_native/Fence.cpp b/chromium/third_party/dawn/src/dawn_native/Fence.cpp
new file mode 100644
index 00000000000..54ed9a94530
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/Fence.cpp
@@ -0,0 +1,98 @@
+// Copyright 2018 The Dawn 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_native/Fence.h"
+
+#include "common/Assert.h"
+#include "dawn_native/Device.h"
+#include "dawn_native/ValidationUtils_autogen.h"
+
+#include <utility>
+
+namespace dawn_native {
+
+ MaybeError ValidateFenceDescriptor(DeviceBase*, const FenceDescriptor* descriptor) {
+ if (descriptor->nextInChain != nullptr) {
+ return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
+ }
+
+ return {};
+ }
+
+ // Fence
+
+ FenceBase::FenceBase(DeviceBase* device, const FenceDescriptor* descriptor)
+ : ObjectBase(device),
+ mSignalValue(descriptor->initialValue),
+ mCompletedValue(descriptor->initialValue) {
+ }
+
+ FenceBase::~FenceBase() {
+ for (auto& request : mRequests.IterateAll()) {
+ request.completionCallback(DAWN_FENCE_COMPLETION_STATUS_UNKNOWN, request.userdata);
+ }
+ mRequests.Clear();
+ }
+
+ uint64_t FenceBase::GetCompletedValue() const {
+ return mCompletedValue;
+ }
+
+ void FenceBase::OnCompletion(uint64_t value,
+ dawn::FenceOnCompletionCallback callback,
+ dawn::CallbackUserdata userdata) {
+ if (GetDevice()->ConsumedError(ValidateOnCompletion(value))) {
+ callback(DAWN_FENCE_COMPLETION_STATUS_ERROR, userdata);
+ return;
+ }
+
+ if (value <= mCompletedValue) {
+ callback(DAWN_FENCE_COMPLETION_STATUS_SUCCESS, userdata);
+ return;
+ }
+
+ OnCompletionData request;
+ request.completionCallback = callback;
+ request.userdata = userdata;
+ mRequests.Enqueue(std::move(request), value);
+ }
+
+ uint64_t FenceBase::GetSignaledValue() const {
+ return mSignalValue;
+ }
+
+ void FenceBase::SetSignaledValue(uint64_t signalValue) {
+ ASSERT(signalValue > mSignalValue);
+ mSignalValue = signalValue;
+ }
+
+ void FenceBase::SetCompletedValue(uint64_t completedValue) {
+ ASSERT(completedValue <= mSignalValue);
+ ASSERT(completedValue > mCompletedValue);
+ mCompletedValue = completedValue;
+
+ for (auto& request : mRequests.IterateUpTo(mCompletedValue)) {
+ request.completionCallback(DAWN_FENCE_COMPLETION_STATUS_SUCCESS, request.userdata);
+ }
+ mRequests.ClearUpTo(mCompletedValue);
+ }
+
+ MaybeError FenceBase::ValidateOnCompletion(uint64_t value) const {
+ if (value > mSignalValue) {
+ return DAWN_VALIDATION_ERROR("Value greater than fence signaled value");
+ }
+ return {};
+ }
+
+} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/Fence.h b/chromium/third_party/dawn/src/dawn_native/Fence.h
new file mode 100644
index 00000000000..e2f4c40f760
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/Fence.h
@@ -0,0 +1,64 @@
+// Copyright 2018 The Dawn 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.
+
+#ifndef DAWNNATIVE_FENCE_H_
+#define DAWNNATIVE_FENCE_H_
+
+#include "common/SerialMap.h"
+#include "dawn_native/Error.h"
+#include "dawn_native/Forward.h"
+#include "dawn_native/ObjectBase.h"
+
+#include "dawn_native/dawn_platform.h"
+
+#include <map>
+
+namespace dawn_native {
+
+ MaybeError ValidateFenceDescriptor(DeviceBase*, const FenceDescriptor* descriptor);
+
+ class FenceBase : public ObjectBase {
+ public:
+ FenceBase(DeviceBase* device, const FenceDescriptor* descriptor);
+ ~FenceBase();
+
+ // Dawn API
+ uint64_t GetCompletedValue() const;
+ void OnCompletion(uint64_t value,
+ dawn::FenceOnCompletionCallback callback,
+ dawn::CallbackUserdata userdata);
+ uint64_t GetSignaledValue() const;
+
+ protected:
+ friend class QueueBase;
+ friend class FenceSignalTracker;
+ void SetSignaledValue(uint64_t signalValue);
+ void SetCompletedValue(uint64_t completedValue);
+
+ private:
+ MaybeError ValidateOnCompletion(uint64_t value) const;
+
+ struct OnCompletionData {
+ dawn::FenceOnCompletionCallback completionCallback = nullptr;
+ dawn::CallbackUserdata userdata = 0;
+ };
+
+ uint64_t mSignalValue;
+ uint64_t mCompletedValue;
+ SerialMap<OnCompletionData> mRequests;
+ };
+
+} // namespace dawn_native
+
+#endif // DAWNNATIVE_FENCE_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/FenceSignalTracker.cpp b/chromium/third_party/dawn/src/dawn_native/FenceSignalTracker.cpp
new file mode 100644
index 00000000000..132ac9c4996
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/FenceSignalTracker.cpp
@@ -0,0 +1,43 @@
+// Copyright 2018 The Dawn 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_native/FenceSignalTracker.h"
+
+#include "dawn_native/Device.h"
+#include "dawn_native/Fence.h"
+
+namespace dawn_native {
+
+ FenceSignalTracker::FenceSignalTracker(DeviceBase* device) : mDevice(device) {
+ }
+
+ FenceSignalTracker::~FenceSignalTracker() {
+ ASSERT(mFencesInFlight.Empty());
+ }
+
+ void FenceSignalTracker::UpdateFenceOnComplete(FenceBase* fence, uint64_t value) {
+ // Because we currently only have a single queue, we can simply update
+ // the fence completed value once the last submitted serial has passed.
+ mFencesInFlight.Enqueue(FenceInFlight{fence, value},
+ mDevice->GetLastSubmittedCommandSerial());
+ }
+
+ void FenceSignalTracker::Tick(Serial finishedSerial) {
+ for (auto& fenceInFlight : mFencesInFlight.IterateUpTo(finishedSerial)) {
+ fenceInFlight.fence->SetCompletedValue(fenceInFlight.value);
+ }
+ mFencesInFlight.ClearUpTo(finishedSerial);
+ }
+
+} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/FenceSignalTracker.h b/chromium/third_party/dawn/src/dawn_native/FenceSignalTracker.h
new file mode 100644
index 00000000000..d689277244e
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/FenceSignalTracker.h
@@ -0,0 +1,47 @@
+// Copyright 2018 The Dawn 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.
+
+#ifndef DAWNNATIVE_FENCESIGNALTRACKER_H_
+#define DAWNNATIVE_FENCESIGNALTRACKER_H_
+
+#include "common/SerialQueue.h"
+#include "dawn_native/RefCounted.h"
+
+namespace dawn_native {
+
+ class DeviceBase;
+ class FenceBase;
+
+ class FenceSignalTracker {
+ struct FenceInFlight {
+ Ref<FenceBase> fence;
+ uint64_t value;
+ };
+
+ public:
+ FenceSignalTracker(DeviceBase* device);
+ ~FenceSignalTracker();
+
+ void UpdateFenceOnComplete(FenceBase* fence, uint64_t value);
+
+ void Tick(Serial finishedSerial);
+
+ private:
+ DeviceBase* mDevice;
+ SerialQueue<FenceInFlight> mFencesInFlight;
+ };
+
+} // namespace dawn_native
+
+#endif // DAWNNATIVE_FENCESIGNALTRACKER_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/Forward.h b/chromium/third_party/dawn/src/dawn_native/Forward.h
index a5ac6e4a3fb..5373f66232f 100644
--- a/chromium/third_party/dawn/src/dawn_native/Forward.h
+++ b/chromium/third_party/dawn/src/dawn_native/Forward.h
@@ -19,25 +19,21 @@
namespace dawn_native {
+ class AdapterBase;
class BindGroupBase;
class BindGroupBuilder;
class BindGroupLayoutBase;
class BindGroupLayoutBuilder;
- class BlendStateBase;
- class BlendStateBuilder;
class BufferBase;
class BufferBuilder;
- class BufferViewBase;
- class BufferViewBuilder;
class ComputePipelineBase;
- class ComputePipelineBuilder;
class CommandBufferBase;
class CommandBufferBuilder;
class ComputePassEncoderBase;
- class DepthStencilStateBase;
- class DepthStencilStateBuilder;
+ class FenceBase;
class InputStateBase;
class InputStateBuilder;
+ class InstanceBase;
class PipelineLayoutBase;
class PipelineLayoutBuilder;
class QueueBase;
@@ -45,7 +41,6 @@ namespace dawn_native {
class RenderPassDescriptorBuilder;
class RenderPassEncoderBase;
class RenderPipelineBase;
- class RenderPipelineBuilder;
class SamplerBase;
class ShaderModuleBase;
class ShaderModuleBuilder;
diff --git a/chromium/third_party/dawn/src/dawn_native/Instance.cpp b/chromium/third_party/dawn/src/dawn_native/Instance.cpp
new file mode 100644
index 00000000000..2f7566c951f
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/Instance.cpp
@@ -0,0 +1,152 @@
+// Copyright 2018 The Dawn 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_native/Instance.h"
+
+#include "common/Assert.h"
+#include "dawn_native/ErrorData.h"
+
+#include <iostream>
+
+namespace dawn_native {
+
+ // Forward definitions of each backend's "Connect" function that creates new BackendConnection.
+ // Conditionally compiled declarations are used to avoid using static constructors instead.
+#if defined(DAWN_ENABLE_BACKEND_D3D12)
+ namespace d3d12 {
+ BackendConnection* Connect(InstanceBase* instance);
+ }
+#endif // defined(DAWN_ENABLE_BACKEND_D3D12)
+#if defined(DAWN_ENABLE_BACKEND_METAL)
+ namespace metal {
+ BackendConnection* Connect(InstanceBase* instance);
+ }
+#endif // defined(DAWN_ENABLE_BACKEND_METAL)
+#if defined(DAWN_ENABLE_BACKEND_NULL)
+ namespace null {
+ BackendConnection* Connect(InstanceBase* instance);
+ }
+#endif // defined(DAWN_ENABLE_BACKEND_NULL)
+#if defined(DAWN_ENABLE_BACKEND_OPENGL)
+ namespace opengl {
+ BackendConnection* Connect(InstanceBase* instance);
+ }
+#endif // defined(DAWN_ENABLE_BACKEND_OPENGL)
+#if defined(DAWN_ENABLE_BACKEND_VULKAN)
+ namespace vulkan {
+ BackendConnection* Connect(InstanceBase* instance);
+ }
+#endif // defined(DAWN_ENABLE_BACKEND_VULKAN)
+
+ // InstanceBase
+
+ void InstanceBase::DiscoverDefaultAdapters() {
+ EnsureBackendConnections();
+
+ // Query and merge all default adapters for all backends
+ for (std::unique_ptr<BackendConnection>& backend : mBackends) {
+ std::vector<std::unique_ptr<AdapterBase>> backendAdapters =
+ backend->DiscoverDefaultAdapters();
+
+ for (std::unique_ptr<AdapterBase>& adapter : backendAdapters) {
+ ASSERT(adapter->GetBackendType() == backend->GetType());
+ ASSERT(adapter->GetInstance() == this);
+ mAdapters.push_back(std::move(adapter));
+ }
+ }
+ }
+
+ // This is just a wrapper around the real logic that uses Error.h error handling.
+ bool InstanceBase::DiscoverAdapters(const AdapterDiscoveryOptionsBase* options) {
+ return !ConsumedError(DiscoverAdaptersInternal(options));
+ }
+
+ const std::vector<std::unique_ptr<AdapterBase>>& InstanceBase::GetAdapters() const {
+ return mAdapters;
+ }
+
+ void InstanceBase::EnsureBackendConnections() {
+ if (mBackendsConnected) {
+ return;
+ }
+
+ auto Register = [this](BackendConnection* connection, BackendType expectedType) {
+ if (connection != nullptr) {
+ ASSERT(connection->GetType() == expectedType);
+ ASSERT(connection->GetInstance() == this);
+ mBackends.push_back(std::unique_ptr<BackendConnection>(connection));
+ }
+ };
+
+#if defined(DAWN_ENABLE_BACKEND_D3D12)
+ Register(d3d12::Connect(this), BackendType::D3D12);
+#endif // defined(DAWN_ENABLE_BACKEND_D3D12)
+#if defined(DAWN_ENABLE_BACKEND_METAL)
+ Register(metal::Connect(this), BackendType::Metal);
+#endif // defined(DAWN_ENABLE_BACKEND_METAL)
+#if defined(DAWN_ENABLE_BACKEND_NULL)
+ Register(null::Connect(this), BackendType::Null);
+#endif // defined(DAWN_ENABLE_BACKEND_NULL)
+#if defined(DAWN_ENABLE_BACKEND_OPENGL)
+ Register(opengl::Connect(this), BackendType::OpenGL);
+#endif // defined(DAWN_ENABLE_BACKEND_OPENGL)
+#if defined(DAWN_ENABLE_BACKEND_VULKAN)
+ Register(vulkan::Connect(this), BackendType::Vulkan);
+#endif // defined(DAWN_ENABLE_BACKEND_VULKAN)
+
+ mBackendsConnected = true;
+ }
+
+ ResultOrError<BackendConnection*> InstanceBase::FindBackend(BackendType type) {
+ for (std::unique_ptr<BackendConnection>& backend : mBackends) {
+ if (backend->GetType() == type) {
+ return backend.get();
+ }
+ }
+
+ return DAWN_VALIDATION_ERROR("Backend isn't present.");
+ }
+
+ MaybeError InstanceBase::DiscoverAdaptersInternal(const AdapterDiscoveryOptionsBase* options) {
+ EnsureBackendConnections();
+
+ BackendConnection* backend;
+ DAWN_TRY_ASSIGN(backend, FindBackend(options->backendType));
+
+ std::vector<std::unique_ptr<AdapterBase>> newAdapters;
+ DAWN_TRY_ASSIGN(newAdapters, backend->DiscoverAdapters(options));
+
+ for (std::unique_ptr<AdapterBase>& adapter : newAdapters) {
+ ASSERT(adapter->GetBackendType() == backend->GetType());
+ ASSERT(adapter->GetInstance() == this);
+ mAdapters.push_back(std::move(adapter));
+ }
+
+ return {};
+ }
+
+ bool InstanceBase::ConsumedError(MaybeError maybeError) {
+ if (maybeError.IsError()) {
+ ErrorData* error = maybeError.AcquireError();
+
+ ASSERT(error != nullptr);
+ std::cout << error->GetMessage() << std::endl;
+ delete error;
+
+ return true;
+ }
+ return false;
+ }
+
+} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/Instance.h b/chromium/third_party/dawn/src/dawn_native/Instance.h
new file mode 100644
index 00000000000..835d51dfdc0
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/Instance.h
@@ -0,0 +1,60 @@
+// Copyright 2018 The Dawn 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.
+
+#ifndef DAWNNATIVE_INSTANCE_H_
+#define DAWNNATIVE_INSTANCE_H_
+
+#include "dawn_native/Adapter.h"
+#include "dawn_native/BackendConnection.h"
+
+#include <memory>
+#include <vector>
+
+namespace dawn_native {
+
+ // This is called InstanceBase for consistency across the frontend, even if the backends don't
+ // specialize this class.
+ class InstanceBase final {
+ public:
+ InstanceBase() = default;
+ ~InstanceBase() = default;
+
+ InstanceBase(const InstanceBase& other) = delete;
+ InstanceBase& operator=(const InstanceBase& other) = delete;
+
+ void DiscoverDefaultAdapters();
+ bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
+
+ const std::vector<std::unique_ptr<AdapterBase>>& GetAdapters() const;
+
+ // Used to handle error that happen up to device creation.
+ bool ConsumedError(MaybeError maybeError);
+
+ private:
+ // Lazily creates connections to all backends that have been compiled.
+ void EnsureBackendConnections();
+ // Finds the BackendConnection for `type` or returns an error.
+ ResultOrError<BackendConnection*> FindBackend(BackendType type);
+
+ MaybeError DiscoverAdaptersInternal(const AdapterDiscoveryOptionsBase* options);
+
+ bool mBackendsConnected = false;
+
+ std::vector<std::unique_ptr<BackendConnection>> mBackends;
+ std::vector<std::unique_ptr<AdapterBase>> mAdapters;
+ };
+
+} // namespace dawn_native
+
+#endif // DAWNNATIVE_INSTANCE_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/Pipeline.cpp b/chromium/third_party/dawn/src/dawn_native/Pipeline.cpp
index 301ef0f6f37..fb2a3112e6e 100644
--- a/chromium/third_party/dawn/src/dawn_native/Pipeline.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/Pipeline.cpp
@@ -14,7 +14,6 @@
#include "dawn_native/Pipeline.h"
-#include "dawn_native/DepthStencilState.h"
#include "dawn_native/Device.h"
#include "dawn_native/InputState.h"
#include "dawn_native/PipelineLayout.h"
@@ -30,30 +29,6 @@ namespace dawn_native {
: ObjectBase(device), mStageMask(stages), mLayout(layout), mDevice(device) {
}
- PipelineBase::PipelineBase(DeviceBase* device, PipelineBuilder* builder)
- : ObjectBase(device),
- mStageMask(builder->mStageMask),
- mLayout(std::move(builder->mLayout)),
- mDevice(device) {
- if (!mLayout) {
- PipelineLayoutDescriptor descriptor;
- descriptor.numBindGroupLayouts = 0;
- descriptor.bindGroupLayouts = nullptr;
- mLayout = device->CreatePipelineLayout(&descriptor);
- // Remove the external ref objects are created with
- mLayout->Release();
- }
-
- for (auto stage : IterateStages(builder->mStageMask)) {
- if (!builder->mStages[stage].module->IsCompatibleWithPipelineLayout(mLayout.Get())) {
- builder->GetParentBuilder()->HandleError("Stage not compatible with layout");
- return;
- }
-
- ExtractModuleData(stage, builder->mStages[stage].module.Get());
- }
- }
-
void PipelineBase::ExtractModuleData(dawn::ShaderStage stage, ShaderModuleBase* module) {
PushConstantInfo* info = &mPushConstants[stage];
@@ -90,47 +65,4 @@ namespace dawn_native {
return mDevice;
}
- // PipelineBuilder
-
- PipelineBuilder::PipelineBuilder(BuilderBase* parentBuilder)
- : mParentBuilder(parentBuilder), mStageMask(static_cast<dawn::ShaderStageBit>(0)) {
- }
-
- const PipelineBuilder::StageInfo& PipelineBuilder::GetStageInfo(dawn::ShaderStage stage) const {
- ASSERT(mStageMask & StageBit(stage));
- return mStages[stage];
- }
-
- BuilderBase* PipelineBuilder::GetParentBuilder() const {
- return mParentBuilder;
- }
-
- void PipelineBuilder::SetLayout(PipelineLayoutBase* layout) {
- mLayout = layout;
- }
-
- void PipelineBuilder::SetStage(dawn::ShaderStage stage,
- ShaderModuleBase* module,
- const char* entryPoint) {
- if (entryPoint != std::string("main")) {
- mParentBuilder->HandleError("Currently the entry point has to be main()");
- return;
- }
-
- if (stage != module->GetExecutionModel()) {
- mParentBuilder->HandleError("Setting module with wrong execution model");
- return;
- }
-
- dawn::ShaderStageBit bit = StageBit(stage);
- if (mStageMask & bit) {
- mParentBuilder->HandleError("Setting already set stage");
- return;
- }
- mStageMask |= bit;
-
- mStages[stage].module = module;
- mStages[stage].entryPoint = entryPoint;
- }
-
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/Pipeline.h b/chromium/third_party/dawn/src/dawn_native/Pipeline.h
index d91dc5bde94..47c10796079 100644
--- a/chromium/third_party/dawn/src/dawn_native/Pipeline.h
+++ b/chromium/third_party/dawn/src/dawn_native/Pipeline.h
@@ -35,12 +35,9 @@ namespace dawn_native {
Float,
};
- class PipelineBuilder;
-
class PipelineBase : public ObjectBase {
public:
PipelineBase(DeviceBase* device, PipelineLayoutBase* layout, dawn::ShaderStageBit stages);
- PipelineBase(DeviceBase* device, PipelineBuilder* builder);
struct PushConstantInfo {
std::bitset<kMaxPushConstants> mask;
@@ -62,30 +59,6 @@ namespace dawn_native {
DeviceBase* mDevice;
};
- class PipelineBuilder {
- public:
- PipelineBuilder(BuilderBase* parentBuilder);
-
- struct StageInfo {
- std::string entryPoint;
- Ref<ShaderModuleBase> module;
- };
- const StageInfo& GetStageInfo(dawn::ShaderStage stage) const;
- BuilderBase* GetParentBuilder() const;
-
- // Dawn API
- void SetLayout(PipelineLayoutBase* layout);
- void SetStage(dawn::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint);
-
- private:
- friend class PipelineBase;
-
- BuilderBase* mParentBuilder;
- Ref<PipelineLayoutBase> mLayout;
- dawn::ShaderStageBit mStageMask;
- PerStage<StageInfo> mStages;
- };
-
} // namespace dawn_native
#endif // DAWNNATIVE_PIPELINE_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/PipelineLayout.cpp b/chromium/third_party/dawn/src/dawn_native/PipelineLayout.cpp
index 1ccb386733f..f067ec54da0 100644
--- a/chromium/third_party/dawn/src/dawn_native/PipelineLayout.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/PipelineLayout.cpp
@@ -70,7 +70,7 @@ namespace dawn_native {
return i;
}
}
- return kMaxBindGroups + 1;
+ return kMaxBindGroups;
}
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp b/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp
index 2f042f80a8f..fdfcf42f689 100644
--- a/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp
@@ -18,6 +18,8 @@
#include "dawn_native/CommandBuffer.h"
#include "dawn_native/Commands.h"
+#include <string.h>
+
namespace dawn_native {
ProgrammablePassEncoder::ProgrammablePassEncoder(DeviceBase* device,
@@ -27,6 +29,10 @@ namespace dawn_native {
}
void ProgrammablePassEncoder::EndPass() {
+ if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) {
+ return;
+ }
+
mTopLevelBuilder->PassEnded();
mAllocator = nullptr;
}
@@ -36,6 +42,11 @@ namespace dawn_native {
return;
}
+ if (group == nullptr) {
+ mTopLevelBuilder->HandleError("BindGroup cannot be null");
+ return;
+ }
+
if (groupIndex >= kMaxBindGroups) {
mTopLevelBuilder->HandleError("Setting bind group over the max");
return;
diff --git a/chromium/third_party/dawn/src/dawn_native/Queue.cpp b/chromium/third_party/dawn/src/dawn_native/Queue.cpp
index 021a095da53..426c963c104 100644
--- a/chromium/third_party/dawn/src/dawn_native/Queue.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/Queue.cpp
@@ -17,6 +17,8 @@
#include "dawn_native/Buffer.h"
#include "dawn_native/CommandBuffer.h"
#include "dawn_native/Device.h"
+#include "dawn_native/Fence.h"
+#include "dawn_native/FenceSignalTracker.h"
#include "dawn_native/Texture.h"
namespace dawn_native {
@@ -34,8 +36,21 @@ namespace dawn_native {
SubmitImpl(numCommands, commands);
}
+ void QueueBase::Signal(FenceBase* fence, uint64_t signalValue) {
+ if (GetDevice()->ConsumedError(ValidateSignal(fence, signalValue))) {
+ return;
+ }
+
+ fence->SetSignaledValue(signalValue);
+ GetDevice()->GetFenceSignalTracker()->UpdateFenceOnComplete(fence, signalValue);
+ }
+
MaybeError QueueBase::ValidateSubmit(uint32_t numCommands, CommandBufferBase* const* commands) {
for (uint32_t i = 0; i < numCommands; ++i) {
+ if (commands[i] == nullptr) {
+ return DAWN_VALIDATION_ERROR("Command buffers cannot be null");
+ }
+
const CommandBufferResourceUsage& usages = commands[i]->GetResourceUsages();
for (const PassResourceUsage& passUsages : usages.perPass) {
@@ -58,4 +73,15 @@ namespace dawn_native {
return {};
}
+ MaybeError QueueBase::ValidateSignal(const FenceBase* fence, uint64_t signalValue) {
+ if (fence == nullptr) {
+ return DAWN_VALIDATION_ERROR("Fence cannot be null");
+ }
+
+ if (signalValue <= fence->GetSignaledValue()) {
+ return DAWN_VALIDATION_ERROR("Signal value less than or equal to fence signaled value");
+ }
+ return {};
+ }
+
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/Queue.h b/chromium/third_party/dawn/src/dawn_native/Queue.h
index a9655f2d81f..0a85af44861 100644
--- a/chromium/third_party/dawn/src/dawn_native/Queue.h
+++ b/chromium/third_party/dawn/src/dawn_native/Queue.h
@@ -30,11 +30,13 @@ namespace dawn_native {
// Dawn API
void Submit(uint32_t numCommands, CommandBufferBase* const* commands);
+ void Signal(FenceBase* fence, uint64_t signalValue);
private:
virtual void SubmitImpl(uint32_t numCommands, CommandBufferBase* const* commands) = 0;
MaybeError ValidateSubmit(uint32_t numCommands, CommandBufferBase* const* commands);
+ MaybeError ValidateSignal(const FenceBase* fence, uint64_t signalValue);
};
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.cpp b/chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.cpp
index 1426095021b..3a40a834521 100644
--- a/chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.cpp
@@ -103,19 +103,20 @@ namespace dawn_native {
RenderPassDescriptorBase* RenderPassDescriptorBuilder::GetResultImpl() {
auto CheckOrSetSize = [this](const TextureViewBase* attachment) -> bool {
+ uint32_t mipLevel = attachment->GetBaseMipLevel();
if (this->mWidth == 0) {
ASSERT(this->mHeight == 0);
- this->mWidth = attachment->GetTexture()->GetSize().width;
- this->mHeight = attachment->GetTexture()->GetSize().height;
+ this->mWidth = attachment->GetTexture()->GetSize().width >> mipLevel;
+ this->mHeight = attachment->GetTexture()->GetSize().height >> mipLevel;
ASSERT(this->mWidth != 0 && this->mHeight != 0);
return true;
}
ASSERT(this->mWidth != 0 && this->mHeight != 0);
- return this->mWidth == attachment->GetTexture()->GetSize().width &&
- this->mHeight == attachment->GetTexture()->GetSize().height;
+ return this->mWidth == attachment->GetTexture()->GetSize().width >> mipLevel &&
+ this->mHeight == attachment->GetTexture()->GetSize().height >> mipLevel;
};
uint32_t attachmentCount = 0;
@@ -143,48 +144,57 @@ namespace dawn_native {
return GetDevice()->CreateRenderPassDescriptor(this);
}
- void RenderPassDescriptorBuilder::SetColorAttachment(uint32_t attachment,
- TextureViewBase* textureView,
- dawn::LoadOp loadOp) {
- if (attachment >= kMaxColorAttachments) {
- HandleError("Setting color attachment out of bounds");
+ void RenderPassDescriptorBuilder::SetColorAttachments(
+ uint32_t count,
+ const RenderPassColorAttachmentDescriptor* attachments) {
+ if (count > kMaxColorAttachments) {
+ HandleError("Setting color attachments out of bounds");
return;
}
- if (!IsColorRenderableTextureFormat(textureView->GetFormat())) {
- HandleError(
- "The format of the texture view used as color attachment is not color renderable");
- return;
- }
+ for (uint32_t i = 0; i < count; ++i) {
+ // TODO(jiawei.shao@intel.com): support resolve target for multisample color attachment.
+ if (attachments[i].resolveTarget != nullptr) {
+ HandleError("Resolve target is not supported now");
+ return;
+ }
- if (!CheckArrayLayersAndLevelCountForAttachment(textureView)) {
- return;
- }
+ TextureViewBase* textureView = attachments[i].attachment;
+ if (textureView == nullptr) {
+ continue;
+ }
+
+ if (!IsColorRenderableTextureFormat(textureView->GetFormat())) {
+ HandleError(
+ "The format of the texture view used as color attachment is not color "
+ "renderable");
+ return;
+ }
+
+ if (!CheckArrayLayersAndLevelCountForAttachment(textureView)) {
+ return;
+ }
- mColorAttachmentsSet.set(attachment);
- mColorAttachments[attachment].loadOp = loadOp;
- mColorAttachments[attachment].view = textureView;
+ // TODO(jiawei.shao@intel.com): set and make use of storeOp
+ mColorAttachmentsSet.set(i);
+ mColorAttachments[i].loadOp = attachments[i].loadOp;
+ mColorAttachments[i].view = textureView;
+
+ mColorAttachments[i].clearColor[0] = attachments[i].clearColor.r;
+ mColorAttachments[i].clearColor[1] = attachments[i].clearColor.g;
+ mColorAttachments[i].clearColor[2] = attachments[i].clearColor.b;
+ mColorAttachments[i].clearColor[3] = attachments[i].clearColor.a;
+ }
}
- void RenderPassDescriptorBuilder::SetColorAttachmentClearColor(uint32_t attachment,
- float clearR,
- float clearG,
- float clearB,
- float clearA) {
- if (attachment >= kMaxColorAttachments) {
- HandleError("Setting color attachment out of bounds");
+ void RenderPassDescriptorBuilder::SetDepthStencilAttachment(
+ const RenderPassDepthStencilAttachmentDescriptor* attachment) {
+ TextureViewBase* textureView = attachment->attachment;
+ if (textureView == nullptr) {
+ HandleError("Texture view cannot be nullptr");
return;
}
- mColorAttachments[attachment].clearColor[0] = clearR;
- mColorAttachments[attachment].clearColor[1] = clearG;
- mColorAttachments[attachment].clearColor[2] = clearB;
- mColorAttachments[attachment].clearColor[3] = clearA;
- }
-
- void RenderPassDescriptorBuilder::SetDepthStencilAttachment(TextureViewBase* textureView,
- dawn::LoadOp depthLoadOp,
- dawn::LoadOp stencilLoadOp) {
if (!TextureFormatHasDepthOrStencil(textureView->GetFormat())) {
HandleError(
"The format of the texture view used as depth stencil attachment is not a depth "
@@ -196,16 +206,13 @@ namespace dawn_native {
return;
}
+ // TODO(jiawei.shao@intel.com): set and make use of depthStoreOp and stencilStoreOp
mDepthStencilAttachmentSet = true;
- mDepthStencilAttachment.depthLoadOp = depthLoadOp;
- mDepthStencilAttachment.stencilLoadOp = stencilLoadOp;
+ mDepthStencilAttachment.depthLoadOp = attachment->depthLoadOp;
+ mDepthStencilAttachment.stencilLoadOp = attachment->stencilLoadOp;
mDepthStencilAttachment.view = textureView;
- }
-
- void RenderPassDescriptorBuilder::SetDepthStencilAttachmentClearValue(float clearDepth,
- uint32_t clearStencil) {
- mDepthStencilAttachment.clearDepth = clearDepth;
- mDepthStencilAttachment.clearStencil = clearStencil;
+ mDepthStencilAttachment.clearDepth = attachment->clearDepth;
+ mDepthStencilAttachment.clearStencil = attachment->clearStencil;
}
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.h b/chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.h
index 9ee4cd0263f..5d8b3224ea6 100644
--- a/chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.h
+++ b/chromium/third_party/dawn/src/dawn_native/RenderPassDescriptor.h
@@ -72,24 +72,18 @@ namespace dawn_native {
uint32_t mHeight;
};
+ // TODO(jiawei.shao@intel.com): remove RenderPassDescriptorBuilder and set data into
+ // RenderPassDescriptor directly.
class RenderPassDescriptorBuilder : public Builder<RenderPassDescriptorBase> {
public:
RenderPassDescriptorBuilder(DeviceBase* device);
// Dawn API
RenderPassDescriptorBase* GetResultImpl() override;
- void SetColorAttachment(uint32_t attachment,
- TextureViewBase* textureView,
- dawn::LoadOp loadOp);
- void SetColorAttachmentClearColor(uint32_t attachment,
- float clearR,
- float clearG,
- float clearB,
- float clearA);
- void SetDepthStencilAttachment(TextureViewBase* textureView,
- dawn::LoadOp depthLoadOp,
- dawn::LoadOp stencilLoadOp);
- void SetDepthStencilAttachmentClearValue(float clearDepth, uint32_t clearStencil);
+ void SetColorAttachments(uint32_t count,
+ const RenderPassColorAttachmentDescriptor* attachments);
+ void SetDepthStencilAttachment(
+ const RenderPassDepthStencilAttachmentDescriptor* attachment);
private:
friend class RenderPassDescriptorBase;
diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp b/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp
index 6e4ec813762..fc8891d22a1 100644
--- a/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp
@@ -19,6 +19,8 @@
#include "dawn_native/Commands.h"
#include "dawn_native/RenderPipeline.h"
+#include <string.h>
+
namespace dawn_native {
RenderPassEncoderBase::RenderPassEncoderBase(DeviceBase* device,
@@ -27,43 +29,50 @@ namespace dawn_native {
: ProgrammablePassEncoder(device, topLevelBuilder, allocator) {
}
- void RenderPassEncoderBase::DrawArrays(uint32_t vertexCount,
- uint32_t instanceCount,
- uint32_t firstVertex,
- uint32_t firstInstance) {
+ void RenderPassEncoderBase::Draw(uint32_t vertexCount,
+ uint32_t instanceCount,
+ uint32_t firstVertex,
+ uint32_t firstInstance) {
if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) {
return;
}
- DrawArraysCmd* draw = mAllocator->Allocate<DrawArraysCmd>(Command::DrawArrays);
- new (draw) DrawArraysCmd;
+ DrawCmd* draw = mAllocator->Allocate<DrawCmd>(Command::Draw);
+ new (draw) DrawCmd;
draw->vertexCount = vertexCount;
draw->instanceCount = instanceCount;
draw->firstVertex = firstVertex;
draw->firstInstance = firstInstance;
}
- void RenderPassEncoderBase::DrawElements(uint32_t indexCount,
- uint32_t instanceCount,
- uint32_t firstIndex,
- uint32_t firstInstance) {
+ void RenderPassEncoderBase::DrawIndexed(uint32_t indexCount,
+ uint32_t instanceCount,
+ uint32_t firstIndex,
+ uint32_t baseVertex,
+ uint32_t firstInstance) {
if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) {
return;
}
- DrawElementsCmd* draw = mAllocator->Allocate<DrawElementsCmd>(Command::DrawElements);
- new (draw) DrawElementsCmd;
+ DrawIndexedCmd* draw = mAllocator->Allocate<DrawIndexedCmd>(Command::DrawIndexed);
+ new (draw) DrawIndexedCmd;
draw->indexCount = indexCount;
draw->instanceCount = instanceCount;
draw->firstIndex = firstIndex;
+ draw->baseVertex = baseVertex;
draw->firstInstance = firstInstance;
}
- void RenderPassEncoderBase::SetRenderPipeline(RenderPipelineBase* pipeline) {
+ void RenderPassEncoderBase::SetPipeline(RenderPipelineBase* pipeline) {
if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) {
return;
}
+ if (pipeline == nullptr) {
+ mTopLevelBuilder->HandleError("Pipeline cannot be null");
+ return;
+ }
+
SetRenderPipelineCmd* cmd =
mAllocator->Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
new (cmd) SetRenderPipelineCmd;
@@ -115,6 +124,11 @@ namespace dawn_native {
return;
}
+ if (buffer == nullptr) {
+ mTopLevelBuilder->HandleError("Buffer cannot be null");
+ return;
+ }
+
SetIndexBufferCmd* cmd = mAllocator->Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer);
new (cmd) SetIndexBufferCmd;
cmd->buffer = buffer;
@@ -129,6 +143,13 @@ namespace dawn_native {
return;
}
+ for (size_t i = 0; i < count; ++i) {
+ if (buffers[i] == nullptr) {
+ mTopLevelBuilder->HandleError("Buffers cannot be null");
+ return;
+ }
+ }
+
SetVertexBuffersCmd* cmd =
mAllocator->Allocate<SetVertexBuffersCmd>(Command::SetVertexBuffers);
new (cmd) SetVertexBuffersCmd;
diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h b/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h
index c2bdad8a9ae..49d77d4dd3d 100644
--- a/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h
+++ b/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h
@@ -30,16 +30,17 @@ namespace dawn_native {
CommandBufferBuilder* topLevelBuilder,
CommandAllocator* allocator);
- void DrawArrays(uint32_t vertexCount,
- uint32_t instanceCount,
- uint32_t firstVertex,
- uint32_t firstInstance);
- void DrawElements(uint32_t vertexCount,
- uint32_t instanceCount,
- uint32_t firstIndex,
- uint32_t firstInstance);
+ void Draw(uint32_t vertexCount,
+ uint32_t instanceCount,
+ uint32_t firstVertex,
+ uint32_t firstInstance);
+ void DrawIndexed(uint32_t vertexCount,
+ uint32_t instanceCount,
+ uint32_t firstIndex,
+ uint32_t baseVertex,
+ uint32_t firstInstance);
- void SetRenderPipeline(RenderPipelineBase* pipeline);
+ void SetPipeline(RenderPipelineBase* pipeline);
void SetStencilReference(uint32_t reference);
void SetBlendColor(float r, float g, float b, float a);
diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp b/chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp
index 047ad2570b0..8d2f5e9130e 100644
--- a/chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp
@@ -15,63 +15,196 @@
#include "dawn_native/RenderPipeline.h"
#include "common/BitSetIterator.h"
-#include "dawn_native/BlendState.h"
-#include "dawn_native/DepthStencilState.h"
#include "dawn_native/Device.h"
#include "dawn_native/InputState.h"
#include "dawn_native/RenderPassDescriptor.h"
#include "dawn_native/Texture.h"
+#include "dawn_native/ValidationUtils_autogen.h"
namespace dawn_native {
+ // Helper functions
+ namespace {
+
+ MaybeError ValidatePipelineStageDescriptor(const PipelineStageDescriptor* descriptor,
+ const PipelineLayoutBase* layout,
+ dawn::ShaderStage stage) {
+ if (descriptor->entryPoint != std::string("main")) {
+ return DAWN_VALIDATION_ERROR("Entry point must be \"main\"");
+ }
+ if (descriptor->module->GetExecutionModel() != stage) {
+ return DAWN_VALIDATION_ERROR("Setting module with wrong stages");
+ }
+ if (!descriptor->module->IsCompatibleWithPipelineLayout(layout)) {
+ return DAWN_VALIDATION_ERROR("Stage not compatible with layout");
+ }
+ return {};
+ }
- // RenderPipelineBase
+ MaybeError ValidateAttachmentsStateDescriptor(
+ const AttachmentsStateDescriptor* descriptor) {
+ if (descriptor->numColorAttachments > kMaxColorAttachments) {
+ return DAWN_VALIDATION_ERROR("Color attachments number exceeds maximum");
+ }
+
+ if (descriptor->numColorAttachments == 0 && !descriptor->hasDepthStencilAttachment) {
+ return DAWN_VALIDATION_ERROR("Should have at least one attachment");
+ }
+
+ if (descriptor->hasDepthStencilAttachment) {
+ dawn::TextureFormat format = descriptor->depthStencilAttachment->format;
+ DAWN_TRY(ValidateTextureFormat(format));
+
+ if (!IsDepthStencilRenderableTextureFormat(format)) {
+ return DAWN_VALIDATION_ERROR(
+ "Depth stencil format must be depth-stencil renderable");
+ }
+ }
+
+ for (uint32_t i = 0; i < descriptor->numColorAttachments; ++i) {
+ dawn::TextureFormat format = descriptor->colorAttachments[i]->format;
+ DAWN_TRY(ValidateTextureFormat(format));
+
+ if (!IsColorRenderableTextureFormat(format)) {
+ return DAWN_VALIDATION_ERROR("Color format must be color renderable");
+ }
+ }
+ return {};
+ }
+
+ MaybeError ValidateBlendStateDescriptor(const BlendStateDescriptor* descriptor) {
+ if (descriptor->nextInChain != nullptr) {
+ return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
+ }
+ DAWN_TRY(ValidateBlendOperation(descriptor->alphaBlend.operation));
+ DAWN_TRY(ValidateBlendFactor(descriptor->alphaBlend.srcFactor));
+ DAWN_TRY(ValidateBlendFactor(descriptor->alphaBlend.dstFactor));
+ DAWN_TRY(ValidateBlendOperation(descriptor->colorBlend.operation));
+ DAWN_TRY(ValidateBlendFactor(descriptor->colorBlend.srcFactor));
+ DAWN_TRY(ValidateBlendFactor(descriptor->colorBlend.dstFactor));
+ DAWN_TRY(ValidateColorWriteMask(descriptor->colorWriteMask));
+ return {};
+ }
+
+ MaybeError ValidateDepthStencilStateDescriptor(
+ const DepthStencilStateDescriptor* descriptor) {
+ if (descriptor->nextInChain != nullptr) {
+ return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
+ }
+ DAWN_TRY(ValidateCompareFunction(descriptor->depthCompare));
+ DAWN_TRY(ValidateCompareFunction(descriptor->front.compare));
+ DAWN_TRY(ValidateStencilOperation(descriptor->front.stencilFailOp));
+ DAWN_TRY(ValidateStencilOperation(descriptor->front.depthFailOp));
+ DAWN_TRY(ValidateStencilOperation(descriptor->front.passOp));
+ DAWN_TRY(ValidateCompareFunction(descriptor->back.compare));
+ DAWN_TRY(ValidateStencilOperation(descriptor->back.stencilFailOp));
+ DAWN_TRY(ValidateStencilOperation(descriptor->back.depthFailOp));
+ DAWN_TRY(ValidateStencilOperation(descriptor->back.passOp));
+ return {};
+ }
- RenderPipelineBase::RenderPipelineBase(RenderPipelineBuilder* builder)
- : PipelineBase(builder->GetDevice(), builder),
- mDepthStencilState(std::move(builder->mDepthStencilState)),
- mIndexFormat(builder->mIndexFormat),
- mInputState(std::move(builder->mInputState)),
- mPrimitiveTopology(builder->mPrimitiveTopology),
- mBlendStates(builder->mBlendStates),
- mColorAttachmentsSet(builder->mColorAttachmentsSet),
- mColorAttachmentFormats(builder->mColorAttachmentFormats),
- mDepthStencilFormatSet(builder->mDepthStencilFormatSet),
- mDepthStencilFormat(builder->mDepthStencilFormat) {
- if (GetStageMask() != (dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment)) {
- builder->HandleError("Render pipeline should have exactly a vertex and fragment stage");
- return;
- }
-
- // TODO(kainino@chromium.org): Need to verify the pipeline against its render subpass.
-
- if ((builder->GetStageInfo(dawn::ShaderStage::Vertex).module->GetUsedVertexAttributes() &
- ~mInputState->GetAttributesSetMask())
+ } // anonymous namespace
+
+ MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
+ const RenderPipelineDescriptor* descriptor) {
+ if (descriptor->nextInChain != nullptr) {
+ return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
+ }
+
+ if (descriptor->layout == nullptr) {
+ return DAWN_VALIDATION_ERROR("Layout must not be null");
+ }
+
+ if (descriptor->inputState == nullptr) {
+ return DAWN_VALIDATION_ERROR("Input state must not be null");
+ }
+
+ if (descriptor->depthStencilState == nullptr) {
+ return DAWN_VALIDATION_ERROR("Depth stencil state must not be null");
+ }
+
+ for (uint32_t i = 0; i < descriptor->numBlendStates; ++i) {
+ DAWN_TRY(ValidateBlendStateDescriptor(&descriptor->blendStates[i]));
+ }
+
+ DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat));
+ DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
+ DAWN_TRY(ValidatePipelineStageDescriptor(descriptor->vertexStage, descriptor->layout,
+ dawn::ShaderStage::Vertex));
+ DAWN_TRY(ValidatePipelineStageDescriptor(descriptor->fragmentStage, descriptor->layout,
+ dawn::ShaderStage::Fragment));
+ DAWN_TRY(ValidateAttachmentsStateDescriptor(descriptor->attachmentsState));
+
+ if ((descriptor->vertexStage->module->GetUsedVertexAttributes() &
+ ~descriptor->inputState->GetAttributesSetMask())
.any()) {
- builder->HandleError("Pipeline vertex stage uses inputs not in the input state");
- return;
+ return DAWN_VALIDATION_ERROR(
+ "Pipeline vertex stage uses inputs not in the input state");
}
- // TODO(cwallez@chromium.org): Check against the shader module that the correct color
- // attachment are set?
+ if (descriptor->sampleCount != 1) {
+ return DAWN_VALIDATION_ERROR("Sample count must be one");
+ }
- size_t attachmentCount = mColorAttachmentsSet.count();
- if (mDepthStencilFormatSet) {
- attachmentCount++;
+ if (descriptor->numBlendStates > kMaxColorAttachments) {
+ return DAWN_VALIDATION_ERROR("Blend states number exceeds maximum");
}
- if (attachmentCount == 0) {
- builder->HandleError("Should have at least one attachment");
- return;
+ if (descriptor->attachmentsState->numColorAttachments != descriptor->numBlendStates) {
+ return DAWN_VALIDATION_ERROR("Each color attachment should have blend state");
}
+
+ DAWN_TRY(ValidateDepthStencilStateDescriptor(descriptor->depthStencilState));
+
+ return {};
}
- BlendStateBase* RenderPipelineBase::GetBlendState(uint32_t attachmentSlot) {
+ bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState) {
+ return mDepthStencilState->back.compare != dawn::CompareFunction::Always ||
+ mDepthStencilState->back.stencilFailOp != dawn::StencilOperation::Keep ||
+ mDepthStencilState->back.depthFailOp != dawn::StencilOperation::Keep ||
+ mDepthStencilState->back.passOp != dawn::StencilOperation::Keep ||
+ mDepthStencilState->front.compare != dawn::CompareFunction::Always ||
+ mDepthStencilState->front.stencilFailOp != dawn::StencilOperation::Keep ||
+ mDepthStencilState->front.depthFailOp != dawn::StencilOperation::Keep ||
+ mDepthStencilState->front.passOp != dawn::StencilOperation::Keep;
+ }
+
+ // RenderPipelineBase
+
+ RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
+ const RenderPipelineDescriptor* descriptor)
+ : PipelineBase(device,
+ descriptor->layout,
+ dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment),
+ mDepthStencilState(*descriptor->depthStencilState),
+ mIndexFormat(descriptor->indexFormat),
+ mInputState(descriptor->inputState),
+ mPrimitiveTopology(descriptor->primitiveTopology),
+ mHasDepthStencilAttachment(descriptor->attachmentsState->hasDepthStencilAttachment) {
+ if (mHasDepthStencilAttachment) {
+ mDepthStencilFormat = descriptor->attachmentsState->depthStencilAttachment->format;
+ }
+ ExtractModuleData(dawn::ShaderStage::Vertex, descriptor->vertexStage->module);
+ ExtractModuleData(dawn::ShaderStage::Fragment, descriptor->fragmentStage->module);
+
+ for (uint32_t i = 0; i < descriptor->attachmentsState->numColorAttachments; ++i) {
+ mColorAttachmentsSet.set(i);
+ mBlendStates[i] = descriptor->blendStates[i];
+ mColorAttachmentFormats[i] = descriptor->attachmentsState->colorAttachments[i]->format;
+ }
+
+ // TODO(cwallez@chromium.org): Check against the shader module that the correct color
+ // attachment are set?
+ }
+
+ const BlendStateDescriptor* RenderPipelineBase::GetBlendStateDescriptor(
+ uint32_t attachmentSlot) {
ASSERT(attachmentSlot < mBlendStates.size());
- return mBlendStates[attachmentSlot].Get();
+ return &mBlendStates[attachmentSlot];
}
- DepthStencilStateBase* RenderPipelineBase::GetDepthStencilState() {
- return mDepthStencilState.Get();
+ const DepthStencilStateDescriptor* RenderPipelineBase::GetDepthStencilStateDescriptor() {
+ return &mDepthStencilState;
}
dawn::IndexFormat RenderPipelineBase::GetIndexFormat() const {
@@ -91,7 +224,7 @@ namespace dawn_native {
}
bool RenderPipelineBase::HasDepthStencilAttachment() const {
- return mDepthStencilFormatSet;
+ return mHasDepthStencilAttachment;
}
dawn::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(uint32_t attachment) const {
@@ -99,6 +232,7 @@ namespace dawn_native {
}
dawn::TextureFormat RenderPipelineBase::GetDepthStencilFormat() const {
+ ASSERT(mHasDepthStencilAttachment);
return mDepthStencilFormat;
}
@@ -118,11 +252,11 @@ namespace dawn_native {
}
}
- if (renderPass->HasDepthStencilAttachment() != mDepthStencilFormatSet) {
+ if (renderPass->HasDepthStencilAttachment() != mHasDepthStencilAttachment) {
return false;
}
- if (mDepthStencilFormatSet &&
+ if (mHasDepthStencilAttachment &&
(renderPass->GetDepthStencilAttachment().view->GetTexture()->GetFormat() !=
mDepthStencilFormat)) {
return false;
@@ -131,92 +265,4 @@ namespace dawn_native {
return true;
}
- // RenderPipelineBuilder
-
- RenderPipelineBuilder::RenderPipelineBuilder(DeviceBase* device)
- : Builder(device), PipelineBuilder(this) {
- }
-
- RenderPipelineBase* RenderPipelineBuilder::GetResultImpl() {
- DeviceBase* device = GetDevice();
- // TODO(cwallez@chromium.org): the layout should be required, and put the default objects in
- // the device
- if (!mInputState) {
- auto builder = device->CreateInputStateBuilder();
- mInputState = builder->GetResult();
- // Remove the external ref objects are created with
- mInputState->Release();
- builder->Release();
- }
- if (!mDepthStencilState) {
- auto builder = device->CreateDepthStencilStateBuilder();
- mDepthStencilState = builder->GetResult();
- // Remove the external ref objects are created with
- mDepthStencilState->Release();
- builder->Release();
- }
-
- if ((mBlendStatesSet | mColorAttachmentsSet) != mColorAttachmentsSet) {
- HandleError("Blend state set on unset color attachment");
- return nullptr;
- }
-
- // Assign all color attachments without a blend state the default state
- // TODO(enga@google.com): Put the default objects in the device
- for (uint32_t attachmentSlot : IterateBitSet(mColorAttachmentsSet & ~mBlendStatesSet)) {
- mBlendStates[attachmentSlot] = device->CreateBlendStateBuilder()->GetResult();
- // Remove the external ref objects are created with
- mBlendStates[attachmentSlot]->Release();
- }
-
- return device->CreateRenderPipeline(this);
- }
-
- void RenderPipelineBuilder::SetColorAttachmentFormat(uint32_t attachmentSlot,
- dawn::TextureFormat format) {
- if (attachmentSlot >= kMaxColorAttachments) {
- HandleError("Attachment index out of bounds");
- return;
- }
-
- mColorAttachmentsSet.set(attachmentSlot);
- mColorAttachmentFormats[attachmentSlot] = format;
- }
-
- void RenderPipelineBuilder::SetColorAttachmentBlendState(uint32_t attachmentSlot,
- BlendStateBase* blendState) {
- if (attachmentSlot >= kMaxColorAttachments) {
- HandleError("Attachment index out of bounds");
- return;
- }
- if (mBlendStatesSet[attachmentSlot]) {
- HandleError("Attachment blend state already set");
- return;
- }
-
- mBlendStatesSet.set(attachmentSlot);
- mBlendStates[attachmentSlot] = blendState;
- }
-
- void RenderPipelineBuilder::SetDepthStencilState(DepthStencilStateBase* depthStencilState) {
- mDepthStencilState = depthStencilState;
- }
-
- void RenderPipelineBuilder::SetDepthStencilAttachmentFormat(dawn::TextureFormat format) {
- mDepthStencilFormatSet = true;
- mDepthStencilFormat = format;
- }
-
- void RenderPipelineBuilder::SetIndexFormat(dawn::IndexFormat format) {
- mIndexFormat = format;
- }
-
- void RenderPipelineBuilder::SetInputState(InputStateBase* inputState) {
- mInputState = inputState;
- }
-
- void RenderPipelineBuilder::SetPrimitiveTopology(dawn::PrimitiveTopology primitiveTopology) {
- mPrimitiveTopology = primitiveTopology;
- }
-
} // namespace dawn_native
diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPipeline.h b/chromium/third_party/dawn/src/dawn_native/RenderPipeline.h
index 73362e7268e..2ede129e257 100644
--- a/chromium/third_party/dawn/src/dawn_native/RenderPipeline.h
+++ b/chromium/third_party/dawn/src/dawn_native/RenderPipeline.h
@@ -15,8 +15,6 @@
#ifndef DAWNNATIVE_RENDERPIPELINE_H_
#define DAWNNATIVE_RENDERPIPELINE_H_
-#include "dawn_native/BlendState.h"
-#include "dawn_native/DepthStencilState.h"
#include "dawn_native/InputState.h"
#include "dawn_native/Pipeline.h"
@@ -27,12 +25,18 @@
namespace dawn_native {
+ class DeviceBase;
+
+ MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
+ const RenderPipelineDescriptor* descriptor);
+ bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState);
+
class RenderPipelineBase : public PipelineBase {
public:
- RenderPipelineBase(RenderPipelineBuilder* builder);
+ RenderPipelineBase(DeviceBase* device, const RenderPipelineDescriptor* descriptor);
- BlendStateBase* GetBlendState(uint32_t attachmentSlot);
- DepthStencilStateBase* GetDepthStencilState();
+ const BlendStateDescriptor* GetBlendStateDescriptor(uint32_t attachmentSlot);
+ const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor();
dawn::IndexFormat GetIndexFormat() const;
InputStateBase* GetInputState();
dawn::PrimitiveTopology GetPrimitiveTopology() const;
@@ -47,47 +51,15 @@ namespace dawn_native {
bool IsCompatibleWith(const RenderPassDescriptorBase* renderPass) const;
private:
- Ref<DepthStencilStateBase> mDepthStencilState;
+ DepthStencilStateDescriptor mDepthStencilState;
dawn::IndexFormat mIndexFormat;
Ref<InputStateBase> mInputState;
dawn::PrimitiveTopology mPrimitiveTopology;
- std::array<Ref<BlendStateBase>, kMaxColorAttachments> mBlendStates;
-
- std::bitset<kMaxColorAttachments> mColorAttachmentsSet;
- std::array<dawn::TextureFormat, kMaxColorAttachments> mColorAttachmentFormats;
- bool mDepthStencilFormatSet = false;
- dawn::TextureFormat mDepthStencilFormat;
- };
+ std::array<BlendStateDescriptor, kMaxColorAttachments> mBlendStates;
- class RenderPipelineBuilder : public Builder<RenderPipelineBase>, public PipelineBuilder {
- public:
- RenderPipelineBuilder(DeviceBase* device);
-
- // Dawn API
- void SetColorAttachmentFormat(uint32_t attachmentSlot, dawn::TextureFormat format);
- void SetColorAttachmentBlendState(uint32_t attachmentSlot, BlendStateBase* blendState);
- void SetDepthStencilAttachmentFormat(dawn::TextureFormat format);
- void SetDepthStencilState(DepthStencilStateBase* depthStencilState);
- void SetPrimitiveTopology(dawn::PrimitiveTopology primitiveTopology);
- void SetIndexFormat(dawn::IndexFormat format);
- void SetInputState(InputStateBase* inputState);
-
- private:
- friend class RenderPipelineBase;
-
- RenderPipelineBase* GetResultImpl() override;
-
- Ref<DepthStencilStateBase> mDepthStencilState;
- Ref<InputStateBase> mInputState;
- // TODO(enga@google.com): Remove default when we validate that all required properties are
- // set
- dawn::PrimitiveTopology mPrimitiveTopology = dawn::PrimitiveTopology::TriangleList;
- dawn::IndexFormat mIndexFormat = dawn::IndexFormat::Uint32;
- std::bitset<kMaxColorAttachments> mBlendStatesSet;
- std::array<Ref<BlendStateBase>, kMaxColorAttachments> mBlendStates;
std::bitset<kMaxColorAttachments> mColorAttachmentsSet;
std::array<dawn::TextureFormat, kMaxColorAttachments> mColorAttachmentFormats;
- bool mDepthStencilFormatSet = false;
+ bool mHasDepthStencilAttachment = false;
dawn::TextureFormat mDepthStencilFormat;
};
diff --git a/chromium/third_party/dawn/src/dawn_native/Sampler.cpp b/chromium/third_party/dawn/src/dawn_native/Sampler.cpp
index 71cca99b4c3..3e688943adf 100644
--- a/chromium/third_party/dawn/src/dawn_native/Sampler.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/Sampler.cpp
@@ -23,12 +23,24 @@ namespace dawn_native {
if (descriptor->nextInChain != nullptr) {
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
}
+
+ if (descriptor->lodMinClamp < 0 || descriptor->lodMaxClamp < 0) {
+ return DAWN_VALIDATION_ERROR("LOD must be positive");
+ }
+
+ if (descriptor->lodMinClamp > descriptor->lodMaxClamp) {
+ return DAWN_VALIDATION_ERROR(
+ "Min lod clamp value cannot greater than max lod clamp value");
+ }
+
DAWN_TRY(ValidateFilterMode(descriptor->minFilter));
DAWN_TRY(ValidateFilterMode(descriptor->magFilter));
DAWN_TRY(ValidateFilterMode(descriptor->mipmapFilter));
DAWN_TRY(ValidateAddressMode(descriptor->addressModeU));
DAWN_TRY(ValidateAddressMode(descriptor->addressModeV));
DAWN_TRY(ValidateAddressMode(descriptor->addressModeW));
+ DAWN_TRY(ValidateCompareFunction(descriptor->compareFunction));
+ DAWN_TRY(ValidateBorderColor(descriptor->borderColor));
return {};
}
diff --git a/chromium/third_party/dawn/src/dawn_native/SwapChain.cpp b/chromium/third_party/dawn/src/dawn_native/SwapChain.cpp
index 6314a0da0f4..c2ea095c20d 100644
--- a/chromium/third_party/dawn/src/dawn_native/SwapChain.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/SwapChain.cpp
@@ -60,7 +60,8 @@ namespace dawn_native {
descriptor.size.width = mWidth;
descriptor.size.height = mHeight;
descriptor.size.depth = 1;
- descriptor.arrayLayer = 1;
+ descriptor.arraySize = 1;
+ descriptor.sampleCount = 1;
descriptor.format = mFormat;
descriptor.levelCount = 1;
descriptor.usage = mAllowedUsage;
diff --git a/chromium/third_party/dawn/src/dawn_native/Texture.cpp b/chromium/third_party/dawn/src/dawn_native/Texture.cpp
index 0923fccb79b..44b416093ee 100644
--- a/chromium/third_party/dawn/src/dawn_native/Texture.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/Texture.cpp
@@ -82,6 +82,15 @@ namespace dawn_native {
}
}
+ // TODO(jiawei.shao@intel.com): support multisampled textures
+ MaybeError ValidateSampleCount(uint32_t sampleCount) {
+ if (sampleCount != 1) {
+ return DAWN_VALIDATION_ERROR("The sample count of the texture is not supported.");
+ }
+
+ return {};
+ }
+
MaybeError ValidateTextureViewDimensionCompatibility(
const TextureBase* texture,
const TextureViewDescriptor* descriptor) {
@@ -142,10 +151,11 @@ namespace dawn_native {
DAWN_TRY(ValidateTextureUsageBit(descriptor->usage));
DAWN_TRY(ValidateTextureDimension(descriptor->dimension));
DAWN_TRY(ValidateTextureFormat(descriptor->format));
+ DAWN_TRY(ValidateSampleCount(descriptor->sampleCount));
// TODO(jiawei.shao@intel.com): check stuff based on the dimension
if (descriptor->size.width == 0 || descriptor->size.height == 0 ||
- descriptor->size.depth == 0 || descriptor->arrayLayer == 0 ||
+ descriptor->size.depth == 0 || descriptor->arraySize == 0 ||
descriptor->levelCount == 0) {
return DAWN_VALIDATION_ERROR("Cannot create an empty texture");
}
@@ -250,6 +260,26 @@ namespace dawn_native {
}
}
+ bool IsDepthStencilRenderableTextureFormat(dawn::TextureFormat format) {
+ switch (format) {
+ case dawn::TextureFormat::D32FloatS8Uint:
+ return true;
+
+ case dawn::TextureFormat::B8G8R8A8Unorm:
+ case dawn::TextureFormat::R8G8B8A8Uint:
+ case dawn::TextureFormat::R8G8B8A8Unorm:
+ case dawn::TextureFormat::R8G8Uint:
+ case dawn::TextureFormat::R8G8Unorm:
+ case dawn::TextureFormat::R8Uint:
+ case dawn::TextureFormat::R8Unorm:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+ }
+
// TextureBase
TextureBase::TextureBase(DeviceBase* device, const TextureDescriptor* descriptor)
@@ -257,7 +287,7 @@ namespace dawn_native {
mDimension(descriptor->dimension),
mFormat(descriptor->format),
mSize(descriptor->size),
- mArrayLayers(descriptor->arrayLayer),
+ mArrayLayers(descriptor->arraySize),
mNumMipLevels(descriptor->levelCount),
mUsage(descriptor->usage) {
}
@@ -300,7 +330,9 @@ namespace dawn_native {
: ObjectBase(texture->GetDevice()),
mTexture(texture),
mFormat(descriptor->format),
+ mBaseMipLevel(descriptor->baseMipLevel),
mLevelCount(descriptor->levelCount),
+ mBaseArrayLayer(descriptor->baseArrayLayer),
mLayerCount(descriptor->layerCount) {
}
@@ -316,10 +348,18 @@ namespace dawn_native {
return mFormat;
}
+ uint32_t TextureViewBase::GetBaseMipLevel() const {
+ return mBaseMipLevel;
+ }
+
uint32_t TextureViewBase::GetLevelCount() const {
return mLevelCount;
}
+ uint32_t TextureViewBase::GetBaseArrayLayer() const {
+ return mBaseArrayLayer;
+ }
+
uint32_t TextureViewBase::GetLayerCount() const {
return mLayerCount;
}
diff --git a/chromium/third_party/dawn/src/dawn_native/Texture.h b/chromium/third_party/dawn/src/dawn_native/Texture.h
index f1194f05b22..12edb3cf6b1 100644
--- a/chromium/third_party/dawn/src/dawn_native/Texture.h
+++ b/chromium/third_party/dawn/src/dawn_native/Texture.h
@@ -33,6 +33,7 @@ namespace dawn_native {
bool TextureFormatHasStencil(dawn::TextureFormat format);
bool TextureFormatHasDepthOrStencil(dawn::TextureFormat format);
bool IsColorRenderableTextureFormat(dawn::TextureFormat format);
+ bool IsDepthStencilRenderableTextureFormat(dawn::TextureFormat format);
static constexpr dawn::TextureUsageBit kReadOnlyTextureUsages =
dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::Sampled |
@@ -76,14 +77,18 @@ namespace dawn_native {
TextureBase* GetTexture();
dawn::TextureFormat GetFormat() const;
+ uint32_t GetBaseMipLevel() const;
uint32_t GetLevelCount() const;
+ uint32_t GetBaseArrayLayer() const;
uint32_t GetLayerCount() const;
private:
Ref<TextureBase> mTexture;
dawn::TextureFormat mFormat;
+ uint32_t mBaseMipLevel;
uint32_t mLevelCount;
+ uint32_t mBaseArrayLayer;
uint32_t mLayerCount;
};
diff --git a/chromium/third_party/dawn/src/dawn_native/ToBackend.h b/chromium/third_party/dawn/src/dawn_native/ToBackend.h
index 1e64f2c80c1..585a40dc93c 100644
--- a/chromium/third_party/dawn/src/dawn_native/ToBackend.h
+++ b/chromium/third_party/dawn/src/dawn_native/ToBackend.h
@@ -24,6 +24,11 @@ namespace dawn_native {
struct ToBackendTraits;
template <typename BackendTraits>
+ struct ToBackendTraits<AdapterBase, BackendTraits> {
+ using BackendType = typename BackendTraits::AdapterType;
+ };
+
+ template <typename BackendTraits>
struct ToBackendTraits<BindGroupBase, BackendTraits> {
using BackendType = typename BackendTraits::BindGroupType;
};
@@ -34,21 +39,11 @@ namespace dawn_native {
};
template <typename BackendTraits>
- struct ToBackendTraits<BlendStateBase, BackendTraits> {
- using BackendType = typename BackendTraits::BlendStateType;
- };
-
- template <typename BackendTraits>
struct ToBackendTraits<BufferBase, BackendTraits> {
using BackendType = typename BackendTraits::BufferType;
};
template <typename BackendTraits>
- struct ToBackendTraits<BufferViewBase, BackendTraits> {
- using BackendType = typename BackendTraits::BufferViewType;
- };
-
- template <typename BackendTraits>
struct ToBackendTraits<CommandBufferBase, BackendTraits> {
using BackendType = typename BackendTraits::CommandBufferType;
};
@@ -59,11 +54,6 @@ namespace dawn_native {
};
template <typename BackendTraits>
- struct ToBackendTraits<DepthStencilStateBase, BackendTraits> {
- using BackendType = typename BackendTraits::DepthStencilStateType;
- };
-
- template <typename BackendTraits>
struct ToBackendTraits<DeviceBase, BackendTraits> {
using BackendType = typename BackendTraits::DeviceType;
};
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.cpp
index c013d80d30d..b9ad9ba1198 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.cpp
@@ -23,7 +23,8 @@
namespace dawn_native { namespace d3d12 {
- BindGroup::BindGroup(BindGroupBuilder* builder) : BindGroupBase(builder) {
+ BindGroup::BindGroup(Device* device, const BindGroupDescriptor* descriptor)
+ : BindGroupBase(device, descriptor) {
}
void BindGroup::RecordDescriptors(const DescriptorHeapHandle& cbvUavSrvHeapStart,
@@ -45,37 +46,54 @@ namespace dawn_native { namespace d3d12 {
const auto& bindingOffsets = bgl->GetBindingOffsets();
auto d3d12Device = ToBackend(GetDevice())->GetD3D12Device();
- for (uint32_t binding : IterateBitSet(layout.mask)) {
- switch (layout.types[binding]) {
+ for (uint32_t bindingIndex : IterateBitSet(layout.mask)) {
+ switch (layout.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer: {
- auto* view = ToBackend(GetBindingAsBufferView(binding));
- auto& cbv = view->GetCBVDescriptor();
+ BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
+
+ D3D12_CONSTANT_BUFFER_VIEW_DESC desc;
+ // TODO(enga@google.com): investigate if this needs to be a constraint at the
+ // API level
+ desc.SizeInBytes = Align(binding.size, 256);
+ desc.BufferLocation = ToBackend(binding.buffer)->GetVA() + binding.offset;
+
d3d12Device->CreateConstantBufferView(
- &cbv, cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset +
- bindingOffsets[binding]));
+ &desc, cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset +
+ bindingOffsets[bindingIndex]));
} break;
case dawn::BindingType::StorageBuffer: {
- auto* view = ToBackend(GetBindingAsBufferView(binding));
- auto& uav = view->GetUAVDescriptor();
+ BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
+
+ D3D12_UNORDERED_ACCESS_VIEW_DESC desc;
+ // TODO(enga@google.com): investigate if this needs to be a constraint at the
+ // API level
+ desc.Buffer.NumElements = Align(binding.size, 256);
+ desc.Format = DXGI_FORMAT_UNKNOWN;
+ desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
+ desc.Buffer.FirstElement = binding.offset;
+ desc.Buffer.StructureByteStride = 1;
+ desc.Buffer.CounterOffsetInBytes = 0;
+ desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
+
d3d12Device->CreateUnorderedAccessView(
- ToBackend(view->GetBuffer())->GetD3D12Resource().Get(), nullptr, &uav,
+ ToBackend(binding.buffer)->GetD3D12Resource().Get(), nullptr, &desc,
cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset +
- bindingOffsets[binding]));
+ bindingOffsets[bindingIndex]));
} break;
case dawn::BindingType::SampledTexture: {
- auto* view = ToBackend(GetBindingAsTextureView(binding));
+ auto* view = ToBackend(GetBindingAsTextureView(bindingIndex));
auto& srv = view->GetSRVDescriptor();
d3d12Device->CreateShaderResourceView(
ToBackend(view->GetTexture())->GetD3D12Resource(), &srv,
cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset +
- bindingOffsets[binding]));
+ bindingOffsets[bindingIndex]));
} break;
case dawn::BindingType::Sampler: {
- auto* sampler = ToBackend(GetBindingAsSampler(binding));
+ auto* sampler = ToBackend(GetBindingAsSampler(bindingIndex));
auto& samplerDesc = sampler->GetSamplerDescriptor();
d3d12Device->CreateSampler(
&samplerDesc, samplerHeapStart.GetCPUHandle(*samplerHeapOffset +
- bindingOffsets[binding]));
+ bindingOffsets[bindingIndex]));
} break;
}
}
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.h
index b5779391275..f8d5fbfdd79 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.h
@@ -27,7 +27,7 @@ namespace dawn_native { namespace d3d12 {
class BindGroup : public BindGroupBase {
public:
- BindGroup(BindGroupBuilder* builder);
+ BindGroup(Device* device, const BindGroupDescriptor* descriptor);
void RecordDescriptors(const DescriptorHeapHandle& cbvSrvUavHeapStart,
uint32_t* cbvUavSrvHeapOffset,
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/BlendStateD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/BlendStateD3D12.cpp
deleted file mode 100644
index 862315eb0c6..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/BlendStateD3D12.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2017 The Dawn 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_native/d3d12/BlendStateD3D12.h"
-
-#include "common/Assert.h"
-#include "dawn_native/d3d12/DeviceD3D12.h"
-
-namespace dawn_native { namespace d3d12 {
-
- namespace {
- D3D12_BLEND D3D12Blend(dawn::BlendFactor factor) {
- switch (factor) {
- case dawn::BlendFactor::Zero:
- return D3D12_BLEND_ZERO;
- case dawn::BlendFactor::One:
- return D3D12_BLEND_ONE;
- case dawn::BlendFactor::SrcColor:
- return D3D12_BLEND_SRC_COLOR;
- case dawn::BlendFactor::OneMinusSrcColor:
- return D3D12_BLEND_INV_SRC_COLOR;
- case dawn::BlendFactor::SrcAlpha:
- return D3D12_BLEND_SRC_ALPHA;
- case dawn::BlendFactor::OneMinusSrcAlpha:
- return D3D12_BLEND_INV_SRC_ALPHA;
- case dawn::BlendFactor::DstColor:
- return D3D12_BLEND_DEST_COLOR;
- case dawn::BlendFactor::OneMinusDstColor:
- return D3D12_BLEND_INV_DEST_COLOR;
- case dawn::BlendFactor::DstAlpha:
- return D3D12_BLEND_DEST_ALPHA;
- case dawn::BlendFactor::OneMinusDstAlpha:
- return D3D12_BLEND_INV_DEST_ALPHA;
- case dawn::BlendFactor::SrcAlphaSaturated:
- return D3D12_BLEND_SRC_ALPHA_SAT;
- case dawn::BlendFactor::BlendColor:
- return D3D12_BLEND_BLEND_FACTOR;
- case dawn::BlendFactor::OneMinusBlendColor:
- return D3D12_BLEND_INV_BLEND_FACTOR;
- default:
- UNREACHABLE();
- }
- }
-
- D3D12_BLEND_OP D3D12BlendOperation(dawn::BlendOperation operation) {
- switch (operation) {
- case dawn::BlendOperation::Add:
- return D3D12_BLEND_OP_ADD;
- case dawn::BlendOperation::Subtract:
- return D3D12_BLEND_OP_SUBTRACT;
- case dawn::BlendOperation::ReverseSubtract:
- return D3D12_BLEND_OP_REV_SUBTRACT;
- case dawn::BlendOperation::Min:
- return D3D12_BLEND_OP_MIN;
- case dawn::BlendOperation::Max:
- return D3D12_BLEND_OP_MAX;
- default:
- UNREACHABLE();
- }
- }
-
- uint8_t D3D12RenderTargetWriteMask(dawn::ColorWriteMask colorWriteMask) {
- static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Red) ==
- D3D12_COLOR_WRITE_ENABLE_RED,
- "ColorWriteMask values must match");
- static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Green) ==
- D3D12_COLOR_WRITE_ENABLE_GREEN,
- "ColorWriteMask values must match");
- static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Blue) ==
- D3D12_COLOR_WRITE_ENABLE_BLUE,
- "ColorWriteMask values must match");
- static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Alpha) ==
- D3D12_COLOR_WRITE_ENABLE_ALPHA,
- "ColorWriteMask values must match");
- return static_cast<uint8_t>(colorWriteMask);
- }
- } // namespace
-
- BlendState::BlendState(BlendStateBuilder* builder) : BlendStateBase(builder) {
- auto& info = GetBlendInfo();
- mBlendDesc.BlendEnable = info.blendEnabled;
- mBlendDesc.SrcBlend = D3D12Blend(info.colorBlend.srcFactor);
- mBlendDesc.DestBlend = D3D12Blend(info.colorBlend.dstFactor);
- mBlendDesc.BlendOp = D3D12BlendOperation(info.colorBlend.operation);
- mBlendDesc.SrcBlendAlpha = D3D12Blend(info.alphaBlend.srcFactor);
- mBlendDesc.DestBlendAlpha = D3D12Blend(info.alphaBlend.dstFactor);
- mBlendDesc.BlendOpAlpha = D3D12BlendOperation(info.alphaBlend.operation);
- mBlendDesc.RenderTargetWriteMask = D3D12RenderTargetWriteMask(info.colorWriteMask);
- mBlendDesc.LogicOpEnable = false;
- mBlendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
- }
-
- const D3D12_RENDER_TARGET_BLEND_DESC& BlendState::GetD3D12BlendDesc() const {
- return mBlendDesc;
- }
-
-}} // namespace dawn_native::d3d12
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.cpp
index 71b6b400e5e..4b75d1f48f0 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.cpp
@@ -197,32 +197,6 @@ namespace dawn_native { namespace d3d12 {
mWrittenMappedRange = {};
}
- BufferView::BufferView(BufferViewBuilder* builder) : BufferViewBase(builder) {
- mCbvDesc.BufferLocation = ToBackend(GetBuffer())->GetVA() + GetOffset();
- mCbvDesc.SizeInBytes = GetD3D12Size();
-
- mUavDesc.Format = DXGI_FORMAT_UNKNOWN;
- mUavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
- mUavDesc.Buffer.FirstElement = GetOffset();
- mUavDesc.Buffer.NumElements = GetD3D12Size();
- mUavDesc.Buffer.StructureByteStride = 1;
- mUavDesc.Buffer.CounterOffsetInBytes = 0;
- mUavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
- }
-
- uint32_t BufferView::GetD3D12Size() const {
- // TODO(enga@google.com): TODO investigate if this needs to be a constraint at the API level
- return Align(GetSize(), 256);
- }
-
- const D3D12_CONSTANT_BUFFER_VIEW_DESC& BufferView::GetCBVDescriptor() const {
- return mCbvDesc;
- }
-
- const D3D12_UNORDERED_ACCESS_VIEW_DESC& BufferView::GetUAVDescriptor() const {
- return mUavDesc;
- }
-
MapRequestTracker::MapRequestTracker(Device* device) : mDevice(device) {
}
@@ -237,7 +211,7 @@ namespace dawn_native { namespace d3d12 {
request.data = data;
request.isWrite = isWrite;
- mInflightRequests.Enqueue(std::move(request), mDevice->GetSerial());
+ mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial());
}
void MapRequestTracker::Tick(Serial finishedSerial) {
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.h
index 9965d49e771..633d2602ea2 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.h
@@ -50,19 +50,6 @@ namespace dawn_native { namespace d3d12 {
D3D12_RANGE mWrittenMappedRange;
};
- class BufferView : public BufferViewBase {
- public:
- BufferView(BufferViewBuilder* builder);
-
- uint32_t GetD3D12Size() const;
- const D3D12_CONSTANT_BUFFER_VIEW_DESC& GetCBVDescriptor() const;
- const D3D12_UNORDERED_ACCESS_VIEW_DESC& GetUAVDescriptor() const;
-
- private:
- D3D12_CONSTANT_BUFFER_VIEW_DESC mCbvDesc;
- D3D12_UNORDERED_ACCESS_VIEW_DESC mUavDesc;
- };
-
class MapRequestTracker {
public:
MapRequestTracker(Device* device);
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/CommandAllocatorManager.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/CommandAllocatorManager.cpp
index 47072fcf6ce..90f7a5a8951 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/CommandAllocatorManager.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/CommandAllocatorManager.cpp
@@ -52,7 +52,7 @@ namespace dawn_native { namespace d3d12 {
// Enqueue the command allocator. It will be scheduled for reset after the next
// ExecuteCommandLists
mInFlightCommandAllocators.Enqueue({mCommandAllocators[firstFreeIndex], firstFreeIndex},
- device->GetSerial());
+ device->GetPendingCommandSerial());
return mCommandAllocators[firstFreeIndex];
}
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.cpp
index 65e7d6cec3d..bff0a4dbd74 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.cpp
@@ -71,7 +71,7 @@ namespace dawn_native { namespace d3d12 {
// Descriptors don't need to be recorded if they have already been recorded in
// the heap. Indices are only updated when descriptors are recorded
- const uint64_t serial = device->GetSerial();
+ const uint64_t serial = device->GetPendingCommandSerial();
if (group->GetHeapSerial() != serial ||
group->GetIndexInSubmit() != indexInSubmit) {
group->RecordDescriptors(cbvSrvUavCPUDescriptorHeap, &cbvSrvUavDescriptorIndex,
@@ -329,10 +329,9 @@ namespace dawn_native { namespace d3d12 {
texture->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferDst);
auto copySplit = ComputeTextureCopySplit(
- copy->destination.x, copy->destination.y, copy->destination.z,
- copy->destination.width, copy->destination.height, copy->destination.depth,
+ copy->destination.origin, copy->copySize,
static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat())),
- copy->source.offset, copy->rowPitch);
+ copy->source.offset, copy->source.rowPitch, copy->source.imageHeight);
D3D12_TEXTURE_COPY_LOCATION textureLocation;
textureLocation.pResource = texture->GetD3D12Resource();
@@ -352,7 +351,7 @@ namespace dawn_native { namespace d3d12 {
bufferLocation.PlacedFootprint.Footprint.Width = info.bufferSize.width;
bufferLocation.PlacedFootprint.Footprint.Height = info.bufferSize.height;
bufferLocation.PlacedFootprint.Footprint.Depth = info.bufferSize.depth;
- bufferLocation.PlacedFootprint.Footprint.RowPitch = copy->rowPitch;
+ bufferLocation.PlacedFootprint.Footprint.RowPitch = copy->source.rowPitch;
D3D12_BOX sourceRegion;
sourceRegion.left = info.bufferOffset.x;
@@ -377,10 +376,10 @@ namespace dawn_native { namespace d3d12 {
buffer->TransitionUsageNow(commandList, dawn::BufferUsageBit::TransferDst);
auto copySplit = ComputeTextureCopySplit(
- copy->source.x, copy->source.y, copy->source.z, copy->source.width,
- copy->source.height, copy->source.depth,
+ copy->source.origin, copy->copySize,
static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat())),
- copy->destination.offset, copy->rowPitch);
+ copy->destination.offset, copy->destination.rowPitch,
+ copy->destination.imageHeight);
D3D12_TEXTURE_COPY_LOCATION textureLocation;
textureLocation.pResource = texture->GetD3D12Resource();
@@ -399,7 +398,8 @@ namespace dawn_native { namespace d3d12 {
bufferLocation.PlacedFootprint.Footprint.Width = info.bufferSize.width;
bufferLocation.PlacedFootprint.Footprint.Height = info.bufferSize.height;
bufferLocation.PlacedFootprint.Footprint.Depth = info.bufferSize.depth;
- bufferLocation.PlacedFootprint.Footprint.RowPitch = copy->rowPitch;
+ bufferLocation.PlacedFootprint.Footprint.RowPitch =
+ copy->destination.rowPitch;
D3D12_BOX sourceRegion;
sourceRegion.left = info.textureOffset.x;
@@ -420,6 +420,47 @@ namespace dawn_native { namespace d3d12 {
}
}
+ void CommandBuffer::FlushSetVertexBuffers(ComPtr<ID3D12GraphicsCommandList> commandList,
+ VertexBuffersInfo* vertexBuffersInfo,
+ const InputState* inputState) {
+ DAWN_ASSERT(vertexBuffersInfo != nullptr);
+ DAWN_ASSERT(inputState != nullptr);
+
+ auto inputsMask = inputState->GetInputsSetMask();
+
+ uint32_t startSlot = vertexBuffersInfo->startSlot;
+ uint32_t endSlot = vertexBuffersInfo->endSlot;
+
+ // If the input state has changed, we need to update the StrideInBytes
+ // for the D3D12 buffer views. We also need to extend the dirty range to
+ // touch all these slots because the stride may have changed.
+ if (vertexBuffersInfo->lastInputState != inputState) {
+ vertexBuffersInfo->lastInputState = inputState;
+
+ for (uint32_t slot : IterateBitSet(inputsMask)) {
+ startSlot = std::min(startSlot, slot);
+ endSlot = std::max(endSlot, slot + 1);
+ vertexBuffersInfo->d3d12BufferViews[slot].StrideInBytes =
+ inputState->GetInput(slot).stride;
+ }
+ }
+
+ if (endSlot <= startSlot) {
+ return;
+ }
+
+ // d3d12BufferViews is kept up to date with the most recent data passed
+ // to SetVertexBuffers. This makes it correct to only track the start
+ // and end of the dirty range. When FlushSetVertexBuffers is called,
+ // we will at worst set non-dirty vertex buffers in duplicate.
+ uint32_t count = endSlot - startSlot;
+ commandList->IASetVertexBuffers(startSlot, count,
+ &vertexBuffersInfo->d3d12BufferViews[startSlot]);
+
+ vertexBuffersInfo->startSlot = kMaxVertexInputs;
+ vertexBuffersInfo->endSlot = 0;
+ }
+
void CommandBuffer::RecordComputePass(ComPtr<ID3D12GraphicsCommandList> commandList,
BindGroupStateTracker* bindingTracker) {
PipelineLayout* lastLayout = nullptr;
@@ -532,6 +573,8 @@ namespace dawn_native { namespace d3d12 {
RenderPipeline* lastPipeline = nullptr;
PipelineLayout* lastLayout = nullptr;
+ InputState* lastInputState = nullptr;
+ VertexBuffersInfo vertexBuffersInfo = {};
Command type;
while (mCommands.NextCommandId(&type)) {
@@ -541,22 +584,28 @@ namespace dawn_native { namespace d3d12 {
return;
} break;
- case Command::DrawArrays: {
- DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>();
+ case Command::Draw: {
+ DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
+
+ FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastInputState);
commandList->DrawInstanced(draw->vertexCount, draw->instanceCount,
draw->firstVertex, draw->firstInstance);
} break;
- case Command::DrawElements: {
- DrawElementsCmd* draw = mCommands.NextCommand<DrawElementsCmd>();
+ case Command::DrawIndexed: {
+ DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
+
+ FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastInputState);
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
- draw->firstIndex, 0, draw->firstInstance);
+ draw->firstIndex, draw->baseVertex,
+ draw->firstInstance);
} break;
case Command::SetRenderPipeline: {
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
PipelineLayout* layout = ToBackend(pipeline->GetLayout());
+ InputState* inputState = ToBackend(pipeline->GetInputState());
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get());
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
@@ -566,6 +615,7 @@ namespace dawn_native { namespace d3d12 {
lastPipeline = pipeline;
lastLayout = layout;
+ lastInputState = inputState;
} break;
case Command::SetStencilReference: {
@@ -616,19 +666,19 @@ namespace dawn_native { namespace d3d12 {
auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
auto offsets = mCommands.NextData<uint32_t>(cmd->count);
- auto inputState = ToBackend(lastPipeline->GetInputState());
+ vertexBuffersInfo.startSlot =
+ std::min(vertexBuffersInfo.startSlot, cmd->startSlot);
+ vertexBuffersInfo.endSlot =
+ std::max(vertexBuffersInfo.endSlot, cmd->startSlot + cmd->count);
- std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexInputs> d3d12BufferViews;
for (uint32_t i = 0; i < cmd->count; ++i) {
- auto input = inputState->GetInput(cmd->startSlot + i);
Buffer* buffer = ToBackend(buffers[i].Get());
- d3d12BufferViews[i].BufferLocation = buffer->GetVA() + offsets[i];
- d3d12BufferViews[i].StrideInBytes = input.stride;
- d3d12BufferViews[i].SizeInBytes = buffer->GetSize() - offsets[i];
+ auto* d3d12BufferView =
+ &vertexBuffersInfo.d3d12BufferViews[cmd->startSlot + i];
+ d3d12BufferView->BufferLocation = buffer->GetVA() + offsets[i];
+ d3d12BufferView->SizeInBytes = buffer->GetSize() - offsets[i];
+ // The bufferView stride is set based on the input state before a draw.
}
-
- commandList->IASetVertexBuffers(cmd->startSlot, cmd->count,
- d3d12BufferViews.data());
} break;
default: { UNREACHABLE(); } break;
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.h
index 95ac8bd1422..2ab0bb4a400 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.h
@@ -18,6 +18,7 @@
#include "dawn_native/CommandAllocator.h"
#include "dawn_native/CommandBuffer.h"
+#include "dawn_native/d3d12/InputStateD3D12.h"
#include "dawn_native/d3d12/d3d12_platform.h"
namespace dawn_native { namespace d3d12 {
@@ -27,6 +28,17 @@ namespace dawn_native { namespace d3d12 {
struct BindGroupStateTracker;
+ struct VertexBuffersInfo {
+ // startSlot and endSlot indicate the range of dirty vertex buffers.
+ // If there are multiple calls to SetVertexBuffers, the start and end
+ // represent the union of the dirty ranges (the union may have non-dirty
+ // data in the middle of the range).
+ const InputState* lastInputState = nullptr;
+ uint32_t startSlot = kMaxVertexInputs;
+ uint32_t endSlot = 0;
+ std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexInputs> d3d12BufferViews = {};
+ };
+
class CommandBuffer : public CommandBufferBase {
public:
CommandBuffer(CommandBufferBuilder* builder);
@@ -35,6 +47,9 @@ namespace dawn_native { namespace d3d12 {
void RecordCommands(ComPtr<ID3D12GraphicsCommandList> commandList, uint32_t indexInSubmit);
private:
+ void FlushSetVertexBuffers(ComPtr<ID3D12GraphicsCommandList> commandList,
+ VertexBuffersInfo* vertexBuffersInfo,
+ const InputState* inputState);
void RecordComputePass(ComPtr<ID3D12GraphicsCommandList> commandList,
BindGroupStateTracker* bindingTracker);
void RecordRenderPass(ComPtr<ID3D12GraphicsCommandList> commandList,
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/D3D12Backend.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/D3D12Backend.cpp
new file mode 100644
index 00000000000..2195f613192
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/D3D12Backend.cpp
@@ -0,0 +1,46 @@
+// Copyright 2019 The Dawn 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.
+
+// D3D12Backend.cpp: contains the definition of symbols exported by D3D12Backend.h so that they
+// can be compiled twice: once export (shared library), once not exported (static library)
+
+#include "dawn_native/D3D12Backend.h"
+
+#include "common/SwapChainUtils.h"
+#include "dawn_native/d3d12/DeviceD3D12.h"
+#include "dawn_native/d3d12/NativeSwapChainImplD3D12.h"
+
+namespace dawn_native { namespace d3d12 {
+
+ dawnDevice CreateDevice() {
+ return reinterpret_cast<dawnDevice>(new Device());
+ }
+
+ dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, HWND window) {
+ Device* backendDevice = reinterpret_cast<Device*>(device);
+
+ dawnSwapChainImplementation impl;
+ impl = CreateSwapChainImplementation(new NativeSwapChainImpl(backendDevice, window));
+ impl.textureUsage = DAWN_TEXTURE_USAGE_BIT_PRESENT;
+
+ return impl;
+ }
+
+ dawnTextureFormat GetNativeSwapChainPreferredFormat(
+ const dawnSwapChainImplementation* swapChain) {
+ NativeSwapChainImpl* impl = reinterpret_cast<NativeSwapChainImpl*>(swapChain->userData);
+ return static_cast<dawnTextureFormat>(impl->GetPreferredFormat());
+ }
+
+}} // namespace dawn_native::d3d12
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/DepthStencilStateD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/DepthStencilStateD3D12.cpp
deleted file mode 100644
index 9b202c8d439..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/DepthStencilStateD3D12.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2017 The Dawn 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_native/d3d12/DepthStencilStateD3D12.h"
-
-#include "common/BitSetIterator.h"
-
-namespace dawn_native { namespace d3d12 {
-
- static D3D12_STENCIL_OP StencilOp(dawn::StencilOperation op) {
- switch (op) {
- case dawn::StencilOperation::Keep:
- return D3D12_STENCIL_OP_KEEP;
- case dawn::StencilOperation::Zero:
- return D3D12_STENCIL_OP_ZERO;
- case dawn::StencilOperation::Replace:
- return D3D12_STENCIL_OP_REPLACE;
- case dawn::StencilOperation::IncrementClamp:
- return D3D12_STENCIL_OP_INCR_SAT;
- case dawn::StencilOperation::DecrementClamp:
- return D3D12_STENCIL_OP_DECR_SAT;
- case dawn::StencilOperation::Invert:
- return D3D12_STENCIL_OP_INVERT;
- case dawn::StencilOperation::IncrementWrap:
- return D3D12_STENCIL_OP_INCR;
- case dawn::StencilOperation::DecrementWrap:
- return D3D12_STENCIL_OP_DECR;
- default:
- UNREACHABLE();
- }
- }
-
- static D3D12_COMPARISON_FUNC ComparisonFunc(dawn::CompareFunction func) {
- switch (func) {
- case dawn::CompareFunction::Always:
- return D3D12_COMPARISON_FUNC_ALWAYS;
- case dawn::CompareFunction::Equal:
- return D3D12_COMPARISON_FUNC_EQUAL;
- case dawn::CompareFunction::Greater:
- return D3D12_COMPARISON_FUNC_GREATER;
- case dawn::CompareFunction::GreaterEqual:
- return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
- case dawn::CompareFunction::Less:
- return D3D12_COMPARISON_FUNC_LESS;
- case dawn::CompareFunction::LessEqual:
- return D3D12_COMPARISON_FUNC_LESS_EQUAL;
- case dawn::CompareFunction::Never:
- return D3D12_COMPARISON_FUNC_NEVER;
- case dawn::CompareFunction::NotEqual:
- return D3D12_COMPARISON_FUNC_NOT_EQUAL;
- default:
- UNREACHABLE();
- }
- }
-
- static D3D12_DEPTH_STENCILOP_DESC StencilOpDesc(
- DepthStencilStateBase::StencilFaceInfo faceInfo) {
- D3D12_DEPTH_STENCILOP_DESC desc;
-
- desc.StencilFailOp = StencilOp(faceInfo.stencilFail);
- desc.StencilDepthFailOp = StencilOp(faceInfo.depthFail);
- desc.StencilPassOp = StencilOp(faceInfo.depthStencilPass);
- desc.StencilFunc = ComparisonFunc(faceInfo.compareFunction);
-
- return desc;
- }
-
- DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder)
- : DepthStencilStateBase(builder) {
- mDepthStencilDescriptor.DepthEnable = TRUE;
- mDepthStencilDescriptor.DepthWriteMask =
- GetDepth().depthWriteEnabled ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
- mDepthStencilDescriptor.DepthFunc = ComparisonFunc(GetDepth().compareFunction);
-
- mDepthStencilDescriptor.StencilEnable = StencilTestEnabled() ? TRUE : FALSE;
- mDepthStencilDescriptor.StencilReadMask = static_cast<UINT8>(GetStencil().readMask);
- mDepthStencilDescriptor.StencilWriteMask = static_cast<UINT8>(GetStencil().writeMask);
-
- mDepthStencilDescriptor.FrontFace = StencilOpDesc(GetStencil().front);
- mDepthStencilDescriptor.BackFace = StencilOpDesc(GetStencil().back);
- }
-
- const D3D12_DEPTH_STENCIL_DESC& DepthStencilState::GetD3D12DepthStencilDescriptor() const {
- return mDepthStencilDescriptor;
- }
-
-}} // namespace dawn_native::d3d12
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/DepthStencilStateD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/DepthStencilStateD3D12.h
deleted file mode 100644
index e7041b77664..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/DepthStencilStateD3D12.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Dawn 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.
-
-#ifndef DAWNNATIVE_D3D12_DEPTHSTENCILSTATED3D12_H_
-#define DAWNNATIVE_D3D12_DEPTHSTENCILSTATED3D12_H_
-
-#include "dawn_native/DepthStencilState.h"
-
-#include "dawn_native/d3d12/d3d12_platform.h"
-
-namespace dawn_native { namespace d3d12 {
-
- class Device;
-
- class DepthStencilState : public DepthStencilStateBase {
- public:
- DepthStencilState(DepthStencilStateBuilder* builder);
-
- const D3D12_DEPTH_STENCIL_DESC& GetD3D12DepthStencilDescriptor() const;
-
- private:
- D3D12_DEPTH_STENCIL_DESC mDepthStencilDescriptor;
- };
-
-}} // namespace dawn_native::d3d12
-
-#endif // DAWNNATIVE_D3D12_DEPTHSTENCILSTATED3D12_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp
index 9374dae33dd..75d188db01e 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp
@@ -127,6 +127,6 @@ namespace dawn_native { namespace d3d12 {
}
void DescriptorHeapAllocator::Release(DescriptorHeapHandle handle) {
- mReleasedHandles.Enqueue(handle, mDevice->GetSerial());
+ mReleasedHandles.Enqueue(handle, mDevice->GetPendingCommandSerial());
}
}} // namespace dawn_native::d3d12
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.cpp
index 1d1f7415093..a72ec89020c 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -15,19 +15,15 @@
#include "dawn_native/d3d12/DeviceD3D12.h"
#include "common/Assert.h"
-#include "common/SwapChainUtils.h"
-#include "dawn_native/D3D12Backend.h"
+#include "dawn_native/BackendConnection.h"
#include "dawn_native/d3d12/BindGroupD3D12.h"
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
-#include "dawn_native/d3d12/BlendStateD3D12.h"
#include "dawn_native/d3d12/BufferD3D12.h"
#include "dawn_native/d3d12/CommandAllocatorManager.h"
#include "dawn_native/d3d12/CommandBufferD3D12.h"
#include "dawn_native/d3d12/ComputePipelineD3D12.h"
-#include "dawn_native/d3d12/DepthStencilStateD3D12.h"
#include "dawn_native/d3d12/DescriptorHeapAllocator.h"
#include "dawn_native/d3d12/InputStateD3D12.h"
-#include "dawn_native/d3d12/NativeSwapChainImplD3D12.h"
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h"
#include "dawn_native/d3d12/QueueD3D12.h"
@@ -44,30 +40,14 @@
namespace dawn_native { namespace d3d12 {
- dawnDevice CreateDevice() {
- return reinterpret_cast<dawnDevice>(new Device());
- }
-
- dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, HWND window) {
- Device* backendDevice = reinterpret_cast<Device*>(device);
-
- dawnSwapChainImplementation impl;
- impl = CreateSwapChainImplementation(new NativeSwapChainImpl(backendDevice, window));
- impl.textureUsage = DAWN_TEXTURE_USAGE_BIT_PRESENT;
-
- return impl;
- }
-
- dawnTextureFormat GetNativeSwapChainPreferredFormat(
- const dawnSwapChainImplementation* swapChain) {
- NativeSwapChainImpl* impl = reinterpret_cast<NativeSwapChainImpl*>(swapChain->userData);
- return static_cast<dawnTextureFormat>(impl->GetPreferredFormat());
- }
-
void ASSERT_SUCCESS(HRESULT hr) {
ASSERT(SUCCEEDED(hr));
}
+ BackendConnection* Connect(InstanceBase* instance) {
+ return nullptr;
+ }
+
namespace {
ComPtr<IDXGIFactory4> CreateFactory(const PlatformFunctions* functions) {
ComPtr<IDXGIFactory4> factory;
@@ -117,7 +97,7 @@ namespace dawn_native { namespace d3d12 {
} // anonymous namespace
- Device::Device() {
+ Device::Device() : DeviceBase(nullptr) {
mFunctions = std::make_unique<PlatformFunctions>();
{
@@ -144,8 +124,8 @@ namespace dawn_native { namespace d3d12 {
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
ASSERT_SUCCESS(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)));
- ASSERT_SUCCESS(
- mD3d12Device->CreateFence(mSerial, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence)));
+ ASSERT_SUCCESS(mD3d12Device->CreateFence(mLastSubmittedSerial, D3D12_FENCE_FLAG_NONE,
+ IID_PPV_ARGS(&mFence)));
mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
ASSERT(mFenceEvent != nullptr);
@@ -160,9 +140,8 @@ namespace dawn_native { namespace d3d12 {
}
Device::~Device() {
- const uint64_t currentSerial = GetSerial();
NextSerial();
- WaitForSerial(currentSerial); // Wait for all in-flight commands to finish executing
+ WaitForSerial(mLastSubmittedSerial); // Wait for all in-flight commands to finish executing
TickImpl(); // Call tick one last time so resources are cleaned up
ASSERT(mUsedComObjectRefs.Empty());
@@ -224,14 +203,26 @@ namespace dawn_native { namespace d3d12 {
return mPendingCommands.commandList;
}
+ Serial Device::GetCompletedCommandSerial() const {
+ return mCompletedSerial;
+ }
+
+ Serial Device::GetLastSubmittedCommandSerial() const {
+ return mLastSubmittedSerial;
+ }
+
+ Serial Device::GetPendingCommandSerial() const {
+ return mLastSubmittedSerial + 1;
+ }
+
void Device::TickImpl() {
// Perform cleanup operations to free unused objects
- const uint64_t lastCompletedSerial = mFence->GetCompletedValue();
- mResourceAllocator->Tick(lastCompletedSerial);
- mCommandAllocatorManager->Tick(lastCompletedSerial);
- mDescriptorHeapAllocator->Tick(lastCompletedSerial);
- mMapRequestTracker->Tick(lastCompletedSerial);
- mUsedComObjectRefs.ClearUpTo(lastCompletedSerial);
+ mCompletedSerial = mFence->GetCompletedValue();
+ mResourceAllocator->Tick(mCompletedSerial);
+ mCommandAllocatorManager->Tick(mCompletedSerial);
+ mDescriptorHeapAllocator->Tick(mCompletedSerial);
+ mMapRequestTracker->Tick(mCompletedSerial);
+ mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
ExecuteCommandLists({});
NextSerial();
}
@@ -240,24 +231,21 @@ namespace dawn_native { namespace d3d12 {
return mPCIInfo;
}
- uint64_t Device::GetSerial() const {
- return mSerial;
- }
-
void Device::NextSerial() {
- ASSERT_SUCCESS(mCommandQueue->Signal(mFence.Get(), mSerial++));
+ mLastSubmittedSerial++;
+ ASSERT_SUCCESS(mCommandQueue->Signal(mFence.Get(), mLastSubmittedSerial));
}
void Device::WaitForSerial(uint64_t serial) {
- const uint64_t lastCompletedSerial = mFence->GetCompletedValue();
- if (lastCompletedSerial < serial) {
+ mCompletedSerial = mFence->GetCompletedValue();
+ if (mCompletedSerial < serial) {
ASSERT_SUCCESS(mFence->SetEventOnCompletion(serial, mFenceEvent));
WaitForSingleObject(mFenceEvent, INFINITE);
}
}
void Device::ReferenceUntilUnused(ComPtr<IUnknown> object) {
- mUsedComObjectRefs.Enqueue(object, mSerial);
+ mUsedComObjectRefs.Enqueue(object, GetPendingCommandSerial());
}
void Device::ExecuteCommandLists(std::initializer_list<ID3D12CommandList*> commandLists) {
@@ -278,22 +266,17 @@ namespace dawn_native { namespace d3d12 {
}
}
- BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
- return new BindGroup(builder);
+ ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) {
+ return new BindGroup(this, descriptor);
}
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return new BindGroupLayout(this, descriptor);
}
- BlendStateBase* Device::CreateBlendState(BlendStateBuilder* builder) {
- return new BlendState(builder);
- }
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
- BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
- return new BufferView(builder);
- }
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}
@@ -301,9 +284,6 @@ namespace dawn_native { namespace d3d12 {
const ComputePipelineDescriptor* descriptor) {
return new ComputePipeline(this, descriptor);
}
- DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
- return new DepthStencilState(builder);
- }
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputState(builder);
}
@@ -318,8 +298,9 @@ namespace dawn_native { namespace d3d12 {
RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder);
}
- RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
- return new RenderPipeline(builder);
+ ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) {
+ return new RenderPipeline(this, descriptor);
}
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor);
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.h
index 3717e2453e2..82302277791 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.h
@@ -41,17 +41,14 @@ namespace dawn_native { namespace d3d12 {
Device();
~Device();
- BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
- BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
- BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
- DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override;
- RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
+ Serial GetCompletedCommandSerial() const final override;
+ Serial GetLastSubmittedCommandSerial() const final override;
void TickImpl() override;
const dawn_native::PCIInfo& GetPCIInfo() const override;
@@ -68,16 +65,18 @@ namespace dawn_native { namespace d3d12 {
void OpenCommandList(ComPtr<ID3D12GraphicsCommandList>* commandList);
ComPtr<ID3D12GraphicsCommandList> GetPendingCommandList();
+ Serial GetPendingCommandSerial() const;
- uint64_t GetSerial() const;
void NextSerial();
- void WaitForSerial(uint64_t serial);
+ void WaitForSerial(Serial serial);
void ReferenceUntilUnused(ComPtr<IUnknown> object);
void ExecuteCommandLists(std::initializer_list<ID3D12CommandList*> commandLists);
private:
+ ResultOrError<BindGroupBase*> CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) override;
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
@@ -86,6 +85,8 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override;
+ ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
@@ -99,7 +100,8 @@ namespace dawn_native { namespace d3d12 {
// D3D12 DLLs are unloaded before we are done using it.
std::unique_ptr<PlatformFunctions> mFunctions;
- uint64_t mSerial = 0;
+ Serial mCompletedSerial = 0;
+ Serial mLastSubmittedSerial = 0;
ComPtr<ID3D12Fence> mFence;
HANDLE mFenceEvent;
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/Forward.h b/chromium/third_party/dawn/src/dawn_native/d3d12/Forward.h
index 80cf0d42417..d4fa3335b48 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/Forward.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/Forward.h
@@ -19,14 +19,12 @@
namespace dawn_native { namespace d3d12 {
+ class Adapter;
class BindGroup;
class BindGroupLayout;
- class BlendState;
class Buffer;
- class BufferView;
class CommandBuffer;
class ComputePipeline;
- class DepthStencilState;
class Device;
class InputState;
class PipelineLayout;
@@ -40,14 +38,12 @@ namespace dawn_native { namespace d3d12 {
class TextureView;
struct D3D12BackendTraits {
+ using AdapterType = Adapter;
using BindGroupType = BindGroup;
using BindGroupLayoutType = BindGroupLayout;
- using BlendStateType = BlendState;
using BufferType = Buffer;
- using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
- using DepthStencilStateType = DepthStencilState;
using DeviceType = Device;
using InputStateType = InputState;
using PipelineLayoutType = PipelineLayout;
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.cpp
index 99ac8f80918..577d8fa2bc7 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.cpp
@@ -107,7 +107,7 @@ namespace dawn_native { namespace d3d12 {
// TODO(cwallez@chromium.org): Make the serial ticking implicit.
mDevice->NextSerial();
- mBufferSerials[mCurrentBuffer] = mDevice->GetSerial();
+ mBufferSerials[mCurrentBuffer] = mDevice->GetPendingCommandSerial();
return DAWN_SWAP_CHAIN_NO_ERROR;
}
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp
index 1ee21e16830..e63d9eaeacb 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp
@@ -65,7 +65,7 @@ namespace dawn_native { namespace d3d12 {
for (uint32_t i = 0; i < rangeCount; ++i) {
ranges[rangeIndex] = descriptorRanges[i];
- ranges[rangeIndex].BaseShaderRegister += group * kMaxBindingsPerGroup;
+ ranges[rangeIndex].RegisterSpace = group;
rangeIndex++;
}
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
index 63385dbf1b6..53a18b34d4e 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
@@ -15,14 +15,13 @@
#include "dawn_native/d3d12/RenderPipelineD3D12.h"
#include "common/Assert.h"
-#include "dawn_native/d3d12/BlendStateD3D12.h"
-#include "dawn_native/d3d12/DepthStencilStateD3D12.h"
#include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/InputStateD3D12.h"
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h"
#include "dawn_native/d3d12/ShaderModuleD3D12.h"
#include "dawn_native/d3d12/TextureD3D12.h"
+#include "dawn_native/d3d12/UtilsD3D12.h"
#include <d3dcompiler.h>
@@ -61,12 +60,148 @@ namespace dawn_native { namespace d3d12 {
UNREACHABLE();
}
}
- } // namespace
- RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
- : RenderPipelineBase(builder),
- mD3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())),
- mDevice(ToBackend(builder->GetDevice())) {
+ D3D12_BLEND D3D12Blend(dawn::BlendFactor factor) {
+ switch (factor) {
+ case dawn::BlendFactor::Zero:
+ return D3D12_BLEND_ZERO;
+ case dawn::BlendFactor::One:
+ return D3D12_BLEND_ONE;
+ case dawn::BlendFactor::SrcColor:
+ return D3D12_BLEND_SRC_COLOR;
+ case dawn::BlendFactor::OneMinusSrcColor:
+ return D3D12_BLEND_INV_SRC_COLOR;
+ case dawn::BlendFactor::SrcAlpha:
+ return D3D12_BLEND_SRC_ALPHA;
+ case dawn::BlendFactor::OneMinusSrcAlpha:
+ return D3D12_BLEND_INV_SRC_ALPHA;
+ case dawn::BlendFactor::DstColor:
+ return D3D12_BLEND_DEST_COLOR;
+ case dawn::BlendFactor::OneMinusDstColor:
+ return D3D12_BLEND_INV_DEST_COLOR;
+ case dawn::BlendFactor::DstAlpha:
+ return D3D12_BLEND_DEST_ALPHA;
+ case dawn::BlendFactor::OneMinusDstAlpha:
+ return D3D12_BLEND_INV_DEST_ALPHA;
+ case dawn::BlendFactor::SrcAlphaSaturated:
+ return D3D12_BLEND_SRC_ALPHA_SAT;
+ case dawn::BlendFactor::BlendColor:
+ return D3D12_BLEND_BLEND_FACTOR;
+ case dawn::BlendFactor::OneMinusBlendColor:
+ return D3D12_BLEND_INV_BLEND_FACTOR;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ D3D12_BLEND_OP D3D12BlendOperation(dawn::BlendOperation operation) {
+ switch (operation) {
+ case dawn::BlendOperation::Add:
+ return D3D12_BLEND_OP_ADD;
+ case dawn::BlendOperation::Subtract:
+ return D3D12_BLEND_OP_SUBTRACT;
+ case dawn::BlendOperation::ReverseSubtract:
+ return D3D12_BLEND_OP_REV_SUBTRACT;
+ case dawn::BlendOperation::Min:
+ return D3D12_BLEND_OP_MIN;
+ case dawn::BlendOperation::Max:
+ return D3D12_BLEND_OP_MAX;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ uint8_t D3D12RenderTargetWriteMask(dawn::ColorWriteMask colorWriteMask) {
+ static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Red) ==
+ D3D12_COLOR_WRITE_ENABLE_RED,
+ "ColorWriteMask values must match");
+ static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Green) ==
+ D3D12_COLOR_WRITE_ENABLE_GREEN,
+ "ColorWriteMask values must match");
+ static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Blue) ==
+ D3D12_COLOR_WRITE_ENABLE_BLUE,
+ "ColorWriteMask values must match");
+ static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Alpha) ==
+ D3D12_COLOR_WRITE_ENABLE_ALPHA,
+ "ColorWriteMask values must match");
+ return static_cast<uint8_t>(colorWriteMask);
+ }
+
+ D3D12_RENDER_TARGET_BLEND_DESC ComputeBlendDesc(const BlendStateDescriptor* descriptor) {
+ D3D12_RENDER_TARGET_BLEND_DESC blendDesc;
+ blendDesc.BlendEnable = descriptor->blendEnabled;
+ blendDesc.SrcBlend = D3D12Blend(descriptor->colorBlend.srcFactor);
+ blendDesc.DestBlend = D3D12Blend(descriptor->colorBlend.dstFactor);
+ blendDesc.BlendOp = D3D12BlendOperation(descriptor->colorBlend.operation);
+ blendDesc.SrcBlendAlpha = D3D12Blend(descriptor->alphaBlend.srcFactor);
+ blendDesc.DestBlendAlpha = D3D12Blend(descriptor->alphaBlend.dstFactor);
+ blendDesc.BlendOpAlpha = D3D12BlendOperation(descriptor->alphaBlend.operation);
+ blendDesc.RenderTargetWriteMask =
+ D3D12RenderTargetWriteMask(descriptor->colorWriteMask);
+ blendDesc.LogicOpEnable = false;
+ blendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
+ return blendDesc;
+ }
+
+ D3D12_STENCIL_OP StencilOp(dawn::StencilOperation op) {
+ switch (op) {
+ case dawn::StencilOperation::Keep:
+ return D3D12_STENCIL_OP_KEEP;
+ case dawn::StencilOperation::Zero:
+ return D3D12_STENCIL_OP_ZERO;
+ case dawn::StencilOperation::Replace:
+ return D3D12_STENCIL_OP_REPLACE;
+ case dawn::StencilOperation::IncrementClamp:
+ return D3D12_STENCIL_OP_INCR_SAT;
+ case dawn::StencilOperation::DecrementClamp:
+ return D3D12_STENCIL_OP_DECR_SAT;
+ case dawn::StencilOperation::Invert:
+ return D3D12_STENCIL_OP_INVERT;
+ case dawn::StencilOperation::IncrementWrap:
+ return D3D12_STENCIL_OP_INCR;
+ case dawn::StencilOperation::DecrementWrap:
+ return D3D12_STENCIL_OP_DECR;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ D3D12_DEPTH_STENCILOP_DESC StencilOpDesc(const StencilStateFaceDescriptor descriptor) {
+ D3D12_DEPTH_STENCILOP_DESC desc;
+
+ desc.StencilFailOp = StencilOp(descriptor.stencilFailOp);
+ desc.StencilDepthFailOp = StencilOp(descriptor.depthFailOp);
+ desc.StencilPassOp = StencilOp(descriptor.passOp);
+ desc.StencilFunc = ToD3D12ComparisonFunc(descriptor.compare);
+
+ return desc;
+ }
+
+ D3D12_DEPTH_STENCIL_DESC ComputeDepthStencilDesc(
+ const DepthStencilStateDescriptor* descriptor) {
+ D3D12_DEPTH_STENCIL_DESC mDepthStencilDescriptor;
+ mDepthStencilDescriptor.DepthEnable = TRUE;
+ mDepthStencilDescriptor.DepthWriteMask = descriptor->depthWriteEnabled
+ ? D3D12_DEPTH_WRITE_MASK_ALL
+ : D3D12_DEPTH_WRITE_MASK_ZERO;
+ mDepthStencilDescriptor.DepthFunc = ToD3D12ComparisonFunc(descriptor->depthCompare);
+
+ mDepthStencilDescriptor.StencilEnable = StencilTestEnabled(descriptor) ? TRUE : FALSE;
+ mDepthStencilDescriptor.StencilReadMask =
+ static_cast<UINT8>(descriptor->stencilReadMask);
+ mDepthStencilDescriptor.StencilWriteMask =
+ static_cast<UINT8>(descriptor->stencilWriteMask);
+
+ mDepthStencilDescriptor.FrontFace = StencilOpDesc(descriptor->front);
+ mDepthStencilDescriptor.BackFace = StencilOpDesc(descriptor->back);
+ return mDepthStencilDescriptor;
+ }
+
+ } // anonymous namespace
+
+ RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
+ : RenderPipelineBase(device, descriptor),
+ mD3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())) {
uint32_t compileFlags = 0;
#if defined(_DEBUG)
// Enable better shader debugging with the graphics debugging tools.
@@ -75,36 +210,41 @@ namespace dawn_native { namespace d3d12 {
// SPRIV-cross does matrix multiplication expecting row major matrices
compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
- D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptor = {};
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptorD3D12 = {};
PerStage<ComPtr<ID3DBlob>> compiledShader;
ComPtr<ID3DBlob> errors;
- for (auto stage : IterateStages(GetStageMask())) {
- const auto& module = ToBackend(builder->GetStageInfo(stage).module);
- const auto& entryPoint = builder->GetStageInfo(stage).entryPoint;
- const auto& hlslSource = module->GetHLSLSource(ToBackend(GetLayout()));
-
+ dawn::ShaderStageBit renderStages =
+ dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment;
+ for (auto stage : IterateStages(renderStages)) {
+ const ShaderModule* module = nullptr;
+ const char* entryPoint = nullptr;
const char* compileTarget = nullptr;
-
D3D12_SHADER_BYTECODE* shader = nullptr;
switch (stage) {
case dawn::ShaderStage::Vertex:
- shader = &descriptor.VS;
+ module = ToBackend(descriptor->vertexStage->module);
+ entryPoint = descriptor->vertexStage->entryPoint;
+ shader = &descriptorD3D12.VS;
compileTarget = "vs_5_1";
break;
case dawn::ShaderStage::Fragment:
- shader = &descriptor.PS;
+ module = ToBackend(descriptor->fragmentStage->module);
+ entryPoint = descriptor->fragmentStage->entryPoint;
+ shader = &descriptorD3D12.PS;
compileTarget = "ps_5_1";
break;
- case dawn::ShaderStage::Compute:
+ default:
UNREACHABLE();
break;
}
- const PlatformFunctions* functions = ToBackend(builder->GetDevice())->GetFunctions();
+ const std::string hlslSource = module->GetHLSLSource(ToBackend(GetLayout()));
+
+ const PlatformFunctions* functions = device->GetFunctions();
if (FAILED(functions->d3dCompile(hlslSource.c_str(), hlslSource.length(), nullptr,
- nullptr, nullptr, entryPoint.c_str(), compileTarget,
+ nullptr, nullptr, entryPoint, compileTarget,
compileFlags, 0, &compiledShader[stage], &errors))) {
printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer()));
ASSERT(false);
@@ -118,54 +258,55 @@ namespace dawn_native { namespace d3d12 {
PipelineLayout* layout = ToBackend(GetLayout());
- descriptor.pRootSignature = layout->GetRootSignature().Get();
+ descriptorD3D12.pRootSignature = layout->GetRootSignature().Get();
// D3D12 logs warnings if any empty input state is used
InputState* inputState = ToBackend(GetInputState());
if (inputState->GetAttributesSetMask().any()) {
- descriptor.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
+ descriptorD3D12.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
}
- descriptor.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
- descriptor.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
- descriptor.RasterizerState.FrontCounterClockwise = FALSE;
- descriptor.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
- descriptor.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
- descriptor.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
- descriptor.RasterizerState.DepthClipEnable = TRUE;
- descriptor.RasterizerState.MultisampleEnable = FALSE;
- descriptor.RasterizerState.AntialiasedLineEnable = FALSE;
- descriptor.RasterizerState.ForcedSampleCount = 0;
- descriptor.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
+ descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
+ descriptorD3D12.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
+ descriptorD3D12.RasterizerState.FrontCounterClockwise = FALSE;
+ descriptorD3D12.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
+ descriptorD3D12.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
+ descriptorD3D12.RasterizerState.SlopeScaledDepthBias =
+ D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
+ descriptorD3D12.RasterizerState.DepthClipEnable = TRUE;
+ descriptorD3D12.RasterizerState.MultisampleEnable = FALSE;
+ descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE;
+ descriptorD3D12.RasterizerState.ForcedSampleCount = 0;
+ descriptorD3D12.RasterizerState.ConservativeRaster =
+ D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
if (HasDepthStencilAttachment()) {
- descriptor.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat());
+ descriptorD3D12.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat());
}
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
- descriptor.RTVFormats[i] = D3D12TextureFormat(GetColorAttachmentFormat(i));
- descriptor.BlendState.RenderTarget[i] =
- ToBackend(GetBlendState(i))->GetD3D12BlendDesc();
+ descriptorD3D12.RTVFormats[i] = D3D12TextureFormat(GetColorAttachmentFormat(i));
+ descriptorD3D12.BlendState.RenderTarget[i] =
+ ComputeBlendDesc(GetBlendStateDescriptor(i));
}
- descriptor.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());
+ descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());
- descriptor.BlendState.AlphaToCoverageEnable = FALSE;
- descriptor.BlendState.IndependentBlendEnable = TRUE;
+ descriptorD3D12.BlendState.AlphaToCoverageEnable = FALSE;
+ descriptorD3D12.BlendState.IndependentBlendEnable = TRUE;
- DepthStencilState* depthStencilState = ToBackend(GetDepthStencilState());
- descriptor.DepthStencilState = depthStencilState->GetD3D12DepthStencilDescriptor();
+ descriptorD3D12.DepthStencilState =
+ ComputeDepthStencilDesc(GetDepthStencilStateDescriptor());
- descriptor.SampleMask = UINT_MAX;
- descriptor.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology());
- descriptor.SampleDesc.Count = 1;
+ descriptorD3D12.SampleMask = UINT_MAX;
+ descriptorD3D12.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology());
+ descriptorD3D12.SampleDesc.Count = 1;
- Device* device = ToBackend(builder->GetDevice());
ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState(
- &descriptor, IID_PPV_ARGS(&mPipelineState)));
+ &descriptorD3D12, IID_PPV_ARGS(&mPipelineState)));
}
RenderPipeline::~RenderPipeline() {
- mDevice->ReferenceUntilUnused(mPipelineState);
+ ToBackend(GetDevice())->ReferenceUntilUnused(mPipelineState);
}
D3D12_PRIMITIVE_TOPOLOGY RenderPipeline::GetD3D12PrimitiveTopology() const {
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.h
index 81596a1e55b..20502bb2cc8 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.h
@@ -25,7 +25,7 @@ namespace dawn_native { namespace d3d12 {
class RenderPipeline : public RenderPipelineBase {
public:
- RenderPipeline(RenderPipelineBuilder* builder);
+ RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
~RenderPipeline();
D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopology() const;
@@ -34,8 +34,6 @@ namespace dawn_native { namespace d3d12 {
private:
D3D12_PRIMITIVE_TOPOLOGY mD3d12PrimitiveTopology;
ComPtr<ID3D12PipelineState> mPipelineState;
-
- Device* mDevice = nullptr;
};
}} // namespace dawn_native::d3d12
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/ResourceAllocator.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/ResourceAllocator.cpp
index c50de5b5c4e..e2822e64cf9 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/ResourceAllocator.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/ResourceAllocator.cpp
@@ -67,7 +67,7 @@ namespace dawn_native { namespace d3d12 {
void ResourceAllocator::Release(ComPtr<ID3D12Resource> resource) {
// Resources may still be in use on the GPU. Enqueue them so that we hold onto them until
// GPU execution has completed
- mReleasedResources.Enqueue(resource, mDevice->GetSerial());
+ mReleasedResources.Enqueue(resource, mDevice->GetPendingCommandSerial());
}
void ResourceAllocator::Tick(uint64_t lastCompletedSerial) {
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.cpp
index 9c3559c25e7..4b78c6cd233 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.cpp
@@ -15,6 +15,7 @@
#include "dawn_native/d3d12/SamplerD3D12.h"
#include "dawn_native/d3d12/DeviceD3D12.h"
+#include "dawn_native/d3d12/UtilsD3D12.h"
namespace dawn_native { namespace d3d12 {
@@ -27,6 +28,8 @@ namespace dawn_native { namespace d3d12 {
return D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
case dawn::AddressMode::ClampToEdge:
return D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
+ case dawn::AddressMode::ClampToBorderColor:
+ return D3D12_TEXTURE_ADDRESS_MODE_BORDER;
default:
UNREACHABLE();
}
@@ -82,11 +85,27 @@ namespace dawn_native { namespace d3d12 {
mSamplerDesc.AddressW = AddressMode(descriptor->addressModeW);
mSamplerDesc.MipLODBias = 0.f;
mSamplerDesc.MaxAnisotropy = 1;
- mSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
- mSamplerDesc.BorderColor[0] = mSamplerDesc.BorderColor[1] = mSamplerDesc.BorderColor[2] =
- mSamplerDesc.BorderColor[3] = 0;
- mSamplerDesc.MinLOD = 0;
- mSamplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
+ mSamplerDesc.ComparisonFunc = ToD3D12ComparisonFunc(descriptor->compareFunction);
+ mSamplerDesc.MinLOD = descriptor->lodMinClamp;
+ mSamplerDesc.MaxLOD = descriptor->lodMaxClamp;
+
+ switch (descriptor->borderColor) {
+ case dawn::BorderColor::TransparentBlack:
+ mSamplerDesc.BorderColor[0] = mSamplerDesc.BorderColor[1] =
+ mSamplerDesc.BorderColor[2] = mSamplerDesc.BorderColor[3] = 0;
+ break;
+ case dawn::BorderColor::OpaqueBlack:
+ mSamplerDesc.BorderColor[0] = mSamplerDesc.BorderColor[1] =
+ mSamplerDesc.BorderColor[2] = 0;
+ mSamplerDesc.BorderColor[3] = 1;
+ break;
+ case dawn::BorderColor::OpaqueWhite:
+ mSamplerDesc.BorderColor[0] = mSamplerDesc.BorderColor[1] =
+ mSamplerDesc.BorderColor[2] = mSamplerDesc.BorderColor[3] = 1;
+ break;
+ default:
+ UNREACHABLE();
+ }
}
const D3D12_SAMPLER_DESC& Sampler::GetSamplerDescriptor() const {
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/ShaderModuleD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
index ad1c5068ad8..9911d51a0cb 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
@@ -52,10 +52,8 @@ namespace dawn_native { namespace d3d12 {
for (uint32_t binding = 0; binding < groupBindingInfo.size(); ++binding) {
const BindingInfo& bindingInfo = groupBindingInfo[binding];
if (bindingInfo.used) {
- uint32_t bindGroupOffset = group * kMaxBindingsPerGroup;
uint32_t bindingOffset = bindingOffsets[binding];
- compiler.set_decoration(bindingInfo.id, spv::DecorationBinding,
- bindGroupOffset + bindingOffset);
+ compiler.set_decoration(bindingInfo.id, spv::DecorationBinding, bindingOffset);
}
}
}
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.cpp
index 32f53094c61..5e58cbcba91 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.cpp
@@ -24,37 +24,26 @@ namespace dawn_native { namespace d3d12 {
uint32_t rowPitch,
uint32_t slicePitch,
uint32_t texelSize,
- uint32_t* texelOffsetX,
- uint32_t* texelOffsetY,
- uint32_t* texelOffsetZ) {
+ Origin3D* texelOffset) {
uint32_t byteOffsetX = offset % rowPitch;
offset -= byteOffsetX;
uint32_t byteOffsetY = offset % slicePitch;
uint32_t byteOffsetZ = offset - byteOffsetY;
- *texelOffsetX = byteOffsetX / texelSize;
- *texelOffsetY = byteOffsetY / rowPitch;
- *texelOffsetZ = byteOffsetZ / slicePitch;
+ texelOffset->x = byteOffsetX / texelSize;
+ texelOffset->y = byteOffsetY / rowPitch;
+ texelOffset->z = byteOffsetZ / slicePitch;
}
} // namespace
- TextureCopySplit ComputeTextureCopySplit(uint32_t x,
- uint32_t y,
- uint32_t z,
- uint32_t width,
- uint32_t height,
- uint32_t depth,
+ TextureCopySplit ComputeTextureCopySplit(Origin3D origin,
+ Extent3D copySize,
uint32_t texelSize,
uint32_t offset,
- uint32_t rowPitch) {
+ uint32_t rowPitch,
+ uint32_t imageHeight) {
TextureCopySplit copy;
- if (z != 0 || depth > 1) {
- // TODO(enga@google.com): Handle 3D
- ASSERT(false);
- return copy;
- }
-
ASSERT(rowPitch % texelSize == 0);
uint32_t alignedOffset = offset & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1);
@@ -63,20 +52,14 @@ namespace dawn_native { namespace d3d12 {
if (offset == alignedOffset) {
copy.count = 1;
- copy.copies[0].textureOffset.x = x;
- copy.copies[0].textureOffset.y = y;
- copy.copies[0].textureOffset.z = z;
+ copy.copies[0].textureOffset = origin;
- copy.copies[0].copySize.width = width;
- copy.copies[0].copySize.height = height;
- copy.copies[0].copySize.depth = depth;
+ copy.copies[0].copySize = copySize;
copy.copies[0].bufferOffset.x = 0;
copy.copies[0].bufferOffset.y = 0;
copy.copies[0].bufferOffset.z = 0;
- copy.copies[0].bufferSize.width = width;
- copy.copies[0].bufferSize.height = height;
- copy.copies[0].bufferSize.depth = depth;
+ copy.copies[0].bufferSize = copySize;
// Return early. There is only one copy needed because the offset is already 512-byte
// aligned
@@ -85,13 +68,13 @@ namespace dawn_native { namespace d3d12 {
ASSERT(alignedOffset < offset);
- uint32_t texelOffsetX, texelOffsetY, texelOffsetZ;
- ComputeTexelOffsets(offset - alignedOffset, rowPitch, rowPitch * height, texelSize,
- &texelOffsetX, &texelOffsetY, &texelOffsetZ);
+ Origin3D texelOffset;
+ ComputeTexelOffsets(offset - alignedOffset, rowPitch, rowPitch * imageHeight, texelSize,
+ &texelOffset);
uint32_t rowPitchInTexels = rowPitch / texelSize;
- if (width + texelOffsetX <= rowPitchInTexels) {
+ if (copySize.width + texelOffset.x <= rowPitchInTexels) {
// The region's rows fit inside the row pitch. In this case, extend the width of the
// PlacedFootprint and copy the buffer with an offset location
// |<--------------- row pitch --------------->|
@@ -117,20 +100,14 @@ namespace dawn_native { namespace d3d12 {
copy.count = 1;
- copy.copies[0].textureOffset.x = x;
- copy.copies[0].textureOffset.y = y;
- copy.copies[0].textureOffset.z = z;
+ copy.copies[0].textureOffset = origin;
- copy.copies[0].copySize.width = width;
- copy.copies[0].copySize.height = height;
- copy.copies[0].copySize.depth = depth;
+ copy.copies[0].copySize = copySize;
- copy.copies[0].bufferOffset.x = texelOffsetX;
- copy.copies[0].bufferOffset.y = texelOffsetY;
- copy.copies[0].bufferOffset.z = texelOffsetZ;
- copy.copies[0].bufferSize.width = width + texelOffsetX;
- copy.copies[0].bufferSize.height = height + texelOffsetY;
- copy.copies[0].bufferSize.depth = depth + texelOffsetZ;
+ copy.copies[0].bufferOffset = texelOffset;
+ copy.copies[0].bufferSize.width = copySize.width + texelOffset.x;
+ copy.copies[0].bufferSize.height = imageHeight + texelOffset.y;
+ copy.copies[0].bufferSize.depth = copySize.depth + texelOffset.z;
return copy;
}
@@ -171,37 +148,33 @@ namespace dawn_native { namespace d3d12 {
copy.count = 2;
- copy.copies[0].textureOffset.x = x;
- copy.copies[0].textureOffset.y = y;
- copy.copies[0].textureOffset.z = z;
+ copy.copies[0].textureOffset = origin;
- ASSERT(rowPitchInTexels > texelOffsetX);
- copy.copies[0].copySize.width = rowPitchInTexels - texelOffsetX;
- copy.copies[0].copySize.height = height;
- copy.copies[0].copySize.depth = depth;
+ ASSERT(rowPitchInTexels > texelOffset.x);
+ copy.copies[0].copySize.width = rowPitchInTexels - texelOffset.x;
+ copy.copies[0].copySize.height = copySize.height;
+ copy.copies[0].copySize.depth = copySize.depth;
- copy.copies[0].bufferOffset.x = texelOffsetX;
- copy.copies[0].bufferOffset.y = texelOffsetY;
- copy.copies[0].bufferOffset.z = texelOffsetZ;
+ copy.copies[0].bufferOffset = texelOffset;
copy.copies[0].bufferSize.width = rowPitchInTexels;
- copy.copies[0].bufferSize.height = height + texelOffsetY;
- copy.copies[0].bufferSize.depth = depth + texelOffsetZ;
+ copy.copies[0].bufferSize.height = imageHeight + texelOffset.y;
+ copy.copies[0].bufferSize.depth = copySize.depth + texelOffset.z;
- copy.copies[1].textureOffset.x = x + copy.copies[0].copySize.width;
- copy.copies[1].textureOffset.y = y;
- copy.copies[1].textureOffset.z = z;
+ copy.copies[1].textureOffset.x = origin.x + copy.copies[0].copySize.width;
+ copy.copies[1].textureOffset.y = origin.y;
+ copy.copies[1].textureOffset.z = origin.z;
- ASSERT(width > copy.copies[0].copySize.width);
- copy.copies[1].copySize.width = width - copy.copies[0].copySize.width;
- copy.copies[1].copySize.height = height;
- copy.copies[1].copySize.depth = depth;
+ ASSERT(copySize.width > copy.copies[0].copySize.width);
+ copy.copies[1].copySize.width = copySize.width - copy.copies[0].copySize.width;
+ copy.copies[1].copySize.height = copySize.height;
+ copy.copies[1].copySize.depth = copySize.depth;
copy.copies[1].bufferOffset.x = 0;
- copy.copies[1].bufferOffset.y = texelOffsetY + 1;
- copy.copies[1].bufferOffset.z = texelOffsetZ;
+ copy.copies[1].bufferOffset.y = texelOffset.y + 1;
+ copy.copies[1].bufferOffset.z = texelOffset.z;
copy.copies[1].bufferSize.width = copy.copies[1].copySize.width;
- copy.copies[1].bufferSize.height = height + texelOffsetY + 1;
- copy.copies[1].bufferSize.depth = depth + texelOffsetZ;
+ copy.copies[1].bufferSize.height = imageHeight + texelOffset.y + 1;
+ copy.copies[1].bufferSize.depth = copySize.depth + texelOffset.z;
return copy;
}
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.h b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.h
index eec55e29868..e468fc67993 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.h
@@ -24,24 +24,12 @@ namespace dawn_native { namespace d3d12 {
struct TextureCopySplit {
static constexpr unsigned int kMaxTextureCopyRegions = 2;
- struct Extent {
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t depth = 0;
- };
-
- struct Origin {
- uint32_t x = 0;
- uint32_t y = 0;
- uint32_t z = 0;
- };
-
struct CopyInfo {
- Origin textureOffset;
- Origin bufferOffset;
- Extent bufferSize;
+ Origin3D textureOffset;
+ Origin3D bufferOffset;
+ Extent3D bufferSize;
- Extent copySize;
+ Extent3D copySize;
};
uint32_t offset = 0;
@@ -49,16 +37,12 @@ namespace dawn_native { namespace d3d12 {
std::array<CopyInfo, kMaxTextureCopyRegions> copies;
};
- TextureCopySplit ComputeTextureCopySplit(uint32_t x,
- uint32_t y,
- uint32_t z,
- uint32_t width,
- uint32_t height,
- uint32_t depth,
+ TextureCopySplit ComputeTextureCopySplit(Origin3D origin,
+ Extent3D copySize,
uint32_t texelSize,
uint32_t offset,
- uint32_t rowPitch);
-
+ uint32_t rowPitch,
+ uint32_t imageHeight);
}} // namespace dawn_native::d3d12
#endif // DAWNNATIVE_D3D12_TEXTURECOPYSPLITTER_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.cpp
index 4fd16ab0f8e..fb49dea1e2b 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -226,22 +226,33 @@ namespace dawn_native { namespace d3d12 {
}
}
+ DXGI_FORMAT TextureView::GetD3D12Format() const {
+ return D3D12TextureFormat(GetFormat());
+ }
+
const D3D12_SHADER_RESOURCE_VIEW_DESC& TextureView::GetSRVDescriptor() const {
return mSrvDesc;
}
- // TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
- D3D12_RENDER_TARGET_VIEW_DESC TextureView::GetRTVDescriptor() {
+ D3D12_RENDER_TARGET_VIEW_DESC TextureView::GetRTVDescriptor() const {
+ ASSERT(GetTexture()->GetDimension() == dawn::TextureDimension::e2D);
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = ToBackend(GetTexture())->GetD3D12Format();
- rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = 0;
- rtvDesc.Texture2D.PlaneSlice = 0;
+ rtvDesc.Format = GetD3D12Format();
+ // Currently we always use D3D12_TEX2D_ARRAY_RTV because we cannot specify base array layer
+ // and layer count in D3D12_TEX2D_RTV. For 2D texture views, we treat them as 1-layer 2D
+ // array textures. (Just like how we treat SRVs)
+ // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_rtv
+ // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array_rtv
+ rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.FirstArraySlice = GetBaseArrayLayer();
+ rtvDesc.Texture2DArray.ArraySize = GetLayerCount();
+ rtvDesc.Texture2DArray.MipSlice = GetBaseMipLevel();
+ rtvDesc.Texture2DArray.PlaneSlice = 0;
return rtvDesc;
}
// TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
- D3D12_DEPTH_STENCIL_VIEW_DESC TextureView::GetDSVDescriptor() {
+ D3D12_DEPTH_STENCIL_VIEW_DESC TextureView::GetDSVDescriptor() const {
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
dsvDesc.Format = ToBackend(GetTexture())->GetD3D12Format();
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.h
index 23a0d52de13..2edfb7ce44a 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.h
@@ -49,9 +49,11 @@ namespace dawn_native { namespace d3d12 {
public:
TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor);
+ DXGI_FORMAT GetD3D12Format() const;
+
const D3D12_SHADER_RESOURCE_VIEW_DESC& GetSRVDescriptor() const;
- D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor();
- D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor();
+ D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor() const;
+ D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor() const;
private:
D3D12_SHADER_RESOURCE_VIEW_DESC mSrvDesc;
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/UtilsD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/UtilsD3D12.cpp
new file mode 100644
index 00000000000..864605c871e
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/UtilsD3D12.cpp
@@ -0,0 +1,44 @@
+// Copyright 2019 The Dawn 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_native/d3d12/UtilsD3D12.h"
+
+#include "common/Assert.h"
+
+namespace dawn_native { namespace d3d12 {
+
+ D3D12_COMPARISON_FUNC ToD3D12ComparisonFunc(dawn::CompareFunction func) {
+ switch (func) {
+ case dawn::CompareFunction::Always:
+ return D3D12_COMPARISON_FUNC_ALWAYS;
+ case dawn::CompareFunction::Equal:
+ return D3D12_COMPARISON_FUNC_EQUAL;
+ case dawn::CompareFunction::Greater:
+ return D3D12_COMPARISON_FUNC_GREATER;
+ case dawn::CompareFunction::GreaterEqual:
+ return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
+ case dawn::CompareFunction::Less:
+ return D3D12_COMPARISON_FUNC_LESS;
+ case dawn::CompareFunction::LessEqual:
+ return D3D12_COMPARISON_FUNC_LESS_EQUAL;
+ case dawn::CompareFunction::Never:
+ return D3D12_COMPARISON_FUNC_NEVER;
+ case dawn::CompareFunction::NotEqual:
+ return D3D12_COMPARISON_FUNC_NOT_EQUAL;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+}} // namespace dawn_native::d3d12
diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/BlendStateD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/UtilsD3D12.h
index ea1a32da071..f47a360fc45 100644
--- a/chromium/third_party/dawn/src/dawn_native/d3d12/BlendStateD3D12.h
+++ b/chromium/third_party/dawn/src/dawn_native/d3d12/UtilsD3D12.h
@@ -1,4 +1,4 @@
-// Copyright 2017 The Dawn Authors
+// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,25 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_D3D12_BLENDSTATED3D12_H_
-#define DAWNNATIVE_D3D12_BLENDSTATED3D12_H_
-
-#include "dawn_native/BlendState.h"
+#ifndef DAWNNATIVE_D3D12_UTILSD3D12_H_
+#define DAWNNATIVE_D3D12_UTILSD3D12_H_
#include "dawn_native/d3d12/d3d12_platform.h"
+#include "dawn_native/dawn_platform.h"
namespace dawn_native { namespace d3d12 {
- class BlendState : public BlendStateBase {
- public:
- BlendState(BlendStateBuilder* builder);
-
- const D3D12_RENDER_TARGET_BLEND_DESC& GetD3D12BlendDesc() const;
-
- private:
- D3D12_RENDER_TARGET_BLEND_DESC mBlendDesc;
- };
+ D3D12_COMPARISON_FUNC ToD3D12ComparisonFunc(dawn::CompareFunction func);
}} // namespace dawn_native::d3d12
-#endif // DAWNNATIVE_D3D12_BLENDSTATED3D12_H_
+#endif // DAWNNATIVE_D3D12_UTILSD3D12_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/BlendStateMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/BlendStateMTL.mm
deleted file mode 100644
index 06227555e3f..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/metal/BlendStateMTL.mm
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2017 The Dawn 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_native/metal/BlendStateMTL.h"
-
-namespace dawn_native { namespace metal {
-
- namespace {
-
- MTLBlendFactor MetalBlendFactor(dawn::BlendFactor factor, bool alpha) {
- switch (factor) {
- case dawn::BlendFactor::Zero:
- return MTLBlendFactorZero;
- case dawn::BlendFactor::One:
- return MTLBlendFactorOne;
- case dawn::BlendFactor::SrcColor:
- return MTLBlendFactorSourceColor;
- case dawn::BlendFactor::OneMinusSrcColor:
- return MTLBlendFactorOneMinusSourceColor;
- case dawn::BlendFactor::SrcAlpha:
- return MTLBlendFactorSourceAlpha;
- case dawn::BlendFactor::OneMinusSrcAlpha:
- return MTLBlendFactorOneMinusSourceAlpha;
- case dawn::BlendFactor::DstColor:
- return MTLBlendFactorDestinationColor;
- case dawn::BlendFactor::OneMinusDstColor:
- return MTLBlendFactorOneMinusDestinationColor;
- case dawn::BlendFactor::DstAlpha:
- return MTLBlendFactorDestinationAlpha;
- case dawn::BlendFactor::OneMinusDstAlpha:
- return MTLBlendFactorOneMinusDestinationAlpha;
- case dawn::BlendFactor::SrcAlphaSaturated:
- return MTLBlendFactorSourceAlphaSaturated;
- case dawn::BlendFactor::BlendColor:
- return alpha ? MTLBlendFactorBlendAlpha : MTLBlendFactorBlendColor;
- case dawn::BlendFactor::OneMinusBlendColor:
- return alpha ? MTLBlendFactorOneMinusBlendAlpha
- : MTLBlendFactorOneMinusBlendColor;
- }
- }
-
- MTLBlendOperation MetalBlendOperation(dawn::BlendOperation operation) {
- switch (operation) {
- case dawn::BlendOperation::Add:
- return MTLBlendOperationAdd;
- case dawn::BlendOperation::Subtract:
- return MTLBlendOperationSubtract;
- case dawn::BlendOperation::ReverseSubtract:
- return MTLBlendOperationReverseSubtract;
- case dawn::BlendOperation::Min:
- return MTLBlendOperationMin;
- case dawn::BlendOperation::Max:
- return MTLBlendOperationMax;
- }
- }
-
- MTLColorWriteMask MetalColorWriteMask(dawn::ColorWriteMask colorWriteMask) {
- return (((colorWriteMask & dawn::ColorWriteMask::Red) != dawn::ColorWriteMask::None
- ? MTLColorWriteMaskRed
- : MTLColorWriteMaskNone) |
- ((colorWriteMask & dawn::ColorWriteMask::Green) != dawn::ColorWriteMask::None
- ? MTLColorWriteMaskGreen
- : MTLColorWriteMaskNone) |
- ((colorWriteMask & dawn::ColorWriteMask::Blue) != dawn::ColorWriteMask::None
- ? MTLColorWriteMaskBlue
- : MTLColorWriteMaskNone) |
- ((colorWriteMask & dawn::ColorWriteMask::Alpha) != dawn::ColorWriteMask::None
- ? MTLColorWriteMaskAlpha
- : MTLColorWriteMaskNone));
- }
- }
-
- BlendState::BlendState(BlendStateBuilder* builder) : BlendStateBase(builder) {
- }
-
- void BlendState::ApplyBlendState(MTLRenderPipelineColorAttachmentDescriptor* descriptor) const {
- auto& info = GetBlendInfo();
- descriptor.blendingEnabled = info.blendEnabled;
- descriptor.sourceRGBBlendFactor = MetalBlendFactor(info.colorBlend.srcFactor, false);
- descriptor.destinationRGBBlendFactor = MetalBlendFactor(info.colorBlend.dstFactor, false);
- descriptor.rgbBlendOperation = MetalBlendOperation(info.colorBlend.operation);
- descriptor.sourceAlphaBlendFactor = MetalBlendFactor(info.alphaBlend.srcFactor, true);
- descriptor.destinationAlphaBlendFactor = MetalBlendFactor(info.alphaBlend.dstFactor, true);
- descriptor.alphaBlendOperation = MetalBlendOperation(info.alphaBlend.operation);
- descriptor.writeMask = MetalColorWriteMask(info.colorWriteMask);
- }
-
-}} // namespace dawn_native::metal
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.h b/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.h
index fbf4d37c5b7..a56af33fe4d 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.h
+++ b/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.h
@@ -42,11 +42,6 @@ namespace dawn_native { namespace metal {
id<MTLBuffer> mMtlBuffer = nil;
};
- class BufferView : public BufferViewBase {
- public:
- BufferView(BufferViewBuilder* builder);
- };
-
class MapRequestTracker {
public:
MapRequestTracker(Device* device);
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.mm
index ebef40d614d..d993e78789e 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.mm
+++ b/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.mm
@@ -68,9 +68,6 @@ namespace dawn_native { namespace metal {
// Nothing to do, Metal StorageModeShared buffers are always mapped.
}
- BufferView::BufferView(BufferViewBuilder* builder) : BufferViewBase(builder) {
- }
-
MapRequestTracker::MapRequestTracker(Device* device) : mDevice(device) {
}
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/CommandBufferMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/CommandBufferMTL.mm
index 3aff3784108..22f8241efaf 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/CommandBufferMTL.mm
+++ b/chromium/third_party/dawn/src/dawn_native/metal/CommandBufferMTL.mm
@@ -18,7 +18,6 @@
#include "dawn_native/Commands.h"
#include "dawn_native/metal/BufferMTL.h"
#include "dawn_native/metal/ComputePipelineMTL.h"
-#include "dawn_native/metal/DepthStencilStateMTL.h"
#include "dawn_native/metal/DeviceMTL.h"
#include "dawn_native/metal/InputStateMTL.h"
#include "dawn_native/metal/PipelineLayoutMTL.h"
@@ -63,9 +62,11 @@ namespace dawn_native { namespace metal {
descriptor.colorAttachments[i].loadAction = MTLLoadActionLoad;
}
- // TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
descriptor.colorAttachments[i].texture =
ToBackend(attachmentInfo.view->GetTexture())->GetMTLTexture();
+ descriptor.colorAttachments[i].level = attachmentInfo.view->GetBaseMipLevel();
+ descriptor.colorAttachments[i].slice = attachmentInfo.view->GetBaseArrayLayer();
+
descriptor.colorAttachments[i].storeAction = MTLStoreActionStore;
}
@@ -119,12 +120,8 @@ namespace dawn_native { namespace metal {
// TODO(kainino@chromium.org): Maintain buffers and offsets arrays in BindGroup
// so that we only have to do one setVertexBuffers and one setFragmentBuffers
// call here.
- for (size_t binding = 0; binding < layout.mask.size(); ++binding) {
- if (!layout.mask[binding]) {
- continue;
- }
-
- auto stage = layout.visibilities[binding];
+ for (uint32_t bindingIndex : IterateBitSet(layout.mask)) {
+ auto stage = layout.visibilities[bindingIndex];
bool hasVertStage = stage & dawn::ShaderStageBit::Vertex && render != nil;
bool hasFragStage = stage & dawn::ShaderStageBit::Fragment && render != nil;
bool hasComputeStage = stage & dawn::ShaderStageBit::Compute && compute != nil;
@@ -135,24 +132,23 @@ namespace dawn_native { namespace metal {
if (hasVertStage) {
vertIndex = pipelineLayout->GetBindingIndexInfo(
- dawn::ShaderStage::Vertex)[index][binding];
+ dawn::ShaderStage::Vertex)[index][bindingIndex];
}
if (hasFragStage) {
fragIndex = pipelineLayout->GetBindingIndexInfo(
- dawn::ShaderStage::Fragment)[index][binding];
+ dawn::ShaderStage::Fragment)[index][bindingIndex];
}
if (hasComputeStage) {
computeIndex = pipelineLayout->GetBindingIndexInfo(
- dawn::ShaderStage::Compute)[index][binding];
+ dawn::ShaderStage::Compute)[index][bindingIndex];
}
- switch (layout.types[binding]) {
+ switch (layout.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::StorageBuffer: {
- BufferView* view = ToBackend(group->GetBindingAsBufferView(binding));
- auto b = ToBackend(view->GetBuffer());
- const id<MTLBuffer> buffer = b->GetMTLBuffer();
- const NSUInteger offset = view->GetOffset();
+ BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
+ const id<MTLBuffer> buffer = ToBackend(binding.buffer)->GetMTLBuffer();
+ const NSUInteger offset = binding.offset;
if (hasVertStage) {
[render setVertexBuffers:&buffer
@@ -173,7 +169,7 @@ namespace dawn_native { namespace metal {
} break;
case dawn::BindingType::Sampler: {
- auto sampler = ToBackend(group->GetBindingAsSampler(binding));
+ auto sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
if (hasVertStage) {
[render setVertexSamplerState:sampler->GetMTLSamplerState()
atIndex:vertIndex];
@@ -189,7 +185,7 @@ namespace dawn_native { namespace metal {
} break;
case dawn::BindingType::SampledTexture: {
- auto textureView = ToBackend(group->GetBindingAsTextureView(binding));
+ auto textureView = ToBackend(group->GetBindingAsTextureView(bindingIndex));
if (hasVertStage) {
[render setVertexTexture:textureView->GetMTLTexture()
atIndex:vertIndex];
@@ -253,24 +249,25 @@ namespace dawn_native { namespace metal {
CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
auto& src = copy->source;
auto& dst = copy->destination;
+ auto& copySize = copy->copySize;
Buffer* buffer = ToBackend(src.buffer.Get());
Texture* texture = ToBackend(dst.texture.Get());
MTLOrigin origin;
- origin.x = dst.x;
- origin.y = dst.y;
- origin.z = dst.z;
+ origin.x = dst.origin.x;
+ origin.y = dst.origin.y;
+ origin.z = dst.origin.z;
MTLSize size;
- size.width = dst.width;
- size.height = dst.height;
- size.depth = dst.depth;
+ size.width = copySize.width;
+ size.height = copySize.height;
+ size.depth = copySize.depth;
encoders.EnsureBlit(commandBuffer);
[encoders.blit copyFromBuffer:buffer->GetMTLBuffer()
sourceOffset:src.offset
- sourceBytesPerRow:copy->rowPitch
- sourceBytesPerImage:(copy->rowPitch * dst.height)
+ sourceBytesPerRow:src.rowPitch
+ sourceBytesPerImage:(src.rowPitch * src.imageHeight)
sourceSize:size
toTexture:texture->GetMTLTexture()
destinationSlice:dst.slice
@@ -282,18 +279,19 @@ namespace dawn_native { namespace metal {
CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
auto& src = copy->source;
auto& dst = copy->destination;
+ auto& copySize = copy->copySize;
Texture* texture = ToBackend(src.texture.Get());
Buffer* buffer = ToBackend(dst.buffer.Get());
MTLOrigin origin;
- origin.x = src.x;
- origin.y = src.y;
- origin.z = src.z;
+ origin.x = src.origin.x;
+ origin.y = src.origin.y;
+ origin.z = src.origin.z;
MTLSize size;
- size.width = src.width;
- size.height = src.height;
- size.depth = src.depth;
+ size.width = copySize.width;
+ size.height = copySize.height;
+ size.depth = copySize.depth;
encoders.EnsureBlit(commandBuffer);
[encoders.blit copyFromTexture:texture->GetMTLTexture()
@@ -303,8 +301,8 @@ namespace dawn_native { namespace metal {
sourceSize:size
toBuffer:buffer->GetMTLBuffer()
destinationOffset:dst.offset
- destinationBytesPerRow:copy->rowPitch
- destinationBytesPerImage:copy->rowPitch * src.height];
+ destinationBytesPerRow:dst.rowPitch
+ destinationBytesPerImage:(dst.rowPitch * dst.imageHeight)];
} break;
default: { UNREACHABLE(); } break;
@@ -407,8 +405,8 @@ namespace dawn_native { namespace metal {
return;
} break;
- case Command::DrawArrays: {
- DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>();
+ case Command::Draw: {
+ DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
[encoder drawPrimitives:lastPipeline->GetMTLPrimitiveTopology()
vertexStart:draw->firstVertex
@@ -417,8 +415,8 @@ namespace dawn_native { namespace metal {
baseInstance:draw->firstInstance];
} break;
- case Command::DrawElements: {
- DrawElementsCmd* draw = mCommands.NextCommand<DrawElementsCmd>();
+ case Command::DrawIndexed: {
+ DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
size_t formatSize = IndexFormatSize(lastPipeline->GetIndexFormat());
[encoder
@@ -428,7 +426,7 @@ namespace dawn_native { namespace metal {
indexBuffer:indexBuffer
indexBufferOffset:indexBufferBaseOffset + draw->firstIndex * formatSize
instanceCount:draw->instanceCount
- baseVertex:0
+ baseVertex:draw->baseVertex
baseInstance:draw->firstInstance];
} break;
@@ -436,9 +434,7 @@ namespace dawn_native { namespace metal {
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
lastPipeline = ToBackend(cmd->pipeline).Get();
- DepthStencilState* depthStencilState =
- ToBackend(lastPipeline->GetDepthStencilState());
- [encoder setDepthStencilState:depthStencilState->GetMTLDepthStencilState()];
+ [encoder setDepthStencilState:lastPipeline->GetMTLDepthStencilState()];
lastPipeline->Encode(encoder);
} break;
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/DepthStencilStateMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/DepthStencilStateMTL.mm
deleted file mode 100644
index fc811339928..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/metal/DepthStencilStateMTL.mm
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2017 The Dawn 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_native/metal/DepthStencilStateMTL.h"
-
-#include "dawn_native/metal/DeviceMTL.h"
-
-namespace dawn_native { namespace metal {
-
- namespace {
- MTLCompareFunction MetalDepthStencilCompareFunction(dawn::CompareFunction compareFunction) {
- switch (compareFunction) {
- case dawn::CompareFunction::Never:
- return MTLCompareFunctionNever;
- case dawn::CompareFunction::Less:
- return MTLCompareFunctionLess;
- case dawn::CompareFunction::LessEqual:
- return MTLCompareFunctionLessEqual;
- case dawn::CompareFunction::Greater:
- return MTLCompareFunctionGreater;
- case dawn::CompareFunction::GreaterEqual:
- return MTLCompareFunctionGreaterEqual;
- case dawn::CompareFunction::NotEqual:
- return MTLCompareFunctionNotEqual;
- case dawn::CompareFunction::Equal:
- return MTLCompareFunctionEqual;
- case dawn::CompareFunction::Always:
- return MTLCompareFunctionAlways;
- }
- }
-
- MTLStencilOperation MetalStencilOperation(dawn::StencilOperation stencilOperation) {
- switch (stencilOperation) {
- case dawn::StencilOperation::Keep:
- return MTLStencilOperationKeep;
- case dawn::StencilOperation::Zero:
- return MTLStencilOperationZero;
- case dawn::StencilOperation::Replace:
- return MTLStencilOperationReplace;
- case dawn::StencilOperation::Invert:
- return MTLStencilOperationInvert;
- case dawn::StencilOperation::IncrementClamp:
- return MTLStencilOperationIncrementClamp;
- case dawn::StencilOperation::DecrementClamp:
- return MTLStencilOperationDecrementClamp;
- case dawn::StencilOperation::IncrementWrap:
- return MTLStencilOperationIncrementWrap;
- case dawn::StencilOperation::DecrementWrap:
- return MTLStencilOperationDecrementWrap;
- }
- }
- }
-
- DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder)
- : DepthStencilStateBase(builder) {
- MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = [MTLDepthStencilDescriptor new];
-
- auto& depth = GetDepth();
- mtlDepthStencilDescriptor.depthCompareFunction =
- MetalDepthStencilCompareFunction(depth.compareFunction);
- mtlDepthStencilDescriptor.depthWriteEnabled = depth.depthWriteEnabled;
-
- auto& stencil = GetStencil();
- if (StencilTestEnabled()) {
- MTLStencilDescriptor* backFaceStencil = [MTLStencilDescriptor new];
- MTLStencilDescriptor* frontFaceStencil = [MTLStencilDescriptor new];
-
- backFaceStencil.stencilCompareFunction =
- MetalDepthStencilCompareFunction(stencil.back.compareFunction);
- backFaceStencil.stencilFailureOperation =
- MetalStencilOperation(stencil.back.stencilFail);
- backFaceStencil.depthFailureOperation = MetalStencilOperation(stencil.back.depthFail);
- backFaceStencil.depthStencilPassOperation =
- MetalStencilOperation(stencil.back.depthStencilPass);
- backFaceStencil.readMask = stencil.readMask;
- backFaceStencil.writeMask = stencil.writeMask;
-
- frontFaceStencil.stencilCompareFunction =
- MetalDepthStencilCompareFunction(stencil.front.compareFunction);
- frontFaceStencil.stencilFailureOperation =
- MetalStencilOperation(stencil.front.stencilFail);
- frontFaceStencil.depthFailureOperation = MetalStencilOperation(stencil.front.depthFail);
- frontFaceStencil.depthStencilPassOperation =
- MetalStencilOperation(stencil.front.depthStencilPass);
- frontFaceStencil.readMask = stencil.readMask;
- frontFaceStencil.writeMask = stencil.writeMask;
-
- mtlDepthStencilDescriptor.backFaceStencil = backFaceStencil;
- mtlDepthStencilDescriptor.frontFaceStencil = frontFaceStencil;
- [backFaceStencil release];
- [frontFaceStencil release];
- }
-
- auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
- mMtlDepthStencilState =
- [mtlDevice newDepthStencilStateWithDescriptor:mtlDepthStencilDescriptor];
- [mtlDepthStencilDescriptor release];
- }
-
- DepthStencilState::~DepthStencilState() {
- [mMtlDepthStencilState release];
- mMtlDepthStencilState = nil;
- }
-
- id<MTLDepthStencilState> DepthStencilState::GetMTLDepthStencilState() {
- return mMtlDepthStencilState;
- }
-
-}} // namespace dawn_native::metal
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.h b/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.h
index da586ee459c..434ffa89706 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.h
+++ b/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.h
@@ -34,20 +34,17 @@ namespace dawn_native { namespace metal {
class Device : public DeviceBase {
public:
- Device(id<MTLDevice> mtlDevice);
+ Device();
~Device();
- BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
- BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
- BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
- DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override;
- RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
+ Serial GetCompletedCommandSerial() const final override;
+ Serial GetLastSubmittedCommandSerial() const final override;
void TickImpl() override;
const dawn_native::PCIInfo& GetPCIInfo() const override;
@@ -55,13 +52,15 @@ namespace dawn_native { namespace metal {
id<MTLDevice> GetMTLDevice();
id<MTLCommandBuffer> GetPendingCommandBuffer();
+ Serial GetPendingCommandSerial() const;
void SubmitPendingCommandBuffer();
- Serial GetPendingCommandSerial();
MapRequestTracker* GetMapTracker() const;
ResourceUploader* GetResourceUploader() const;
private:
+ ResultOrError<BindGroupBase*> CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) override;
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
@@ -70,6 +69,8 @@ namespace dawn_native { namespace metal {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override;
+ ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
@@ -86,8 +87,8 @@ namespace dawn_native { namespace metal {
std::unique_ptr<MapRequestTracker> mMapTracker;
std::unique_ptr<ResourceUploader> mResourceUploader;
- Serial mFinishedCommandSerial = 0;
- Serial mPendingCommandSerial = 1;
+ Serial mCompletedSerial = 0;
+ Serial mLastSubmittedSerial = 0;
id<MTLCommandBuffer> mPendingCommands = nil;
dawn_native::PCIInfo mPCIInfo;
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.mm
index a01ab6a83e8..f71fe9afc79 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.mm
+++ b/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.mm
@@ -14,15 +14,13 @@
#include "dawn_native/metal/DeviceMTL.h"
+#include "dawn_native/BackendConnection.h"
#include "dawn_native/BindGroup.h"
#include "dawn_native/BindGroupLayout.h"
-#include "dawn_native/MetalBackend.h"
#include "dawn_native/RenderPassDescriptor.h"
-#include "dawn_native/metal/BlendStateMTL.h"
#include "dawn_native/metal/BufferMTL.h"
#include "dawn_native/metal/CommandBufferMTL.h"
#include "dawn_native/metal/ComputePipelineMTL.h"
-#include "dawn_native/metal/DepthStencilStateMTL.h"
#include "dawn_native/metal/InputStateMTL.h"
#include "dawn_native/metal/PipelineLayoutMTL.h"
#include "dawn_native/metal/QueueMTL.h"
@@ -123,14 +121,15 @@ namespace dawn_native { namespace metal {
}
} // anonymous namespace
- dawnDevice CreateDevice(id<MTLDevice> metalDevice) {
- return reinterpret_cast<dawnDevice>(new Device(metalDevice));
+ BackendConnection* Connect(InstanceBase* instance) {
+ return nullptr;
}
// Device
- Device::Device(id<MTLDevice> mtlDevice)
- : mMtlDevice(mtlDevice),
+ Device::Device()
+ : DeviceBase(nullptr),
+ mMtlDevice(MTLCreateSystemDefaultDevice()),
mMapTracker(new MapRequestTracker(this)),
mResourceUploader(new ResourceUploader(this)) {
[mMtlDevice retain];
@@ -144,7 +143,7 @@ namespace dawn_native { namespace metal {
// store the pendingSerial before SubmitPendingCommandBuffer then wait for it to be passed.
// Instead we submit and wait for the serial before the next pendingCommandSerial.
SubmitPendingCommandBuffer();
- while (mFinishedCommandSerial != mPendingCommandSerial - 1) {
+ while (mCompletedSerial != mLastSubmittedSerial) {
usleep(100);
}
Tick();
@@ -162,22 +161,17 @@ namespace dawn_native { namespace metal {
mCommandQueue = nil;
}
- BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
- return new BindGroup(builder);
+ ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) {
+ return new BindGroup(this, descriptor);
}
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return new BindGroupLayout(this, descriptor);
}
- BlendStateBase* Device::CreateBlendState(BlendStateBuilder* builder) {
- return new BlendState(builder);
- }
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
- BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
- return new BufferView(builder);
- }
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}
@@ -185,9 +179,6 @@ namespace dawn_native { namespace metal {
const ComputePipelineDescriptor* descriptor) {
return new ComputePipeline(this, descriptor);
}
- DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
- return new DepthStencilState(builder);
- }
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputState(builder);
}
@@ -199,12 +190,13 @@ namespace dawn_native { namespace metal {
RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder);
}
- RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
- return new RenderPipeline(builder);
- }
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
return new Queue(this);
}
+ ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) {
+ return new RenderPipeline(this, descriptor);
+ }
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor);
}
@@ -224,13 +216,30 @@ namespace dawn_native { namespace metal {
return new TextureView(texture, descriptor);
}
- void Device::TickImpl() {
- mResourceUploader->Tick(mFinishedCommandSerial);
- mMapTracker->Tick(mFinishedCommandSerial);
+ Serial Device::GetCompletedCommandSerial() const {
+ return mCompletedSerial;
+ }
- // Code above might have added GPU work, submit it. This also makes sure
- // that even when no GPU work is happening, the serial number keeps incrementing.
- SubmitPendingCommandBuffer();
+ Serial Device::GetLastSubmittedCommandSerial() const {
+ return mLastSubmittedSerial;
+ }
+
+ Serial Device::GetPendingCommandSerial() const {
+ return mLastSubmittedSerial + 1;
+ }
+
+ void Device::TickImpl() {
+ mResourceUploader->Tick(mCompletedSerial);
+ mMapTracker->Tick(mCompletedSerial);
+
+ if (mPendingCommands != nil) {
+ SubmitPendingCommandBuffer();
+ } else if (mCompletedSerial == mLastSubmittedSerial) {
+ // If there's no GPU work in flight we still need to artificially increment the serial
+ // so that CPU operations waiting on GPU completion can know they don't have to wait.
+ mCompletedSerial++;
+ mLastSubmittedSerial++;
+ }
}
const dawn_native::PCIInfo& Device::GetPCIInfo() const {
@@ -258,24 +267,15 @@ namespace dawn_native { namespace metal {
// so this-> works as expected. However it is unclear how members are captured, (are they
// captured using this-> or by value?) so we make a copy of the pendingCommandSerial on the
// stack.
- Serial pendingSerial = mPendingCommandSerial;
+ mLastSubmittedSerial++;
+ Serial pendingSerial = mLastSubmittedSerial;
[mPendingCommands addCompletedHandler:^(id<MTLCommandBuffer>) {
- this->mFinishedCommandSerial = pendingSerial;
+ this->mCompletedSerial = pendingSerial;
}];
[mPendingCommands commit];
[mPendingCommands release];
mPendingCommands = nil;
- mPendingCommandSerial++;
- }
-
- uint64_t Device::GetPendingCommandSerial() {
- // If this is called, then it means some piece of code somewhere will wait for this serial
- // to complete. Make sure the pending command buffer is created so that it is on the worst
- // case enqueued on the next Tick() and eventually increments the serial. Otherwise if no
- // GPU work happens we could be waiting for this serial forever.
- GetPendingCommandBuffer();
- return mPendingCommandSerial;
}
MapRequestTracker* Device::GetMapTracker() const {
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/Forward.h b/chromium/third_party/dawn/src/dawn_native/metal/Forward.h
index d11f5a95b30..df8b1d021b7 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/Forward.h
+++ b/chromium/third_party/dawn/src/dawn_native/metal/Forward.h
@@ -25,14 +25,12 @@ namespace {
namespace dawn_native { namespace metal {
+ class Adapter;
using BindGroup = BindGroupBase;
using BindGroupLayout = BindGroupLayoutBase;
- class BlendState;
class Buffer;
- class BufferView;
class CommandBuffer;
class ComputePipeline;
- class DepthStencilState;
class Device;
class Framebuffer;
class InputState;
@@ -47,14 +45,12 @@ namespace dawn_native { namespace metal {
class TextureView;
struct MetalBackendTraits {
+ using AdapterType = Adapter;
using BindGroupType = BindGroup;
using BindGroupLayoutType = BindGroupLayout;
- using BlendStateType = BlendState;
using BufferType = Buffer;
- using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
- using DepthStencilStateType = DepthStencilState;
using DeviceType = Device;
using InputStateType = InputState;
using PipelineLayoutType = PipelineLayout;
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/DepthStencilStateMTL.h b/chromium/third_party/dawn/src/dawn_native/metal/MetalBackend.mm
index c33fadfbd2e..b90a4d511b4 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/DepthStencilStateMTL.h
+++ b/chromium/third_party/dawn/src/dawn_native/metal/MetalBackend.mm
@@ -1,4 +1,4 @@
-// Copyright 2017 The Dawn Authors
+// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,28 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_METAL_DEPTHSTENCILSTATEMTL_H_
-#define DAWNNATIVE_METAL_DEPTHSTENCILSTATEMTL_H_
+// MetalBackend.cpp: contains the definition of symbols exported by MetalBackend.h so that they
+// can be compiled twice: once export (shared library), once not exported (static library)
-#include "dawn_native/DepthStencilState.h"
+#include "dawn_native/MetalBackend.h"
-#import <Metal/Metal.h>
+#include "dawn_native/metal/DeviceMTL.h"
namespace dawn_native { namespace metal {
- class Device;
+ dawnDevice CreateDevice() {
+ return reinterpret_cast<dawnDevice>(new Device());
+ }
- class DepthStencilState : public DepthStencilStateBase {
- public:
- DepthStencilState(DepthStencilStateBuilder* builder);
- ~DepthStencilState();
-
- id<MTLDepthStencilState> GetMTLDepthStencilState();
-
- private:
- id<MTLDepthStencilState> mMtlDepthStencilState = nil;
- };
+ id<MTLDevice> GetMetalDevice(dawnDevice cDevice) {
+ Device* device = reinterpret_cast<Device*>(cDevice);
+ return device->GetMTLDevice();
+ }
}} // namespace dawn_native::metal
-
-#endif // DAWNNATIVE_METAL_DEPTHSTENCILSTATEMTL_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.h b/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.h
index beace61cc10..6da06e2f4b0 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.h
+++ b/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.h
@@ -21,9 +21,11 @@
namespace dawn_native { namespace metal {
+ class Device;
+
class RenderPipeline : public RenderPipelineBase {
public:
- RenderPipeline(RenderPipelineBuilder* builder);
+ RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
~RenderPipeline();
MTLIndexType GetMTLIndexType() const;
@@ -31,10 +33,13 @@ namespace dawn_native { namespace metal {
void Encode(id<MTLRenderCommandEncoder> encoder);
+ id<MTLDepthStencilState> GetMTLDepthStencilState();
+
private:
MTLIndexType mMtlIndexType;
MTLPrimitiveType mMtlPrimitiveTopology;
id<MTLRenderPipelineState> mMtlRenderPipelineState = nil;
+ id<MTLDepthStencilState> mMtlDepthStencilState = nil;
};
}} // namespace dawn_native::metal
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.mm
index 2b38e0389bd..70887f84ebe 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.mm
+++ b/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.mm
@@ -14,13 +14,12 @@
#include "dawn_native/metal/RenderPipelineMTL.h"
-#include "dawn_native/metal/BlendStateMTL.h"
-#include "dawn_native/metal/DepthStencilStateMTL.h"
#include "dawn_native/metal/DeviceMTL.h"
#include "dawn_native/metal/InputStateMTL.h"
#include "dawn_native/metal/PipelineLayoutMTL.h"
#include "dawn_native/metal/ShaderModuleMTL.h"
#include "dawn_native/metal/TextureMTL.h"
+#include "dawn_native/metal/UtilsMetal.h"
namespace dawn_native { namespace metal {
@@ -62,71 +61,216 @@ namespace dawn_native { namespace metal {
return MTLIndexTypeUInt32;
}
}
- }
- RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
- : RenderPipelineBase(builder),
- mMtlIndexType(MTLIndexFormat(GetIndexFormat())),
- mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) {
- auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
-
- MTLRenderPipelineDescriptor* descriptor = [MTLRenderPipelineDescriptor new];
-
- for (auto stage : IterateStages(GetStageMask())) {
- const auto& module = ToBackend(builder->GetStageInfo(stage).module);
-
- const auto& entryPoint = builder->GetStageInfo(stage).entryPoint;
- ShaderModule::MetalFunctionData data =
- module->GetFunction(entryPoint.c_str(), stage, ToBackend(GetLayout()));
- id<MTLFunction> function = data.function;
-
- switch (stage) {
- case dawn::ShaderStage::Vertex:
- descriptor.vertexFunction = function;
- break;
- case dawn::ShaderStage::Fragment:
- descriptor.fragmentFunction = function;
- break;
- case dawn::ShaderStage::Compute:
- UNREACHABLE();
+ MTLBlendFactor MetalBlendFactor(dawn::BlendFactor factor, bool alpha) {
+ switch (factor) {
+ case dawn::BlendFactor::Zero:
+ return MTLBlendFactorZero;
+ case dawn::BlendFactor::One:
+ return MTLBlendFactorOne;
+ case dawn::BlendFactor::SrcColor:
+ return MTLBlendFactorSourceColor;
+ case dawn::BlendFactor::OneMinusSrcColor:
+ return MTLBlendFactorOneMinusSourceColor;
+ case dawn::BlendFactor::SrcAlpha:
+ return MTLBlendFactorSourceAlpha;
+ case dawn::BlendFactor::OneMinusSrcAlpha:
+ return MTLBlendFactorOneMinusSourceAlpha;
+ case dawn::BlendFactor::DstColor:
+ return MTLBlendFactorDestinationColor;
+ case dawn::BlendFactor::OneMinusDstColor:
+ return MTLBlendFactorOneMinusDestinationColor;
+ case dawn::BlendFactor::DstAlpha:
+ return MTLBlendFactorDestinationAlpha;
+ case dawn::BlendFactor::OneMinusDstAlpha:
+ return MTLBlendFactorOneMinusDestinationAlpha;
+ case dawn::BlendFactor::SrcAlphaSaturated:
+ return MTLBlendFactorSourceAlphaSaturated;
+ case dawn::BlendFactor::BlendColor:
+ return alpha ? MTLBlendFactorBlendAlpha : MTLBlendFactorBlendColor;
+ case dawn::BlendFactor::OneMinusBlendColor:
+ return alpha ? MTLBlendFactorOneMinusBlendAlpha
+ : MTLBlendFactorOneMinusBlendColor;
+ }
+ }
+
+ MTLBlendOperation MetalBlendOperation(dawn::BlendOperation operation) {
+ switch (operation) {
+ case dawn::BlendOperation::Add:
+ return MTLBlendOperationAdd;
+ case dawn::BlendOperation::Subtract:
+ return MTLBlendOperationSubtract;
+ case dawn::BlendOperation::ReverseSubtract:
+ return MTLBlendOperationReverseSubtract;
+ case dawn::BlendOperation::Min:
+ return MTLBlendOperationMin;
+ case dawn::BlendOperation::Max:
+ return MTLBlendOperationMax;
+ }
+ }
+
+ MTLColorWriteMask MetalColorWriteMask(dawn::ColorWriteMask colorWriteMask) {
+ MTLColorWriteMask mask = MTLColorWriteMaskNone;
+
+ if (colorWriteMask & dawn::ColorWriteMask::Red) {
+ mask |= MTLColorWriteMaskRed;
+ }
+ if (colorWriteMask & dawn::ColorWriteMask::Green) {
+ mask |= MTLColorWriteMaskGreen;
+ }
+ if (colorWriteMask & dawn::ColorWriteMask::Blue) {
+ mask |= MTLColorWriteMaskBlue;
+ }
+ if (colorWriteMask & dawn::ColorWriteMask::Alpha) {
+ mask |= MTLColorWriteMaskAlpha;
+ }
+
+ return mask;
+ }
+
+ void ComputeBlendDesc(MTLRenderPipelineColorAttachmentDescriptor* attachment,
+ const BlendStateDescriptor* descriptor) {
+ attachment.blendingEnabled = descriptor->blendEnabled;
+ attachment.sourceRGBBlendFactor =
+ MetalBlendFactor(descriptor->colorBlend.srcFactor, false);
+ attachment.destinationRGBBlendFactor =
+ MetalBlendFactor(descriptor->colorBlend.dstFactor, false);
+ attachment.rgbBlendOperation = MetalBlendOperation(descriptor->colorBlend.operation);
+ attachment.sourceAlphaBlendFactor =
+ MetalBlendFactor(descriptor->alphaBlend.srcFactor, true);
+ attachment.destinationAlphaBlendFactor =
+ MetalBlendFactor(descriptor->alphaBlend.dstFactor, true);
+ attachment.alphaBlendOperation = MetalBlendOperation(descriptor->alphaBlend.operation);
+ attachment.writeMask = MetalColorWriteMask(descriptor->colorWriteMask);
+ }
+
+ MTLStencilOperation MetalStencilOperation(dawn::StencilOperation stencilOperation) {
+ switch (stencilOperation) {
+ case dawn::StencilOperation::Keep:
+ return MTLStencilOperationKeep;
+ case dawn::StencilOperation::Zero:
+ return MTLStencilOperationZero;
+ case dawn::StencilOperation::Replace:
+ return MTLStencilOperationReplace;
+ case dawn::StencilOperation::Invert:
+ return MTLStencilOperationInvert;
+ case dawn::StencilOperation::IncrementClamp:
+ return MTLStencilOperationIncrementClamp;
+ case dawn::StencilOperation::DecrementClamp:
+ return MTLStencilOperationDecrementClamp;
+ case dawn::StencilOperation::IncrementWrap:
+ return MTLStencilOperationIncrementWrap;
+ case dawn::StencilOperation::DecrementWrap:
+ return MTLStencilOperationDecrementWrap;
}
}
+ MTLDepthStencilDescriptor* ComputeDepthStencilDesc(
+ const DepthStencilStateDescriptor* descriptor) {
+ MTLDepthStencilDescriptor* mtlDepthStencilDescriptor =
+ [[MTLDepthStencilDescriptor new] autorelease];
+ mtlDepthStencilDescriptor.depthCompareFunction =
+ ToMetalCompareFunction(descriptor->depthCompare);
+ mtlDepthStencilDescriptor.depthWriteEnabled = descriptor->depthWriteEnabled;
+
+ if (StencilTestEnabled(descriptor)) {
+ MTLStencilDescriptor* backFaceStencil = [[MTLStencilDescriptor new] autorelease];
+ MTLStencilDescriptor* frontFaceStencil = [[MTLStencilDescriptor new] autorelease];
+
+ backFaceStencil.stencilCompareFunction =
+ ToMetalCompareFunction(descriptor->back.compare);
+ backFaceStencil.stencilFailureOperation =
+ MetalStencilOperation(descriptor->back.stencilFailOp);
+ backFaceStencil.depthFailureOperation =
+ MetalStencilOperation(descriptor->back.depthFailOp);
+ backFaceStencil.depthStencilPassOperation =
+ MetalStencilOperation(descriptor->back.passOp);
+ backFaceStencil.readMask = descriptor->stencilReadMask;
+ backFaceStencil.writeMask = descriptor->stencilWriteMask;
+
+ frontFaceStencil.stencilCompareFunction =
+ ToMetalCompareFunction(descriptor->front.compare);
+ frontFaceStencil.stencilFailureOperation =
+ MetalStencilOperation(descriptor->front.stencilFailOp);
+ frontFaceStencil.depthFailureOperation =
+ MetalStencilOperation(descriptor->front.depthFailOp);
+ frontFaceStencil.depthStencilPassOperation =
+ MetalStencilOperation(descriptor->front.passOp);
+ frontFaceStencil.readMask = descriptor->stencilReadMask;
+ frontFaceStencil.writeMask = descriptor->stencilWriteMask;
+
+ mtlDepthStencilDescriptor.backFaceStencil = backFaceStencil;
+ mtlDepthStencilDescriptor.frontFaceStencil = frontFaceStencil;
+ }
+ return mtlDepthStencilDescriptor;
+ }
+
+ } // anonymous namespace
+
+ RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
+ : RenderPipelineBase(device, descriptor),
+ mMtlIndexType(MTLIndexFormat(GetIndexFormat())),
+ mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) {
+ auto mtlDevice = device->GetMTLDevice();
+
+ MTLRenderPipelineDescriptor* descriptorMTL = [MTLRenderPipelineDescriptor new];
+
+ const ShaderModule* vertexModule = ToBackend(descriptor->vertexStage->module);
+ const char* vertexEntryPoint = descriptor->vertexStage->entryPoint;
+ ShaderModule::MetalFunctionData vertexData = vertexModule->GetFunction(
+ vertexEntryPoint, dawn::ShaderStage::Vertex, ToBackend(GetLayout()));
+ descriptorMTL.vertexFunction = vertexData.function;
+
+ const ShaderModule* fragmentModule = ToBackend(descriptor->fragmentStage->module);
+ const char* fragmentEntryPoint = descriptor->fragmentStage->entryPoint;
+ ShaderModule::MetalFunctionData fragmentData = fragmentModule->GetFunction(
+ fragmentEntryPoint, dawn::ShaderStage::Fragment, ToBackend(GetLayout()));
+ descriptorMTL.fragmentFunction = fragmentData.function;
+
if (HasDepthStencilAttachment()) {
// TODO(kainino@chromium.org): Handle depth-only and stencil-only formats.
dawn::TextureFormat depthStencilFormat = GetDepthStencilFormat();
- descriptor.depthAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
- descriptor.stencilAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
+ descriptorMTL.depthAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
+ descriptorMTL.stencilAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
}
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
- descriptor.colorAttachments[i].pixelFormat =
+ descriptorMTL.colorAttachments[i].pixelFormat =
MetalPixelFormat(GetColorAttachmentFormat(i));
- ToBackend(GetBlendState(i))->ApplyBlendState(descriptor.colorAttachments[i]);
+ const BlendStateDescriptor* descriptor = GetBlendStateDescriptor(i);
+ ComputeBlendDesc(descriptorMTL.colorAttachments[i], descriptor);
}
- descriptor.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology());
+ descriptorMTL.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology());
InputState* inputState = ToBackend(GetInputState());
- descriptor.vertexDescriptor = inputState->GetMTLVertexDescriptor();
+ descriptorMTL.vertexDescriptor = inputState->GetMTLVertexDescriptor();
// TODO(kainino@chromium.org): push constants, textures, samplers
- NSError* error = nil;
- mMtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor:descriptor
- error:&error];
- if (error != nil) {
- NSLog(@" error => %@", error);
- builder->HandleError("Error creating pipeline state");
- [descriptor release];
- return;
+ {
+ NSError* error = nil;
+ mMtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL
+ error:&error];
+ [descriptorMTL release];
+ if (error != nil) {
+ NSLog(@" error => %@", error);
+ device->HandleError("Error creating rendering pipeline state");
+ return;
+ }
}
- [descriptor release];
+ // create depth stencil state and cache it, fetch the cached depth stencil state when we
+ // call setDepthStencilState() for a given render pipeline in CommandBuffer, in order to
+ // improve performance.
+ mMtlDepthStencilState =
+ [mtlDevice newDepthStencilStateWithDescriptor:ComputeDepthStencilDesc(
+ GetDepthStencilStateDescriptor())];
}
RenderPipeline::~RenderPipeline() {
[mMtlRenderPipelineState release];
+ [mMtlDepthStencilState release];
}
MTLIndexType RenderPipeline::GetMTLIndexType() const {
@@ -141,4 +285,8 @@ namespace dawn_native { namespace metal {
[encoder setRenderPipelineState:mMtlRenderPipelineState];
}
+ id<MTLDepthStencilState> RenderPipeline::GetMTLDepthStencilState() {
+ return mMtlDepthStencilState;
+ }
+
}} // namespace dawn_native::metal
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/SamplerMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/SamplerMTL.mm
index 539431ce783..19d374b8bc3 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/SamplerMTL.mm
+++ b/chromium/third_party/dawn/src/dawn_native/metal/SamplerMTL.mm
@@ -15,6 +15,7 @@
#include "dawn_native/metal/SamplerMTL.h"
#include "dawn_native/metal/DeviceMTL.h"
+#include "dawn_native/metal/UtilsMetal.h"
namespace dawn_native { namespace metal {
@@ -45,6 +46,19 @@ namespace dawn_native { namespace metal {
return MTLSamplerAddressModeMirrorRepeat;
case dawn::AddressMode::ClampToEdge:
return MTLSamplerAddressModeClampToEdge;
+ case dawn::AddressMode::ClampToBorderColor:
+ return MTLSamplerAddressModeClampToBorderColor;
+ }
+ }
+
+ MTLSamplerBorderColor BorderColor(dawn::BorderColor color) {
+ switch (color) {
+ case dawn::BorderColor::TransparentBlack:
+ return MTLSamplerBorderColorTransparentBlack;
+ case dawn::BorderColor::OpaqueBlack:
+ return MTLSamplerBorderColorOpaqueBlack;
+ case dawn::BorderColor::OpaqueWhite:
+ return MTLSamplerBorderColorOpaqueWhite;
}
}
}
@@ -61,6 +75,11 @@ namespace dawn_native { namespace metal {
mtlDesc.tAddressMode = AddressMode(descriptor->addressModeV);
mtlDesc.rAddressMode = AddressMode(descriptor->addressModeW);
+ mtlDesc.lodMinClamp = descriptor->lodMinClamp;
+ mtlDesc.lodMaxClamp = descriptor->lodMaxClamp;
+ mtlDesc.compareFunction = ToMetalCompareFunction(descriptor->compareFunction);
+ mtlDesc.borderColor = BorderColor(descriptor->borderColor);
+
mMtlSamplerState = [device->GetMTLDevice() newSamplerStateWithDescriptor:mtlDesc];
}
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.mm
index 818c8daf6d1..b6ebdfa7f91 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.mm
+++ b/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.mm
@@ -17,7 +17,6 @@
#include "dawn_native/metal/DeviceMTL.h"
namespace dawn_native { namespace metal {
-
MTLPixelFormat MetalPixelFormat(dawn::TextureFormat format) {
switch (format) {
case dawn::TextureFormat::R8G8B8A8Unorm:
@@ -40,6 +39,12 @@ namespace dawn_native { namespace metal {
}
namespace {
+ bool UsageNeedsTextureView(dawn::TextureUsageBit usage) {
+ constexpr dawn::TextureUsageBit kUsageNeedsTextureView =
+ dawn::TextureUsageBit::Storage | dawn::TextureUsageBit::Sampled;
+ return usage & kUsageNeedsTextureView;
+ }
+
MTLTextureUsage MetalTextureUsage(dawn::TextureUsageBit usage) {
MTLTextureUsage result = MTLTextureUsageUnknown; // This is 0
@@ -55,9 +60,9 @@ namespace dawn_native { namespace metal {
result |= MTLTextureUsageRenderTarget;
}
- // TODO(jiawei.shao@intel.com): investigate if we should skip setting this flag when the
- // texture is only used as a render target.
- result |= MTLTextureUsagePixelFormatView;
+ if (UsageNeedsTextureView(usage)) {
+ result |= MTLTextureUsagePixelFormatView;
+ }
return result;
}
@@ -85,6 +90,31 @@ namespace dawn_native { namespace metal {
return MTLTextureType2D;
}
}
+
+ bool RequiresCreatingNewTextureView(const TextureBase* texture,
+ const TextureViewDescriptor* textureViewDescriptor) {
+ if (texture->GetFormat() != textureViewDescriptor->format) {
+ return true;
+ }
+
+ if (texture->GetArrayLayers() != textureViewDescriptor->layerCount) {
+ return true;
+ }
+
+ if (texture->GetNumMipLevels() != textureViewDescriptor->levelCount) {
+ return true;
+ }
+
+ switch (textureViewDescriptor->dimension) {
+ case dawn::TextureViewDimension::Cube:
+ case dawn::TextureViewDimension::CubeArray:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
}
Texture::Texture(Device* device, const TextureDescriptor* descriptor)
@@ -121,20 +151,25 @@ namespace dawn_native { namespace metal {
return mMtlTexture;
}
- // TODO(jiawei.shao@intel.com): use the original texture directly when the descriptor covers the
- // whole texture in the same format (for example, when CreateDefaultTextureView() is called).
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
: TextureViewBase(texture, descriptor) {
- MTLPixelFormat format = MetalPixelFormat(descriptor->format);
- MTLTextureType textureViewType = MetalTextureViewType(descriptor->dimension);
- auto mipLevelRange = NSMakeRange(descriptor->baseMipLevel, descriptor->levelCount);
- auto arrayLayerRange = NSMakeRange(descriptor->baseArrayLayer, descriptor->layerCount);
-
id<MTLTexture> mtlTexture = ToBackend(texture)->GetMTLTexture();
- mMtlTextureView = [mtlTexture newTextureViewWithPixelFormat:format
- textureType:textureViewType
- levels:mipLevelRange
- slices:arrayLayerRange];
+
+ if (!UsageNeedsTextureView(texture->GetUsage())) {
+ mMtlTextureView = nil;
+ } else if (!RequiresCreatingNewTextureView(texture, descriptor)) {
+ mMtlTextureView = [mtlTexture retain];
+ } else {
+ MTLPixelFormat format = MetalPixelFormat(descriptor->format);
+ MTLTextureType textureViewType = MetalTextureViewType(descriptor->dimension);
+ auto mipLevelRange = NSMakeRange(descriptor->baseMipLevel, descriptor->levelCount);
+ auto arrayLayerRange = NSMakeRange(descriptor->baseArrayLayer, descriptor->layerCount);
+
+ mMtlTextureView = [mtlTexture newTextureViewWithPixelFormat:format
+ textureType:textureViewType
+ levels:mipLevelRange
+ slices:arrayLayerRange];
+ }
}
TextureView::~TextureView() {
@@ -142,6 +177,7 @@ namespace dawn_native { namespace metal {
}
id<MTLTexture> TextureView::GetMTLTexture() {
+ ASSERT(mMtlTextureView != nil);
return mMtlTextureView;
}
}} // namespace dawn_native::metal
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/BlendStateMTL.h b/chromium/third_party/dawn/src/dawn_native/metal/UtilsMetal.h
index 484bf519f3e..574036d6438 100644
--- a/chromium/third_party/dawn/src/dawn_native/metal/BlendStateMTL.h
+++ b/chromium/third_party/dawn/src/dawn_native/metal/UtilsMetal.h
@@ -1,4 +1,4 @@
-// Copyright 2017 The Dawn Authors
+// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,21 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_METAL_BLENDSTATEMTL_H_
-#define DAWNNATIVE_METAL_BLENDSTATEMTL_H_
+#ifndef DAWNNATIVE_METAL_UTILSMETAL_H_
+#define DAWNNATIVE_METAL_UTILSMETAL_H_
-#include "dawn_native/BlendState.h"
+#include "dawn_native/dawn_platform.h"
#import <Metal/Metal.h>
-namespace dawn_native { namespace metal {
- class BlendState : public BlendStateBase {
- public:
- BlendState(BlendStateBuilder* builder);
+namespace dawn_native { namespace metal {
- void ApplyBlendState(MTLRenderPipelineColorAttachmentDescriptor* descriptor) const;
- };
+ MTLCompareFunction ToMetalCompareFunction(dawn::CompareFunction compareFunction);
}} // namespace dawn_native::metal
-#endif // DAWNNATIVE_METAL_BLENDSTATEMTL_H_
+#endif // DAWNNATIVE_METAL_UTILSMETAL_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/metal/UtilsMetal.mm b/chromium/third_party/dawn/src/dawn_native/metal/UtilsMetal.mm
new file mode 100644
index 00000000000..86210379521
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/metal/UtilsMetal.mm
@@ -0,0 +1,40 @@
+// Copyright 2019 The Dawn 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_native/metal/UtilsMetal.h"
+
+namespace dawn_native { namespace metal {
+
+ MTLCompareFunction ToMetalCompareFunction(dawn::CompareFunction compareFunction) {
+ switch (compareFunction) {
+ case dawn::CompareFunction::Never:
+ return MTLCompareFunctionNever;
+ case dawn::CompareFunction::Less:
+ return MTLCompareFunctionLess;
+ case dawn::CompareFunction::LessEqual:
+ return MTLCompareFunctionLessEqual;
+ case dawn::CompareFunction::Greater:
+ return MTLCompareFunctionGreater;
+ case dawn::CompareFunction::GreaterEqual:
+ return MTLCompareFunctionGreaterEqual;
+ case dawn::CompareFunction::NotEqual:
+ return MTLCompareFunctionNotEqual;
+ case dawn::CompareFunction::Equal:
+ return MTLCompareFunctionEqual;
+ case dawn::CompareFunction::Always:
+ return MTLCompareFunctionAlways;
+ }
+ }
+
+}} // namespace dawn_native::metal
diff --git a/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.cpp b/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.cpp
new file mode 100644
index 00000000000..72444353718
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.cpp
@@ -0,0 +1,275 @@
+// Copyright 2017 The Dawn 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_native/null/DeviceNull.h"
+
+#include "dawn_native/BackendConnection.h"
+#include "dawn_native/Commands.h"
+
+#include <spirv-cross/spirv_cross.hpp>
+
+namespace dawn_native { namespace null {
+
+ // Implementation of pre-Device objects: the null adapter, null backend connection and Connect()
+
+ class Adapter : public AdapterBase {
+ public:
+ Adapter(InstanceBase* instance) : AdapterBase(instance, BackendType::Null) {
+ mPCIInfo.name = "Null backend";
+ }
+ virtual ~Adapter() = default;
+
+ private:
+ ResultOrError<DeviceBase*> CreateDeviceImpl() override {
+ return {new Device(this)};
+ }
+ };
+
+ class Backend : public BackendConnection {
+ public:
+ Backend(InstanceBase* instance) : BackendConnection(instance, BackendType::Null) {
+ }
+
+ std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override {
+ // There is always a single Null adapter because it is purely CPU based and doesn't
+ // depend on the system.
+ std::vector<std::unique_ptr<AdapterBase>> adapters;
+ adapters.push_back(std::make_unique<Adapter>(GetInstance()));
+ return adapters;
+ }
+ };
+
+ BackendConnection* Connect(InstanceBase* instance) {
+ return new Backend(instance);
+ }
+
+ // Device
+
+ Device::Device(Adapter* adapter) : DeviceBase(adapter) {
+ }
+
+ Device::~Device() {
+ }
+
+ ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) {
+ return new BindGroup(this, descriptor);
+ }
+ ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
+ const BindGroupLayoutDescriptor* descriptor) {
+ return new BindGroupLayout(this, descriptor);
+ }
+ ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
+ return new Buffer(this, descriptor);
+ }
+ CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
+ return new CommandBuffer(builder);
+ }
+ ResultOrError<ComputePipelineBase*> Device::CreateComputePipelineImpl(
+ const ComputePipelineDescriptor* descriptor) {
+ return new ComputePipeline(this, descriptor);
+ }
+ InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
+ return new InputState(builder);
+ }
+ ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
+ const PipelineLayoutDescriptor* descriptor) {
+ return new PipelineLayout(this, descriptor);
+ }
+ ResultOrError<QueueBase*> Device::CreateQueueImpl() {
+ return new Queue(this);
+ }
+ RenderPassDescriptorBase* Device::CreateRenderPassDescriptor(
+ RenderPassDescriptorBuilder* builder) {
+ return new RenderPassDescriptor(builder);
+ }
+ ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) {
+ return new RenderPipeline(this, descriptor);
+ }
+ ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
+ return new Sampler(this, descriptor);
+ }
+ ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl(
+ const ShaderModuleDescriptor* descriptor) {
+ auto module = new ShaderModule(this, descriptor);
+
+ spirv_cross::Compiler compiler(descriptor->code, descriptor->codeSize);
+ module->ExtractSpirvInfo(compiler);
+
+ return module;
+ }
+ SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) {
+ return new SwapChain(builder);
+ }
+ ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
+ return new Texture(this, descriptor);
+ }
+ ResultOrError<TextureViewBase*> Device::CreateTextureViewImpl(
+ TextureBase* texture,
+ const TextureViewDescriptor* descriptor) {
+ return new TextureView(texture, descriptor);
+ }
+
+ Serial Device::GetCompletedCommandSerial() const {
+ return mCompletedSerial;
+ }
+
+ Serial Device::GetLastSubmittedCommandSerial() const {
+ return mLastSubmittedSerial;
+ }
+
+ void Device::TickImpl() {
+ SubmitPendingOperations();
+ }
+
+ void Device::AddPendingOperation(std::unique_ptr<PendingOperation> operation) {
+ mPendingOperations.emplace_back(std::move(operation));
+ }
+ void Device::SubmitPendingOperations() {
+ for (auto& operation : mPendingOperations) {
+ operation->Execute();
+ }
+ mPendingOperations.clear();
+
+ mCompletedSerial = mLastSubmittedSerial;
+ mLastSubmittedSerial++;
+ }
+
+ // Buffer
+
+ struct BufferMapReadOperation : PendingOperation {
+ virtual void Execute() {
+ buffer->MapReadOperationCompleted(serial, ptr, isWrite);
+ }
+
+ Ref<Buffer> buffer;
+ void* ptr;
+ uint32_t serial;
+ bool isWrite;
+ };
+
+ Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)
+ : BufferBase(device, descriptor) {
+ if (GetUsage() & (dawn::BufferUsageBit::TransferDst | dawn::BufferUsageBit::MapRead |
+ dawn::BufferUsageBit::MapWrite)) {
+ mBackingData = std::unique_ptr<char[]>(new char[GetSize()]);
+ }
+ }
+
+ Buffer::~Buffer() {
+ }
+
+ void Buffer::MapReadOperationCompleted(uint32_t serial, void* ptr, bool isWrite) {
+ if (isWrite) {
+ CallMapWriteCallback(serial, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, ptr);
+ } else {
+ CallMapReadCallback(serial, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, ptr);
+ }
+ }
+
+ void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) {
+ ASSERT(start + count <= GetSize());
+ ASSERT(mBackingData);
+ memcpy(mBackingData.get() + start, data, count);
+ }
+
+ void Buffer::MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) {
+ MapAsyncImplCommon(serial, start, count, false);
+ }
+
+ void Buffer::MapWriteAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) {
+ MapAsyncImplCommon(serial, start, count, true);
+ }
+
+ void Buffer::MapAsyncImplCommon(uint32_t serial, uint32_t start, uint32_t count, bool isWrite) {
+ ASSERT(start + count <= GetSize());
+ ASSERT(mBackingData);
+
+ auto operation = new BufferMapReadOperation;
+ operation->buffer = this;
+ operation->ptr = mBackingData.get() + start;
+ operation->serial = serial;
+ operation->isWrite = isWrite;
+
+ ToBackend(GetDevice())->AddPendingOperation(std::unique_ptr<PendingOperation>(operation));
+ }
+
+ void Buffer::UnmapImpl() {
+ }
+
+ // CommandBuffer
+
+ CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
+ : CommandBufferBase(builder), mCommands(builder->AcquireCommands()) {
+ }
+
+ CommandBuffer::~CommandBuffer() {
+ FreeCommands(&mCommands);
+ }
+
+ // Queue
+
+ Queue::Queue(Device* device) : QueueBase(device) {
+ }
+
+ Queue::~Queue() {
+ }
+
+ void Queue::SubmitImpl(uint32_t, CommandBufferBase* const*) {
+ ToBackend(GetDevice())->SubmitPendingOperations();
+ }
+
+ // SwapChain
+
+ SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) {
+ const auto& im = GetImplementation();
+ im.Init(im.userData, nullptr);
+ }
+
+ SwapChain::~SwapChain() {
+ }
+
+ TextureBase* SwapChain::GetNextTextureImpl(const TextureDescriptor* descriptor) {
+ return GetDevice()->CreateTexture(descriptor);
+ }
+
+ void SwapChain::OnBeforePresent(TextureBase*) {
+ }
+
+ // NativeSwapChainImpl
+
+ void NativeSwapChainImpl::Init(WSIContext* context) {
+ }
+
+ dawnSwapChainError NativeSwapChainImpl::Configure(dawnTextureFormat format,
+ dawnTextureUsageBit,
+ uint32_t width,
+ uint32_t height) {
+ return DAWN_SWAP_CHAIN_NO_ERROR;
+ }
+
+ dawnSwapChainError NativeSwapChainImpl::GetNextTexture(dawnSwapChainNextTexture* nextTexture) {
+ return DAWN_SWAP_CHAIN_NO_ERROR;
+ }
+
+ dawnSwapChainError NativeSwapChainImpl::Present() {
+ return DAWN_SWAP_CHAIN_NO_ERROR;
+ }
+
+ dawn::TextureFormat NativeSwapChainImpl::GetPreferredFormat() const {
+ return dawn::TextureFormat::R8G8B8A8Unorm;
+ }
+
+}} // namespace dawn_native::null
diff --git a/chromium/third_party/dawn/src/dawn_native/null/NullBackend.h b/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.h
index 0c50ae9493e..03f8967e3c7 100644
--- a/chromium/third_party/dawn/src/dawn_native/null/NullBackend.h
+++ b/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.h
@@ -12,18 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_NULL_NULLBACKEND_H_
-#define DAWNNATIVE_NULL_NULLBACKEND_H_
-
-#include "dawn_native/dawn_platform.h"
+#ifndef DAWNNATIVE_NULL_DEVICENULL_H_
+#define DAWNNATIVE_NULL_DEVICENULL_H_
#include "dawn_native/BindGroup.h"
#include "dawn_native/BindGroupLayout.h"
-#include "dawn_native/BlendState.h"
#include "dawn_native/Buffer.h"
#include "dawn_native/CommandBuffer.h"
#include "dawn_native/ComputePipeline.h"
-#include "dawn_native/DepthStencilState.h"
#include "dawn_native/Device.h"
#include "dawn_native/InputState.h"
#include "dawn_native/PipelineLayout.h"
@@ -35,17 +31,16 @@
#include "dawn_native/SwapChain.h"
#include "dawn_native/Texture.h"
#include "dawn_native/ToBackend.h"
+#include "dawn_native/dawn_platform.h"
namespace dawn_native { namespace null {
+ class Adapter;
using BindGroup = BindGroupBase;
using BindGroupLayout = BindGroupLayoutBase;
- using BlendState = BlendStateBase;
class Buffer;
- using BufferView = BufferViewBase;
class CommandBuffer;
using ComputePipeline = ComputePipelineBase;
- using DepthStencilState = DepthStencilStateBase;
class Device;
using InputState = InputStateBase;
using PipelineLayout = PipelineLayoutBase;
@@ -59,14 +54,12 @@ namespace dawn_native { namespace null {
using TextureView = TextureViewBase;
struct NullBackendTraits {
+ using AdapterType = Adapter;
using BindGroupType = BindGroup;
using BindGroupLayoutType = BindGroupLayout;
- using BlendStateType = BlendState;
using BufferType = Buffer;
- using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
- using DepthStencilStateType = DepthStencilState;
using DeviceType = Device;
using InputStateType = InputState;
using PipelineLayoutType = PipelineLayout;
@@ -92,28 +85,25 @@ namespace dawn_native { namespace null {
class Device : public DeviceBase {
public:
- Device();
+ Device(Adapter* adapter);
~Device();
- BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
- BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
- BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
- DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override;
- RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
+ Serial GetCompletedCommandSerial() const final override;
+ Serial GetLastSubmittedCommandSerial() const final override;
void TickImpl() override;
- const dawn_native::PCIInfo& GetPCIInfo() const override;
-
void AddPendingOperation(std::unique_ptr<PendingOperation> operation);
- std::vector<std::unique_ptr<PendingOperation>> AcquirePendingOperations();
+ void SubmitPendingOperations();
private:
+ ResultOrError<BindGroupBase*> CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) override;
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
@@ -122,6 +112,8 @@ namespace dawn_native { namespace null {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override;
+ ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
@@ -129,10 +121,10 @@ namespace dawn_native { namespace null {
ResultOrError<TextureViewBase*> CreateTextureViewImpl(
TextureBase* texture,
const TextureViewDescriptor* descriptor) override;
- void InitFakePCIInfo();
+ Serial mCompletedSerial = 0;
+ Serial mLastSubmittedSerial = 0;
std::vector<std::unique_ptr<PendingOperation>> mPendingOperations;
- dawn_native::PCIInfo mPCIInfo;
};
class Buffer : public BufferBase {
@@ -181,6 +173,19 @@ namespace dawn_native { namespace null {
void OnBeforePresent(TextureBase*) override;
};
+ class NativeSwapChainImpl {
+ public:
+ using WSIContext = struct {};
+ void Init(WSIContext* context);
+ dawnSwapChainError Configure(dawnTextureFormat format,
+ dawnTextureUsageBit,
+ uint32_t width,
+ uint32_t height);
+ dawnSwapChainError GetNextTexture(dawnSwapChainNextTexture* nextTexture);
+ dawnSwapChainError Present();
+ dawn::TextureFormat GetPreferredFormat() const;
+ };
+
}} // namespace dawn_native::null
-#endif // DAWNNATIVE_NULL_NULLBACKEND_H_
+#endif // DAWNNATIVE_NULL_DEVICENULL_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/null/NullBackend.cpp b/chromium/third_party/dawn/src/dawn_native/null/NullBackend.cpp
index 86fbca71e96..7f66df0242a 100644
--- a/chromium/third_party/dawn/src/dawn_native/null/NullBackend.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/null/NullBackend.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 The Dawn Authors
+// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,218 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "dawn_native/null/NullBackend.h"
+// NullBackend.cpp: contains the definition of symbols exported by NullBackend.h so that they
+// can be compiled twice: once export (shared library), once not exported (static library)
-#include "dawn_native/Commands.h"
#include "dawn_native/NullBackend.h"
-#include <spirv-cross/spirv_cross.hpp>
+#include "common/SwapChainUtils.h"
+#include "dawn_native/null/DeviceNull.h"
namespace dawn_native { namespace null {
- dawnDevice CreateDevice() {
- return reinterpret_cast<dawnDevice>(new Device);
- }
-
- // Device
-
- Device::Device() {
- InitFakePCIInfo();
- }
-
- Device::~Device() {
- }
-
- BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
- return new BindGroup(builder);
- }
- ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
- const BindGroupLayoutDescriptor* descriptor) {
- return new BindGroupLayout(this, descriptor);
- }
- BlendStateBase* Device::CreateBlendState(BlendStateBuilder* builder) {
- return new BlendState(builder);
- }
- ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
- return new Buffer(this, descriptor);
- }
- BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
- return new BufferView(builder);
- }
- CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
- return new CommandBuffer(builder);
- }
- ResultOrError<ComputePipelineBase*> Device::CreateComputePipelineImpl(
- const ComputePipelineDescriptor* descriptor) {
- return new ComputePipeline(this, descriptor);
- }
- DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
- return new DepthStencilState(builder);
- }
- InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
- return new InputState(builder);
- }
- ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
- const PipelineLayoutDescriptor* descriptor) {
- return new PipelineLayout(this, descriptor);
- }
- ResultOrError<QueueBase*> Device::CreateQueueImpl() {
- return new Queue(this);
- }
- RenderPassDescriptorBase* Device::CreateRenderPassDescriptor(
- RenderPassDescriptorBuilder* builder) {
- return new RenderPassDescriptor(builder);
- }
- RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
- return new RenderPipeline(builder);
- }
- ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
- return new Sampler(this, descriptor);
- }
- ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl(
- const ShaderModuleDescriptor* descriptor) {
- auto module = new ShaderModule(this, descriptor);
-
- spirv_cross::Compiler compiler(descriptor->code, descriptor->codeSize);
- module->ExtractSpirvInfo(compiler);
-
- return module;
- }
- SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) {
- return new SwapChain(builder);
- }
- ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
- return new Texture(this, descriptor);
- }
- ResultOrError<TextureViewBase*> Device::CreateTextureViewImpl(
- TextureBase* texture,
- const TextureViewDescriptor* descriptor) {
- return new TextureView(texture, descriptor);
- }
-
- void Device::InitFakePCIInfo() {
- mPCIInfo.name = "Null backend";
- }
-
- const dawn_native::PCIInfo& Device::GetPCIInfo() const {
- return mPCIInfo;
- }
-
- void Device::TickImpl() {
- }
-
- void Device::AddPendingOperation(std::unique_ptr<PendingOperation> operation) {
- mPendingOperations.emplace_back(std::move(operation));
- }
- std::vector<std::unique_ptr<PendingOperation>> Device::AcquirePendingOperations() {
- return std::move(mPendingOperations);
- }
-
- // Buffer
-
- struct BufferMapReadOperation : PendingOperation {
- virtual void Execute() {
- buffer->MapReadOperationCompleted(serial, ptr, isWrite);
- }
-
- Ref<Buffer> buffer;
- void* ptr;
- uint32_t serial;
- bool isWrite;
- };
-
- Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)
- : BufferBase(device, descriptor) {
- if (GetUsage() & (dawn::BufferUsageBit::TransferDst | dawn::BufferUsageBit::MapRead |
- dawn::BufferUsageBit::MapWrite)) {
- mBackingData = std::unique_ptr<char[]>(new char[GetSize()]);
- }
- }
-
- Buffer::~Buffer() {
- }
-
- void Buffer::MapReadOperationCompleted(uint32_t serial, void* ptr, bool isWrite) {
- if (isWrite) {
- CallMapWriteCallback(serial, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, ptr);
- } else {
- CallMapReadCallback(serial, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, ptr);
- }
- }
-
- void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) {
- ASSERT(start + count <= GetSize());
- ASSERT(mBackingData);
- memcpy(mBackingData.get() + start, data, count);
- }
-
- void Buffer::MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) {
- MapAsyncImplCommon(serial, start, count, false);
- }
-
- void Buffer::MapWriteAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) {
- MapAsyncImplCommon(serial, start, count, true);
- }
-
- void Buffer::MapAsyncImplCommon(uint32_t serial, uint32_t start, uint32_t count, bool isWrite) {
- ASSERT(start + count <= GetSize());
- ASSERT(mBackingData);
-
- auto operation = new BufferMapReadOperation;
- operation->buffer = this;
- operation->ptr = mBackingData.get() + start;
- operation->serial = serial;
- operation->isWrite = isWrite;
-
- ToBackend(GetDevice())->AddPendingOperation(std::unique_ptr<PendingOperation>(operation));
- }
-
- void Buffer::UnmapImpl() {
- }
-
- // CommandBuffer
-
- CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
- : CommandBufferBase(builder), mCommands(builder->AcquireCommands()) {
- }
-
- CommandBuffer::~CommandBuffer() {
- FreeCommands(&mCommands);
- }
-
- // Queue
-
- Queue::Queue(Device* device) : QueueBase(device) {
- }
-
- Queue::~Queue() {
- }
-
- void Queue::SubmitImpl(uint32_t, CommandBufferBase* const*) {
- auto operations = ToBackend(GetDevice())->AcquirePendingOperations();
-
- for (auto& operation : operations) {
- operation->Execute();
- }
-
- operations.clear();
- }
-
- // SwapChain
-
- SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) {
- const auto& im = GetImplementation();
- im.Init(im.userData, nullptr);
- }
-
- SwapChain::~SwapChain() {
- }
-
- TextureBase* SwapChain::GetNextTextureImpl(const TextureDescriptor* descriptor) {
- return GetDevice()->CreateTexture(descriptor);
- }
-
- void SwapChain::OnBeforePresent(TextureBase*) {
+ dawnSwapChainImplementation CreateNativeSwapChainImpl() {
+ dawnSwapChainImplementation impl;
+ impl = CreateSwapChainImplementation(new NativeSwapChainImpl());
+ impl.textureUsage = DAWN_TEXTURE_USAGE_BIT_PRESENT;
+ return impl;
}
}} // namespace dawn_native::null
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.cpp
new file mode 100644
index 00000000000..1b80d678e5f
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.cpp
@@ -0,0 +1,86 @@
+// Copyright 2019 The Dawn 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_native/opengl/BackendGL.h"
+
+#include "dawn_native/OpenGLBackend.h"
+#include "dawn_native/opengl/DeviceGL.h"
+
+namespace dawn_native { namespace opengl {
+
+ // The OpenGL backend's Adapter.
+
+ class Adapter : public AdapterBase {
+ public:
+ Adapter(InstanceBase* instance, const AdapterDiscoveryOptions* options)
+ : AdapterBase(instance, BackendType::OpenGL) {
+ // Use getProc to populate GLAD.
+ gladLoadGLLoader(reinterpret_cast<GLADloadproc>(options->getProc));
+
+ // Set state that never changes between devices.
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
+
+ mPCIInfo.name = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
+ }
+ virtual ~Adapter() = default;
+
+ private:
+ ResultOrError<DeviceBase*> CreateDeviceImpl() override {
+ // There is no limit on the number of devices created from this adapter because they can
+ // all share the same backing OpenGL context.
+ return {new Device(this)};
+ }
+ };
+
+ // Implementation of the OpenGL backend's BackendConnection
+
+ Backend::Backend(InstanceBase* instance) : BackendConnection(instance, BackendType::OpenGL) {
+ }
+
+ std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
+ // The OpenGL backend needs at least "getProcAddress" to discover an adapter.
+ return {};
+ }
+
+ ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> Backend::DiscoverAdapters(
+ const AdapterDiscoveryOptionsBase* optionsBase) {
+ // TODO(cwallez@chromium.org): For now we can only create a single adapter because glad uses
+ // static variables to store the pointers to OpenGL procs. Also, if we could create
+ // multiple adapters, we would need to figure out what to do about MakeCurrent.
+ if (mCreatedAdapter) {
+ return DAWN_VALIDATION_ERROR("The OpenGL backend can only create a single adapter");
+ }
+
+ ASSERT(optionsBase->backendType == BackendType::OpenGL);
+ const AdapterDiscoveryOptions* options =
+ reinterpret_cast<const AdapterDiscoveryOptions*>(optionsBase);
+
+ if (options->getProc == nullptr) {
+ return DAWN_VALIDATION_ERROR("AdapterDiscoveryOptions::getProc must be set");
+ }
+
+ std::vector<std::unique_ptr<AdapterBase>> adapters;
+ adapters.push_back(std::make_unique<Adapter>(GetInstance(), options));
+
+ mCreatedAdapter = true;
+ return std::move(adapters);
+ }
+
+ BackendConnection* Connect(InstanceBase* instance) {
+ return new Backend(instance);
+ }
+
+}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/DepthStencilStateGL.h b/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.h
index da06830db7b..eb5923ab3cd 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/DepthStencilStateGL.h
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.h
@@ -1,4 +1,4 @@
-// Copyright 2017 The Dawn Authors
+// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,23 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_OPENGL_DEPTHSTENCILSTATEGL_H_
-#define DAWNNATIVE_OPENGL_DEPTHSTENCILSTATEGL_H_
-
-#include "dawn_native/DepthStencilState.h"
+#include "dawn_native/BackendConnection.h"
namespace dawn_native { namespace opengl {
- class Device;
- class PersistentPipelineState;
-
- class DepthStencilState : public DepthStencilStateBase {
+ class Backend : public BackendConnection {
public:
- DepthStencilState(DepthStencilStateBuilder* builder);
+ Backend(InstanceBase* instance);
- void ApplyNow(PersistentPipelineState& persistentPipelineState) const;
+ std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
+ ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
+ const AdapterDiscoveryOptionsBase* options) override;
+
+ private:
+ bool mCreatedAdapter = false;
};
}} // namespace dawn_native::opengl
-
-#endif // DAWNNATIVE_OPENGL_DEPTHSTENCILSTATEGL_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/BlendStateGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/BlendStateGL.cpp
deleted file mode 100644
index 6460cec282e..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/opengl/BlendStateGL.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2017 The Dawn 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_native/opengl/BlendStateGL.h"
-
-#include "common/Assert.h"
-
-namespace dawn_native { namespace opengl {
-
- namespace {
- GLenum GLBlendFactor(dawn::BlendFactor factor, bool alpha) {
- switch (factor) {
- case dawn::BlendFactor::Zero:
- return GL_ZERO;
- case dawn::BlendFactor::One:
- return GL_ONE;
- case dawn::BlendFactor::SrcColor:
- return GL_SRC_COLOR;
- case dawn::BlendFactor::OneMinusSrcColor:
- return GL_ONE_MINUS_SRC_COLOR;
- case dawn::BlendFactor::SrcAlpha:
- return GL_SRC_ALPHA;
- case dawn::BlendFactor::OneMinusSrcAlpha:
- return GL_ONE_MINUS_SRC_ALPHA;
- case dawn::BlendFactor::DstColor:
- return GL_DST_COLOR;
- case dawn::BlendFactor::OneMinusDstColor:
- return GL_ONE_MINUS_DST_COLOR;
- case dawn::BlendFactor::DstAlpha:
- return GL_DST_ALPHA;
- case dawn::BlendFactor::OneMinusDstAlpha:
- return GL_ONE_MINUS_DST_ALPHA;
- case dawn::BlendFactor::SrcAlphaSaturated:
- return GL_SRC_ALPHA_SATURATE;
- case dawn::BlendFactor::BlendColor:
- return alpha ? GL_CONSTANT_ALPHA : GL_CONSTANT_COLOR;
- case dawn::BlendFactor::OneMinusBlendColor:
- return alpha ? GL_ONE_MINUS_CONSTANT_ALPHA : GL_ONE_MINUS_CONSTANT_COLOR;
- default:
- UNREACHABLE();
- }
- }
-
- GLenum GLBlendMode(dawn::BlendOperation operation) {
- switch (operation) {
- case dawn::BlendOperation::Add:
- return GL_FUNC_ADD;
- case dawn::BlendOperation::Subtract:
- return GL_FUNC_SUBTRACT;
- case dawn::BlendOperation::ReverseSubtract:
- return GL_FUNC_REVERSE_SUBTRACT;
- case dawn::BlendOperation::Min:
- return GL_MIN;
- case dawn::BlendOperation::Max:
- return GL_MAX;
- default:
- UNREACHABLE();
- }
- }
- } // namespace
-
- BlendState::BlendState(BlendStateBuilder* builder) : BlendStateBase(builder) {
- }
-
- void BlendState::ApplyNow(uint32_t attachment) {
- const auto& info = GetBlendInfo();
-
- if (info.blendEnabled) {
- glEnablei(GL_BLEND, attachment);
- glBlendEquationSeparatei(attachment, GLBlendMode(info.colorBlend.operation),
- GLBlendMode(info.alphaBlend.operation));
- glBlendFuncSeparatei(attachment, GLBlendFactor(info.colorBlend.srcFactor, false),
- GLBlendFactor(info.colorBlend.dstFactor, false),
- GLBlendFactor(info.alphaBlend.srcFactor, true),
- GLBlendFactor(info.alphaBlend.dstFactor, true));
- } else {
- glDisablei(GL_BLEND, attachment);
- }
- glColorMaski(attachment, info.colorWriteMask & dawn::ColorWriteMask::Red,
- info.colorWriteMask & dawn::ColorWriteMask::Green,
- info.colorWriteMask & dawn::ColorWriteMask::Blue,
- info.colorWriteMask & dawn::ColorWriteMask::Alpha);
- }
-
-}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.cpp
index 6f2387bdad7..e14307f4563 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.cpp
@@ -57,9 +57,4 @@ namespace dawn_native { namespace opengl {
glUnmapBuffer(GL_ARRAY_BUFFER);
}
- // BufferView
-
- BufferView::BufferView(BufferViewBuilder* builder) : BufferViewBase(builder) {
- }
-
}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.h b/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.h
index 98c3d1e8ebf..497beec991b 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.h
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.h
@@ -38,11 +38,6 @@ namespace dawn_native { namespace opengl {
GLuint mBuffer = 0;
};
- class BufferView : public BufferViewBase {
- public:
- BufferView(BufferViewBuilder* builder);
- };
-
}} // namespace dawn_native::opengl
#endif // DAWNNATIVE_OPENGL_BUFFERGL_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/CommandBufferGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/CommandBufferGL.cpp
index ec03c77995f..d0761852b6e 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/CommandBufferGL.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/CommandBufferGL.cpp
@@ -235,21 +235,21 @@ namespace dawn_native { namespace opengl {
const auto& indices = pipelineLayout->GetBindingIndexInfo()[index];
const auto& layout = group->GetLayout()->GetBindingInfo();
- for (uint32_t binding : IterateBitSet(layout.mask)) {
- switch (layout.types[binding]) {
+ for (uint32_t bindingIndex : IterateBitSet(layout.mask)) {
+ switch (layout.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer: {
- BufferView* view = ToBackend(group->GetBindingAsBufferView(binding));
- GLuint buffer = ToBackend(view->GetBuffer())->GetHandle();
- GLuint uboIndex = indices[binding];
+ BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
+ GLuint buffer = ToBackend(binding.buffer)->GetHandle();
+ GLuint uboIndex = indices[bindingIndex];
- glBindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, view->GetOffset(),
- view->GetSize());
+ glBindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, binding.offset,
+ binding.size);
} break;
case dawn::BindingType::Sampler: {
GLuint sampler =
- ToBackend(group->GetBindingAsSampler(binding))->GetHandle();
- GLuint samplerIndex = indices[binding];
+ ToBackend(group->GetBindingAsSampler(bindingIndex))->GetHandle();
+ GLuint samplerIndex = indices[bindingIndex];
for (auto unit : pipeline->GetTextureUnitsForSampler(samplerIndex)) {
glBindSampler(unit, sampler);
@@ -257,10 +257,10 @@ namespace dawn_native { namespace opengl {
} break;
case dawn::BindingType::SampledTexture: {
- TextureView* view = ToBackend(group->GetBindingAsTextureView(binding));
+ TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
GLuint handle = view->GetHandle();
GLenum target = view->GetGLTarget();
- GLuint viewIndex = indices[binding];
+ GLuint viewIndex = indices[bindingIndex];
for (auto unit : pipeline->GetTextureUnitsForTextureView(viewIndex)) {
glActiveTexture(GL_TEXTURE0 + unit);
@@ -269,12 +269,12 @@ namespace dawn_native { namespace opengl {
} break;
case dawn::BindingType::StorageBuffer: {
- BufferView* view = ToBackend(group->GetBindingAsBufferView(binding));
- GLuint buffer = ToBackend(view->GetBuffer())->GetHandle();
- GLuint ssboIndex = indices[binding];
+ BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
+ GLuint buffer = ToBackend(binding.buffer)->GetHandle();
+ GLuint ssboIndex = indices[bindingIndex];
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer,
- view->GetOffset(), view->GetSize());
+ binding.offset, binding.size);
} break;
}
}
@@ -321,6 +321,7 @@ namespace dawn_native { namespace opengl {
CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
auto& src = copy->source;
auto& dst = copy->destination;
+ auto& copySize = copy->copySize;
Buffer* buffer = ToBackend(src.buffer.Get());
Texture* texture = ToBackend(dst.texture.Get());
GLenum target = texture->GetGLTarget();
@@ -331,18 +332,19 @@ namespace dawn_native { namespace opengl {
glBindTexture(target, texture->GetHandle());
glPixelStorei(GL_UNPACK_ROW_LENGTH,
- copy->rowPitch / TextureFormatPixelSize(texture->GetFormat()));
+ src.rowPitch / TextureFormatPixelSize(texture->GetFormat()));
+ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.imageHeight);
switch (texture->GetDimension()) {
case dawn::TextureDimension::e2D:
if (texture->GetArrayLayers() > 1) {
glTexSubImage3D(
- target, dst.level, dst.x, dst.y, dst.slice, dst.width,
- dst.height, 1, format.format, format.type,
+ target, dst.level, dst.origin.x, dst.origin.y, dst.slice,
+ copySize.width, copySize.height, 1, format.format, format.type,
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
} else {
glTexSubImage2D(
- target, dst.level, dst.x, dst.y, dst.width, dst.height,
- format.format, format.type,
+ target, dst.level, dst.origin.x, dst.origin.y, copySize.width,
+ copySize.height, format.format, format.type,
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
}
break;
@@ -351,6 +353,7 @@ namespace dawn_native { namespace opengl {
UNREACHABLE();
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
} break;
@@ -359,6 +362,7 @@ namespace dawn_native { namespace opengl {
CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
auto& src = copy->source;
auto& dst = copy->destination;
+ auto& copySize = copy->copySize;
Texture* texture = ToBackend(src.texture.Get());
Buffer* buffer = ToBackend(dst.buffer.Get());
auto format = texture->GetGLFormat();
@@ -390,12 +394,14 @@ namespace dawn_native { namespace opengl {
glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
glPixelStorei(GL_PACK_ROW_LENGTH,
- copy->rowPitch / TextureFormatPixelSize(texture->GetFormat()));
- ASSERT(src.depth == 1 && src.z == 0);
+ dst.rowPitch / TextureFormatPixelSize(texture->GetFormat()));
+ glPixelStorei(GL_PACK_IMAGE_HEIGHT, dst.imageHeight);
+ ASSERT(copySize.depth == 1 && src.origin.z == 0);
void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
- glReadPixels(src.x, src.y, src.width, src.height, format.format, format.type,
- offset);
+ glReadPixels(src.origin.x, src.origin.y, copySize.width, copySize.height,
+ format.format, format.type, offset);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glDeleteFramebuffers(1, &readFBO);
@@ -482,8 +488,14 @@ namespace dawn_native { namespace opengl {
GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
// Attach color buffers.
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
- texture, 0);
+ if (textureView->GetTexture()->GetArrayLayers() == 1) {
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+ GL_TEXTURE_2D, texture, textureView->GetBaseMipLevel());
+ } else {
+ glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+ texture, textureView->GetBaseMipLevel(),
+ textureView->GetBaseArrayLayer());
+ }
drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
attachmentCount = i + 1;
@@ -581,8 +593,8 @@ namespace dawn_native { namespace opengl {
return;
} break;
- case Command::DrawArrays: {
- DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>();
+ case Command::Draw: {
+ DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
pushConstants.Apply(lastPipeline, lastPipeline);
inputBuffers.Apply();
@@ -598,8 +610,8 @@ namespace dawn_native { namespace opengl {
}
} break;
- case Command::DrawElements: {
- DrawElementsCmd* draw = mCommands.NextCommand<DrawElementsCmd>();
+ case Command::DrawIndexed: {
+ DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
pushConstants.Apply(lastPipeline, lastPipeline);
inputBuffers.Apply();
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/DepthStencilStateGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/DepthStencilStateGL.cpp
deleted file mode 100644
index 03cf76319c8..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/opengl/DepthStencilStateGL.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2017 The Dawn 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_native/opengl/DepthStencilStateGL.h"
-
-#include "common/Assert.h"
-#include "dawn_native/opengl/PersistentPipelineStateGL.h"
-
-namespace dawn_native { namespace opengl {
-
- namespace {
- GLuint OpenGLCompareFunction(dawn::CompareFunction compareFunction) {
- switch (compareFunction) {
- case dawn::CompareFunction::Never:
- return GL_NEVER;
- case dawn::CompareFunction::Less:
- return GL_LESS;
- case dawn::CompareFunction::LessEqual:
- return GL_LEQUAL;
- case dawn::CompareFunction::Greater:
- return GL_GREATER;
- case dawn::CompareFunction::GreaterEqual:
- return GL_GEQUAL;
- case dawn::CompareFunction::NotEqual:
- return GL_NOTEQUAL;
- case dawn::CompareFunction::Equal:
- return GL_EQUAL;
- case dawn::CompareFunction::Always:
- return GL_ALWAYS;
- default:
- UNREACHABLE();
- }
- }
-
- GLuint OpenGLStencilOperation(dawn::StencilOperation stencilOperation) {
- switch (stencilOperation) {
- case dawn::StencilOperation::Keep:
- return GL_KEEP;
- case dawn::StencilOperation::Zero:
- return GL_ZERO;
- case dawn::StencilOperation::Replace:
- return GL_REPLACE;
- case dawn::StencilOperation::Invert:
- return GL_INVERT;
- case dawn::StencilOperation::IncrementClamp:
- return GL_INCR;
- case dawn::StencilOperation::DecrementClamp:
- return GL_DECR;
- case dawn::StencilOperation::IncrementWrap:
- return GL_INCR_WRAP;
- case dawn::StencilOperation::DecrementWrap:
- return GL_DECR_WRAP;
- default:
- UNREACHABLE();
- }
- }
- } // namespace
-
- DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder)
- : DepthStencilStateBase(builder) {
- }
-
- void DepthStencilState::ApplyNow(PersistentPipelineState& persistentPipelineState) const {
- auto& depthInfo = GetDepth();
-
- // Depth writes only occur if depth is enabled
- if (depthInfo.compareFunction == dawn::CompareFunction::Always &&
- !depthInfo.depthWriteEnabled) {
- glDisable(GL_DEPTH_TEST);
- } else {
- glEnable(GL_DEPTH_TEST);
- }
-
- if (depthInfo.depthWriteEnabled) {
- glDepthMask(GL_TRUE);
- } else {
- glDepthMask(GL_FALSE);
- }
-
- glDepthFunc(OpenGLCompareFunction(depthInfo.compareFunction));
-
- if (StencilTestEnabled()) {
- glEnable(GL_STENCIL_TEST);
- } else {
- glDisable(GL_STENCIL_TEST);
- }
-
- auto& stencilInfo = GetStencil();
-
- GLenum backCompareFunction = OpenGLCompareFunction(stencilInfo.back.compareFunction);
- GLenum frontCompareFunction = OpenGLCompareFunction(stencilInfo.front.compareFunction);
- persistentPipelineState.SetStencilFuncsAndMask(backCompareFunction, frontCompareFunction,
- stencilInfo.readMask);
-
- glStencilOpSeparate(GL_BACK, OpenGLStencilOperation(stencilInfo.back.stencilFail),
- OpenGLStencilOperation(stencilInfo.back.depthFail),
- OpenGLStencilOperation(stencilInfo.back.depthStencilPass));
- glStencilOpSeparate(GL_FRONT, OpenGLStencilOperation(stencilInfo.front.stencilFail),
- OpenGLStencilOperation(stencilInfo.front.depthFail),
- OpenGLStencilOperation(stencilInfo.front.depthStencilPass));
-
- glStencilMask(stencilInfo.writeMask);
- }
-
-}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.cpp
index f2dc8bcdae9..934a9b68f33 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.cpp
@@ -14,15 +14,13 @@
#include "dawn_native/opengl/DeviceGL.h"
+#include "dawn_native/BackendConnection.h"
#include "dawn_native/BindGroup.h"
#include "dawn_native/BindGroupLayout.h"
-#include "dawn_native/OpenGLBackend.h"
#include "dawn_native/RenderPassDescriptor.h"
-#include "dawn_native/opengl/BlendStateGL.h"
#include "dawn_native/opengl/BufferGL.h"
#include "dawn_native/opengl/CommandBufferGL.h"
#include "dawn_native/opengl/ComputePipelineGL.h"
-#include "dawn_native/opengl/DepthStencilStateGL.h"
#include "dawn_native/opengl/InputStateGL.h"
#include "dawn_native/opengl/PipelineLayoutGL.h"
#include "dawn_native/opengl/QueueGL.h"
@@ -34,38 +32,31 @@
namespace dawn_native { namespace opengl {
- dawnDevice CreateDevice(void* (*getProc)(const char*)) {
- gladLoadGLLoader(reinterpret_cast<GLADloadproc>(getProc));
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_SCISSOR_TEST);
- glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
-
- return reinterpret_cast<dawnDevice>(new Device);
+ Device::Device(AdapterBase* adapter) : DeviceBase(adapter) {
}
- // Device
+ Device::~Device() {
+ CheckPassedFences();
+ ASSERT(mFencesInFlight.empty());
- Device::Device() {
- CollectPCIInfo();
+ // Some operations might have been started since the last submit and waiting
+ // on a serial that doesn't have a corresponding fence enqueued. Force all
+ // operations to look as if they were completed (because they were).
+ mCompletedSerial = mLastSubmittedSerial + 1;
+ Tick();
}
- BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
- return new BindGroup(builder);
+ ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) {
+ return new BindGroup(this, descriptor);
}
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return new BindGroupLayout(this, descriptor);
}
- BlendStateBase* Device::CreateBlendState(BlendStateBuilder* builder) {
- return new BlendState(builder);
- }
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
- BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
- return new BufferView(builder);
- }
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}
@@ -73,9 +64,6 @@ namespace dawn_native { namespace opengl {
const ComputePipelineDescriptor* descriptor) {
return new ComputePipeline(this, descriptor);
}
- DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
- return new DepthStencilState(builder);
- }
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputState(builder);
}
@@ -90,8 +78,9 @@ namespace dawn_native { namespace opengl {
RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder);
}
- RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
- return new RenderPipeline(builder);
+ ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) {
+ return new RenderPipeline(this, descriptor);
}
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor);
@@ -112,15 +101,47 @@ namespace dawn_native { namespace opengl {
return new TextureView(texture, descriptor);
}
- void Device::TickImpl() {
+ void Device::SubmitFenceSync() {
+ GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ mLastSubmittedSerial++;
+ mFencesInFlight.emplace(sync, mLastSubmittedSerial);
+ }
+
+ Serial Device::GetCompletedCommandSerial() const {
+ return mCompletedSerial;
}
- const dawn_native::PCIInfo& Device::GetPCIInfo() const {
- return mPCIInfo;
+ Serial Device::GetLastSubmittedCommandSerial() const {
+ return mLastSubmittedSerial;
}
- void Device::CollectPCIInfo() {
- mPCIInfo.name = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
+ void Device::TickImpl() {
+ CheckPassedFences();
+ }
+
+ void Device::CheckPassedFences() {
+ while (!mFencesInFlight.empty()) {
+ GLsync sync = mFencesInFlight.front().first;
+ Serial fenceSerial = mFencesInFlight.front().second;
+
+ GLint status = 0;
+ GLsizei length;
+ glGetSynciv(sync, GL_SYNC_CONDITION, sizeof(GLint), &length, &status);
+ ASSERT(length == 1);
+
+ // Fence are added in order, so we can stop searching as soon
+ // as we see one that's not ready.
+ if (!status) {
+ return;
+ }
+
+ glDeleteSync(sync);
+
+ mFencesInFlight.pop();
+
+ ASSERT(fenceSerial > mCompletedSerial);
+ mCompletedSerial = fenceSerial;
+ }
}
}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.h b/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.h
index 2b39db54e43..192b9f2d0db 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.h
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.h
@@ -23,6 +23,8 @@
#include "glad/glad.h"
+#include <queue>
+
// Remove windows.h macros after glad's include of windows.h
#if defined(DAWN_PLATFORM_WINDOWS)
# include "common/windows_with_undefs.h"
@@ -32,23 +34,25 @@ namespace dawn_native { namespace opengl {
class Device : public DeviceBase {
public:
- Device();
- BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
- BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
- BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
+ Device(AdapterBase* adapter);
+ ~Device();
+
+ void SubmitFenceSync();
+
+ // Dawn API
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
- DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override;
- RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
+ Serial GetCompletedCommandSerial() const final override;
+ Serial GetLastSubmittedCommandSerial() const final override;
void TickImpl() override;
- const dawn_native::PCIInfo& GetPCIInfo() const override;
-
private:
+ ResultOrError<BindGroupBase*> CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) override;
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
@@ -57,6 +61,8 @@ namespace dawn_native { namespace opengl {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override;
+ ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
@@ -64,9 +70,12 @@ namespace dawn_native { namespace opengl {
ResultOrError<TextureViewBase*> CreateTextureViewImpl(
TextureBase* texture,
const TextureViewDescriptor* descriptor) override;
- void CollectPCIInfo();
- dawn_native::PCIInfo mPCIInfo;
+ void CheckPassedFences();
+
+ Serial mCompletedSerial = 0;
+ Serial mLastSubmittedSerial = 0;
+ std::queue<std::pair<GLsync, Serial>> mFencesInFlight;
};
}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/Forward.h b/chromium/third_party/dawn/src/dawn_native/opengl/Forward.h
index 154919fa853..486bb13917c 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/Forward.h
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/Forward.h
@@ -25,14 +25,12 @@ namespace {
namespace dawn_native { namespace opengl {
+ class Adapter;
using BindGroup = BindGroupBase;
using BindGroupLayout = BindGroupLayoutBase;
- class BlendState;
class Buffer;
- class BufferView;
class CommandBuffer;
class ComputePipeline;
- class DepthStencilState;
class Device;
class InputState;
class PersistentPipelineState;
@@ -47,14 +45,12 @@ namespace dawn_native { namespace opengl {
class TextureView;
struct OpenGLBackendTraits {
+ using AdapterType = Adapter;
using BindGroupType = BindGroup;
using BindGroupLayoutType = BindGroupLayout;
- using BlendStateType = BlendState;
using BufferType = Buffer;
- using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
- using DepthStencilStateType = DepthStencilState;
using DeviceType = Device;
using InputStateType = InputState;
using PipelineLayoutType = PipelineLayout;
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/OpenGLBackend.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/OpenGLBackend.cpp
new file mode 100644
index 00000000000..f91518991e7
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/OpenGLBackend.cpp
@@ -0,0 +1,28 @@
+// Copyright 2019 The Dawn 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.
+
+// OpenGLBackend.cpp: contains the definition of symbols exported by OpenGLBackend.h so that they
+// can be compiled twice: once export (shared library), once not exported (static library)
+
+#include "dawn_native/OpenGLBackend.h"
+
+#include "dawn_native/opengl/DeviceGL.h"
+
+namespace dawn_native { namespace opengl {
+
+ AdapterDiscoveryOptions::AdapterDiscoveryOptions()
+ : AdapterDiscoveryOptionsBase(BackendType::OpenGL) {
+ }
+
+}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/QueueGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/QueueGL.cpp
index ad171603073..a03fb180df2 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/QueueGL.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/QueueGL.cpp
@@ -23,9 +23,13 @@ namespace dawn_native { namespace opengl {
}
void Queue::SubmitImpl(uint32_t numCommands, CommandBufferBase* const* commands) {
+ Device* device = ToBackend(GetDevice());
+
for (uint32_t i = 0; i < numCommands; ++i) {
ToBackend(commands[i])->Execute();
}
+
+ device->SubmitFenceSync();
}
}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.cpp
index f6faca0a760..10b4d37d7b5 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.cpp
@@ -14,11 +14,11 @@
#include "dawn_native/opengl/RenderPipelineGL.h"
-#include "dawn_native/opengl/BlendStateGL.h"
-#include "dawn_native/opengl/DepthStencilStateGL.h"
+#include "dawn_native/opengl/DeviceGL.h"
#include "dawn_native/opengl/Forward.h"
#include "dawn_native/opengl/InputStateGL.h"
#include "dawn_native/opengl/PersistentPipelineStateGL.h"
+#include "dawn_native/opengl/UtilsGL.h"
namespace dawn_native { namespace opengl {
@@ -39,15 +39,146 @@ namespace dawn_native { namespace opengl {
UNREACHABLE();
}
}
- } // namespace
- RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
- : RenderPipelineBase(builder),
+ GLenum GLBlendFactor(dawn::BlendFactor factor, bool alpha) {
+ switch (factor) {
+ case dawn::BlendFactor::Zero:
+ return GL_ZERO;
+ case dawn::BlendFactor::One:
+ return GL_ONE;
+ case dawn::BlendFactor::SrcColor:
+ return GL_SRC_COLOR;
+ case dawn::BlendFactor::OneMinusSrcColor:
+ return GL_ONE_MINUS_SRC_COLOR;
+ case dawn::BlendFactor::SrcAlpha:
+ return GL_SRC_ALPHA;
+ case dawn::BlendFactor::OneMinusSrcAlpha:
+ return GL_ONE_MINUS_SRC_ALPHA;
+ case dawn::BlendFactor::DstColor:
+ return GL_DST_COLOR;
+ case dawn::BlendFactor::OneMinusDstColor:
+ return GL_ONE_MINUS_DST_COLOR;
+ case dawn::BlendFactor::DstAlpha:
+ return GL_DST_ALPHA;
+ case dawn::BlendFactor::OneMinusDstAlpha:
+ return GL_ONE_MINUS_DST_ALPHA;
+ case dawn::BlendFactor::SrcAlphaSaturated:
+ return GL_SRC_ALPHA_SATURATE;
+ case dawn::BlendFactor::BlendColor:
+ return alpha ? GL_CONSTANT_ALPHA : GL_CONSTANT_COLOR;
+ case dawn::BlendFactor::OneMinusBlendColor:
+ return alpha ? GL_ONE_MINUS_CONSTANT_ALPHA : GL_ONE_MINUS_CONSTANT_COLOR;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ GLenum GLBlendMode(dawn::BlendOperation operation) {
+ switch (operation) {
+ case dawn::BlendOperation::Add:
+ return GL_FUNC_ADD;
+ case dawn::BlendOperation::Subtract:
+ return GL_FUNC_SUBTRACT;
+ case dawn::BlendOperation::ReverseSubtract:
+ return GL_FUNC_REVERSE_SUBTRACT;
+ case dawn::BlendOperation::Min:
+ return GL_MIN;
+ case dawn::BlendOperation::Max:
+ return GL_MAX;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ void ApplyBlendState(uint32_t attachment, const BlendStateDescriptor* descriptor) {
+ if (descriptor->blendEnabled) {
+ glEnablei(GL_BLEND, attachment);
+ glBlendEquationSeparatei(attachment, GLBlendMode(descriptor->colorBlend.operation),
+ GLBlendMode(descriptor->alphaBlend.operation));
+ glBlendFuncSeparatei(attachment,
+ GLBlendFactor(descriptor->colorBlend.srcFactor, false),
+ GLBlendFactor(descriptor->colorBlend.dstFactor, false),
+ GLBlendFactor(descriptor->alphaBlend.srcFactor, true),
+ GLBlendFactor(descriptor->alphaBlend.dstFactor, true));
+ } else {
+ glDisablei(GL_BLEND, attachment);
+ }
+ glColorMaski(attachment, descriptor->colorWriteMask & dawn::ColorWriteMask::Red,
+ descriptor->colorWriteMask & dawn::ColorWriteMask::Green,
+ descriptor->colorWriteMask & dawn::ColorWriteMask::Blue,
+ descriptor->colorWriteMask & dawn::ColorWriteMask::Alpha);
+ }
+
+ GLuint OpenGLStencilOperation(dawn::StencilOperation stencilOperation) {
+ switch (stencilOperation) {
+ case dawn::StencilOperation::Keep:
+ return GL_KEEP;
+ case dawn::StencilOperation::Zero:
+ return GL_ZERO;
+ case dawn::StencilOperation::Replace:
+ return GL_REPLACE;
+ case dawn::StencilOperation::Invert:
+ return GL_INVERT;
+ case dawn::StencilOperation::IncrementClamp:
+ return GL_INCR;
+ case dawn::StencilOperation::DecrementClamp:
+ return GL_DECR;
+ case dawn::StencilOperation::IncrementWrap:
+ return GL_INCR_WRAP;
+ case dawn::StencilOperation::DecrementWrap:
+ return GL_DECR_WRAP;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ void ApplyDepthStencilState(const DepthStencilStateDescriptor* descriptor,
+ PersistentPipelineState* persistentPipelineState) {
+ // Depth writes only occur if depth is enabled
+ if (descriptor->depthCompare == dawn::CompareFunction::Always &&
+ !descriptor->depthWriteEnabled) {
+ glDisable(GL_DEPTH_TEST);
+ } else {
+ glEnable(GL_DEPTH_TEST);
+ }
+
+ if (descriptor->depthWriteEnabled) {
+ glDepthMask(GL_TRUE);
+ } else {
+ glDepthMask(GL_FALSE);
+ }
+
+ glDepthFunc(ToOpenGLCompareFunction(descriptor->depthCompare));
+
+ if (StencilTestEnabled(descriptor)) {
+ glEnable(GL_STENCIL_TEST);
+ } else {
+ glDisable(GL_STENCIL_TEST);
+ }
+
+ GLenum backCompareFunction = ToOpenGLCompareFunction(descriptor->back.compare);
+ GLenum frontCompareFunction = ToOpenGLCompareFunction(descriptor->front.compare);
+ persistentPipelineState->SetStencilFuncsAndMask(
+ backCompareFunction, frontCompareFunction, descriptor->stencilReadMask);
+
+ glStencilOpSeparate(GL_BACK, OpenGLStencilOperation(descriptor->back.stencilFailOp),
+ OpenGLStencilOperation(descriptor->back.depthFailOp),
+ OpenGLStencilOperation(descriptor->back.passOp));
+ glStencilOpSeparate(GL_FRONT, OpenGLStencilOperation(descriptor->front.stencilFailOp),
+ OpenGLStencilOperation(descriptor->front.depthFailOp),
+ OpenGLStencilOperation(descriptor->front.passOp));
+
+ glStencilMask(descriptor->stencilWriteMask);
+ }
+
+ } // anonymous namespace
+
+ RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
+ : RenderPipelineBase(device, descriptor),
mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
PerStage<const ShaderModule*> modules(nullptr);
- for (dawn::ShaderStage stage : IterateStages(GetStageMask())) {
- modules[stage] = ToBackend(builder->GetStageInfo(stage).module.Get());
- }
+ modules[dawn::ShaderStage::Vertex] = ToBackend(descriptor->vertexStage->module);
+ modules[dawn::ShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module);
PipelineGL::Initialize(ToBackend(GetLayout()), modules);
}
@@ -62,11 +193,10 @@ namespace dawn_native { namespace opengl {
auto inputState = ToBackend(GetInputState());
glBindVertexArray(inputState->GetVAO());
- auto depthStencilState = ToBackend(GetDepthStencilState());
- depthStencilState->ApplyNow(persistentPipelineState);
+ ApplyDepthStencilState(GetDepthStencilStateDescriptor(), &persistentPipelineState);
for (uint32_t attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
- ToBackend(GetBlendState(attachmentSlot))->ApplyNow(attachmentSlot);
+ ApplyBlendState(attachmentSlot, GetBlendStateDescriptor(attachmentSlot));
}
}
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.h b/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.h
index 042000c558c..28458e0f125 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.h
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.h
@@ -25,11 +25,12 @@
namespace dawn_native { namespace opengl {
+ class Device;
class PersistentPipelineState;
class RenderPipeline : public RenderPipelineBase, public PipelineGL {
public:
- RenderPipeline(RenderPipelineBuilder* builder);
+ RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
GLenum GetGLPrimitiveTopology() const;
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/SamplerGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/SamplerGL.cpp
index ebf47578afc..cb2e0df08b7 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/SamplerGL.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/SamplerGL.cpp
@@ -16,6 +16,7 @@
#include "common/Assert.h"
#include "dawn_native/opengl/DeviceGL.h"
+#include "dawn_native/opengl/UtilsGL.h"
namespace dawn_native { namespace opengl {
@@ -64,11 +65,17 @@ namespace dawn_native { namespace opengl {
return GL_MIRRORED_REPEAT;
case dawn::AddressMode::ClampToEdge:
return GL_CLAMP_TO_EDGE;
+ case dawn::AddressMode::ClampToBorderColor:
+ return GL_CLAMP_TO_BORDER;
default:
UNREACHABLE();
}
}
+ static const float kTransparentBlack[4] = {0.0, 0.0, 0.0, 0.0};
+ static const float kOpaqueBlack[4] = {0.0, 0.0, 0.0, 1.0};
+ static const float kOpaqueWhite[4] = {1.0, 1.0, 1.0, 1.0};
+
} // namespace
Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor)
@@ -80,6 +87,29 @@ namespace dawn_native { namespace opengl {
glSamplerParameteri(mHandle, GL_TEXTURE_WRAP_R, WrapMode(descriptor->addressModeW));
glSamplerParameteri(mHandle, GL_TEXTURE_WRAP_S, WrapMode(descriptor->addressModeU));
glSamplerParameteri(mHandle, GL_TEXTURE_WRAP_T, WrapMode(descriptor->addressModeV));
+
+ glSamplerParameterf(mHandle, GL_TEXTURE_MIN_LOD, descriptor->lodMinClamp);
+ glSamplerParameterf(mHandle, GL_TEXTURE_MAX_LOD, descriptor->lodMaxClamp);
+
+ if (ToOpenGLCompareFunction(descriptor->compareFunction) != GL_NEVER) {
+ glSamplerParameteri(mHandle, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
+ glSamplerParameteri(mHandle, GL_TEXTURE_COMPARE_FUNC,
+ ToOpenGLCompareFunction(descriptor->compareFunction));
+ }
+
+ switch (descriptor->borderColor) {
+ case dawn::BorderColor::TransparentBlack:
+ glSamplerParameterfv(mHandle, GL_TEXTURE_BORDER_COLOR, kTransparentBlack);
+ break;
+ case dawn::BorderColor::OpaqueBlack:
+ glSamplerParameterfv(mHandle, GL_TEXTURE_BORDER_COLOR, kOpaqueBlack);
+ break;
+ case dawn::BorderColor::OpaqueWhite:
+ glSamplerParameterfv(mHandle, GL_TEXTURE_BORDER_COLOR, kOpaqueWhite);
+ break;
+ default:
+ UNREACHABLE();
+ }
}
GLuint Sampler::GetHandle() const {
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/UtilsGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/UtilsGL.cpp
new file mode 100644
index 00000000000..0419d4be998
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/UtilsGL.cpp
@@ -0,0 +1,44 @@
+// Copyright 2019 The Dawn 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_native/opengl/UtilsGL.h"
+
+#include "common/Assert.h"
+
+namespace dawn_native { namespace opengl {
+
+ GLuint ToOpenGLCompareFunction(dawn::CompareFunction compareFunction) {
+ switch (compareFunction) {
+ case dawn::CompareFunction::Never:
+ return GL_NEVER;
+ case dawn::CompareFunction::Less:
+ return GL_LESS;
+ case dawn::CompareFunction::LessEqual:
+ return GL_LEQUAL;
+ case dawn::CompareFunction::Greater:
+ return GL_GREATER;
+ case dawn::CompareFunction::GreaterEqual:
+ return GL_GEQUAL;
+ case dawn::CompareFunction::NotEqual:
+ return GL_NOTEQUAL;
+ case dawn::CompareFunction::Equal:
+ return GL_EQUAL;
+ case dawn::CompareFunction::Always:
+ return GL_ALWAYS;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+}} // namespace dawn_native::opengl
diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/BlendStateGL.h b/chromium/third_party/dawn/src/dawn_native/opengl/UtilsGL.h
index afc2bdecf22..f82eb286671 100644
--- a/chromium/third_party/dawn/src/dawn_native/opengl/BlendStateGL.h
+++ b/chromium/third_party/dawn/src/dawn_native/opengl/UtilsGL.h
@@ -1,4 +1,4 @@
-// Copyright 2017 The Dawn Authors
+// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,22 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_OPENGL_BLENDSTATEGL_H_
-#define DAWNNATIVE_OPENGL_BLENDSTATEGL_H_
-
-#include "dawn_native/BlendState.h"
+#ifndef DAWNNATIVE_OPENGL_UTILSGL_H_
+#define DAWNNATIVE_OPENGL_UTILSGL_H_
+#include "dawn_native/dawn_platform.h"
#include "glad/glad.h"
namespace dawn_native { namespace opengl {
- class BlendState : public BlendStateBase {
- public:
- BlendState(BlendStateBuilder* builder);
-
- void ApplyNow(uint32_t attachment);
- };
+ GLuint ToOpenGLCompareFunction(dawn::CompareFunction compareFunction);
}} // namespace dawn_native::opengl
-#endif // DAWNNATIVE_OPENGL_BLENDSTATEGL_H_
+#endif // DAWNNATIVE_OPENGL_UTILSGL_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.cpp
index 49a972c2e0a..c8c92175516 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.cpp
@@ -25,7 +25,8 @@
namespace dawn_native { namespace vulkan {
- BindGroup::BindGroup(BindGroupBuilder* builder) : BindGroupBase(builder) {
+ BindGroup::BindGroup(Device* device, const BindGroupDescriptor* descriptor)
+ : BindGroupBase(device, descriptor) {
// Create a pool to hold our descriptor set.
// TODO(cwallez@chromium.org): This horribly inefficient, find a way to be better, for
// example by having one pool per bind group layout instead.
@@ -40,7 +41,6 @@ namespace dawn_native { namespace vulkan {
createInfo.poolSizeCount = numPoolSizes;
createInfo.pPoolSizes = poolSizes.data();
- Device* device = ToBackend(GetDevice());
if (device->fn.CreateDescriptorPool(device->GetVkDevice(), &createInfo, nullptr, &mPool) !=
VK_SUCCESS) {
ASSERT(false);
@@ -82,12 +82,11 @@ namespace dawn_native { namespace vulkan {
switch (layoutInfo.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::StorageBuffer: {
- BufferViewBase* view = GetBindingAsBufferView(bindingIndex);
- Buffer* buffer = ToBackend(view->GetBuffer());
+ BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
- writeBufferInfo[numWrites].buffer = buffer->GetHandle();
- writeBufferInfo[numWrites].offset = view->GetOffset();
- writeBufferInfo[numWrites].range = view->GetSize();
+ writeBufferInfo[numWrites].buffer = ToBackend(binding.buffer)->GetHandle();
+ writeBufferInfo[numWrites].offset = binding.offset;
+ writeBufferInfo[numWrites].range = binding.size;
write.pBufferInfo = &writeBufferInfo[numWrites];
} break;
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.h
index 9dee3a3bcf2..5071796e284 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.h
@@ -25,7 +25,7 @@ namespace dawn_native { namespace vulkan {
class BindGroup : public BindGroupBase {
public:
- BindGroup(BindGroupBuilder* builder);
+ BindGroup(Device* device, const BindGroupDescriptor* descriptor);
~BindGroup();
VkDescriptorSet GetHandle() const;
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/BlendStateVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/BlendStateVk.cpp
deleted file mode 100644
index cc4911b609f..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/BlendStateVk.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2018 The Dawn 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_native/vulkan/BlendStateVk.h"
-
-#include "common/Assert.h"
-
-namespace dawn_native { namespace vulkan {
-
- namespace {
- VkBlendFactor VulkanBlendFactor(dawn::BlendFactor factor) {
- switch (factor) {
- case dawn::BlendFactor::Zero:
- return VK_BLEND_FACTOR_ZERO;
- case dawn::BlendFactor::One:
- return VK_BLEND_FACTOR_ONE;
- case dawn::BlendFactor::SrcColor:
- return VK_BLEND_FACTOR_SRC_COLOR;
- case dawn::BlendFactor::OneMinusSrcColor:
- return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
- case dawn::BlendFactor::SrcAlpha:
- return VK_BLEND_FACTOR_SRC_ALPHA;
- case dawn::BlendFactor::OneMinusSrcAlpha:
- return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- case dawn::BlendFactor::DstColor:
- return VK_BLEND_FACTOR_DST_COLOR;
- case dawn::BlendFactor::OneMinusDstColor:
- return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
- case dawn::BlendFactor::DstAlpha:
- return VK_BLEND_FACTOR_DST_ALPHA;
- case dawn::BlendFactor::OneMinusDstAlpha:
- return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
- case dawn::BlendFactor::SrcAlphaSaturated:
- return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
- case dawn::BlendFactor::BlendColor:
- return VK_BLEND_FACTOR_CONSTANT_COLOR;
- case dawn::BlendFactor::OneMinusBlendColor:
- return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
- default:
- UNREACHABLE();
- }
- }
-
- VkBlendOp VulkanBlendOperation(dawn::BlendOperation operation) {
- switch (operation) {
- case dawn::BlendOperation::Add:
- return VK_BLEND_OP_ADD;
- case dawn::BlendOperation::Subtract:
- return VK_BLEND_OP_SUBTRACT;
- case dawn::BlendOperation::ReverseSubtract:
- return VK_BLEND_OP_REVERSE_SUBTRACT;
- case dawn::BlendOperation::Min:
- return VK_BLEND_OP_MIN;
- case dawn::BlendOperation::Max:
- return VK_BLEND_OP_MAX;
- default:
- UNREACHABLE();
- }
- }
-
- VkColorComponentFlagBits VulkanColorWriteMask(dawn::ColorWriteMask mask) {
- // Vulkan and Dawn color write masks match, static assert it and return the mask
- static_assert(static_cast<VkColorComponentFlagBits>(dawn::ColorWriteMask::Red) ==
- VK_COLOR_COMPONENT_R_BIT,
- "");
- static_assert(static_cast<VkColorComponentFlagBits>(dawn::ColorWriteMask::Green) ==
- VK_COLOR_COMPONENT_G_BIT,
- "");
- static_assert(static_cast<VkColorComponentFlagBits>(dawn::ColorWriteMask::Blue) ==
- VK_COLOR_COMPONENT_B_BIT,
- "");
- static_assert(static_cast<VkColorComponentFlagBits>(dawn::ColorWriteMask::Alpha) ==
- VK_COLOR_COMPONENT_A_BIT,
- "");
-
- return static_cast<VkColorComponentFlagBits>(mask);
- }
- } // anonymous namespace
-
- BlendState::BlendState(BlendStateBuilder* builder) : BlendStateBase(builder) {
- // Fill the "color blend attachment info" that will be copied in an array and chained in
- // the pipeline create info.
- const auto& info = GetBlendInfo();
-
- mState.blendEnable = info.blendEnabled ? VK_TRUE : VK_FALSE;
- mState.srcColorBlendFactor = VulkanBlendFactor(info.colorBlend.srcFactor);
- mState.dstColorBlendFactor = VulkanBlendFactor(info.colorBlend.dstFactor);
- mState.colorBlendOp = VulkanBlendOperation(info.colorBlend.operation);
- mState.srcAlphaBlendFactor = VulkanBlendFactor(info.alphaBlend.srcFactor);
- mState.dstAlphaBlendFactor = VulkanBlendFactor(info.alphaBlend.dstFactor);
- mState.alphaBlendOp = VulkanBlendOperation(info.alphaBlend.operation);
- mState.colorWriteMask = VulkanColorWriteMask(info.colorWriteMask);
- }
-
- const VkPipelineColorBlendAttachmentState& BlendState::GetState() const {
- return mState;
- }
-
-}} // namespace dawn_native::vulkan
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.cpp
index 3c7d1370b7d..73e15384197 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.cpp
@@ -252,7 +252,7 @@ namespace dawn_native { namespace vulkan {
request.data = data;
request.isWrite = isWrite;
- mInflightRequests.Enqueue(std::move(request), mDevice->GetSerial());
+ mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial());
}
void MapRequestTracker::Tick(Serial finishedSerial) {
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.h
index d2ff4f63ba6..41ef9c40d9d 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.h
@@ -52,8 +52,6 @@ namespace dawn_native { namespace vulkan {
dawn::BufferUsageBit mLastUsage = dawn::BufferUsageBit::None;
};
- using BufferView = BufferViewBase;
-
class MapRequestTracker {
public:
MapRequestTracker(Device* device);
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/CommandBufferVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/CommandBufferVk.cpp
index 8f5c46271c0..74e796490de 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/CommandBufferVk.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/CommandBufferVk.cpp
@@ -39,30 +39,31 @@ namespace dawn_native { namespace vulkan {
}
}
- VkBufferImageCopy ComputeBufferImageCopyRegion(uint32_t rowPitch,
- const BufferCopyLocation& bufferLocation,
- const TextureCopyLocation& textureLocation) {
- const Texture* texture = ToBackend(textureLocation.texture).Get();
+ VkBufferImageCopy ComputeBufferImageCopyRegion(const BufferCopy& bufferCopy,
+ const TextureCopy& textureCopy,
+ const Extent3D& copySize) {
+ const Texture* texture = ToBackend(textureCopy.texture.Get());
VkBufferImageCopy region;
- region.bufferOffset = bufferLocation.offset;
+ region.bufferOffset = bufferCopy.offset;
// In Vulkan the row length is in texels while it is in bytes for Dawn
- region.bufferRowLength = rowPitch / TextureFormatPixelSize(texture->GetFormat());
- region.bufferImageHeight = rowPitch * textureLocation.height;
+ region.bufferRowLength =
+ bufferCopy.rowPitch / TextureFormatPixelSize(texture->GetFormat());
+ region.bufferImageHeight = bufferCopy.imageHeight;
region.imageSubresource.aspectMask = texture->GetVkAspectMask();
- region.imageSubresource.mipLevel = textureLocation.level;
- region.imageSubresource.baseArrayLayer = textureLocation.slice;
+ region.imageSubresource.mipLevel = textureCopy.level;
+ region.imageSubresource.baseArrayLayer = textureCopy.slice;
region.imageSubresource.layerCount = 1;
- region.imageOffset.x = textureLocation.x;
- region.imageOffset.y = textureLocation.y;
- region.imageOffset.z = textureLocation.z;
+ region.imageOffset.x = textureCopy.origin.x;
+ region.imageOffset.y = textureCopy.origin.y;
+ region.imageOffset.z = textureCopy.origin.z;
- region.imageExtent.width = textureLocation.width;
- region.imageExtent.height = textureLocation.height;
- region.imageExtent.depth = textureLocation.depth;
+ region.imageExtent.width = copySize.width;
+ region.imageExtent.height = copySize.height;
+ region.imageExtent.depth = copySize.depth;
return region;
}
@@ -173,7 +174,7 @@ namespace dawn_native { namespace vulkan {
VkImage dstImage = ToBackend(dst.texture)->GetHandle();
VkBufferImageCopy region =
- ComputeBufferImageCopyRegion(copy->rowPitch, src, dst);
+ ComputeBufferImageCopyRegion(src, dst, copy->copySize);
// The image is written to so the Dawn guarantees make sure it is in the
// TRANSFER_DST_OPTIMAL layout
@@ -196,7 +197,7 @@ namespace dawn_native { namespace vulkan {
VkBuffer dstBuffer = ToBackend(dst.buffer)->GetHandle();
VkBufferImageCopy region =
- ComputeBufferImageCopyRegion(copy->rowPitch, dst, src);
+ ComputeBufferImageCopyRegion(dst, src, copy->copySize);
// The Dawn TransferSrc usage is always mapped to GENERAL
device->fn.CmdCopyImageToBuffer(commands, srcImage, VK_IMAGE_LAYOUT_GENERAL,
@@ -319,21 +320,21 @@ namespace dawn_native { namespace vulkan {
return;
} break;
- case Command::DrawArrays: {
- DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>();
+ case Command::Draw: {
+ DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
device->fn.CmdDraw(commands, draw->vertexCount, draw->instanceCount,
draw->firstVertex, draw->firstInstance);
} break;
- case Command::DrawElements: {
- DrawElementsCmd* draw = mCommands.NextCommand<DrawElementsCmd>();
+ case Command::DrawIndexed: {
+ DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
- uint32_t vertexOffset = 0;
device->fn.CmdDrawIndexed(commands, draw->indexCount, draw->instanceCount,
- draw->firstIndex, vertexOffset, draw->firstInstance);
+ draw->firstIndex, draw->baseVertex,
+ draw->firstInstance);
} break;
case Command::SetBindGroup: {
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/DepthStencilStateVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/DepthStencilStateVk.cpp
deleted file mode 100644
index a50bb0d7748..00000000000
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/DepthStencilStateVk.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2018 The Dawn 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_native/vulkan/DepthStencilStateVk.h"
-
-#include "common/Assert.h"
-
-namespace dawn_native { namespace vulkan {
-
- namespace {
- VkCompareOp VulkanCompareOp(dawn::CompareFunction op) {
- switch (op) {
- case dawn::CompareFunction::Always:
- return VK_COMPARE_OP_ALWAYS;
- case dawn::CompareFunction::Equal:
- return VK_COMPARE_OP_EQUAL;
- case dawn::CompareFunction::Greater:
- return VK_COMPARE_OP_GREATER;
- case dawn::CompareFunction::GreaterEqual:
- return VK_COMPARE_OP_GREATER_OR_EQUAL;
- case dawn::CompareFunction::Less:
- return VK_COMPARE_OP_LESS;
- case dawn::CompareFunction::LessEqual:
- return VK_COMPARE_OP_LESS_OR_EQUAL;
- case dawn::CompareFunction::Never:
- return VK_COMPARE_OP_NEVER;
- case dawn::CompareFunction::NotEqual:
- return VK_COMPARE_OP_NOT_EQUAL;
- default:
- UNREACHABLE();
- }
- }
-
- VkStencilOp VulkanStencilOp(dawn::StencilOperation op) {
- switch (op) {
- case dawn::StencilOperation::Keep:
- return VK_STENCIL_OP_KEEP;
- case dawn::StencilOperation::Zero:
- return VK_STENCIL_OP_ZERO;
- case dawn::StencilOperation::Replace:
- return VK_STENCIL_OP_REPLACE;
- case dawn::StencilOperation::IncrementClamp:
- return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
- case dawn::StencilOperation::DecrementClamp:
- return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
- case dawn::StencilOperation::Invert:
- return VK_STENCIL_OP_INVERT;
- case dawn::StencilOperation::IncrementWrap:
- return VK_STENCIL_OP_INCREMENT_AND_WRAP;
- case dawn::StencilOperation::DecrementWrap:
- return VK_STENCIL_OP_DECREMENT_AND_WRAP;
- default:
- UNREACHABLE();
- }
- }
-
- } // anonymous namespace
-
- DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder)
- : DepthStencilStateBase(builder) {
- mCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
- mCreateInfo.pNext = nullptr;
- mCreateInfo.flags = 0;
-
- const auto& depth = GetDepth();
- mCreateInfo.depthTestEnable = VK_TRUE;
- mCreateInfo.depthWriteEnable = depth.depthWriteEnabled ? VK_TRUE : VK_FALSE;
- mCreateInfo.depthCompareOp = VulkanCompareOp(depth.compareFunction);
- mCreateInfo.depthBoundsTestEnable = false;
- mCreateInfo.minDepthBounds = 0.0f;
- mCreateInfo.maxDepthBounds = 0.0f;
-
- const auto& stencil = GetStencil();
- mCreateInfo.stencilTestEnable = StencilTestEnabled() ? VK_TRUE : VK_FALSE;
-
- mCreateInfo.front.failOp = VulkanStencilOp(stencil.front.stencilFail);
- mCreateInfo.front.passOp = VulkanStencilOp(stencil.front.depthStencilPass);
- mCreateInfo.front.depthFailOp = VulkanStencilOp(stencil.front.depthFail);
- mCreateInfo.front.compareOp = VulkanCompareOp(stencil.front.compareFunction);
-
- mCreateInfo.back.failOp = VulkanStencilOp(stencil.back.stencilFail);
- mCreateInfo.back.passOp = VulkanStencilOp(stencil.back.depthStencilPass);
- mCreateInfo.back.depthFailOp = VulkanStencilOp(stencil.back.depthFail);
- mCreateInfo.back.compareOp = VulkanCompareOp(stencil.back.compareFunction);
-
- // Dawn doesn't have separate front and back stencil masks.
- mCreateInfo.front.compareMask = stencil.readMask;
- mCreateInfo.back.compareMask = stencil.readMask;
- mCreateInfo.front.writeMask = stencil.writeMask;
- mCreateInfo.back.writeMask = stencil.writeMask;
-
- // The stencil reference is always dynamic
- mCreateInfo.front.reference = 0;
- mCreateInfo.back.reference = 0;
- }
-
- const VkPipelineDepthStencilStateCreateInfo* DepthStencilState::GetCreateInfo() const {
- return &mCreateInfo;
- }
-
-}} // namespace dawn_native::vulkan
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.cpp
index 5b3b976fa4c..da23c0ac47e 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.cpp
@@ -15,20 +15,17 @@
#include "dawn_native/vulkan/DeviceVk.h"
#include "common/Platform.h"
-#include "common/SwapChainUtils.h"
+#include "dawn_native/BackendConnection.h"
#include "dawn_native/Commands.h"
-#include "dawn_native/VulkanBackend.h"
+#include "dawn_native/ErrorData.h"
#include "dawn_native/vulkan/BindGroupLayoutVk.h"
#include "dawn_native/vulkan/BindGroupVk.h"
-#include "dawn_native/vulkan/BlendStateVk.h"
#include "dawn_native/vulkan/BufferUploader.h"
#include "dawn_native/vulkan/BufferVk.h"
#include "dawn_native/vulkan/CommandBufferVk.h"
#include "dawn_native/vulkan/ComputePipelineVk.h"
-#include "dawn_native/vulkan/DepthStencilStateVk.h"
#include "dawn_native/vulkan/FencedDeleter.h"
#include "dawn_native/vulkan/InputStateVk.h"
-#include "dawn_native/vulkan/NativeSwapChainImplVk.h"
#include "dawn_native/vulkan/PipelineLayoutVk.h"
#include "dawn_native/vulkan/QueueVk.h"
#include "dawn_native/vulkan/RenderPassCache.h"
@@ -38,6 +35,7 @@
#include "dawn_native/vulkan/ShaderModuleVk.h"
#include "dawn_native/vulkan/SwapChainVk.h"
#include "dawn_native/vulkan/TextureVk.h"
+#include "dawn_native/vulkan/VulkanError.h"
#include <spirv-cross/spirv_cross.hpp>
@@ -53,96 +51,61 @@ const char kVulkanLibName[] = "vulkan-1.dll";
namespace dawn_native { namespace vulkan {
- dawnDevice CreateDevice(const std::vector<const char*>& requiredInstanceExtensions) {
- return reinterpret_cast<dawnDevice>(new Device(requiredInstanceExtensions));
+ BackendConnection* Connect(InstanceBase* instance) {
+ return nullptr;
}
- VkInstance GetInstance(dawnDevice device) {
- Device* backendDevice = reinterpret_cast<Device*>(device);
- return backendDevice->GetInstance();
- }
-
- DAWN_NATIVE_EXPORT dawnSwapChainImplementation
- CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHRNative surfaceNative) {
- Device* backendDevice = reinterpret_cast<Device*>(device);
- VkSurfaceKHR surface = VkSurfaceKHR::CreateFromHandle(surfaceNative);
-
- dawnSwapChainImplementation impl;
- impl = CreateSwapChainImplementation(new NativeSwapChainImpl(backendDevice, surface));
- impl.textureUsage = DAWN_TEXTURE_USAGE_BIT_PRESENT;
+ // Device
- return impl;
- }
+ Device::Device() : DeviceBase(nullptr) {
+ MaybeError maybeError = Initialize();
- dawnTextureFormat GetNativeSwapChainPreferredFormat(
- const dawnSwapChainImplementation* swapChain) {
- NativeSwapChainImpl* impl = reinterpret_cast<NativeSwapChainImpl*>(swapChain->userData);
- return static_cast<dawnTextureFormat>(impl->GetPreferredFormat());
+ // In device initialization, the error callback can't have been set yet.
+ // So it's too early to use ConsumedError - consume the error manually.
+ if (DAWN_UNLIKELY(maybeError.IsError())) {
+ ErrorData* error = maybeError.AcquireError();
+ printf("Device initialization error: %s\n", error->GetMessage().c_str());
+ delete error;
+ ASSERT(false);
+ return;
+ }
}
- // Device
-
- Device::Device(const std::vector<const char*>& requiredInstanceExtensions) {
+ MaybeError Device::Initialize() {
if (!mVulkanLib.Open(kVulkanLibName)) {
- ASSERT(false);
- return;
+ return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't open ") + kVulkanLibName);
}
VulkanFunctions* functions = GetMutableFunctions();
+ DAWN_TRY(functions->LoadGlobalProcs(mVulkanLib));
- if (!functions->LoadGlobalProcs(mVulkanLib)) {
- ASSERT(false);
- return;
- }
-
- if (!GatherGlobalInfo(*this, &mGlobalInfo)) {
- ASSERT(false);
- return;
- }
+ DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(*this));
VulkanGlobalKnobs usedGlobalKnobs = {};
- if (!CreateInstance(&usedGlobalKnobs, requiredInstanceExtensions)) {
- ASSERT(false);
- return;
- }
+ DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance());
*static_cast<VulkanGlobalKnobs*>(&mGlobalInfo) = usedGlobalKnobs;
- if (!functions->LoadInstanceProcs(mInstance, usedGlobalKnobs)) {
- ASSERT(false);
- return;
- }
+ DAWN_TRY(functions->LoadInstanceProcs(mInstance, mGlobalInfo));
if (usedGlobalKnobs.debugReport) {
- if (!RegisterDebugReport()) {
- ASSERT(false);
- return;
- }
+ DAWN_TRY(RegisterDebugReport());
}
std::vector<VkPhysicalDevice> physicalDevices;
- if (!GetPhysicalDevices(*this, &physicalDevices) || physicalDevices.empty()) {
- ASSERT(false);
- return;
+ DAWN_TRY_ASSIGN(physicalDevices, GetPhysicalDevices(*this));
+ if (physicalDevices.empty()) {
+ return DAWN_CONTEXT_LOST_ERROR("No physical devices");
}
// TODO(cwallez@chromium.org): Choose the physical device based on ???
mPhysicalDevice = physicalDevices[0];
- if (!GatherDeviceInfo(*this, mPhysicalDevice, &mDeviceInfo)) {
- ASSERT(false);
- return;
- }
+ DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this, mPhysicalDevice));
VulkanDeviceKnobs usedDeviceKnobs = {};
- if (!CreateDevice(&usedDeviceKnobs)) {
- ASSERT(false);
- return;
- }
+ DAWN_TRY_ASSIGN(usedDeviceKnobs, CreateDevice());
*static_cast<VulkanDeviceKnobs*>(&mDeviceInfo) = usedDeviceKnobs;
- if (!functions->LoadDeviceProcs(mVkDevice, usedDeviceKnobs)) {
- ASSERT(false);
- return;
- }
+ DAWN_TRY(functions->LoadDeviceProcs(mVkDevice, mDeviceInfo));
GatherQueueFromDevice();
@@ -155,6 +118,8 @@ namespace dawn_native { namespace vulkan {
mPCIInfo.deviceId = mDeviceInfo.properties.deviceID;
mPCIInfo.vendorId = mDeviceInfo.properties.vendorID;
mPCIInfo.name = mDeviceInfo.properties.deviceName;
+
+ return {};
}
Device::~Device() {
@@ -165,12 +130,27 @@ namespace dawn_native { namespace vulkan {
ASSERT(false);
}
CheckPassedFences();
- ASSERT(mFencesInFlight.empty());
+
+ // Make sure all fences are complete by explicitly waiting on them all
+ while (!mFencesInFlight.empty()) {
+ VkFence fence = mFencesInFlight.front().first;
+ Serial fenceSerial = mFencesInFlight.front().second;
+ ASSERT(fenceSerial > mCompletedSerial);
+
+ VkResult result = VK_TIMEOUT;
+ do {
+ result = fn.WaitForFences(mVkDevice, 1, &fence, true, UINT64_MAX);
+ } while (result == VK_TIMEOUT);
+ fn.DestroyFence(mVkDevice, fence, nullptr);
+
+ mFencesInFlight.pop();
+ mCompletedSerial = fenceSerial;
+ }
// Some operations might have been started since the last submit and waiting
// on a serial that doesn't have a corresponding fence enqueued. Force all
// operations to look as if they were completed (because they were).
- mCompletedSerial = mNextSerial;
+ mCompletedSerial = mLastSubmittedSerial + 1;
Tick();
ASSERT(mCommandsInFlight.Empty());
@@ -214,22 +194,17 @@ namespace dawn_native { namespace vulkan {
}
}
- BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
- return new BindGroup(builder);
+ ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) {
+ return new BindGroup(this, descriptor);
}
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return new BindGroupLayout(this, descriptor);
}
- BlendStateBase* Device::CreateBlendState(BlendStateBuilder* builder) {
- return new BlendState(builder);
- }
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
- BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
- return new BufferView(builder);
- }
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}
@@ -237,9 +212,6 @@ namespace dawn_native { namespace vulkan {
const ComputePipelineDescriptor* descriptor) {
return new ComputePipeline(this, descriptor);
}
- DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
- return new DepthStencilState(builder);
- }
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputState(builder);
}
@@ -254,8 +226,9 @@ namespace dawn_native { namespace vulkan {
RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder);
}
- RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
- return new RenderPipeline(builder);
+ ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) {
+ return new RenderPipeline(this, descriptor);
}
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor);
@@ -277,6 +250,18 @@ namespace dawn_native { namespace vulkan {
return new TextureView(texture, descriptor);
}
+ Serial Device::GetCompletedCommandSerial() const {
+ return mCompletedSerial;
+ }
+
+ Serial Device::GetLastSubmittedCommandSerial() const {
+ return mLastSubmittedSerial;
+ }
+
+ Serial Device::GetPendingCommandSerial() const {
+ return mLastSubmittedSerial + 1;
+ }
+
void Device::TickImpl() {
CheckPassedFences();
RecycleCompletedCommands();
@@ -289,11 +274,11 @@ namespace dawn_native { namespace vulkan {
if (mPendingCommands.pool != VK_NULL_HANDLE) {
SubmitPendingCommands();
- } else if (mCompletedSerial == mNextSerial - 1) {
+ } else if (mCompletedSerial == mLastSubmittedSerial) {
// If there's no GPU work in flight we still need to artificially increment the serial
// so that CPU operations waiting on GPU completion can know they don't have to wait.
mCompletedSerial++;
- mNextSerial++;
+ mLastSubmittedSerial++;
}
}
@@ -345,10 +330,6 @@ namespace dawn_native { namespace vulkan {
return mRenderPassCache.get();
}
- Serial Device::GetSerial() const {
- return mNextSerial;
- }
-
VkCommandBuffer Device::GetPendingCommandBuffer() {
if (mPendingCommands.pool == VK_NULL_HANDLE) {
mPendingCommands = GetUnusedCommands();
@@ -395,36 +376,26 @@ namespace dawn_native { namespace vulkan {
ASSERT(false);
}
- mCommandsInFlight.Enqueue(mPendingCommands, mNextSerial);
+ mLastSubmittedSerial++;
+ mCommandsInFlight.Enqueue(mPendingCommands, mLastSubmittedSerial);
mPendingCommands = CommandPoolAndBuffer();
- mFencesInFlight.emplace(fence, mNextSerial);
+ mFencesInFlight.emplace(fence, mLastSubmittedSerial);
for (VkSemaphore semaphore : mWaitSemaphores) {
mDeleter->DeleteWhenUnused(semaphore);
}
mWaitSemaphores.clear();
-
- mNextSerial++;
}
void Device::AddWaitSemaphore(VkSemaphore semaphore) {
mWaitSemaphores.push_back(semaphore);
}
- bool Device::CreateInstance(VulkanGlobalKnobs* usedKnobs,
- const std::vector<const char*>& requiredExtensions) {
- std::vector<const char*> layersToRequest;
- std::vector<const char*> extensionsToRequest = requiredExtensions;
+ ResultOrError<VulkanGlobalKnobs> Device::CreateInstance() {
+ VulkanGlobalKnobs usedKnobs = {};
- auto AddExtensionIfNotPresent = [](std::vector<const char*>* extensions,
- const char* extension) {
- for (const char* present : *extensions) {
- if (strcmp(present, extension) == 0) {
- return;
- }
- }
- extensions->push_back(extension);
- };
+ std::vector<const char*> layersToRequest;
+ std::vector<const char*> extensionsToRequest;
// vktrace works by instering a layer, but we hide it behind a macro due to the vktrace
// layer crashes when used without vktrace server started, see this vktrace issue:
@@ -434,7 +405,7 @@ namespace dawn_native { namespace vulkan {
#if defined(DAWN_USE_VKTRACE)
if (mGlobalInfo.vktrace) {
layersToRequest.push_back(kLayerNameLunargVKTrace);
- usedKnobs->vktrace = true;
+ usedKnobs.vktrace = true;
}
#endif
// RenderDoc installs a layer at the system level for its capture but we don't want to use
@@ -442,22 +413,44 @@ namespace dawn_native { namespace vulkan {
#if defined(DAWN_USE_RENDERDOC)
if (mGlobalInfo.renderDocCapture) {
layersToRequest.push_back(kLayerNameRenderDocCapture);
- usedKnobs->renderDocCapture = true;
+ usedKnobs.renderDocCapture = true;
}
#endif
#if defined(DAWN_ENABLE_ASSERTS)
if (mGlobalInfo.standardValidation) {
layersToRequest.push_back(kLayerNameLunargStandardValidation);
- usedKnobs->standardValidation = true;
+ usedKnobs.standardValidation = true;
}
if (mGlobalInfo.debugReport) {
- AddExtensionIfNotPresent(&extensionsToRequest, kExtensionNameExtDebugReport);
- usedKnobs->debugReport = true;
+ extensionsToRequest.push_back(kExtensionNameExtDebugReport);
+ usedKnobs.debugReport = true;
}
#endif
+ // Always request all extensions used to create VkSurfaceKHR objects so that they are
+ // always available for embedders looking to create VkSurfaceKHR on our VkInstance.
+ if (mGlobalInfo.macosSurface) {
+ extensionsToRequest.push_back(kExtensionNameMvkMacosSurface);
+ usedKnobs.macosSurface = true;
+ }
if (mGlobalInfo.surface) {
- AddExtensionIfNotPresent(&extensionsToRequest, kExtensionNameKhrSurface);
- usedKnobs->surface = true;
+ extensionsToRequest.push_back(kExtensionNameKhrSurface);
+ usedKnobs.surface = true;
+ }
+ if (mGlobalInfo.waylandSurface) {
+ extensionsToRequest.push_back(kExtensionNameKhrWaylandSurface);
+ usedKnobs.waylandSurface = true;
+ }
+ if (mGlobalInfo.win32Surface) {
+ extensionsToRequest.push_back(kExtensionNameKhrWin32Surface);
+ usedKnobs.win32Surface = true;
+ }
+ if (mGlobalInfo.xcbSurface) {
+ extensionsToRequest.push_back(kExtensionNameKhrXcbSurface);
+ usedKnobs.xcbSurface = true;
+ }
+ if (mGlobalInfo.xlibSurface) {
+ extensionsToRequest.push_back(kExtensionNameKhrXlibSurface);
+ usedKnobs.xlibSurface = true;
}
VkApplicationInfo appInfo;
@@ -479,14 +472,15 @@ namespace dawn_native { namespace vulkan {
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionsToRequest.size());
createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
- if (fn.CreateInstance(&createInfo, nullptr, &mInstance) != VK_SUCCESS) {
- return false;
- }
+ DAWN_TRY(CheckVkSuccess(fn.CreateInstance(&createInfo, nullptr, &mInstance),
+ "vkCreateInstance"));
- return true;
+ return usedKnobs;
}
- bool Device::CreateDevice(VulkanDeviceKnobs* usedKnobs) {
+ ResultOrError<VulkanDeviceKnobs> Device::CreateDevice() {
+ VulkanDeviceKnobs usedKnobs = {};
+
float zero = 0.0f;
std::vector<const char*> layersToRequest;
std::vector<const char*> extensionsToRequest;
@@ -494,13 +488,13 @@ namespace dawn_native { namespace vulkan {
if (mDeviceInfo.swapchain) {
extensionsToRequest.push_back(kExtensionNameKhrSwapchain);
- usedKnobs->swapchain = true;
+ usedKnobs.swapchain = true;
}
// Always require independentBlend because it is a core Dawn feature
- usedKnobs->features.independentBlend = VK_TRUE;
+ usedKnobs.features.independentBlend = VK_TRUE;
// Always require imageCubeArray because it is a core Dawn feature
- usedKnobs->features.imageCubeArray = VK_TRUE;
+ usedKnobs.features.imageCubeArray = VK_TRUE;
// Find a universal queue family
{
@@ -516,7 +510,7 @@ namespace dawn_native { namespace vulkan {
}
if (universalQueueFamily == -1) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("No universal queue family");
}
mQueueFamily = static_cast<uint32_t>(universalQueueFamily);
}
@@ -544,20 +538,19 @@ namespace dawn_native { namespace vulkan {
createInfo.ppEnabledLayerNames = layersToRequest.data();
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionsToRequest.size());
createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
- createInfo.pEnabledFeatures = &usedKnobs->features;
+ createInfo.pEnabledFeatures = &usedKnobs.features;
- if (fn.CreateDevice(mPhysicalDevice, &createInfo, nullptr, &mVkDevice) != VK_SUCCESS) {
- return false;
- }
+ DAWN_TRY(CheckVkSuccess(fn.CreateDevice(mPhysicalDevice, &createInfo, nullptr, &mVkDevice),
+ "vkCreateDevice"));
- return true;
+ return usedKnobs;
}
void Device::GatherQueueFromDevice() {
fn.GetDeviceQueue(mVkDevice, mQueueFamily, 0, &mQueue);
}
- bool Device::RegisterDebugReport() {
+ MaybeError Device::RegisterDebugReport() {
VkDebugReportCallbackCreateInfoEXT createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
createInfo.pNext = nullptr;
@@ -565,12 +558,9 @@ namespace dawn_native { namespace vulkan {
createInfo.pfnCallback = Device::OnDebugReportCallback;
createInfo.pUserData = this;
- if (fn.CreateDebugReportCallbackEXT(mInstance, &createInfo, nullptr,
- &mDebugReportCallback) != VK_SUCCESS) {
- return false;
- }
-
- return true;
+ return CheckVkSuccess(
+ fn.CreateDebugReportCallbackEXT(mInstance, &createInfo, nullptr, &mDebugReportCallback),
+ "vkCreateDebugReportcallback");
}
VKAPI_ATTR VkBool32 VKAPI_CALL
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.h
index c11427c2df3..b3af48a2d80 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.h
@@ -38,7 +38,7 @@ namespace dawn_native { namespace vulkan {
class Device : public DeviceBase {
public:
- Device(const std::vector<const char*>& requiredInstanceExtensions);
+ Device();
~Device();
// Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo.
@@ -57,29 +57,27 @@ namespace dawn_native { namespace vulkan {
MemoryAllocator* GetMemoryAllocator() const;
RenderPassCache* GetRenderPassCache() const;
- Serial GetSerial() const;
-
VkCommandBuffer GetPendingCommandBuffer();
+ Serial GetPendingCommandSerial() const;
void SubmitPendingCommands();
void AddWaitSemaphore(VkSemaphore semaphore);
// Dawn API
- BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
- BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
- BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
- DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override;
- RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
+ Serial GetCompletedCommandSerial() const final override;
+ Serial GetLastSubmittedCommandSerial() const final override;
void TickImpl() override;
const dawn_native::PCIInfo& GetPCIInfo() const override;
private:
+ ResultOrError<BindGroupBase*> CreateBindGroupImpl(
+ const BindGroupDescriptor* descriptor) override;
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
@@ -88,6 +86,8 @@ namespace dawn_native { namespace vulkan {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override;
+ ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
+ const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
@@ -96,12 +96,12 @@ namespace dawn_native { namespace vulkan {
TextureBase* texture,
const TextureViewDescriptor* descriptor) override;
- bool CreateInstance(VulkanGlobalKnobs* usedKnobs,
- const std::vector<const char*>& requiredExtensions);
- bool CreateDevice(VulkanDeviceKnobs* usedKnobs);
+ MaybeError Initialize();
+ ResultOrError<VulkanGlobalKnobs> CreateInstance();
+ ResultOrError<VulkanDeviceKnobs> CreateDevice();
void GatherQueueFromDevice();
- bool RegisterDebugReport();
+ MaybeError RegisterDebugReport();
static VKAPI_ATTR VkBool32 VKAPI_CALL
OnDebugReportCallback(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
@@ -116,8 +116,8 @@ namespace dawn_native { namespace vulkan {
// the Device is allowed to mutate them through these private methods.
VulkanFunctions* GetMutableFunctions();
- VulkanGlobalInfo mGlobalInfo;
- VulkanDeviceInfo mDeviceInfo;
+ VulkanGlobalInfo mGlobalInfo = {};
+ VulkanDeviceInfo mDeviceInfo = {};
DynamicLib mVulkanLib;
@@ -143,8 +143,8 @@ namespace dawn_native { namespace vulkan {
// have finished.
std::queue<std::pair<VkFence, Serial>> mFencesInFlight;
std::vector<VkFence> mUnusedFences;
- Serial mNextSerial = 1;
Serial mCompletedSerial = 0;
+ Serial mLastSubmittedSerial = 0;
struct CommandPoolAndBuffer {
VkCommandPool pool = VK_NULL_HANDLE;
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/FencedDeleter.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/FencedDeleter.cpp
index 6503f7334d5..729ea29ae89 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/FencedDeleter.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/FencedDeleter.cpp
@@ -39,59 +39,59 @@ namespace dawn_native { namespace vulkan {
}
void FencedDeleter::DeleteWhenUnused(VkBuffer buffer) {
- mBuffersToDelete.Enqueue(buffer, mDevice->GetSerial());
+ mBuffersToDelete.Enqueue(buffer, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkDescriptorPool pool) {
- mDescriptorPoolsToDelete.Enqueue(pool, mDevice->GetSerial());
+ mDescriptorPoolsToDelete.Enqueue(pool, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkDeviceMemory memory) {
- mMemoriesToDelete.Enqueue(memory, mDevice->GetSerial());
+ mMemoriesToDelete.Enqueue(memory, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkFramebuffer framebuffer) {
- mFramebuffersToDelete.Enqueue(framebuffer, mDevice->GetSerial());
+ mFramebuffersToDelete.Enqueue(framebuffer, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkImage image) {
- mImagesToDelete.Enqueue(image, mDevice->GetSerial());
+ mImagesToDelete.Enqueue(image, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkImageView view) {
- mImageViewsToDelete.Enqueue(view, mDevice->GetSerial());
+ mImageViewsToDelete.Enqueue(view, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkPipeline pipeline) {
- mPipelinesToDelete.Enqueue(pipeline, mDevice->GetSerial());
+ mPipelinesToDelete.Enqueue(pipeline, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkPipelineLayout layout) {
- mPipelineLayoutsToDelete.Enqueue(layout, mDevice->GetSerial());
+ mPipelineLayoutsToDelete.Enqueue(layout, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkRenderPass renderPass) {
- mRenderPassesToDelete.Enqueue(renderPass, mDevice->GetSerial());
+ mRenderPassesToDelete.Enqueue(renderPass, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkSampler sampler) {
- mSamplersToDelete.Enqueue(sampler, mDevice->GetSerial());
+ mSamplersToDelete.Enqueue(sampler, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkSemaphore semaphore) {
- mSemaphoresToDelete.Enqueue(semaphore, mDevice->GetSerial());
+ mSemaphoresToDelete.Enqueue(semaphore, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkShaderModule module) {
- mShaderModulesToDelete.Enqueue(module, mDevice->GetSerial());
+ mShaderModulesToDelete.Enqueue(module, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkSurfaceKHR surface) {
- mSurfacesToDelete.Enqueue(surface, mDevice->GetSerial());
+ mSurfacesToDelete.Enqueue(surface, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::DeleteWhenUnused(VkSwapchainKHR swapChain) {
- mSwapChainsToDelete.Enqueue(swapChain, mDevice->GetSerial());
+ mSwapChainsToDelete.Enqueue(swapChain, mDevice->GetPendingCommandSerial());
}
void FencedDeleter::Tick(Serial completedSerial) {
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/Forward.h b/chromium/third_party/dawn/src/dawn_native/vulkan/Forward.h
index b89261ccfce..aade94e10bb 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/Forward.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/Forward.h
@@ -17,20 +17,14 @@
#include "dawn_native/ToBackend.h"
-namespace dawn_native {
- class BufferViewBase;
-}
-
namespace dawn_native { namespace vulkan {
+ class Adapter;
class BindGroup;
class BindGroupLayout;
- class BlendState;
class Buffer;
- using BufferView = BufferViewBase;
class CommandBuffer;
class ComputePipeline;
- class DepthStencilState;
class Device;
class InputState;
class PipelineLayout;
@@ -44,14 +38,12 @@ namespace dawn_native { namespace vulkan {
class TextureView;
struct VulkanBackendTraits {
+ using AdapterType = Adapter;
using BindGroupType = BindGroup;
using BindGroupLayoutType = BindGroupLayout;
- using BlendStateType = BlendState;
using BufferType = Buffer;
- using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
- using DepthStencilStateType = DepthStencilState;
using DeviceType = Device;
using InputStateType = InputState;
using PipelineLayoutType = PipelineLayout;
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp
index a49aaffde9d..a1da700a511 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp
@@ -58,7 +58,7 @@ namespace dawn_native { namespace vulkan {
}
void NativeSwapChainImpl::Init(dawnWSIContextVulkan* /*context*/) {
- if (!GatherSurfaceInfo(*mDevice, mSurface, &mInfo)) {
+ if (mDevice->ConsumedError(GatherSurfaceInfo(*mDevice, mSurface, &mInfo))) {
ASSERT(false);
}
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/QueueVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/QueueVk.cpp
index e3de8b39649..773a4f0682d 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/QueueVk.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/QueueVk.cpp
@@ -28,6 +28,8 @@ namespace dawn_native { namespace vulkan {
void Queue::SubmitImpl(uint32_t numCommands, CommandBufferBase* const* commands) {
Device* device = ToBackend(GetDevice());
+ device->Tick();
+
VkCommandBuffer commandBuffer = device->GetPendingCommandBuffer();
for (uint32_t i = 0; i < numCommands; ++i) {
ToBackend(commands[i])->RecordCommands(commandBuffer);
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.cpp
index 6c8f65331ce..ca9358faccf 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.cpp
@@ -14,8 +14,6 @@
#include "dawn_native/vulkan/RenderPipelineVk.h"
-#include "dawn_native/vulkan/BlendStateVk.h"
-#include "dawn_native/vulkan/DepthStencilStateVk.h"
#include "dawn_native/vulkan/DeviceVk.h"
#include "dawn_native/vulkan/FencedDeleter.h"
#include "dawn_native/vulkan/InputStateVk.h"
@@ -23,6 +21,7 @@
#include "dawn_native/vulkan/RenderPassCache.h"
#include "dawn_native/vulkan/RenderPassDescriptorVk.h"
#include "dawn_native/vulkan/ShaderModuleVk.h"
+#include "dawn_native/vulkan/UtilsVulkan.h"
namespace dawn_native { namespace vulkan {
@@ -45,34 +44,181 @@ namespace dawn_native { namespace vulkan {
}
}
+ VkBlendFactor VulkanBlendFactor(dawn::BlendFactor factor) {
+ switch (factor) {
+ case dawn::BlendFactor::Zero:
+ return VK_BLEND_FACTOR_ZERO;
+ case dawn::BlendFactor::One:
+ return VK_BLEND_FACTOR_ONE;
+ case dawn::BlendFactor::SrcColor:
+ return VK_BLEND_FACTOR_SRC_COLOR;
+ case dawn::BlendFactor::OneMinusSrcColor:
+ return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
+ case dawn::BlendFactor::SrcAlpha:
+ return VK_BLEND_FACTOR_SRC_ALPHA;
+ case dawn::BlendFactor::OneMinusSrcAlpha:
+ return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ case dawn::BlendFactor::DstColor:
+ return VK_BLEND_FACTOR_DST_COLOR;
+ case dawn::BlendFactor::OneMinusDstColor:
+ return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
+ case dawn::BlendFactor::DstAlpha:
+ return VK_BLEND_FACTOR_DST_ALPHA;
+ case dawn::BlendFactor::OneMinusDstAlpha:
+ return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
+ case dawn::BlendFactor::SrcAlphaSaturated:
+ return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
+ case dawn::BlendFactor::BlendColor:
+ return VK_BLEND_FACTOR_CONSTANT_COLOR;
+ case dawn::BlendFactor::OneMinusBlendColor:
+ return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ VkBlendOp VulkanBlendOperation(dawn::BlendOperation operation) {
+ switch (operation) {
+ case dawn::BlendOperation::Add:
+ return VK_BLEND_OP_ADD;
+ case dawn::BlendOperation::Subtract:
+ return VK_BLEND_OP_SUBTRACT;
+ case dawn::BlendOperation::ReverseSubtract:
+ return VK_BLEND_OP_REVERSE_SUBTRACT;
+ case dawn::BlendOperation::Min:
+ return VK_BLEND_OP_MIN;
+ case dawn::BlendOperation::Max:
+ return VK_BLEND_OP_MAX;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ VkColorComponentFlagBits VulkanColorWriteMask(dawn::ColorWriteMask mask) {
+ // Vulkan and Dawn color write masks match, static assert it and return the mask
+ static_assert(static_cast<VkColorComponentFlagBits>(dawn::ColorWriteMask::Red) ==
+ VK_COLOR_COMPONENT_R_BIT,
+ "");
+ static_assert(static_cast<VkColorComponentFlagBits>(dawn::ColorWriteMask::Green) ==
+ VK_COLOR_COMPONENT_G_BIT,
+ "");
+ static_assert(static_cast<VkColorComponentFlagBits>(dawn::ColorWriteMask::Blue) ==
+ VK_COLOR_COMPONENT_B_BIT,
+ "");
+ static_assert(static_cast<VkColorComponentFlagBits>(dawn::ColorWriteMask::Alpha) ==
+ VK_COLOR_COMPONENT_A_BIT,
+ "");
+
+ return static_cast<VkColorComponentFlagBits>(mask);
+ }
+
+ VkPipelineColorBlendAttachmentState ComputeBlendDesc(
+ const BlendStateDescriptor* descriptor) {
+ VkPipelineColorBlendAttachmentState attachment;
+ attachment.blendEnable = descriptor->blendEnabled ? VK_TRUE : VK_FALSE;
+ attachment.srcColorBlendFactor = VulkanBlendFactor(descriptor->colorBlend.srcFactor);
+ attachment.dstColorBlendFactor = VulkanBlendFactor(descriptor->colorBlend.dstFactor);
+ attachment.colorBlendOp = VulkanBlendOperation(descriptor->colorBlend.operation);
+ attachment.srcAlphaBlendFactor = VulkanBlendFactor(descriptor->alphaBlend.srcFactor);
+ attachment.dstAlphaBlendFactor = VulkanBlendFactor(descriptor->alphaBlend.dstFactor);
+ attachment.alphaBlendOp = VulkanBlendOperation(descriptor->alphaBlend.operation);
+ attachment.colorWriteMask = VulkanColorWriteMask(descriptor->colorWriteMask);
+ return attachment;
+ }
+
+ VkStencilOp VulkanStencilOp(dawn::StencilOperation op) {
+ switch (op) {
+ case dawn::StencilOperation::Keep:
+ return VK_STENCIL_OP_KEEP;
+ case dawn::StencilOperation::Zero:
+ return VK_STENCIL_OP_ZERO;
+ case dawn::StencilOperation::Replace:
+ return VK_STENCIL_OP_REPLACE;
+ case dawn::StencilOperation::IncrementClamp:
+ return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
+ case dawn::StencilOperation::DecrementClamp:
+ return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
+ case dawn::StencilOperation::Invert:
+ return VK_STENCIL_OP_INVERT;
+ case dawn::StencilOperation::IncrementWrap:
+ return VK_STENCIL_OP_INCREMENT_AND_WRAP;
+ case dawn::StencilOperation::DecrementWrap:
+ return VK_STENCIL_OP_DECREMENT_AND_WRAP;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ VkPipelineDepthStencilStateCreateInfo ComputeDepthStencilDesc(
+ const DepthStencilStateDescriptor* descriptor) {
+ VkPipelineDepthStencilStateCreateInfo depthStencilState;
+ depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+ depthStencilState.pNext = nullptr;
+ depthStencilState.flags = 0;
+
+ // Depth writes only occur if depth is enabled
+ depthStencilState.depthTestEnable =
+ (descriptor->depthCompare == dawn::CompareFunction::Always &&
+ !descriptor->depthWriteEnabled)
+ ? VK_FALSE
+ : VK_TRUE;
+ depthStencilState.depthWriteEnable = descriptor->depthWriteEnabled ? VK_TRUE : VK_FALSE;
+ depthStencilState.depthCompareOp = ToVulkanCompareOp(descriptor->depthCompare);
+ depthStencilState.depthBoundsTestEnable = false;
+ depthStencilState.minDepthBounds = 0.0f;
+ depthStencilState.maxDepthBounds = 1.0f;
+
+ depthStencilState.stencilTestEnable =
+ StencilTestEnabled(descriptor) ? VK_TRUE : VK_FALSE;
+
+ depthStencilState.front.failOp = VulkanStencilOp(descriptor->front.stencilFailOp);
+ depthStencilState.front.passOp = VulkanStencilOp(descriptor->front.passOp);
+ depthStencilState.front.depthFailOp = VulkanStencilOp(descriptor->front.depthFailOp);
+ depthStencilState.front.compareOp = ToVulkanCompareOp(descriptor->front.compare);
+
+ depthStencilState.back.failOp = VulkanStencilOp(descriptor->back.stencilFailOp);
+ depthStencilState.back.passOp = VulkanStencilOp(descriptor->back.passOp);
+ depthStencilState.back.depthFailOp = VulkanStencilOp(descriptor->back.depthFailOp);
+ depthStencilState.back.compareOp = ToVulkanCompareOp(descriptor->back.compare);
+
+ // Dawn doesn't have separate front and back stencil masks.
+ depthStencilState.front.compareMask = descriptor->stencilReadMask;
+ depthStencilState.back.compareMask = descriptor->stencilReadMask;
+ depthStencilState.front.writeMask = descriptor->stencilWriteMask;
+ depthStencilState.back.writeMask = descriptor->stencilWriteMask;
+
+ // The stencil reference is always dynamic
+ depthStencilState.front.reference = 0;
+ depthStencilState.back.reference = 0;
+
+ return depthStencilState;
+ }
+
} // anonymous namespace
- RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
- : RenderPipelineBase(builder), mDevice(ToBackend(builder->GetDevice())) {
+ RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
+ : RenderPipelineBase(device, descriptor) {
// Eventually a bunch of the structures that need to be chained in the create info will be
// held by objects such as the BlendState. They aren't implemented yet so we initialize
// everything here.
VkPipelineShaderStageCreateInfo shaderStages[2];
{
- const auto& vertexStageInfo = builder->GetStageInfo(dawn::ShaderStage::Vertex);
- const auto& fragmentStageInfo = builder->GetStageInfo(dawn::ShaderStage::Fragment);
-
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStages[0].pNext = nullptr;
shaderStages[0].flags = 0;
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
- shaderStages[0].module = ToBackend(vertexStageInfo.module)->GetHandle();
- shaderStages[0].pName = vertexStageInfo.entryPoint.c_str();
shaderStages[0].pSpecializationInfo = nullptr;
+ shaderStages[0].module = ToBackend(descriptor->vertexStage->module)->GetHandle();
+ shaderStages[0].pName = descriptor->vertexStage->entryPoint;
shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStages[1].pNext = nullptr;
shaderStages[1].flags = 0;
shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
- shaderStages[1].module = ToBackend(fragmentStageInfo.module)->GetHandle();
- shaderStages[1].pName = fragmentStageInfo.entryPoint.c_str();
shaderStages[1].pSpecializationInfo = nullptr;
+ shaderStages[1].module = ToBackend(descriptor->fragmentStage->module)->GetHandle();
+ shaderStages[1].pName = descriptor->fragmentStage->entryPoint;
}
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
@@ -132,11 +278,15 @@ namespace dawn_native { namespace vulkan {
multisample.alphaToCoverageEnable = VK_FALSE;
multisample.alphaToOneEnable = VK_FALSE;
+ VkPipelineDepthStencilStateCreateInfo depthStencilState =
+ ComputeDepthStencilDesc(GetDepthStencilStateDescriptor());
+
// Initialize the "blend state info" that will be chained in the "create info" from the data
// pre-computed in the BlendState
std::array<VkPipelineColorBlendAttachmentState, kMaxColorAttachments> colorBlendAttachments;
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
- colorBlendAttachments[i] = ToBackend(GetBlendState(i))->GetState();
+ const BlendStateDescriptor* descriptor = GetBlendStateDescriptor(i);
+ colorBlendAttachments[i] = ComputeBlendDesc(descriptor);
}
VkPipelineColorBlendStateCreateInfo colorBlend;
colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
@@ -183,7 +333,7 @@ namespace dawn_native { namespace vulkan {
dawn::LoadOp::Load);
}
- renderPass = mDevice->GetRenderPassCache()->GetRenderPass(query);
+ renderPass = device->GetRenderPassCache()->GetRenderPass(query);
}
// The create info chains in a bunch of things created on the stack here or inside state
@@ -200,7 +350,7 @@ namespace dawn_native { namespace vulkan {
createInfo.pViewportState = &viewport;
createInfo.pRasterizationState = &rasterization;
createInfo.pMultisampleState = &multisample;
- createInfo.pDepthStencilState = ToBackend(GetDepthStencilState())->GetCreateInfo();
+ createInfo.pDepthStencilState = &depthStencilState;
createInfo.pColorBlendState = &colorBlend;
createInfo.pDynamicState = &dynamic;
createInfo.layout = ToBackend(GetLayout())->GetHandle();
@@ -209,15 +359,15 @@ namespace dawn_native { namespace vulkan {
createInfo.basePipelineHandle = VK_NULL_HANDLE;
createInfo.basePipelineIndex = -1;
- if (mDevice->fn.CreateGraphicsPipelines(mDevice->GetVkDevice(), VK_NULL_HANDLE, 1,
- &createInfo, nullptr, &mHandle) != VK_SUCCESS) {
+ if (device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1,
+ &createInfo, nullptr, &mHandle) != VK_SUCCESS) {
ASSERT(false);
}
}
RenderPipeline::~RenderPipeline() {
if (mHandle != VK_NULL_HANDLE) {
- mDevice->GetFencedDeleter()->DeleteWhenUnused(mHandle);
+ ToBackend(GetDevice())->GetFencedDeleter()->DeleteWhenUnused(mHandle);
mHandle = VK_NULL_HANDLE;
}
}
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.h
index e43676e7577..744772d6966 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.h
@@ -25,14 +25,13 @@ namespace dawn_native { namespace vulkan {
class RenderPipeline : public RenderPipelineBase {
public:
- RenderPipeline(RenderPipelineBuilder* builder);
+ RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
~RenderPipeline();
VkPipeline GetHandle() const;
private:
VkPipeline mHandle = VK_NULL_HANDLE;
- Device* mDevice = nullptr;
};
}} // namespace dawn_native::vulkan
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/SamplerVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/SamplerVk.cpp
index d54f358b0d9..aa23b3c1bd8 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/SamplerVk.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/SamplerVk.cpp
@@ -16,6 +16,7 @@
#include "dawn_native/vulkan/DeviceVk.h"
#include "dawn_native/vulkan/FencedDeleter.h"
+#include "dawn_native/vulkan/UtilsVulkan.h"
namespace dawn_native { namespace vulkan {
@@ -28,6 +29,8 @@ namespace dawn_native { namespace vulkan {
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case dawn::AddressMode::ClampToEdge:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+ case dawn::AddressMode::ClampToBorderColor:
+ return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
default:
UNREACHABLE();
}
@@ -54,6 +57,19 @@ namespace dawn_native { namespace vulkan {
UNREACHABLE();
}
}
+
+ VkBorderColor VulkanBorderColor(dawn::BorderColor color) {
+ switch (color) {
+ case dawn::BorderColor::TransparentBlack:
+ return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
+ case dawn::BorderColor::OpaqueBlack:
+ return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
+ case dawn::BorderColor::OpaqueWhite:
+ return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
+ default:
+ UNREACHABLE();
+ }
+ }
} // anonymous namespace
Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor)
@@ -71,11 +87,11 @@ namespace dawn_native { namespace vulkan {
createInfo.mipLodBias = 0.0f;
createInfo.anisotropyEnable = VK_FALSE;
createInfo.maxAnisotropy = 1.0f;
- createInfo.compareEnable = VK_FALSE;
- createInfo.compareOp = VK_COMPARE_OP_NEVER;
- createInfo.minLod = 0.0f;
- createInfo.maxLod = 1000.0f;
- createInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
+ createInfo.compareOp = ToVulkanCompareOp(descriptor->compareFunction);
+ createInfo.compareEnable = createInfo.compareOp == VK_COMPARE_OP_NEVER ? VK_FALSE : VK_TRUE;
+ createInfo.minLod = descriptor->lodMinClamp;
+ createInfo.maxLod = descriptor->lodMaxClamp;
+ createInfo.borderColor = VulkanBorderColor(descriptor->borderColor);
createInfo.unnormalizedCoordinates = VK_FALSE;
if (device->fn.CreateSampler(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/UtilsVulkan.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/UtilsVulkan.cpp
new file mode 100644
index 00000000000..723a6bb9c80
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/UtilsVulkan.cpp
@@ -0,0 +1,44 @@
+// Copyright 2019 The Dawn 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_native/vulkan/UtilsVulkan.h"
+
+#include "common/Assert.h"
+
+namespace dawn_native { namespace vulkan {
+
+ VkCompareOp ToVulkanCompareOp(dawn::CompareFunction op) {
+ switch (op) {
+ case dawn::CompareFunction::Always:
+ return VK_COMPARE_OP_ALWAYS;
+ case dawn::CompareFunction::Equal:
+ return VK_COMPARE_OP_EQUAL;
+ case dawn::CompareFunction::Greater:
+ return VK_COMPARE_OP_GREATER;
+ case dawn::CompareFunction::GreaterEqual:
+ return VK_COMPARE_OP_GREATER_OR_EQUAL;
+ case dawn::CompareFunction::Less:
+ return VK_COMPARE_OP_LESS;
+ case dawn::CompareFunction::LessEqual:
+ return VK_COMPARE_OP_LESS_OR_EQUAL;
+ case dawn::CompareFunction::Never:
+ return VK_COMPARE_OP_NEVER;
+ case dawn::CompareFunction::NotEqual:
+ return VK_COMPARE_OP_NOT_EQUAL;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+}} // namespace dawn_native::vulkan
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/BlendStateVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/UtilsVulkan.h
index fd025707c55..80fa2da0479 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/BlendStateVk.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/UtilsVulkan.h
@@ -1,4 +1,4 @@
-// Copyright 2018 The Dawn Authors
+// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,28 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_VULKAN_BLENDSTATEVK_H_
-#define DAWNNATIVE_VULKAN_BLENDSTATEVK_H_
-
-#include "dawn_native/BlendState.h"
+#ifndef DAWNNATIVE_VULKAN_UTILSVULKAN_H_
+#define DAWNNATIVE_VULKAN_UTILSVULKAN_H_
#include "common/vulkan_platform.h"
+#include "dawn_native/dawn_platform.h"
namespace dawn_native { namespace vulkan {
- class Device;
-
- // Pre-computes the blend state configuration to give to a graphics pipeline create info.
- class BlendState : public BlendStateBase {
- public:
- BlendState(BlendStateBuilder* builder);
-
- const VkPipelineColorBlendAttachmentState& GetState() const;
-
- private:
- VkPipelineColorBlendAttachmentState mState;
- };
+ VkCompareOp ToVulkanCompareOp(dawn::CompareFunction op);
}} // namespace dawn_native::vulkan
-#endif // DAWNNATIVE_VULKAN_BLENDSTATEVK_H_
+#endif // DAWNNATIVE_VULKAN_UTILSVULKAN_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanBackend.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanBackend.cpp
new file mode 100644
index 00000000000..ec169294ef4
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanBackend.cpp
@@ -0,0 +1,57 @@
+// Copyright 2019 The Dawn 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.
+
+// VulkanBackend.cpp: contains the definition of symbols exported by VulkanBackend.h so that they
+// can be compiled twice: once export (shared library), once not exported (static library)
+
+// Include vulkan_platform.h before VulkanBackend.h includes vulkan.h so that we use our version
+// of the non-dispatchable handles.
+#include "common/vulkan_platform.h"
+
+#include "dawn_native/VulkanBackend.h"
+
+#include "common/SwapChainUtils.h"
+#include "dawn_native/vulkan/DeviceVk.h"
+#include "dawn_native/vulkan/NativeSwapChainImplVk.h"
+
+namespace dawn_native { namespace vulkan {
+
+ dawnDevice CreateDevice() {
+ return reinterpret_cast<dawnDevice>(new Device());
+ }
+
+ VkInstance GetInstance(dawnDevice device) {
+ Device* backendDevice = reinterpret_cast<Device*>(device);
+ return backendDevice->GetInstance();
+ }
+
+ DAWN_NATIVE_EXPORT dawnSwapChainImplementation
+ CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHRNative surfaceNative) {
+ Device* backendDevice = reinterpret_cast<Device*>(device);
+ VkSurfaceKHR surface = VkSurfaceKHR::CreateFromHandle(surfaceNative);
+
+ dawnSwapChainImplementation impl;
+ impl = CreateSwapChainImplementation(new NativeSwapChainImpl(backendDevice, surface));
+ impl.textureUsage = DAWN_TEXTURE_USAGE_BIT_PRESENT;
+
+ return impl;
+ }
+
+ dawnTextureFormat GetNativeSwapChainPreferredFormat(
+ const dawnSwapChainImplementation* swapChain) {
+ NativeSwapChainImpl* impl = reinterpret_cast<NativeSwapChainImpl*>(swapChain->userData);
+ return static_cast<dawnTextureFormat>(impl->GetPreferredFormat());
+ }
+
+}} // namespace dawn_native::vulkan
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanError.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanError.cpp
new file mode 100644
index 00000000000..a01475c23f4
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanError.cpp
@@ -0,0 +1,73 @@
+// Copyright 2019 The Dawn 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_native/vulkan/VulkanError.h"
+
+#include <string>
+
+namespace dawn_native { namespace vulkan {
+
+ const char* VkResultAsString(VkResult result) {
+ switch (result) {
+ case VK_SUCCESS:
+ return "VK_SUCCESS";
+ case VK_NOT_READY:
+ return "VK_NOT_READY";
+ case VK_TIMEOUT:
+ return "VK_TIMEOUT";
+ case VK_EVENT_SET:
+ return "VK_EVENT_SET";
+ case VK_EVENT_RESET:
+ return "VK_EVENT_RESET";
+ case VK_INCOMPLETE:
+ return "VK_INCOMPLETE";
+ case VK_ERROR_OUT_OF_HOST_MEMORY:
+ return "VK_ERROR_OUT_OF_HOST_MEMORY";
+ case VK_ERROR_OUT_OF_DEVICE_MEMORY:
+ return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
+ case VK_ERROR_INITIALIZATION_FAILED:
+ return "VK_ERROR_INITIALIZATION_FAILED";
+ case VK_ERROR_DEVICE_LOST:
+ return "VK_ERROR_DEVICE_LOST";
+ case VK_ERROR_MEMORY_MAP_FAILED:
+ return "VK_ERROR_MEMORY_MAP_FAILED";
+ case VK_ERROR_LAYER_NOT_PRESENT:
+ return "VK_ERROR_LAYER_NOT_PRESENT";
+ case VK_ERROR_EXTENSION_NOT_PRESENT:
+ return "VK_ERROR_EXTENSION_NOT_PRESENT";
+ case VK_ERROR_FEATURE_NOT_PRESENT:
+ return "VK_ERROR_FEATURE_NOT_PRESENT";
+ case VK_ERROR_INCOMPATIBLE_DRIVER:
+ return "VK_ERROR_INCOMPATIBLE_DRIVER";
+ case VK_ERROR_TOO_MANY_OBJECTS:
+ return "VK_ERROR_TOO_MANY_OBJECTS";
+ case VK_ERROR_FORMAT_NOT_SUPPORTED:
+ return "VK_ERROR_FORMAT_NOT_SUPPORTED";
+ case VK_ERROR_FRAGMENTED_POOL:
+ return "VK_ERROR_FRAGMENTED_POOL";
+ default:
+ return "<Unknown VkResult>";
+ }
+ }
+
+ MaybeError CheckVkSuccess(VkResult result, const char* context) {
+ if (DAWN_LIKELY(result == VK_SUCCESS)) {
+ return {};
+ }
+
+ std::string message = std::string(context) + " failed with " + VkResultAsString(result);
+ return DAWN_CONTEXT_LOST_ERROR(message);
+ }
+
+}} // namespace dawn_native::vulkan
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/DepthStencilStateVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanError.h
index 1f9a2a52210..3dedece1ad4 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/DepthStencilStateVk.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanError.h
@@ -1,4 +1,4 @@
-// Copyright 2018 The Dawn Authors
+// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,28 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef DAWNNATIVE_VULKAN_DEPTHSTENCILSTATEVK_H_
-#define DAWNNATIVE_VULKAN_DEPTHSTENCILSTATEVK_H_
-
-#include "dawn_native/DepthStencilState.h"
+#ifndef DAWNNATIVE_VULKAN_VULKANERROR_H_
+#define DAWNNATIVE_VULKAN_VULKANERROR_H_
#include "common/vulkan_platform.h"
+#include "dawn_native/Error.h"
namespace dawn_native { namespace vulkan {
- class Device;
-
- // Pre-computes the depth-stencil configuration to give to a graphics pipeline create info.
- class DepthStencilState : public DepthStencilStateBase {
- public:
- DepthStencilState(DepthStencilStateBuilder* builder);
-
- const VkPipelineDepthStencilStateCreateInfo* GetCreateInfo() const;
+ // Returns a string version of the result.
+ const char* VkResultAsString(VkResult result);
- private:
- VkPipelineDepthStencilStateCreateInfo mCreateInfo;
- };
+ // Returns a success only if result if VK_SUCCESS, an error with the context and stringified
+ // result value instead. Can be used like this:
+ //
+ // DAWN_TRY(CheckVkSuccess(vkDoSomething, "doing something"));
+ MaybeError CheckVkSuccess(VkResult result, const char* context);
}} // namespace dawn_native::vulkan
-#endif // DAWNNATIVE_VULKAN_DEPTHSTENCILSTATEVK_H_
+#endif // DAWNNATIVE_VULKAN_VULKANERROR_H_
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.cpp
index 09f6e512f45..39f3a194242 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.cpp
@@ -22,29 +22,29 @@ namespace dawn_native { namespace vulkan {
#define GET_GLOBAL_PROC(name) \
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(nullptr, "vk" #name)); \
if (name == nullptr) { \
- return false; \
+ return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
}
- bool VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) {
+ MaybeError VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) {
if (!vulkanLib.GetProc(&GetInstanceProcAddr, "vkGetInstanceProcAddr")) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("Couldn't get vkGetInstanceProcAddr");
}
GET_GLOBAL_PROC(CreateInstance);
GET_GLOBAL_PROC(EnumerateInstanceExtensionProperties);
GET_GLOBAL_PROC(EnumerateInstanceLayerProperties);
- return true;
+ return {};
}
#define GET_INSTANCE_PROC(name) \
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #name)); \
if (name == nullptr) { \
- return false; \
+ return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
}
- bool VulkanFunctions::LoadInstanceProcs(VkInstance instance,
- const VulkanGlobalKnobs& usedKnobs) {
+ MaybeError VulkanFunctions::LoadInstanceProcs(VkInstance instance,
+ const VulkanGlobalKnobs& usedKnobs) {
// Load this proc first so that we can destroy the instance even if some other
// GET_INSTANCE_PROC fails
GET_INSTANCE_PROC(DestroyInstance);
@@ -77,16 +77,17 @@ namespace dawn_native { namespace vulkan {
GET_INSTANCE_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
}
- return true;
+ return {};
}
-#define GET_DEVICE_PROC(name) \
- name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
- if (name == nullptr) { \
- return false; \
+#define GET_DEVICE_PROC(name) \
+ name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
+ if (name == nullptr) { \
+ return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
}
- bool VulkanFunctions::LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs) {
+ MaybeError VulkanFunctions::LoadDeviceProcs(VkDevice device,
+ const VulkanDeviceKnobs& usedKnobs) {
GET_DEVICE_PROC(AllocateCommandBuffers);
GET_DEVICE_PROC(AllocateDescriptorSets);
GET_DEVICE_PROC(AllocateMemory);
@@ -215,7 +216,7 @@ namespace dawn_native { namespace vulkan {
GET_DEVICE_PROC(QueuePresentKHR);
}
- return true;
+ return {};
}
}} // namespace dawn_native::vulkan
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.h b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.h
index a9a6a54654a..e229cb084a4 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanFunctions.h
@@ -17,6 +17,8 @@
#include "common/vulkan_platform.h"
+#include "dawn_native/Error.h"
+
class DynamicLib;
namespace dawn_native { namespace vulkan {
@@ -27,9 +29,9 @@ namespace dawn_native { namespace vulkan {
// Stores the Vulkan entry points. Also loads them from the dynamic library
// and the vkGet*ProcAddress entry points.
struct VulkanFunctions {
- bool LoadGlobalProcs(const DynamicLib& vulkanLib);
- bool LoadInstanceProcs(VkInstance instance, const VulkanGlobalKnobs& usedGlobals);
- bool LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs);
+ MaybeError LoadGlobalProcs(const DynamicLib& vulkanLib);
+ MaybeError LoadInstanceProcs(VkInstance instance, const VulkanGlobalKnobs& usedGlobals);
+ MaybeError LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs);
// ---------- Global procs
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.cpp
index d7b4a846a4a..c8c11a84b92 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.cpp
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.cpp
@@ -35,10 +35,17 @@ namespace dawn_native { namespace vulkan {
const char kLayerNameRenderDocCapture[] = "VK_LAYER_RENDERDOC_Capture";
const char kExtensionNameExtDebugReport[] = "VK_EXT_debug_report";
+ const char kExtensionNameMvkMacosSurface[] = "VK_MVK_macos_surface";
const char kExtensionNameKhrSurface[] = "VK_KHR_surface";
const char kExtensionNameKhrSwapchain[] = "VK_KHR_swapchain";
+ const char kExtensionNameKhrWaylandSurface[] = "VK_KHR_wayland_surface";
+ const char kExtensionNameKhrWin32Surface[] = "VK_KHR_win32_surface";
+ const char kExtensionNameKhrXcbSurface[] = "VK_KHR_xcb_surface";
+ const char kExtensionNameKhrXlibSurface[] = "VK_KHR_xlib_surface";
+
+ ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Device& device) {
+ VulkanGlobalInfo info = {};
- bool GatherGlobalInfo(const Device& device, VulkanGlobalInfo* info) {
// Gather the info about the instance layers
{
uint32_t count = 0;
@@ -47,24 +54,24 @@ namespace dawn_native { namespace vulkan {
// incomplete otherwise. This means that both values represent a success.
// This is the same for all Enumarte functions
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceLayerProperties");
}
- info->layers.resize(count);
- result = device.fn.EnumerateInstanceLayerProperties(&count, info->layers.data());
+ info.layers.resize(count);
+ result = device.fn.EnumerateInstanceLayerProperties(&count, info.layers.data());
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceLayerProperties");
}
- for (const auto& layer : info->layers) {
+ for (const auto& layer : info.layers) {
if (IsLayerName(layer, kLayerNameLunargStandardValidation)) {
- info->standardValidation = true;
+ info.standardValidation = true;
}
if (IsLayerName(layer, kLayerNameLunargVKTrace)) {
- info->vktrace = true;
+ info.vktrace = true;
}
if (IsLayerName(layer, kLayerNameRenderDocCapture)) {
- info->renderDocCapture = true;
+ info.renderDocCapture = true;
}
}
}
@@ -75,65 +82,81 @@ namespace dawn_native { namespace vulkan {
VkResult result =
device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceExtensionProperties");
}
- info->extensions.resize(count);
+ info.extensions.resize(count);
result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count,
- info->extensions.data());
+ info.extensions.data());
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceExtensionProperties");
}
- for (const auto& extension : info->extensions) {
+ for (const auto& extension : info.extensions) {
if (IsExtensionName(extension, kExtensionNameExtDebugReport)) {
- info->debugReport = true;
+ info.debugReport = true;
+ }
+ if (IsExtensionName(extension, kExtensionNameMvkMacosSurface)) {
+ info.macosSurface = true;
}
if (IsExtensionName(extension, kExtensionNameKhrSurface)) {
- info->surface = true;
+ info.surface = true;
+ }
+ if (IsExtensionName(extension, kExtensionNameKhrWaylandSurface)) {
+ info.waylandSurface = true;
+ }
+ if (IsExtensionName(extension, kExtensionNameKhrWin32Surface)) {
+ info.win32Surface = true;
+ }
+ if (IsExtensionName(extension, kExtensionNameKhrXcbSurface)) {
+ info.xcbSurface = true;
+ }
+ if (IsExtensionName(extension, kExtensionNameKhrXlibSurface)) {
+ info.xlibSurface = true;
}
}
}
// TODO(cwallez@chromium:org): Each layer can expose additional extensions, query them?
- return true;
+ return info;
}
- bool GetPhysicalDevices(const Device& device, std::vector<VkPhysicalDevice>* physicalDevices) {
+ ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Device& device) {
VkInstance instance = device.GetInstance();
uint32_t count = 0;
VkResult result = device.fn.EnumeratePhysicalDevices(instance, &count, nullptr);
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumeratePhysicalDevices");
}
- physicalDevices->resize(count);
- result = device.fn.EnumeratePhysicalDevices(instance, &count, physicalDevices->data());
+ std::vector<VkPhysicalDevice> physicalDevices(count);
+ result = device.fn.EnumeratePhysicalDevices(instance, &count, physicalDevices.data());
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumeratePhysicalDevices");
}
- return true;
+ return physicalDevices;
}
- bool GatherDeviceInfo(const Device& device,
- VkPhysicalDevice physicalDevice,
- VulkanDeviceInfo* info) {
+ ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Device& device,
+ VkPhysicalDevice physicalDevice) {
+ VulkanDeviceInfo info = {};
+
// Gather general info about the device
- device.fn.GetPhysicalDeviceProperties(physicalDevice, &info->properties);
- device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info->features);
+ device.fn.GetPhysicalDeviceProperties(physicalDevice, &info.properties);
+ device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info.features);
// Gather info about device memory.
{
VkPhysicalDeviceMemoryProperties memory;
device.fn.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory);
- info->memoryTypes.assign(memory.memoryTypes,
- memory.memoryTypes + memory.memoryTypeCount);
- info->memoryHeaps.assign(memory.memoryHeaps,
- memory.memoryHeaps + memory.memoryHeapCount);
+ info.memoryTypes.assign(memory.memoryTypes,
+ memory.memoryTypes + memory.memoryTypeCount);
+ info.memoryHeaps.assign(memory.memoryHeaps,
+ memory.memoryHeaps + memory.memoryHeapCount);
}
// Gather info about device queue families
@@ -141,9 +164,9 @@ namespace dawn_native { namespace vulkan {
uint32_t count = 0;
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
- info->queueFamilies.resize(count);
+ info.queueFamilies.resize(count);
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count,
- info->queueFamilies.data());
+ info.queueFamilies.data());
}
// Gather the info about the device layers
@@ -152,14 +175,14 @@ namespace dawn_native { namespace vulkan {
VkResult result =
device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr);
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceLayerProperties");
}
- info->layers.resize(count);
+ info.layers.resize(count);
result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count,
- info->layers.data());
+ info.layers.data());
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceLayerProperties");
}
}
@@ -169,29 +192,31 @@ namespace dawn_native { namespace vulkan {
VkResult result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr,
&count, nullptr);
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceExtensionProperties");
}
- info->extensions.resize(count);
+ info.extensions.resize(count);
result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count,
- info->extensions.data());
+ info.extensions.data());
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceExtensionProperties");
}
- for (const auto& extension : info->extensions) {
+ for (const auto& extension : info.extensions) {
if (IsExtensionName(extension, kExtensionNameKhrSwapchain)) {
- info->swapchain = true;
+ info.swapchain = true;
}
}
}
// TODO(cwallez@chromium.org): gather info about formats
- return true;
+ return info;
}
- bool GatherSurfaceInfo(const Device& device, VkSurfaceKHR surface, VulkanSurfaceInfo* info) {
+ MaybeError GatherSurfaceInfo(const Device& device,
+ VkSurfaceKHR surface,
+ VulkanSurfaceInfo* info) {
VkPhysicalDevice physicalDevice = device.GetPhysicalDevice();
// Get the surface capabilities
@@ -199,7 +224,7 @@ namespace dawn_native { namespace vulkan {
VkResult result = device.fn.GetPhysicalDeviceSurfaceCapabilitiesKHR(
physicalDevice, surface, &info->capabilities);
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
}
}
@@ -214,7 +239,7 @@ namespace dawn_native { namespace vulkan {
surface, &supported);
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceSupportKHR");
}
info->supportedQueueFamilies[i] = (supported == VK_TRUE);
@@ -227,14 +252,14 @@ namespace dawn_native { namespace vulkan {
VkResult result = device.fn.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
&count, nullptr);
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR");
}
info->formats.resize(count);
result = device.fn.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count,
info->formats.data());
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR");
}
}
@@ -244,18 +269,18 @@ namespace dawn_native { namespace vulkan {
VkResult result = device.fn.GetPhysicalDeviceSurfacePresentModesKHR(
physicalDevice, surface, &count, nullptr);
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR");
}
info->presentModes.resize(count);
result = device.fn.GetPhysicalDeviceSurfacePresentModesKHR(
physicalDevice, surface, &count, info->presentModes.data());
if (result != VK_SUCCESS) {
- return false;
+ return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR");
}
}
- return true;
+ return {};
}
}} // namespace dawn_native::vulkan
diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.h b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.h
index b87b666fef4..fee253b84ad 100644
--- a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.h
+++ b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanInfo.h
@@ -16,6 +16,7 @@
#define DAWNNATIVE_VULKAN_VULKANINFO_H_
#include "common/vulkan_platform.h"
+#include "dawn_native/Error.h"
#include <vector>
@@ -28,8 +29,13 @@ namespace dawn_native { namespace vulkan {
extern const char kLayerNameRenderDocCapture[];
extern const char kExtensionNameExtDebugReport[];
+ extern const char kExtensionNameMvkMacosSurface[];
extern const char kExtensionNameKhrSurface[];
extern const char kExtensionNameKhrSwapchain[];
+ extern const char kExtensionNameKhrWaylandSurface[];
+ extern const char kExtensionNameKhrWin32Surface[];
+ extern const char kExtensionNameKhrXcbSurface[];
+ extern const char kExtensionNameKhrXlibSurface[];
// Global information - gathered before the instance is created
struct VulkanGlobalKnobs {
@@ -40,7 +46,12 @@ namespace dawn_native { namespace vulkan {
// Extensions
bool debugReport = false;
+ bool macosSurface = false;
bool surface = false;
+ bool waylandSurface = false;
+ bool win32Surface = false;
+ bool xcbSurface = false;
+ bool xlibSurface = false;
};
struct VulkanGlobalInfo : VulkanGlobalKnobs {
@@ -76,13 +87,13 @@ namespace dawn_native { namespace vulkan {
std::vector<bool> supportedQueueFamilies;
};
- bool GatherGlobalInfo(const Device& device, VulkanGlobalInfo* info);
- bool GetPhysicalDevices(const Device& device, std::vector<VkPhysicalDevice>* physicalDevices);
- bool GatherDeviceInfo(const Device& device,
- VkPhysicalDevice physicalDevice,
- VulkanDeviceInfo* info);
- bool GatherSurfaceInfo(const Device& device, VkSurfaceKHR surface, VulkanSurfaceInfo* info);
-
+ ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Device& device);
+ ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Device& device);
+ ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Device& device,
+ VkPhysicalDevice physicalDevice);
+ MaybeError GatherSurfaceInfo(const Device& device,
+ VkSurfaceKHR surface,
+ VulkanSurfaceInfo* info);
}} // namespace dawn_native::vulkan
#endif // DAWNNATIVE_VULKAN_VULKANINFO_H_
diff --git a/chromium/third_party/dawn/src/dawn_wire/DawnWire.cpp b/chromium/third_party/dawn/src/dawn_wire/DawnWire.cpp
new file mode 100644
index 00000000000..7e502738fb5
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/DawnWire.cpp
@@ -0,0 +1,29 @@
+// Copyright 2019 The Dawn 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_wire/client/Client.h"
+#include "dawn_wire/client/Device_autogen.h"
+
+namespace dawn_wire {
+ CommandHandler* NewClientDevice(dawnProcTable* procs,
+ dawnDevice* device,
+ CommandSerializer* serializer) {
+ auto clientDevice = new client::Device(serializer);
+
+ *device = reinterpret_cast<dawnDeviceImpl*>(clientDevice);
+ *procs = client::GetProcs();
+
+ return new client::Client(clientDevice);
+ }
+} // namespace dawn_wire
diff --git a/chromium/third_party/dawn/src/dawn_wire/WireCmd.h b/chromium/third_party/dawn/src/dawn_wire/WireCmd.h
deleted file mode 100644
index 7419cd2f0a4..00000000000
--- a/chromium/third_party/dawn/src/dawn_wire/WireCmd.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2017 The Dawn 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.
-
-#ifndef DAWNWIRE_WIRECMD_H_
-#define DAWNWIRE_WIRECMD_H_
-
-#include <dawn/dawn.h>
-
-#include "dawn_wire/WireCmd_autogen.h"
-
-namespace dawn_wire {
-
- struct ReturnDeviceErrorCallbackCmd {
- ReturnWireCmd commandId = ReturnWireCmd::DeviceErrorCallback;
-
- size_t messageStrlen;
- };
-
- struct BufferMapAsyncCmd {
- WireCmd commandId = WireCmd::BufferMapAsync;
-
- ObjectId bufferId;
- ObjectSerial requestSerial;
- uint32_t start;
- uint32_t size;
- bool isWrite;
- };
-
- struct ReturnBufferMapReadAsyncCallbackCmd {
- ReturnWireCmd commandId = ReturnWireCmd::BufferMapReadAsyncCallback;
-
- ObjectId bufferId;
- ObjectSerial bufferSerial;
- uint32_t requestSerial;
- uint32_t status;
- uint32_t dataLength;
- };
-
- struct ReturnBufferMapWriteAsyncCallbackCmd {
- ReturnWireCmd commandId = ReturnWireCmd::BufferMapWriteAsyncCallback;
-
- ObjectId bufferId;
- ObjectSerial bufferSerial;
- uint32_t requestSerial;
- uint32_t status;
- };
-
- struct BufferUpdateMappedDataCmd {
- WireCmd commandId = WireCmd::BufferUpdateMappedDataCmd;
-
- ObjectId bufferId;
- uint32_t dataLength;
- };
-
-} // namespace dawn_wire
-
-#endif // DAWNWIRE_WIRECMD_H_
diff --git a/chromium/third_party/dawn/src/dawn_wire/WireDeserializeAllocator.cpp b/chromium/third_party/dawn/src/dawn_wire/WireDeserializeAllocator.cpp
new file mode 100644
index 00000000000..7ae1b35c3fa
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/WireDeserializeAllocator.cpp
@@ -0,0 +1,60 @@
+// Copyright 2019 The Dawn 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_wire/WireDeserializeAllocator.h"
+
+#include <algorithm>
+
+namespace dawn_wire {
+ WireDeserializeAllocator::WireDeserializeAllocator() {
+ Reset();
+ }
+
+ WireDeserializeAllocator::~WireDeserializeAllocator() {
+ Reset();
+ }
+
+ void* WireDeserializeAllocator::GetSpace(size_t size) {
+ // Return space in the current buffer if possible first.
+ if (mRemainingSize >= size) {
+ char* buffer = mCurrentBuffer;
+ mCurrentBuffer += size;
+ mRemainingSize -= size;
+ return buffer;
+ }
+
+ // Otherwise allocate a new buffer and try again.
+ size_t allocationSize = std::max(size, size_t(2048));
+ char* allocation = static_cast<char*>(malloc(allocationSize));
+ if (allocation == nullptr) {
+ return nullptr;
+ }
+
+ mAllocations.push_back(allocation);
+ mCurrentBuffer = allocation;
+ mRemainingSize = allocationSize;
+ return GetSpace(size);
+ }
+
+ void WireDeserializeAllocator::Reset() {
+ for (auto allocation : mAllocations) {
+ free(allocation);
+ }
+ mAllocations.clear();
+
+ // The initial buffer is the inline buffer so that some allocations can be skipped
+ mCurrentBuffer = mStaticBuffer;
+ mRemainingSize = sizeof(mStaticBuffer);
+ }
+} // namespace dawn_wire
diff --git a/chromium/third_party/dawn/src/dawn_wire/WireDeserializeAllocator.h b/chromium/third_party/dawn/src/dawn_wire/WireDeserializeAllocator.h
new file mode 100644
index 00000000000..c900a23cbd5
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/WireDeserializeAllocator.h
@@ -0,0 +1,43 @@
+// Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_WIREDESERIALIZEALLOCATOR_H_
+#define DAWNWIRE_WIREDESERIALIZEALLOCATOR_H_
+
+#include "dawn_wire/WireCmd_autogen.h"
+
+#include <vector>
+
+namespace dawn_wire {
+ // A really really simple implementation of the DeserializeAllocator. It's main feature
+ // is that it has some inline storage so as to avoid allocations for the majority of
+ // commands.
+ class WireDeserializeAllocator : public DeserializeAllocator {
+ public:
+ WireDeserializeAllocator();
+ ~WireDeserializeAllocator();
+
+ void* GetSpace(size_t size) override;
+
+ void Reset();
+
+ private:
+ size_t mRemainingSize = 0;
+ char* mCurrentBuffer = nullptr;
+ char mStaticBuffer[2048];
+ std::vector<char*> mAllocations;
+ };
+} // namespace dawn_wire
+
+#endif // DAWNWIRE_WIREDESERIALIZEALLOCATOR_H_
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/ApiObjects.h b/chromium/third_party/dawn/src/dawn_wire/client/ApiObjects.h
new file mode 100644
index 00000000000..c7a52c3cbaf
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/ApiObjects.h
@@ -0,0 +1,25 @@
+// Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_APIOBJECTS_H_
+#define DAWNWIRE_CLIENT_APIOBJECTS_H_
+
+#include "dawn_wire/client/ObjectBase.h"
+
+#include "dawn_wire/client/Buffer.h"
+#include "dawn_wire/client/Fence.h"
+
+#include "dawn_wire/client/ApiObjects_autogen.h"
+
+#endif // DAWNWIRE_CLIENT_APIOBJECTS_H_
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/ApiProcs.cpp b/chromium/third_party/dawn/src/dawn_wire/client/ApiProcs.cpp
new file mode 100644
index 00000000000..99f620a61ba
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/ApiProcs.cpp
@@ -0,0 +1,172 @@
+// Copyright 2019 The Dawn 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_wire/client/ApiProcs_autogen.h"
+#include "dawn_wire/client/Device_autogen.h"
+
+namespace dawn_wire { namespace client {
+
+ void ClientBufferMapReadAsync(dawnBuffer cBuffer,
+ uint32_t start,
+ uint32_t size,
+ dawnBufferMapReadCallback callback,
+ dawnCallbackUserdata userdata) {
+ Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
+
+ uint32_t serial = buffer->requestSerial++;
+ ASSERT(buffer->requests.find(serial) == buffer->requests.end());
+
+ Buffer::MapRequestData request;
+ request.readCallback = callback;
+ request.userdata = userdata;
+ request.size = size;
+ request.isWrite = false;
+ buffer->requests[serial] = request;
+
+ BufferMapAsyncCmd cmd;
+ cmd.bufferId = buffer->id;
+ cmd.requestSerial = serial;
+ cmd.start = start;
+ cmd.size = size;
+ cmd.isWrite = false;
+
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(buffer->device->GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
+ }
+
+ void ClientBufferMapWriteAsync(dawnBuffer cBuffer,
+ uint32_t start,
+ uint32_t size,
+ dawnBufferMapWriteCallback callback,
+ dawnCallbackUserdata userdata) {
+ Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
+
+ uint32_t serial = buffer->requestSerial++;
+ ASSERT(buffer->requests.find(serial) == buffer->requests.end());
+
+ Buffer::MapRequestData request;
+ request.writeCallback = callback;
+ request.userdata = userdata;
+ request.size = size;
+ request.isWrite = true;
+ buffer->requests[serial] = request;
+
+ BufferMapAsyncCmd cmd;
+ cmd.bufferId = buffer->id;
+ cmd.requestSerial = serial;
+ cmd.start = start;
+ cmd.size = size;
+ cmd.isWrite = true;
+
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer = static_cast<char*>(buffer->device->GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
+ }
+
+ uint64_t ClientFenceGetCompletedValue(dawnFence cSelf) {
+ auto fence = reinterpret_cast<Fence*>(cSelf);
+ return fence->completedValue;
+ }
+
+ void ClientFenceOnCompletion(dawnFence cFence,
+ uint64_t value,
+ dawnFenceOnCompletionCallback callback,
+ dawnCallbackUserdata userdata) {
+ Fence* fence = reinterpret_cast<Fence*>(cFence);
+ if (value > fence->signaledValue) {
+ fence->device->HandleError("Value greater than fence signaled value");
+ callback(DAWN_FENCE_COMPLETION_STATUS_ERROR, userdata);
+ return;
+ }
+
+ if (value <= fence->completedValue) {
+ callback(DAWN_FENCE_COMPLETION_STATUS_SUCCESS, userdata);
+ return;
+ }
+
+ Fence::OnCompletionData request;
+ request.completionCallback = callback;
+ request.userdata = userdata;
+ fence->requests.Enqueue(std::move(request), value);
+ }
+
+ void ProxyClientBufferUnmap(dawnBuffer cBuffer) {
+ Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
+
+ // Invalidate the local pointer, and cancel all other in-flight requests that would
+ // turn into
+ // errors anyway (you can't double map). This prevents race when the following happens,
+ // where
+ // the application code would have unmapped a buffer but still receive a callback:
+ // - Client -> Server: MapRequest1, Unmap, MapRequest2
+ // - Server -> Client: Result of MapRequest1
+ // - Unmap locally on the client
+ // - Server -> Client: Result of MapRequest2
+ if (buffer->mappedData) {
+ // If the buffer was mapped for writing, send the update to the data to the server
+ if (buffer->isWriteMapped) {
+ BufferUpdateMappedDataCmd cmd;
+ cmd.bufferId = buffer->id;
+ cmd.dataLength = static_cast<uint32_t>(buffer->mappedDataSize);
+ cmd.data = reinterpret_cast<const uint8_t*>(buffer->mappedData);
+
+ size_t requiredSize = cmd.GetRequiredSize();
+ char* allocatedBuffer =
+ static_cast<char*>(buffer->device->GetCmdSpace(requiredSize));
+ cmd.Serialize(allocatedBuffer);
+ }
+
+ free(buffer->mappedData);
+ buffer->mappedData = nullptr;
+ }
+ buffer->ClearMapRequests(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN);
+
+ ClientBufferUnmap(cBuffer);
+ }
+
+ dawnFence ProxyClientDeviceCreateFence(dawnDevice cSelf,
+ dawnFenceDescriptor const* descriptor) {
+ dawnFence cFence = ClientDeviceCreateFence(cSelf, descriptor);
+ Fence* fence = reinterpret_cast<Fence*>(cFence);
+ fence->signaledValue = descriptor->initialValue;
+ fence->completedValue = descriptor->initialValue;
+ return cFence;
+ }
+
+ void ProxyClientQueueSignal(dawnQueue cQueue, dawnFence cFence, uint64_t signalValue) {
+ Fence* fence = reinterpret_cast<Fence*>(cFence);
+ if (signalValue <= fence->signaledValue) {
+ fence->device->HandleError("Fence value less than or equal to signaled value");
+ return;
+ }
+ fence->signaledValue = signalValue;
+ ClientQueueSignal(cQueue, cFence, signalValue);
+ }
+
+ void ClientDeviceReference(dawnDevice) {
+ }
+
+ void ClientDeviceRelease(dawnDevice) {
+ }
+
+ void ClientDeviceSetErrorCallback(dawnDevice cSelf,
+ dawnDeviceErrorCallback callback,
+ dawnCallbackUserdata userdata) {
+ Device* self = reinterpret_cast<Device*>(cSelf);
+ self->errorCallback = callback;
+ self->errorUserdata = userdata;
+ }
+
+}} // namespace dawn_wire::client
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/Buffer.cpp b/chromium/third_party/dawn/src/dawn_wire/client/Buffer.cpp
new file mode 100644
index 00000000000..aa82c0e58a1
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/Buffer.cpp
@@ -0,0 +1,40 @@
+// Copyright 2019 The Dawn 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_wire/client/Buffer.h"
+
+namespace dawn_wire { namespace client {
+
+ Buffer::~Buffer() {
+ // Callbacks need to be fired in all cases, as they can handle freeing resources
+ // so we call them with "Unknown" status.
+ ClearMapRequests(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN);
+
+ if (mappedData) {
+ free(mappedData);
+ }
+ }
+
+ void Buffer::ClearMapRequests(dawnBufferMapAsyncStatus status) {
+ for (auto& it : requests) {
+ if (it.second.isWrite) {
+ it.second.writeCallback(status, nullptr, it.second.userdata);
+ } else {
+ it.second.readCallback(status, nullptr, it.second.userdata);
+ }
+ }
+ requests.clear();
+ }
+
+}} // namespace dawn_wire::client
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/Buffer.h b/chromium/third_party/dawn/src/dawn_wire/client/Buffer.h
new file mode 100644
index 00000000000..3561bc60814
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/Buffer.h
@@ -0,0 +1,54 @@
+// Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_BUFFER_H_
+#define DAWNWIRE_CLIENT_BUFFER_H_
+
+#include <dawn/dawn.h>
+
+#include "dawn_wire/client/ObjectBase.h"
+
+#include <map>
+
+namespace dawn_wire { namespace client {
+
+ struct Buffer : ObjectBase {
+ using ObjectBase::ObjectBase;
+
+ ~Buffer();
+ void ClearMapRequests(dawnBufferMapAsyncStatus status);
+
+ // We want to defer all the validation to the server, which means we could have multiple
+ // map request in flight at a single time and need to track them separately.
+ // On well-behaved applications, only one request should exist at a single time.
+ struct MapRequestData {
+ dawnBufferMapReadCallback readCallback = nullptr;
+ dawnBufferMapWriteCallback writeCallback = nullptr;
+ dawnCallbackUserdata userdata = 0;
+ uint32_t size = 0;
+ bool isWrite = false;
+ };
+ std::map<uint32_t, MapRequestData> requests;
+ uint32_t requestSerial = 0;
+
+ // Only one mapped pointer can be active at a time because Unmap clears all the in-flight
+ // requests.
+ void* mappedData = nullptr;
+ size_t mappedDataSize = 0;
+ bool isWriteMapped = false;
+ };
+
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_BUFFER_H_
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/Client.cpp b/chromium/third_party/dawn/src/dawn_wire/client/Client.cpp
new file mode 100644
index 00000000000..6921fa95888
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/Client.cpp
@@ -0,0 +1,22 @@
+// Copyright 2019 The Dawn 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_wire/client/Client.h"
+
+namespace dawn_wire { namespace client {
+
+ Client::Client(Device* device) : mDevice(device) {
+ }
+
+}} // namespace dawn_wire::client
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/Client.h b/chromium/third_party/dawn/src/dawn_wire/client/Client.h
new file mode 100644
index 00000000000..cf975e8b95e
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/Client.h
@@ -0,0 +1,43 @@
+// Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_CLIENT_H_
+#define DAWNWIRE_CLIENT_CLIENT_H_
+
+#include <dawn_wire/Wire.h>
+
+#include "dawn_wire/WireCmd_autogen.h"
+#include "dawn_wire/WireDeserializeAllocator.h"
+
+namespace dawn_wire { namespace client {
+
+ class Device;
+
+ class Client : public CommandHandler {
+ public:
+ Client(Device* device);
+ const char* HandleCommands(const char* commands, size_t size);
+
+ private:
+#include "dawn_wire/client/ClientPrototypes_autogen.inl"
+
+ Device* mDevice;
+ WireDeserializeAllocator mAllocator;
+ };
+
+ dawnProcTable GetProcs();
+
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_CLIENT_H_
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/ClientHandlers.cpp b/chromium/third_party/dawn/src/dawn_wire/client/ClientHandlers.cpp
new file mode 100644
index 00000000000..dc64ec2cc2c
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/ClientHandlers.cpp
@@ -0,0 +1,172 @@
+// Copyright 2019 The Dawn 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 "common/Assert.h"
+#include "dawn_wire/client/Client.h"
+#include "dawn_wire/client/Device_autogen.h"
+
+namespace dawn_wire { namespace client {
+
+ bool Client::HandleDeviceErrorCallback(const char** commands, size_t* size) {
+ ReturnDeviceErrorCallbackCmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
+
+ if (deserializeResult == DeserializeResult::FatalError) {
+ return false;
+ }
+
+ DAWN_ASSERT(cmd.message != nullptr);
+ mDevice->HandleError(cmd.message);
+
+ return true;
+ }
+
+ bool Client::HandleBufferMapReadAsyncCallback(const char** commands, size_t* size) {
+ ReturnBufferMapReadAsyncCallbackCmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
+
+ if (deserializeResult == DeserializeResult::FatalError) {
+ return false;
+ }
+
+ auto* buffer = mDevice->buffer.GetObject(cmd.buffer.id);
+ uint32_t bufferSerial = mDevice->buffer.GetSerial(cmd.buffer.id);
+
+ // The buffer might have been deleted or recreated so this isn't an error.
+ if (buffer == nullptr || bufferSerial != cmd.buffer.serial) {
+ return true;
+ }
+
+ // The requests can have been deleted via an Unmap so this isn't an error.
+ auto requestIt = buffer->requests.find(cmd.requestSerial);
+ if (requestIt == buffer->requests.end()) {
+ return true;
+ }
+
+ // It is an error for the server to call the read callback when we asked for a map write
+ if (requestIt->second.isWrite) {
+ return false;
+ }
+
+ auto request = requestIt->second;
+ // Delete the request before calling the callback otherwise the callback could be fired a
+ // second time. If, for example, buffer.Unmap() is called inside the callback.
+ buffer->requests.erase(requestIt);
+
+ // On success, we copy the data locally because the IPC buffer isn't valid outside of this
+ // function
+ if (cmd.status == DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS) {
+ // The server didn't send the right amount of data, this is an error and could cause
+ // the application to crash if we did call the callback.
+ if (request.size != cmd.dataLength) {
+ return false;
+ }
+
+ ASSERT(cmd.data != nullptr);
+
+ if (buffer->mappedData != nullptr) {
+ return false;
+ }
+
+ buffer->isWriteMapped = false;
+ buffer->mappedDataSize = request.size;
+ buffer->mappedData = malloc(request.size);
+ memcpy(buffer->mappedData, cmd.data, request.size);
+
+ request.readCallback(static_cast<dawnBufferMapAsyncStatus>(cmd.status),
+ buffer->mappedData, request.userdata);
+ } else {
+ request.readCallback(static_cast<dawnBufferMapAsyncStatus>(cmd.status), nullptr,
+ request.userdata);
+ }
+
+ return true;
+ }
+
+ bool Client::HandleBufferMapWriteAsyncCallback(const char** commands, size_t* size) {
+ ReturnBufferMapWriteAsyncCallbackCmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
+
+ if (deserializeResult == DeserializeResult::FatalError) {
+ return false;
+ }
+
+ auto* buffer = mDevice->buffer.GetObject(cmd.buffer.id);
+ uint32_t bufferSerial = mDevice->buffer.GetSerial(cmd.buffer.id);
+
+ // The buffer might have been deleted or recreated so this isn't an error.
+ if (buffer == nullptr || bufferSerial != cmd.buffer.serial) {
+ return true;
+ }
+
+ // The requests can have been deleted via an Unmap so this isn't an error.
+ auto requestIt = buffer->requests.find(cmd.requestSerial);
+ if (requestIt == buffer->requests.end()) {
+ return true;
+ }
+
+ // It is an error for the server to call the write callback when we asked for a map read
+ if (!requestIt->second.isWrite) {
+ return false;
+ }
+
+ auto request = requestIt->second;
+ // Delete the request before calling the callback otherwise the callback could be fired a
+ // second time. If, for example, buffer.Unmap() is called inside the callback.
+ buffer->requests.erase(requestIt);
+
+ // On success, we copy the data locally because the IPC buffer isn't valid outside of this
+ // function
+ if (cmd.status == DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS) {
+ if (buffer->mappedData != nullptr) {
+ return false;
+ }
+
+ buffer->isWriteMapped = true;
+ buffer->mappedDataSize = request.size;
+ buffer->mappedData = malloc(request.size);
+ memset(buffer->mappedData, 0, request.size);
+
+ request.writeCallback(static_cast<dawnBufferMapAsyncStatus>(cmd.status),
+ buffer->mappedData, request.userdata);
+ } else {
+ request.writeCallback(static_cast<dawnBufferMapAsyncStatus>(cmd.status), nullptr,
+ request.userdata);
+ }
+
+ return true;
+ }
+
+ bool Client::HandleFenceUpdateCompletedValue(const char** commands, size_t* size) {
+ ReturnFenceUpdateCompletedValueCmd cmd;
+ DeserializeResult deserializeResult = cmd.Deserialize(commands, size, &mAllocator);
+
+ if (deserializeResult == DeserializeResult::FatalError) {
+ return false;
+ }
+
+ auto* fence = mDevice->fence.GetObject(cmd.fence.id);
+ uint32_t fenceSerial = mDevice->fence.GetSerial(cmd.fence.id);
+
+ // The fence might have been deleted or recreated so this isn't an error.
+ if (fence == nullptr || fenceSerial != cmd.fence.serial) {
+ return true;
+ }
+
+ fence->completedValue = cmd.value;
+ fence->CheckPassedFences();
+ return true;
+ }
+
+}} // namespace dawn_wire::client
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/Fence.cpp b/chromium/third_party/dawn/src/dawn_wire/client/Fence.cpp
new file mode 100644
index 00000000000..497b714f50c
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/Fence.cpp
@@ -0,0 +1,35 @@
+// Copyright 2019 The Dawn 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_wire/client/Fence.h"
+
+namespace dawn_wire { namespace client {
+
+ Fence::~Fence() {
+ // Callbacks need to be fired in all cases, as they can handle freeing resources
+ // so we call them with "Unknown" status.
+ for (auto& request : requests.IterateAll()) {
+ request.completionCallback(DAWN_FENCE_COMPLETION_STATUS_UNKNOWN, request.userdata);
+ }
+ requests.Clear();
+ }
+
+ void Fence::CheckPassedFences() {
+ for (auto& request : requests.IterateUpTo(completedValue)) {
+ request.completionCallback(DAWN_FENCE_COMPLETION_STATUS_SUCCESS, request.userdata);
+ }
+ requests.ClearUpTo(completedValue);
+ }
+
+}} // namespace dawn_wire::client
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/Fence.h b/chromium/third_party/dawn/src/dawn_wire/client/Fence.h
new file mode 100644
index 00000000000..dd17b7c03eb
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/Fence.h
@@ -0,0 +1,42 @@
+// Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_FENCE_H_
+#define DAWNWIRE_CLIENT_FENCE_H_
+
+#include <dawn/dawn.h>
+
+#include "common/SerialMap.h"
+#include "dawn_wire/client/ObjectBase.h"
+
+namespace dawn_wire { namespace client {
+
+ struct Fence : ObjectBase {
+ using ObjectBase::ObjectBase;
+
+ ~Fence();
+ void CheckPassedFences();
+
+ struct OnCompletionData {
+ dawnFenceOnCompletionCallback completionCallback = nullptr;
+ dawnCallbackUserdata userdata = 0;
+ };
+ uint64_t signaledValue = 0;
+ uint64_t completedValue = 0;
+ SerialMap<OnCompletionData> requests;
+ };
+
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_FENCE_H_
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/ObjectAllocator.h b/chromium/third_party/dawn/src/dawn_wire/client/ObjectAllocator.h
new file mode 100644
index 00000000000..c50307cc1b6
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/ObjectAllocator.h
@@ -0,0 +1,103 @@
+// Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_OBJECTALLOCATOR_H_
+#define DAWNWIRE_CLIENT_OBJECTALLOCATOR_H_
+
+#include "common/Assert.h"
+
+#include <memory>
+#include <vector>
+
+namespace dawn_wire { namespace client {
+
+ class Device;
+
+ // TODO(cwallez@chromium.org): Do something with objects before they are destroyed ?
+ // - Call still uncalled builder callbacks
+ template <typename T>
+ class ObjectAllocator {
+ public:
+ struct ObjectAndSerial {
+ ObjectAndSerial(std::unique_ptr<T> object, uint32_t serial)
+ : object(std::move(object)), serial(serial) {
+ }
+ std::unique_ptr<T> object;
+ uint32_t serial;
+ };
+
+ ObjectAllocator(Device* device) : mDevice(device) {
+ // ID 0 is nullptr
+ mObjects.emplace_back(nullptr, 0);
+ }
+
+ ObjectAndSerial* New() {
+ uint32_t id = GetNewId();
+ T* result = new T(mDevice, 1, id);
+ auto object = std::unique_ptr<T>(result);
+
+ if (id >= mObjects.size()) {
+ ASSERT(id == mObjects.size());
+ mObjects.emplace_back(std::move(object), 0);
+ } else {
+ ASSERT(mObjects[id].object == nullptr);
+ // TODO(cwallez@chromium.org): investigate if overflows could cause bad things to
+ // happen
+ mObjects[id].serial++;
+ mObjects[id].object = std::move(object);
+ }
+
+ return &mObjects[id];
+ }
+ void Free(T* obj) {
+ FreeId(obj->id);
+ mObjects[obj->id].object = nullptr;
+ }
+
+ T* GetObject(uint32_t id) {
+ if (id >= mObjects.size()) {
+ return nullptr;
+ }
+ return mObjects[id].object.get();
+ }
+
+ uint32_t GetSerial(uint32_t id) {
+ if (id >= mObjects.size()) {
+ return 0;
+ }
+ return mObjects[id].serial;
+ }
+
+ private:
+ uint32_t GetNewId() {
+ if (mFreeIds.empty()) {
+ return mCurrentId++;
+ }
+ uint32_t id = mFreeIds.back();
+ mFreeIds.pop_back();
+ return id;
+ }
+ void FreeId(uint32_t id) {
+ mFreeIds.push_back(id);
+ }
+
+ // 0 is an ID reserved to represent nullptr
+ uint32_t mCurrentId = 1;
+ std::vector<uint32_t> mFreeIds;
+ std::vector<ObjectAndSerial> mObjects;
+ Device* mDevice;
+ };
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_OBJECTALLOCATOR_H_
diff --git a/chromium/third_party/dawn/src/dawn_wire/client/ObjectBase.h b/chromium/third_party/dawn/src/dawn_wire/client/ObjectBase.h
new file mode 100644
index 00000000000..70005f2cc6c
--- /dev/null
+++ b/chromium/third_party/dawn/src/dawn_wire/client/ObjectBase.h
@@ -0,0 +1,60 @@
+// Copyright 2019 The Dawn 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.
+
+#ifndef DAWNWIRE_CLIENT_OBJECTBASE_H_
+#define DAWNWIRE_CLIENT_OBJECTBASE_H_
+
+#include <dawn/dawn.h>
+
+namespace dawn_wire { namespace client {
+
+ class Device;
+
+ struct BuilderCallbackData {
+ bool Call(dawnBuilderErrorStatus status, const char* message) {
+ if (canCall && callback != nullptr) {
+ canCall = true;
+ callback(status, message, userdata1, userdata2);
+ return true;
+ }
+
+ return false;
+ }
+
+ // For help with development, prints all builder errors by default.
+ dawnBuilderErrorCallback callback = nullptr;
+ dawnCallbackUserdata userdata1 = 0;
+ dawnCallbackUserdata userdata2 = 0;
+ bool canCall = true;
+ };
+
+ // All non-Device objects of the client side have:
+ // - A pointer to the device to get where to serialize commands
+ // - The external reference count
+ // - An ID that is used to refer to this object when talking with the server side
+ struct ObjectBase {
+ ObjectBase(Device* device, uint32_t refcount, uint32_t id)
+ : device(device), refcount(refcount), id(id) {
+ }
+
+ Device* device;
+ uint32_t refcount;
+ uint32_t id;
+
+ BuilderCallbackData builderCallback;
+ };
+
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_OBJECTBASE_H_
diff --git a/chromium/third_party/dawn/src/fuzzers/BUILD.gn b/chromium/third_party/dawn/src/fuzzers/BUILD.gn
index 00f378940cf..9df69ebcc4c 100644
--- a/chromium/third_party/dawn/src/fuzzers/BUILD.gn
+++ b/chromium/third_party/dawn/src/fuzzers/BUILD.gn
@@ -76,7 +76,7 @@ static_library("dawn_spirv_cross_fuzzer_common") {
"DawnSPIRVCrossFuzzer.h",
]
public_deps = [
- "${dawn_top_level}/third_party:spirv_cross",
+ "${dawn_top_level}/third_party:spirv_cross_full_for_fuzzers",
]
}
@@ -164,10 +164,13 @@ dawn_fuzzer_test("dawn_wire_server_and_frontend_fuzzer") {
]
deps = [
- "${dawn_top_level}:libdawn_sources",
- "${dawn_top_level}:libdawn_native_sources",
- "${dawn_top_level}:libdawn_wire_sources",
+ "${dawn_top_level}:dawn_common",
+ "${dawn_top_level}:libdawn_static",
+ "${dawn_top_level}:libdawn_native_static",
+ "${dawn_top_level}:libdawn_wire_static",
]
- additional_configs = [ "${dawn_top_level}:dawn_shared_library_public" ]
+ additional_configs = [
+ "${dawn_top_level}:dawn_internal",
+ ]
}
diff --git a/chromium/third_party/dawn/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp b/chromium/third_party/dawn/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
index f6778921521..9160b299ce1 100644
--- a/chromium/third_party/dawn/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
+++ b/chromium/third_party/dawn/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "common/Assert.h"
#include "dawn/dawncpp.h"
#include "dawn_native/DawnNative.h"
-#include "dawn_native/NullBackend.h"
#include "dawn_wire/Wire.h"
#include <vector>
@@ -45,7 +45,20 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
procs.swapChainBuilderSetImplementation = SkipSwapChainBuilderSetImplementation;
dawnSetProcs(&procs);
- dawn::Device nullDevice = dawn::Device::Acquire(dawn_native::null::CreateDevice());
+ // Create an instance and find the null adapter to create a device with.
+ std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
+ instance->DiscoverDefaultAdapters();
+
+ std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
+
+ dawn::Device nullDevice;
+ for (dawn_native::Adapter adapter : adapters) {
+ if (adapter.GetBackendType() == dawn_native::BackendType::Null) {
+ nullDevice = dawn::Device::Acquire(adapter.CreateDevice());
+ break;
+ }
+ }
+ ASSERT(nullDevice.Get() != nullptr);
DevNull devNull;
std::unique_ptr<dawn_wire::CommandHandler> wireServer(
@@ -53,5 +66,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
wireServer->HandleCommands(reinterpret_cast<const char*>(data), size);
+ // Fake waiting for all previous commands before destroying the server.
+ nullDevice.Tick();
+
+ // Destroy the server before the device because it needs to free all objects.
+ wireServer = nullptr;
+ nullDevice = nullptr;
+ instance = nullptr;
+
return 0;
}
diff --git a/chromium/third_party/dawn/src/include/dawn/dawn_export.h b/chromium/third_party/dawn/src/include/dawn/dawn_export.h
index d00c8fdb857..354bcfff0fe 100644
--- a/chromium/third_party/dawn/src/include/dawn/dawn_export.h
+++ b/chromium/third_party/dawn/src/include/dawn/dawn_export.h
@@ -15,18 +15,22 @@
#ifndef DAWN_EXPORT_H_
#define DAWN_EXPORT_H_
-#if defined(_WIN32)
-# if defined(DAWN_IMPLEMENTATION)
-# define DAWN_EXPORT __declspec(dllexport)
-# else
-# define DAWN_EXPORT __declspec(dllimport)
-# endif
-#else
-# if defined(DAWN_IMPLEMENTATION)
-# define DAWN_EXPORT __attribute__((visibility("default")))
-# else
-# define DAWN_EXPORT
-# endif
-#endif
+#if defined(DAWN_SHARED_LIBRARY)
+# if defined(_WIN32)
+# if defined(DAWN_IMPLEMENTATION)
+# define DAWN_EXPORT __declspec(dllexport)
+# else
+# define DAWN_EXPORT __declspec(dllimport)
+# endif
+# else // defined(_WIN32)
+# if defined(DAWN_IMPLEMENTATION)
+# define DAWN_EXPORT __attribute__((visibility("default")))
+# else
+# define DAWN_EXPORT
+# endif
+# endif // defined(_WIN32)
+#else // defined(DAWN_SHARED_LIBRARY)
+# define DAWN_EXPORT
+#endif // defined(DAWN_SHARED_LIBRARY)
#endif // DAWN_EXPORT_H_
diff --git a/chromium/third_party/dawn/src/include/dawn_native/DawnNative.h b/chromium/third_party/dawn/src/include/dawn_native/DawnNative.h
index f90dc9eaa6d..c1c439edf19 100644
--- a/chromium/third_party/dawn/src/include/dawn_native/DawnNative.h
+++ b/chromium/third_party/dawn/src/include/dawn_native/DawnNative.h
@@ -19,14 +19,88 @@
#include <dawn_native/dawn_native_export.h>
#include <string>
+#include <vector>
namespace dawn_native {
+
struct PCIInfo {
uint32_t deviceId = 0;
uint32_t vendorId = 0;
std::string name;
};
+ enum class BackendType {
+ D3D12,
+ Metal,
+ Null,
+ OpenGL,
+ Vulkan,
+ };
+
+ class InstanceBase;
+ class AdapterBase;
+
+ // An adapter is an object that represent on possibility of creating devices in the system.
+ // Most of the time it will represent a combination of a physical GPU and an API. Not that the
+ // same GPU can be represented by multiple adapters but on different APIs.
+ //
+ // The underlying Dawn adapter is owned by the Dawn instance so this class is not RAII but just
+ // a reference to an underlying adapter.
+ class DAWN_NATIVE_EXPORT Adapter {
+ public:
+ Adapter();
+ Adapter(AdapterBase* impl);
+ ~Adapter();
+
+ BackendType GetBackendType() const;
+ const PCIInfo& GetPCIInfo() const;
+
+ // Create a device on this adapter, note that the interface will change to include at least
+ // a device descriptor and a pointer to backend specific options.
+ // On an error, nullptr is returned.
+ dawnDevice CreateDevice();
+
+ private:
+ AdapterBase* mImpl = nullptr;
+ };
+
+ // Base class for options passed to Instance::DiscoverAdapters.
+ struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptionsBase {
+ public:
+ const BackendType backendType;
+
+ protected:
+ AdapterDiscoveryOptionsBase(BackendType type);
+ };
+
+ // Represents a connection to dawn_native and is used for dependency injection, discovering
+ // system adapters and injecting custom adapters (like a Swiftshader Vulkan adapter).
+ //
+ // This is an RAII class for Dawn instances and also controls the lifetime of all adapters
+ // for this instance.
+ class DAWN_NATIVE_EXPORT Instance {
+ public:
+ Instance();
+ ~Instance();
+
+ Instance(const Instance& other) = delete;
+ Instance& operator=(const Instance& other) = delete;
+
+ // Gather all adapters in the system that can be accessed with no special options. These
+ // adapters will later be returned by GetAdapters.
+ void DiscoverDefaultAdapters();
+
+ // Adds adapters that can be discovered with the options provided (like a getProcAddress).
+ // The backend is chosen based on the type of the options used. Returns true on success.
+ bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
+
+ // Returns all the adapters that the instance knows about.
+ std::vector<Adapter> GetAdapters() const;
+
+ private:
+ InstanceBase* mImpl = nullptr;
+ };
+
// Backend-agnostic API for dawn_native
DAWN_NATIVE_EXPORT dawnProcTable GetProcs();
diff --git a/chromium/third_party/dawn/src/include/dawn_native/MetalBackend.h b/chromium/third_party/dawn/src/include/dawn_native/MetalBackend.h
index 758868d1f3a..aad945a7b6d 100644
--- a/chromium/third_party/dawn/src/include/dawn_native/MetalBackend.h
+++ b/chromium/third_party/dawn/src/include/dawn_native/MetalBackend.h
@@ -23,9 +23,8 @@
#import <QuartzCore/CAMetalLayer.h>
namespace dawn_native { namespace metal {
- DAWN_NATIVE_EXPORT dawnDevice CreateDevice(id<MTLDevice> metalDevice);
- DAWN_NATIVE_EXPORT void SetNextDrawable(dawnDevice device, id<CAMetalDrawable> drawable);
- DAWN_NATIVE_EXPORT void Present(dawnDevice device);
+ DAWN_NATIVE_EXPORT dawnDevice CreateDevice();
+ DAWN_NATIVE_EXPORT id<MTLDevice> GetMetalDevice(dawnDevice device);
}} // namespace dawn_native::metal
#endif // DAWNNATIVE_METALBACKEND_H_
diff --git a/chromium/third_party/dawn/src/include/dawn_native/NullBackend.h b/chromium/third_party/dawn/src/include/dawn_native/NullBackend.h
index be7c3e715e1..7862c5f3586 100644
--- a/chromium/third_party/dawn/src/include/dawn_native/NullBackend.h
+++ b/chromium/third_party/dawn/src/include/dawn_native/NullBackend.h
@@ -15,11 +15,11 @@
#ifndef DAWNNATIVE_NULLBACKEND_H_
#define DAWNNATIVE_NULLBACKEND_H_
-#include <dawn/dawn.h>
-#include <dawn_native/dawn_native_export.h>
+#include <dawn/dawn_wsi.h>
+#include <dawn_native/DawnNative.h>
namespace dawn_native { namespace null {
- DAWN_NATIVE_EXPORT dawnDevice CreateDevice();
+ DAWN_NATIVE_EXPORT dawnSwapChainImplementation CreateNativeSwapChainImpl();
}} // namespace dawn_native::null
#endif // DAWNNATIVE_NULLBACKEND_H_
diff --git a/chromium/third_party/dawn/src/include/dawn_native/OpenGLBackend.h b/chromium/third_party/dawn/src/include/dawn_native/OpenGLBackend.h
index e31f7d38d5d..10b00004a55 100644
--- a/chromium/third_party/dawn/src/include/dawn_native/OpenGLBackend.h
+++ b/chromium/third_party/dawn/src/include/dawn_native/OpenGLBackend.h
@@ -15,11 +15,16 @@
#ifndef DAWNNATIVE_OPENGLBACKEND_H_
#define DAWNNATIVE_OPENGLBACKEND_H_
-#include <dawn/dawn.h>
-#include <dawn_native/dawn_native_export.h>
+#include <dawn_native/DawnNative.h>
namespace dawn_native { namespace opengl {
- DAWN_NATIVE_EXPORT dawnDevice CreateDevice(void* (*getProc)(const char*));
+
+ struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
+ AdapterDiscoveryOptions();
+
+ void* (*getProc)(const char*);
+ };
+
}} // namespace dawn_native::opengl
#endif // DAWNNATIVE_OPENGLBACKEND_H_
diff --git a/chromium/third_party/dawn/src/include/dawn_native/VulkanBackend.h b/chromium/third_party/dawn/src/include/dawn_native/VulkanBackend.h
index e52e0cec046..9bf7a2a0359 100644
--- a/chromium/third_party/dawn/src/include/dawn_native/VulkanBackend.h
+++ b/chromium/third_party/dawn/src/include/dawn_native/VulkanBackend.h
@@ -24,8 +24,7 @@
#include <vector>
namespace dawn_native { namespace vulkan {
- DAWN_NATIVE_EXPORT dawnDevice
- CreateDevice(const std::vector<const char*>& requiredInstanceExtensions);
+ DAWN_NATIVE_EXPORT dawnDevice CreateDevice();
DAWN_NATIVE_EXPORT VkInstance GetInstance(dawnDevice device);
diff --git a/chromium/third_party/dawn/src/include/dawn_native/dawn_native_export.h b/chromium/third_party/dawn/src/include/dawn_native/dawn_native_export.h
index f2581679543..ffbd9cc369f 100644
--- a/chromium/third_party/dawn/src/include/dawn_native/dawn_native_export.h
+++ b/chromium/third_party/dawn/src/include/dawn_native/dawn_native_export.h
@@ -15,18 +15,22 @@
#ifndef DAWNNATIVE_EXPORT_H_
#define DAWNNATIVE_EXPORT_H_
-#if defined(_WIN32)
-# if defined(DAWN_NATIVE_IMPLEMENTATION)
-# define DAWN_NATIVE_EXPORT __declspec(dllexport)
-# else
-# define DAWN_NATIVE_EXPORT __declspec(dllimport)
-# endif
-#else
-# if defined(DAWN_NATIVE_IMPLEMENTATION)
-# define DAWN_NATIVE_EXPORT __attribute__((visibility("default")))
-# else
-# define DAWN_NATIVE_EXPORT
-# endif
-#endif
+#if defined(DAWN_NATIVE_SHARED_LIBRARY)
+# if defined(_WIN32)
+# if defined(DAWN_NATIVE_IMPLEMENTATION)
+# define DAWN_NATIVE_EXPORT __declspec(dllexport)
+# else
+# define DAWN_NATIVE_EXPORT __declspec(dllimport)
+# endif
+# else // defined(_WIN32)
+# if defined(DAWN_NATIVE_IMPLEMENTATION)
+# define DAWN_NATIVE_EXPORT __attribute__((visibility("default")))
+# else
+# define DAWN_NATIVE_EXPORT
+# endif
+# endif // defined(_WIN32)
+#else // defined(DAWN_NATIVE_SHARED_LIBRARY)
+# define DAWN_NATIVE_EXPORT
+#endif // defined(DAWN_NATIVE_SHARED_LIBRARY)
#endif // DAWNNATIVE_EXPORT_H_
diff --git a/chromium/third_party/dawn/src/include/dawn_wire/dawn_wire_export.h b/chromium/third_party/dawn/src/include/dawn_wire/dawn_wire_export.h
index d22376266d3..8043f618c19 100644
--- a/chromium/third_party/dawn/src/include/dawn_wire/dawn_wire_export.h
+++ b/chromium/third_party/dawn/src/include/dawn_wire/dawn_wire_export.h
@@ -15,18 +15,22 @@
#ifndef DAWNWIRE_EXPORT_H_
#define DAWNWIRE_EXPORT_H_
-#if defined(_WIN32)
-# if defined(DAWN_WIRE_IMPLEMENTATION)
-# define DAWN_WIRE_EXPORT __declspec(dllexport)
-# else
-# define DAWN_WIRE_EXPORT __declspec(dllimport)
-# endif
-#else
-# if defined(DAWN_WIRE_IMPLEMENTATION)
-# define DAWN_WIRE_EXPORT __attribute__((visibility("default")))
-# else
-# define DAWN_WIRE_EXPORT
-# endif
-#endif
+#if defined(DAWN_WIRE_SHARED_LIBRARY)
+# if defined(_WIN32)
+# if defined(DAWN_WIRE_IMPLEMENTATION)
+# define DAWN_WIRE_EXPORT __declspec(dllexport)
+# else
+# define DAWN_WIRE_EXPORT __declspec(dllimport)
+# endif
+# else // defined(_WIN32)
+# if defined(DAWN_WIRE_IMPLEMENTATION)
+# define DAWN_WIRE_EXPORT __attribute__((visibility("default")))
+# else
+# define DAWN_WIRE_EXPORT
+# endif
+# endif // defined(_WIN32)
+#else // defined(DAWN_WIRE_SHARED_LIBRARY)
+# define DAWN_WIRE_EXPORT
+#endif // defined(DAWN_WIRE_SHARED_LIBRARY)
#endif // DAWNWIRE_EXPORT_H_
diff --git a/chromium/third_party/dawn/src/utils/ComboRenderPipelineDescriptor.cpp b/chromium/third_party/dawn/src/utils/ComboRenderPipelineDescriptor.cpp
new file mode 100644
index 00000000000..8a07da165cb
--- /dev/null
+++ b/chromium/third_party/dawn/src/utils/ComboRenderPipelineDescriptor.cpp
@@ -0,0 +1,95 @@
+// Copyright 2018 The Dawn 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 "utils/ComboRenderPipelineDescriptor.h"
+
+#include "utils/DawnHelpers.h"
+
+namespace utils {
+
+ ComboRenderPipelineDescriptor::ComboRenderPipelineDescriptor(const dawn::Device& device) {
+ dawn::RenderPipelineDescriptor* descriptor = this;
+
+ descriptor->indexFormat = dawn::IndexFormat::Uint32;
+ descriptor->primitiveTopology = dawn::PrimitiveTopology::TriangleList;
+ descriptor->sampleCount = 1;
+
+ // Set defaults for the vertex stage descriptor.
+ {
+ descriptor->vertexStage = &cVertexStage;
+ cVertexStage.entryPoint = "main";
+ }
+
+ // Set defaults for the fragment stage desriptor.
+ {
+ descriptor->fragmentStage = &cFragmentStage;
+ cFragmentStage.entryPoint = "main";
+ }
+
+ // Set defaults for the attachment states.
+ {
+ descriptor->attachmentsState = &cAttachmentsState;
+ cAttachmentsState.numColorAttachments = 1;
+ cAttachmentsState.colorAttachments = &cColorAttachments[0];
+ cAttachmentsState.depthStencilAttachment = &cDepthStencilAttachment;
+ cAttachmentsState.hasDepthStencilAttachment = false;
+
+ for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
+ colorAttachments[i].format = dawn::TextureFormat::R8G8B8A8Unorm;
+ cColorAttachments[i] = &colorAttachments[i];
+ }
+ }
+
+ // Set defaults for the blend state descriptors.
+ {
+ descriptor->numBlendStates = 1;
+ descriptor->blendStates = &cBlendStates[0];
+
+ dawn::BlendDescriptor blend;
+ blend.operation = dawn::BlendOperation::Add;
+ blend.srcFactor = dawn::BlendFactor::One;
+ blend.dstFactor = dawn::BlendFactor::Zero;
+ dawn::BlendStateDescriptor blendStateDescriptor;
+ blendStateDescriptor.blendEnabled = false;
+ blendStateDescriptor.alphaBlend = blend;
+ blendStateDescriptor.colorBlend = blend;
+ blendStateDescriptor.colorWriteMask = dawn::ColorWriteMask::All;
+ for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
+ cBlendStates[i] = blendStateDescriptor;
+ }
+ }
+
+ // Set defaults for the depth stencil state descriptors.
+ {
+ dawn::StencilStateFaceDescriptor stencilFace;
+ stencilFace.compare = dawn::CompareFunction::Always;
+ stencilFace.stencilFailOp = dawn::StencilOperation::Keep;
+ stencilFace.depthFailOp = dawn::StencilOperation::Keep;
+ stencilFace.passOp = dawn::StencilOperation::Keep;
+
+ // dawn::DepthStencilStateDescriptor depthStencilState;
+ cDepthStencilState.depthWriteEnabled = false;
+ cDepthStencilState.depthCompare = dawn::CompareFunction::Always;
+ cDepthStencilState.back = stencilFace;
+ cDepthStencilState.front = stencilFace;
+ cDepthStencilState.stencilReadMask = 0xff;
+ cDepthStencilState.stencilWriteMask = 0xff;
+ descriptor->depthStencilState = &cDepthStencilState;
+ }
+
+ descriptor->inputState = device.CreateInputStateBuilder().GetResult();
+ descriptor->layout = utils::MakeBasicPipelineLayout(device, nullptr);
+ }
+
+} // namespace utils
diff --git a/chromium/third_party/dawn/src/utils/ComboRenderPipelineDescriptor.h b/chromium/third_party/dawn/src/utils/ComboRenderPipelineDescriptor.h
new file mode 100644
index 00000000000..3fa120210d9
--- /dev/null
+++ b/chromium/third_party/dawn/src/utils/ComboRenderPipelineDescriptor.h
@@ -0,0 +1,45 @@
+// Copyright 2018 The Dawn 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.
+
+#ifndef UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_
+#define UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_
+
+#include <dawn/dawncpp.h>
+
+#include "common/Constants.h"
+
+#include <array>
+
+namespace utils {
+
+ class ComboRenderPipelineDescriptor : public dawn::RenderPipelineDescriptor {
+ public:
+ ComboRenderPipelineDescriptor(const dawn::Device& device);
+
+ dawn::PipelineStageDescriptor cVertexStage;
+ dawn::PipelineStageDescriptor cFragmentStage;
+
+ dawn::AttachmentsStateDescriptor cAttachmentsState;
+ std::array<dawn::AttachmentDescriptor*, kMaxColorAttachments> cColorAttachments;
+ dawn::AttachmentDescriptor cDepthStencilAttachment;
+ std::array<dawn::BlendStateDescriptor, kMaxColorAttachments> cBlendStates;
+ dawn::DepthStencilStateDescriptor cDepthStencilState;
+
+ private:
+ dawn::AttachmentDescriptor colorAttachments[kMaxColorAttachments];
+ };
+
+} // namespace utils
+
+#endif // UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_
diff --git a/chromium/third_party/dawn/src/utils/DawnHelpers.cpp b/chromium/third_party/dawn/src/utils/DawnHelpers.cpp
index e88a92d11c8..063e39e6404 100644
--- a/chromium/third_party/dawn/src/utils/DawnHelpers.cpp
+++ b/chromium/third_party/dawn/src/utils/DawnHelpers.cpp
@@ -15,6 +15,7 @@
#include "utils/DawnHelpers.h"
#include "common/Assert.h"
+#include "common/Constants.h"
#include <shaderc/shaderc.hpp>
@@ -138,7 +139,8 @@ namespace utils {
descriptor.size.width = width;
descriptor.size.height = height;
descriptor.size.depth = 1;
- descriptor.arrayLayer = 1;
+ descriptor.arraySize = 1;
+ descriptor.sampleCount = 1;
descriptor.format = result.colorFormat;
descriptor.levelCount = 1;
descriptor.usage =
@@ -146,8 +148,14 @@ namespace utils {
result.color = device.CreateTexture(&descriptor);
dawn::TextureView colorView = result.color.CreateDefaultTextureView();
+ dawn::RenderPassColorAttachmentDescriptor colorAttachment;
+ colorAttachment.attachment = colorView;
+ colorAttachment.resolveTarget = nullptr;
+ colorAttachment.clearColor = {0.0f, 0.0f, 0.0f, 0.0f};
+ colorAttachment.loadOp = dawn::LoadOp::Clear;
+ colorAttachment.storeOp = dawn::StoreOp::Store;
result.renderPassInfo = device.CreateRenderPassDescriptorBuilder()
- .SetColorAttachment(0, colorView, dawn::LoadOp::Clear)
+ .SetColorAttachments(1, &colorAttachment)
.GetResult();
return result;
@@ -169,14 +177,12 @@ namespace utils {
dawn::TextureCopyView CreateTextureCopyView(dawn::Texture texture,
uint32_t level,
uint32_t slice,
- dawn::Origin3D origin,
- dawn::TextureAspect aspect) {
+ dawn::Origin3D origin) {
dawn::TextureCopyView textureCopyView;
textureCopyView.texture = texture;
textureCopyView.level = level;
textureCopyView.slice = slice;
textureCopyView.origin = origin;
- textureCopyView.aspect = aspect;
return textureCopyView;
}
@@ -190,6 +196,10 @@ namespace utils {
desc.addressModeU = dawn::AddressMode::Repeat;
desc.addressModeV = dawn::AddressMode::Repeat;
desc.addressModeW = dawn::AddressMode::Repeat;
+ desc.lodMinClamp = kLodMin;
+ desc.lodMaxClamp = kLodMax;
+ desc.compareFunction = dawn::CompareFunction::Never;
+ desc.borderColor = dawn::BorderColor::TransparentBlack;
return desc;
}
@@ -209,10 +219,11 @@ namespace utils {
dawn::BindGroupLayout MakeBindGroupLayout(
const dawn::Device& device,
- std::initializer_list<dawn::BindGroupBinding> bindingsInitializer) {
- std::vector<dawn::BindGroupBinding> bindings;
- dawn::ShaderStageBit kNoStages{};
- for (const dawn::BindGroupBinding& binding : bindingsInitializer) {
+ std::initializer_list<dawn::BindGroupLayoutBinding> bindingsInitializer) {
+ constexpr dawn::ShaderStageBit kNoStages{};
+
+ std::vector<dawn::BindGroupLayoutBinding> bindings;
+ for (const dawn::BindGroupLayoutBinding& binding : bindingsInitializer) {
if (binding.visibility != kNoStages) {
bindings.push_back(binding);
}
@@ -224,4 +235,51 @@ namespace utils {
return device.CreateBindGroupLayout(&descriptor);
}
+ BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
+ const dawn::Sampler& sampler)
+ : binding(binding), sampler(sampler) {
+ }
+
+ BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
+ const dawn::TextureView& textureView)
+ : binding(binding), textureView(textureView) {
+ }
+
+ BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
+ const dawn::Buffer& buffer,
+ uint32_t offset,
+ uint32_t size)
+ : binding(binding), buffer(buffer), offset(offset), size(size) {
+ }
+
+ dawn::BindGroupBinding BindingInitializationHelper::GetAsBinding() const {
+ dawn::BindGroupBinding result;
+
+ result.binding = binding;
+ result.sampler = sampler;
+ result.textureView = textureView;
+ result.buffer = buffer;
+ result.offset = offset;
+ result.size = size;
+
+ return result;
+ }
+
+ dawn::BindGroup MakeBindGroup(
+ const dawn::Device& device,
+ const dawn::BindGroupLayout& layout,
+ std::initializer_list<BindingInitializationHelper> bindingsInitializer) {
+ std::vector<dawn::BindGroupBinding> bindings;
+ for (const BindingInitializationHelper& helper : bindingsInitializer) {
+ bindings.push_back(helper.GetAsBinding());
+ }
+
+ dawn::BindGroupDescriptor descriptor;
+ descriptor.layout = layout;
+ descriptor.numBindings = bindings.size();
+ descriptor.bindings = bindings.data();
+
+ return device.CreateBindGroup(&descriptor);
+ }
+
} // namespace utils
diff --git a/chromium/third_party/dawn/src/utils/DawnHelpers.h b/chromium/third_party/dawn/src/utils/DawnHelpers.h
index e1e0ed04874..538ebe0e7cf 100644
--- a/chromium/third_party/dawn/src/utils/DawnHelpers.h
+++ b/chromium/third_party/dawn/src/utils/DawnHelpers.h
@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#ifndef UTILS_DAWNHELPERS_H_
+#define UTILS_DAWNHELPERS_H_
+
#include <dawn/dawncpp.h>
#include <initializer_list>
@@ -44,8 +47,7 @@ namespace utils {
dawn::TextureCopyView CreateTextureCopyView(dawn::Texture texture,
uint32_t level,
uint32_t slice,
- dawn::Origin3D origin,
- dawn::TextureAspect aspect);
+ dawn::Origin3D origin);
struct BasicRenderPass {
uint32_t width;
@@ -63,6 +65,41 @@ namespace utils {
const dawn::BindGroupLayout* bindGroupLayout);
dawn::BindGroupLayout MakeBindGroupLayout(
const dawn::Device& device,
- std::initializer_list<dawn::BindGroupBinding> bindingsInitializer);
+ std::initializer_list<dawn::BindGroupLayoutBinding> bindingsInitializer);
+
+ // Helpers to make creating bind groups look nicer:
+ //
+ // utils::MakeBindGroup(device, layout, {
+ // {0, mySampler},
+ // {1, myBuffer, offset, size},
+ // {3, myTexture}
+ // });
+
+ // Structure with one constructor per-type of bindings, so that the initializer_list accepts
+ // bindings with the right type and no extra information.
+ struct BindingInitializationHelper {
+ BindingInitializationHelper(uint32_t binding, const dawn::Sampler& sampler);
+ BindingInitializationHelper(uint32_t binding, const dawn::TextureView& textureView);
+ BindingInitializationHelper(uint32_t binding,
+ const dawn::Buffer& buffer,
+ uint32_t offset,
+ uint32_t size);
+
+ dawn::BindGroupBinding GetAsBinding() const;
+
+ uint32_t binding;
+ dawn::Sampler sampler;
+ dawn::TextureView textureView;
+ dawn::Buffer buffer;
+ uint32_t offset = 0;
+ uint32_t size = 0;
+ };
+
+ dawn::BindGroup MakeBindGroup(
+ const dawn::Device& device,
+ const dawn::BindGroupLayout& layout,
+ std::initializer_list<BindingInitializationHelper> bindingsInitializer);
} // namespace utils
+
+#endif // UTILS_DAWNHELPERS_H_ \ No newline at end of file
diff --git a/chromium/third_party/dawn/src/utils/MetalBinding.mm b/chromium/third_party/dawn/src/utils/MetalBinding.mm
index 8eaba1712b0..55558eda024 100644
--- a/chromium/third_party/dawn/src/utils/MetalBinding.mm
+++ b/chromium/third_party/dawn/src/utils/MetalBinding.mm
@@ -41,7 +41,7 @@ namespace utils {
}
dawnSwapChainError Configure(dawnTextureFormat format,
- dawnTextureUsageBit,
+ dawnTextureUsageBit usage,
uint32_t width,
uint32_t height) {
if (format != DAWN_TEXTURE_FORMAT_B8_G8_R8_A8_UNORM) {
@@ -60,9 +60,15 @@ namespace utils {
mLayer = [CAMetalLayer layer];
[mLayer setDevice:mMtlDevice];
[mLayer setPixelFormat:MTLPixelFormatBGRA8Unorm];
- [mLayer setFramebufferOnly:YES];
[mLayer setDrawableSize:size];
+ constexpr uint32_t kFramebufferOnlyTextureUsages =
+ DAWN_TEXTURE_USAGE_BIT_OUTPUT_ATTACHMENT | DAWN_TEXTURE_USAGE_BIT_PRESENT;
+ bool hasOnlyFramebufferUsages = !(usage & (~kFramebufferOnlyTextureUsages));
+ if (hasOnlyFramebufferUsages) {
+ [mLayer setFramebufferOnly:YES];
+ }
+
[contentView setLayer:mLayer];
return DAWN_SWAP_CHAIN_NO_ERROR;
@@ -105,9 +111,11 @@ namespace utils {
void SetupGLFWWindowHints() override {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
}
+
dawnDevice CreateDevice() override {
- mMetalDevice = MTLCreateSystemDefaultDevice();
- return dawn_native::metal::CreateDevice(mMetalDevice);
+ dawnDevice device = dawn_native::metal::CreateDevice();
+ mMetalDevice = dawn_native::metal::GetMetalDevice(device);
+ return device;
}
uint64_t GetSwapChainImplementation() override {
diff --git a/chromium/third_party/dawn/src/utils/NullBinding.cpp b/chromium/third_party/dawn/src/utils/NullBinding.cpp
index 558531e33cd..213cca7f097 100644
--- a/chromium/third_party/dawn/src/utils/NullBinding.cpp
+++ b/chromium/third_party/dawn/src/utils/NullBinding.cpp
@@ -14,8 +14,11 @@
#include "utils/BackendBinding.h"
+#include "common/Assert.h"
#include "dawn_native/NullBackend.h"
+#include <memory>
+
namespace utils {
class NullBinding : public BackendBinding {
@@ -23,14 +26,33 @@ namespace utils {
void SetupGLFWWindowHints() override {
}
dawnDevice CreateDevice() override {
- return dawn_native::null::CreateDevice();
+ // Make an instance and find the null adapter
+ mInstance = std::make_unique<dawn_native::Instance>();
+ mInstance->DiscoverDefaultAdapters();
+
+ std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
+ for (dawn_native::Adapter adapter : adapters) {
+ if (adapter.GetBackendType() == dawn_native::BackendType::Null) {
+ return adapter.CreateDevice();
+ }
+ }
+
+ UNREACHABLE();
+ return {};
}
uint64_t GetSwapChainImplementation() override {
- return 0;
+ if (mSwapchainImpl.userData == nullptr) {
+ mSwapchainImpl = dawn_native::null::CreateNativeSwapChainImpl();
+ }
+ return reinterpret_cast<uint64_t>(&mSwapchainImpl);
}
dawnTextureFormat GetPreferredSwapChainTextureFormat() override {
return DAWN_TEXTURE_FORMAT_R8_G8_B8_A8_UNORM;
}
+
+ private:
+ std::unique_ptr<dawn_native::Instance> mInstance;
+ dawnSwapChainImplementation mSwapchainImpl = {};
};
BackendBinding* CreateNullBinding() {
diff --git a/chromium/third_party/dawn/src/utils/OpenGLBinding.cpp b/chromium/third_party/dawn/src/utils/OpenGLBinding.cpp
index a0fbc002a60..146cfbee8eb 100644
--- a/chromium/third_party/dawn/src/utils/OpenGLBinding.cpp
+++ b/chromium/third_party/dawn/src/utils/OpenGLBinding.cpp
@@ -108,13 +108,23 @@ namespace utils {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif
}
+
dawnDevice CreateDevice() override {
glfwMakeContextCurrent(mWindow);
// Load the GL entry points in our copy of the glad static library
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress));
- return dawn_native::opengl::CreateDevice(
- reinterpret_cast<void* (*)(const char*)>(glfwGetProcAddress));
+ // Make an instance and "discover" an OpenGL adapter with glfw's getProc
+ mInstance = std::make_unique<dawn_native::Instance>();
+
+ dawn_native::opengl::AdapterDiscoveryOptions adapterOptions;
+ adapterOptions.getProc = reinterpret_cast<void* (*)(const char*)>(glfwGetProcAddress);
+ mInstance->DiscoverAdapters(&adapterOptions);
+
+ std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
+ ASSERT(adapters.size() == 1);
+
+ return adapters[0].CreateDevice();
}
uint64_t GetSwapChainImplementation() override {
@@ -129,6 +139,7 @@ namespace utils {
}
private:
+ std::unique_ptr<dawn_native::Instance> mInstance;
dawnSwapChainImplementation mSwapchainImpl = {};
};
diff --git a/chromium/third_party/dawn/src/utils/SystemUtils.h b/chromium/third_party/dawn/src/utils/SystemUtils.h
index 465e0f66e77..828eb58aabf 100644
--- a/chromium/third_party/dawn/src/utils/SystemUtils.h
+++ b/chromium/third_party/dawn/src/utils/SystemUtils.h
@@ -12,7 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#ifndef UTILS_SYSTEMUTILS_H_
+#define UTILS_SYSTEMUTILS_H_
+
namespace utils {
void USleep(unsigned int usecs);
}
+
+#endif // UTILS_SYSTEMUTILS_H_ \ No newline at end of file
diff --git a/chromium/third_party/dawn/src/utils/VulkanBinding.cpp b/chromium/third_party/dawn/src/utils/VulkanBinding.cpp
index 81068d332ad..7cae7b4776a 100644
--- a/chromium/third_party/dawn/src/utils/VulkanBinding.cpp
+++ b/chromium/third_party/dawn/src/utils/VulkanBinding.cpp
@@ -22,45 +22,13 @@
namespace utils {
- class SwapChainImplVulkan {
- public:
- using WSIContext = dawnWSIContextVulkan;
-
- SwapChainImplVulkan(GLFWwindow* /*window*/) {
- }
-
- ~SwapChainImplVulkan() {
- }
-
- void Init(dawnWSIContextVulkan*) {
- }
-
- dawnSwapChainError Configure(dawnTextureFormat, dawnTextureUsageBit, uint32_t, uint32_t) {
- return DAWN_SWAP_CHAIN_NO_ERROR;
- }
-
- dawnSwapChainError GetNextTexture(dawnSwapChainNextTexture*) {
- return DAWN_SWAP_CHAIN_NO_ERROR;
- }
-
- dawnSwapChainError Present() {
- return DAWN_SWAP_CHAIN_NO_ERROR;
- }
- };
-
class VulkanBinding : public BackendBinding {
public:
void SetupGLFWWindowHints() override {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
}
dawnDevice CreateDevice() override {
- uint32_t extensionCount = 0;
- const char** glfwInstanceExtensions =
- glfwGetRequiredInstanceExtensions(&extensionCount);
- std::vector<const char*> requiredExtensions(glfwInstanceExtensions,
- glfwInstanceExtensions + extensionCount);
-
- mDevice = dawn_native::vulkan::CreateDevice(requiredExtensions);
+ mDevice = dawn_native::vulkan::CreateDevice();
return mDevice;
}
uint64_t GetSwapChainImplementation() override {
diff --git a/chromium/third_party/dawn/third_party/BUILD.gn b/chromium/third_party/dawn/third_party/BUILD.gn
index 62766a4556f..bc1d359f675 100644
--- a/chromium/third_party/dawn/third_party/BUILD.gn
+++ b/chromium/third_party/dawn/third_party/BUILD.gn
@@ -16,10 +16,6 @@ import("../scripts/dawn_overrides_with_defaults.gni")
import("../scripts/dawn_features.gni")
import("//build_overrides/build.gni")
-if (build_with_chromium) {
- import("//testing/libfuzzer/fuzzer_test.gni")
-}
-
is_msvc = is_win && !is_clang
###############################################################################
@@ -49,16 +45,22 @@ config("spirv_cross_public") {
defines = [ "SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS" ]
}
-static_library("spirv_cross") {
- public_configs = [ ":spirv_cross_public" ]
-
+config("spirv_cross_internal") {
if (!is_msvc) {
cflags_cc = [
"-Wno-implicit-fallthrough",
"-Wno-return-type",
"-Wno-sign-compare",
]
+ } else {
+ # Disable "not all control paths return a value" warning.
+ cflags_cc = [ "/wd4715" ]
}
+}
+
+static_library("spirv_cross") {
+ public_configs = [ ":spirv_cross_public" ]
+ configs += [ ":spirv_cross_internal" ]
sources = [
"${spirv_cross_dir}/GLSL.std.450.h",
@@ -72,12 +74,7 @@ static_library("spirv_cross") {
need_glsl_cross = dawn_enable_opengl
- is_fuzzing = false
- if (build_with_chromium) {
- is_fuzzing = use_fuzzing_engine
- }
-
- if (dawn_enable_d3d12 || is_fuzzing) {
+ if (dawn_enable_d3d12) {
sources += [
"${spirv_cross_dir}/spirv_hlsl.cpp",
"${spirv_cross_dir}/spirv_hlsl.hpp",
@@ -85,7 +82,7 @@ static_library("spirv_cross") {
need_glsl_cross = true
}
- if (dawn_enable_metal || is_fuzzing) {
+ if (dawn_enable_metal) {
sources += [
"${spirv_cross_dir}/spirv_msl.cpp",
"${spirv_cross_dir}/spirv_msl.hpp",
@@ -93,7 +90,7 @@ static_library("spirv_cross") {
need_glsl_cross = true
}
- if (need_glsl_cross || is_fuzzing) {
+ if (need_glsl_cross) {
sources += [
"${spirv_cross_dir}/spirv_glsl.cpp",
"${spirv_cross_dir}/spirv_glsl.hpp",
@@ -101,6 +98,27 @@ static_library("spirv_cross") {
}
}
+static_library("spirv_cross_full_for_fuzzers") {
+ public_configs = [ ":spirv_cross_public" ]
+ configs += [ ":spirv_cross_internal" ]
+
+ sources = [
+ "${spirv_cross_dir}/GLSL.std.450.h",
+ "${spirv_cross_dir}/spirv.hpp",
+ "${spirv_cross_dir}/spirv_cfg.cpp",
+ "${spirv_cross_dir}/spirv_cfg.hpp",
+ "${spirv_cross_dir}/spirv_common.hpp",
+ "${spirv_cross_dir}/spirv_cross.cpp",
+ "${spirv_cross_dir}/spirv_cross.hpp",
+ "${spirv_cross_dir}/spirv_glsl.cpp",
+ "${spirv_cross_dir}/spirv_glsl.hpp",
+ "${spirv_cross_dir}/spirv_hlsl.cpp",
+ "${spirv_cross_dir}/spirv_hlsl.hpp",
+ "${spirv_cross_dir}/spirv_msl.cpp",
+ "${spirv_cross_dir}/spirv_msl.hpp",
+ ]
+}
+
# An empty Vulkan target to add the include dirs and list the sources
# for the header inclusion check.
config("vulkan_headers_public") {
@@ -211,7 +229,10 @@ static_library("glfw") {
# nonstandard extension, function/data pointer conversion in expression
cflags_c = [ "/wd4152" ]
} else {
- cflags_c = [ "-Wno-sign-compare" ]
+ cflags_c = [
+ "-Wno-sign-compare",
+ "-Wno-missing-field-initializers",
+ ]
}
sources = [
@@ -240,8 +261,8 @@ static_library("glfw") {
"${glfw_dir}/src/win32_joystick.h",
"${glfw_dir}/src/win32_monitor.c",
"${glfw_dir}/src/win32_platform.h",
- "${glfw_dir}/src/win32_time.c",
"${glfw_dir}/src/win32_thread.c",
+ "${glfw_dir}/src/win32_time.c",
"${glfw_dir}/src/win32_window.c",
]
}