diff options
Diffstat (limited to 'chromium/third_party/dawn/src/dawn_native')
126 files changed, 2226 insertions, 1695 deletions
diff --git a/chromium/third_party/dawn/src/dawn_native/Adapter.cpp b/chromium/third_party/dawn/src/dawn_native/Adapter.cpp index 137a1c7e70a..e108acc3972 100644 --- a/chromium/third_party/dawn/src/dawn_native/Adapter.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Adapter.cpp @@ -26,6 +26,10 @@ namespace dawn_native { return mBackend; } + DeviceType AdapterBase::GetDeviceType() const { + return mDeviceType; + } + const PCIInfo& AdapterBase::GetPCIInfo() const { return mPCIInfo; } diff --git a/chromium/third_party/dawn/src/dawn_native/Adapter.h b/chromium/third_party/dawn/src/dawn_native/Adapter.h index bb15e70a92c..6f1c0b254b2 100644 --- a/chromium/third_party/dawn/src/dawn_native/Adapter.h +++ b/chromium/third_party/dawn/src/dawn_native/Adapter.h @@ -29,6 +29,7 @@ namespace dawn_native { virtual ~AdapterBase() = default; BackendType GetBackendType() const; + DeviceType GetDeviceType() const; const PCIInfo& GetPCIInfo() const; InstanceBase* GetInstance() const; @@ -36,6 +37,7 @@ namespace dawn_native { protected: PCIInfo mPCIInfo = {}; + DeviceType mDeviceType = DeviceType::Unknown; private: virtual ResultOrError<DeviceBase*> CreateDeviceImpl() = 0; diff --git a/chromium/third_party/dawn/src/dawn_native/BindGroup.cpp b/chromium/third_party/dawn/src/dawn_native/BindGroup.cpp index dc1fe6dd371..b776c911ca2 100644 --- a/chromium/third_party/dawn/src/dawn_native/BindGroup.cpp +++ b/chromium/third_party/dawn/src/dawn_native/BindGroup.cpp @@ -37,7 +37,7 @@ namespace dawn_native { } DAWN_TRY(device->ValidateObject(binding.buffer)); - uint32_t bufferSize = binding.buffer->GetSize(); + uint64_t bufferSize = binding.buffer->GetSize(); if (binding.size > bufferSize) { return DAWN_VALIDATION_ERROR("Buffer binding size larger than the buffer"); } @@ -138,6 +138,10 @@ namespace dawn_native { case dawn::BindingType::Sampler: DAWN_TRY(ValidateSamplerBinding(device, binding)); break; + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + return DAWN_VALIDATION_ERROR("Dawn doesn't support dynamic buffer yet"); } } diff --git a/chromium/third_party/dawn/src/dawn_native/BindGroup.h b/chromium/third_party/dawn/src/dawn_native/BindGroup.h index 32988ea970d..d31fff4f83f 100644 --- a/chromium/third_party/dawn/src/dawn_native/BindGroup.h +++ b/chromium/third_party/dawn/src/dawn_native/BindGroup.h @@ -34,8 +34,8 @@ namespace dawn_native { struct BufferBinding { BufferBase* buffer; - uint32_t offset; - uint32_t size; + uint64_t offset; + uint64_t size; }; class BindGroupBase : public ObjectBase { diff --git a/chromium/third_party/dawn/src/dawn_native/Buffer.cpp b/chromium/third_party/dawn/src/dawn_native/Buffer.cpp index 4a68302bdd5..74ac084be98 100644 --- a/chromium/third_party/dawn/src/dawn_native/Buffer.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Buffer.cpp @@ -128,7 +128,7 @@ namespace dawn_native { } void BufferBase::CallMapReadCallback(uint32_t serial, - dawnBufferMapAsyncStatus status, + DawnBufferMapAsyncStatus status, const void* pointer, uint32_t dataLength) { ASSERT(!IsError()); @@ -136,14 +136,14 @@ namespace dawn_native { ASSERT(mMapWriteCallback == nullptr); // Tag the callback as fired before firing it, otherwise it could fire a second time if // for example buffer.Unmap() is called inside the application-provided callback. - dawnBufferMapReadCallback callback = mMapReadCallback; + DawnBufferMapReadCallback callback = mMapReadCallback; mMapReadCallback = nullptr; callback(status, pointer, dataLength, mMapUserdata); } } void BufferBase::CallMapWriteCallback(uint32_t serial, - dawnBufferMapAsyncStatus status, + DawnBufferMapAsyncStatus status, void* pointer, uint32_t dataLength) { ASSERT(!IsError()); @@ -151,7 +151,7 @@ namespace dawn_native { ASSERT(mMapReadCallback == nullptr); // Tag the callback as fired before firing it, otherwise it could fire a second time if // for example buffer.Unmap() is called inside the application-provided callback. - dawnBufferMapWriteCallback callback = mMapWriteCallback; + DawnBufferMapWriteCallback callback = mMapWriteCallback; mMapWriteCallback = nullptr; callback(status, pointer, dataLength, mMapUserdata); } @@ -168,8 +168,8 @@ namespace dawn_native { } } - void BufferBase::MapReadAsync(dawnBufferMapReadCallback callback, - dawnCallbackUserdata userdata) { + void BufferBase::MapReadAsync(DawnBufferMapReadCallback callback, + DawnCallbackUserdata userdata) { if (GetDevice()->ConsumedError(ValidateMap(dawn::BufferUsageBit::MapRead))) { callback(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0, userdata); return; @@ -207,8 +207,8 @@ namespace dawn_native { return {}; } - void BufferBase::MapWriteAsync(dawnBufferMapWriteCallback callback, - dawnCallbackUserdata userdata) { + void BufferBase::MapWriteAsync(DawnBufferMapWriteCallback callback, + DawnCallbackUserdata userdata) { if (GetDevice()->ConsumedError(ValidateMap(dawn::BufferUsageBit::MapWrite))) { callback(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0, userdata); return; @@ -235,8 +235,7 @@ namespace dawn_native { if (mState == BufferState::Mapped) { Unmap(); } - DestroyImpl(); - mState = BufferState::Destroyed; + DestroyInternal(); } void BufferBase::Unmap() { @@ -331,4 +330,11 @@ namespace dawn_native { return {}; } + void BufferBase::DestroyInternal() { + if (mState != BufferState::Destroyed) { + DestroyImpl(); + } + mState = BufferState::Destroyed; + } + } // 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 28653dc2060..46fe1fa0021 100644 --- a/chromium/third_party/dawn/src/dawn_native/Buffer.h +++ b/chromium/third_party/dawn/src/dawn_native/Buffer.h @@ -15,7 +15,6 @@ #ifndef DAWNNATIVE_BUFFER_H_ #define DAWNNATIVE_BUFFER_H_ -#include "dawn_native/Builder.h" #include "dawn_native/Error.h" #include "dawn_native/Forward.h" #include "dawn_native/ObjectBase.h" @@ -54,8 +53,8 @@ namespace dawn_native { // Dawn API void SetSubData(uint32_t start, uint32_t count, const uint8_t* data); - void MapReadAsync(dawnBufferMapReadCallback callback, dawnCallbackUserdata userdata); - void MapWriteAsync(dawnBufferMapWriteCallback callback, dawnCallbackUserdata userdata); + void MapReadAsync(DawnBufferMapReadCallback callback, DawnCallbackUserdata userdata); + void MapWriteAsync(DawnBufferMapWriteCallback callback, DawnCallbackUserdata userdata); void Unmap(); void Destroy(); @@ -63,14 +62,16 @@ namespace dawn_native { BufferBase(DeviceBase* device, ObjectBase::ErrorTag tag); void CallMapReadCallback(uint32_t serial, - dawnBufferMapAsyncStatus status, + DawnBufferMapAsyncStatus status, const void* pointer, uint32_t dataLength); void CallMapWriteCallback(uint32_t serial, - dawnBufferMapAsyncStatus status, + DawnBufferMapAsyncStatus status, void* pointer, uint32_t dataLength); + void DestroyInternal(); + private: virtual MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data); virtual void MapReadAsyncImpl(uint32_t serial) = 0; @@ -83,29 +84,17 @@ namespace dawn_native { MaybeError ValidateUnmap() const; MaybeError ValidateDestroy() const; - uint32_t mSize = 0; + uint64_t mSize = 0; dawn::BufferUsageBit mUsage = dawn::BufferUsageBit::None; - dawnBufferMapReadCallback mMapReadCallback = nullptr; - dawnBufferMapWriteCallback mMapWriteCallback = nullptr; - dawnCallbackUserdata mMapUserdata = 0; + DawnBufferMapReadCallback mMapReadCallback = nullptr; + DawnBufferMapWriteCallback mMapWriteCallback = nullptr; + DawnCallbackUserdata mMapUserdata = 0; uint32_t mMapSerial = 0; BufferState mState; }; - // This builder class is kept around purely for testing but should not be used. - class BufferBuilder : public Builder<BufferBase> { - public: - BufferBuilder(DeviceBase* device) : Builder(device) { - UNREACHABLE(); - } - - void SetSize(uint32_t) { - UNREACHABLE(); - } - }; - } // namespace dawn_native #endif // DAWNNATIVE_BUFFER_H_ diff --git a/chromium/third_party/dawn/src/dawn_native/Builder.cpp b/chromium/third_party/dawn/src/dawn_native/Builder.cpp deleted file mode 100644 index e9deb236a7b..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/Builder.cpp +++ /dev/null @@ -1,93 +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/Builder.h" - -#include "common/Assert.h" -#include "dawn_native/Device.h" - -namespace dawn_native { - - bool BuilderBase::CanBeUsed() const { - return !mIsConsumed && !mGotStatus; - } - - void BuilderBase::HandleError(const char* message) { - SetStatus(dawn::BuilderErrorStatus::Error, message); - } - - void BuilderBase::SetErrorCallback(dawn::BuilderErrorCallback callback, - dawn::CallbackUserdata userdata1, - dawn::CallbackUserdata userdata2) { - mCallback = callback; - mUserdata1 = userdata1; - mUserdata2 = userdata2; - } - - BuilderBase::BuilderBase(DeviceBase* device) : ObjectBase(device) { - } - - BuilderBase::~BuilderBase() { - if (!mIsConsumed && mCallback != nullptr) { - mCallback(DAWN_BUILDER_ERROR_STATUS_UNKNOWN, "Builder destroyed before GetResult", - mUserdata1, mUserdata2); - } - } - - void BuilderBase::SetStatus(dawn::BuilderErrorStatus status, const char* message) { - ASSERT(status != dawn::BuilderErrorStatus::Success); - ASSERT(status != dawn::BuilderErrorStatus::Unknown); - ASSERT(!mGotStatus); // This is not strictly necessary but something to strive for. - mGotStatus = true; - - mStoredStatus = status; - mStoredMessage = message; - } - - bool BuilderBase::HandleResult(ObjectBase* result) { - // GetResult can only be called once. - ASSERT(!mIsConsumed); - mIsConsumed = true; - - // result == nullptr implies there was an error which implies we should have a status set. - ASSERT(result != nullptr || mGotStatus); - - // If we have any error, then we have to return nullptr - if (mGotStatus) { - ASSERT(mStoredStatus != dawn::BuilderErrorStatus::Success); - - // The application will never see "result" so we need to remove the - // external ref here. - if (result != nullptr) { - result->Release(); - result = nullptr; - } - - // Unhandled builder errors are promoted to device errors - if (!mCallback) - GetDevice()->HandleError(("Unhandled builder error: " + mStoredMessage).c_str()); - } else { - ASSERT(mStoredStatus == dawn::BuilderErrorStatus::Success); - ASSERT(mStoredMessage.empty()); - } - - if (mCallback != nullptr) { - mCallback(static_cast<dawnBuilderErrorStatus>(mStoredStatus), mStoredMessage.c_str(), - mUserdata1, mUserdata2); - } - - return result != nullptr; - } - -} // namespace dawn_native diff --git a/chromium/third_party/dawn/src/dawn_native/Builder.h b/chromium/third_party/dawn/src/dawn_native/Builder.h deleted file mode 100644 index 19fef8e2bc1..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/Builder.h +++ /dev/null @@ -1,105 +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_BUILDER_H_ -#define DAWNNATIVE_BUILDER_H_ - -#include "dawn_native/Forward.h" -#include "dawn_native/ObjectBase.h" - -#include "dawn_native/dawn_platform.h" - -#include <string> - -namespace dawn_native { - - // This class implements behavior shared by all builders: - // - Tracking whether GetResult has been called already, needed by the autogenerated code to - // prevent operations on "consumed" builders. - // - The error status callback of the API. The callback is guaranteed to be called exactly once - // with an error, a success, or "unknown" if the builder is destroyed; also the builder - // callback cannot be called before either the object is destroyed or GetResult is called. - // - // It is possible for error to be generated before the error callback is registered when a - // builder "set" function performance validation inline. Because of this we have to store the - // status in the builder and defer calling the callback to GetResult. - - class BuilderBase : public ObjectBase { - public: - // Used by the auto-generated validation to prevent usage of the builder - // after GetResult or an error. - bool CanBeUsed() const; - - // Set the status of the builder to an error. - void HandleError(const char* message); - - // Internal API, to be used by builder and BackendProcTable only. - // Returns true for success cases, and calls the callback with appropriate status. - bool HandleResult(ObjectBase* result); - - // Dawn API - void SetErrorCallback(dawn::BuilderErrorCallback callback, - dawn::CallbackUserdata userdata1, - dawn::CallbackUserdata userdata2); - - protected: - BuilderBase(DeviceBase* device); - ~BuilderBase(); - - bool mGotStatus = false; - - private: - void SetStatus(dawn::BuilderErrorStatus status, const char* message); - - dawn::BuilderErrorCallback mCallback = nullptr; - dawn::CallbackUserdata mUserdata1 = 0; - dawn::CallbackUserdata mUserdata2 = 0; - - dawn::BuilderErrorStatus mStoredStatus = dawn::BuilderErrorStatus::Success; - std::string mStoredMessage; - - bool mIsConsumed = false; - }; - - // This builder base class is used to capture the calls to GetResult and make sure that either: - // - There was an error, callback is called with an error and nullptr is returned. - // - There was no error, callback is called with success and a non-null T* is returned. - template <typename T> - class Builder : public BuilderBase { - public: - // Dawn API - T* GetResult(); - - protected: - using BuilderBase::BuilderBase; - - private: - virtual T* GetResultImpl() = 0; - }; - - template <typename T> - T* Builder<T>::GetResult() { - T* result = GetResultImpl(); - // An object can have been returned but failed its initialization, so if an error happened, - // return nullptr instead of result. - if (HandleResult(result)) { - return result; - } else { - return nullptr; - } - } - -} // namespace dawn_native - -#endif // DAWNNATIVE_BUILDER_H_ diff --git a/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp b/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp index 9a7fdd988e3..26970410939 100644 --- a/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp +++ b/chromium/third_party/dawn/src/dawn_native/CommandBufferStateTracker.cpp @@ -19,7 +19,6 @@ #include "dawn_native/BindGroup.h" #include "dawn_native/ComputePipeline.h" #include "dawn_native/Forward.h" -#include "dawn_native/InputState.h" #include "dawn_native/PipelineLayout.h" #include "dawn_native/RenderPipeline.h" @@ -92,7 +91,8 @@ namespace dawn_native { bool matches = true; for (uint32_t i : IterateBitSet(mLastPipelineLayout->GetBindGroupLayoutsMask())) { - if (mLastPipelineLayout->GetBindGroupLayout(i) != mBindgroups[i]->GetLayout()) { + if (mBindgroups[i] == nullptr || + mLastPipelineLayout->GetBindGroupLayout(i) != mBindgroups[i]->GetLayout()) { matches = false; break; } @@ -106,7 +106,7 @@ namespace dawn_native { if (aspects[VALIDATION_ASPECT_VERTEX_BUFFERS]) { ASSERT(mLastRenderPipeline != nullptr); - auto requiredInputs = mLastRenderPipeline->GetInputState()->GetInputsSetMask(); + auto requiredInputs = mLastRenderPipeline->GetInputsSetMask(); if ((mInputsSet & requiredInputs) == requiredInputs) { mAspects.set(VALIDATION_ASPECT_VERTEX_BUFFERS); } diff --git a/chromium/third_party/dawn/src/dawn_native/CommandEncoder.cpp b/chromium/third_party/dawn/src/dawn_native/CommandEncoder.cpp index 89297ebe3d8..080990a0bf9 100644 --- a/chromium/third_party/dawn/src/dawn_native/CommandEncoder.cpp +++ b/chromium/third_party/dawn/src/dawn_native/CommandEncoder.cpp @@ -55,19 +55,19 @@ namespace dawn_native { // TODO(cwallez@chromium.org): Check the depth bound differently for 2D arrays and 3D // textures - if (textureCopy.origin.z != 0 || copySize.depth != 1) { - return DAWN_VALIDATION_ERROR("No support for z != 0 and depth != 1 for now"); + if (textureCopy.origin.z != 0 || copySize.depth > 1) { + return DAWN_VALIDATION_ERROR("No support for z != 0 and depth > 1 for now"); } return {}; } - bool FitsInBuffer(const BufferBase* buffer, uint32_t offset, uint32_t size) { - uint32_t bufferSize = buffer->GetSize(); + bool FitsInBuffer(const BufferBase* buffer, uint64_t offset, uint64_t size) { + uint64_t bufferSize = buffer->GetSize(); return offset <= bufferSize && (size <= (bufferSize - offset)); } - MaybeError ValidateCopySizeFitsInBuffer(const BufferCopy& bufferCopy, uint32_t dataSize) { + MaybeError ValidateCopySizeFitsInBuffer(const BufferCopy& bufferCopy, uint64_t dataSize) { if (!FitsInBuffer(bufferCopy.buffer.Get(), bufferCopy.offset, dataSize)) { return DAWN_VALIDATION_ERROR("Copy would overflow the buffer"); } @@ -75,9 +75,9 @@ namespace dawn_native { return {}; } - MaybeError ValidateB2BCopySizeAlignment(uint32_t dataSize, - uint32_t srcOffset, - uint32_t dstOffset) { + MaybeError ValidateB2BCopySizeAlignment(uint64_t dataSize, + uint64_t srcOffset, + uint64_t dstOffset) { // Copy size must be a multiple of 4 bytes on macOS. if (dataSize % 4 != 0) { return DAWN_VALIDATION_ERROR("Copy size must be a multiple of 4 bytes"); @@ -141,6 +141,49 @@ namespace dawn_native { return {}; } + MaybeError ValidateEntireSubresourceCopied(const TextureCopy& src, + const TextureCopy& dst, + const Extent3D& copySize) { + Extent3D srcSize = src.texture.Get()->GetSize(); + + if (dst.origin.x != 0 || dst.origin.y != 0 || dst.origin.z != 0 || + srcSize.width != copySize.width || srcSize.height != copySize.height || + srcSize.depth != copySize.depth) { + return DAWN_VALIDATION_ERROR( + "The entire subresource must be copied when using a depth/stencil texture or " + "when samples are greater than 1."); + } + + return {}; + } + + MaybeError ValidateTextureToTextureCopyRestrictions(const TextureCopy& src, + const TextureCopy& dst, + const Extent3D& copySize) { + const uint32_t srcSamples = src.texture.Get()->GetSampleCount(); + const uint32_t dstSamples = dst.texture.Get()->GetSampleCount(); + + if (srcSamples != dstSamples) { + return DAWN_VALIDATION_ERROR( + "Source and destination textures must have matching sample counts."); + } else if (srcSamples > 1) { + // D3D12 requires entire subresource to be copied when using CopyTextureRegion when + // samples > 1. + DAWN_TRY(ValidateEntireSubresourceCopied(src, dst, copySize)); + } + + if (src.texture.Get()->GetFormat() != dst.texture.Get()->GetFormat()) { + // Metal requires texture-to-texture copies be the same format + return DAWN_VALIDATION_ERROR("Source and destination texture formats must match."); + } else if (TextureFormatHasDepthOrStencil(src.texture.Get()->GetFormat())) { + // D3D12 requires entire subresource to be copied when using CopyTextureRegion is + // used with depth/stencil. + DAWN_TRY(ValidateEntireSubresourceCopied(src, dst, copySize)); + } + + return {}; + } + MaybeError ComputeTextureCopyBufferSize(const Extent3D& copySize, uint32_t rowPitch, uint32_t imageHeight, @@ -230,20 +273,80 @@ namespace dawn_native { return {}; } + MaybeError ValidateOrSetColorAttachmentSampleCount(const TextureViewBase* colorAttachment, + uint32_t* sampleCount) { + if (*sampleCount == 0) { + *sampleCount = colorAttachment->GetTexture()->GetSampleCount(); + DAWN_ASSERT(*sampleCount != 0); + } else if (*sampleCount != colorAttachment->GetTexture()->GetSampleCount()) { + return DAWN_VALIDATION_ERROR("Color attachment sample counts mismatch"); + } + + return {}; + } + + MaybeError ValidateResolveTarget( + const DeviceBase* device, + const RenderPassColorAttachmentDescriptor* colorAttachment) { + if (colorAttachment->resolveTarget == nullptr) { + return {}; + } + + DAWN_TRY(device->ValidateObject(colorAttachment->resolveTarget)); + + if (!colorAttachment->attachment->GetTexture()->IsMultisampledTexture()) { + return DAWN_VALIDATION_ERROR( + "Cannot set resolve target when the sample count of the color attachment is 1"); + } + + if (colorAttachment->resolveTarget->GetTexture()->IsMultisampledTexture()) { + return DAWN_VALIDATION_ERROR("Cannot use multisampled texture as resolve target"); + } + + if (colorAttachment->resolveTarget->GetLayerCount() > 1) { + return DAWN_VALIDATION_ERROR( + "The array layer count of the resolve target must be 1"); + } + + if (colorAttachment->resolveTarget->GetLevelCount() > 1) { + return DAWN_VALIDATION_ERROR("The mip level count of the resolve target must be 1"); + } + + uint32_t colorAttachmentBaseMipLevel = colorAttachment->attachment->GetBaseMipLevel(); + const Extent3D& colorTextureSize = colorAttachment->attachment->GetTexture()->GetSize(); + uint32_t colorAttachmentWidth = colorTextureSize.width >> colorAttachmentBaseMipLevel; + uint32_t colorAttachmentHeight = colorTextureSize.height >> colorAttachmentBaseMipLevel; + + uint32_t resolveTargetBaseMipLevel = colorAttachment->resolveTarget->GetBaseMipLevel(); + const Extent3D& resolveTextureSize = + colorAttachment->resolveTarget->GetTexture()->GetSize(); + uint32_t resolveTargetWidth = resolveTextureSize.width >> resolveTargetBaseMipLevel; + uint32_t resolveTargetHeight = resolveTextureSize.height >> resolveTargetBaseMipLevel; + if (colorAttachmentWidth != resolveTargetWidth || + colorAttachmentHeight != resolveTargetHeight) { + return DAWN_VALIDATION_ERROR( + "The size of the resolve target must be the same as the color attachment"); + } + + dawn::TextureFormat resolveTargetFormat = colorAttachment->resolveTarget->GetFormat(); + if (resolveTargetFormat != colorAttachment->attachment->GetFormat()) { + return DAWN_VALIDATION_ERROR( + "The format of the resolve target must be the same as the color attachment"); + } + + return {}; + } + MaybeError ValidateRenderPassColorAttachment( const DeviceBase* device, const RenderPassColorAttachmentDescriptor* colorAttachment, uint32_t* width, - uint32_t* height) { + uint32_t* height, + uint32_t* sampleCount) { DAWN_ASSERT(colorAttachment != nullptr); DAWN_TRY(device->ValidateObject(colorAttachment->attachment)); - // TODO(jiawei.shao@intel.com): support resolve target for multisample color attachment. - if (colorAttachment->resolveTarget != nullptr) { - return DAWN_VALIDATION_ERROR("Resolve target is not supported now"); - } - const TextureViewBase* attachment = colorAttachment->attachment; if (!IsColorRenderableTextureFormat(attachment->GetFormat())) { return DAWN_VALIDATION_ERROR( @@ -251,6 +354,10 @@ namespace dawn_native { "renderable"); } + DAWN_TRY(ValidateOrSetColorAttachmentSampleCount(attachment, sampleCount)); + + DAWN_TRY(ValidateResolveTarget(device, colorAttachment)); + DAWN_TRY(ValidateAttachmentArrayLayersAndLevelCount(attachment)); DAWN_TRY(ValidateOrSetAttachmentSize(attachment, width, height)); @@ -261,7 +368,8 @@ namespace dawn_native { const DeviceBase* device, const RenderPassDepthStencilAttachmentDescriptor* depthStencilAttachment, uint32_t* width, - uint32_t* height) { + uint32_t* height, + uint32_t* sampleCount) { DAWN_ASSERT(depthStencilAttachment != nullptr); DAWN_TRY(device->ValidateObject(depthStencilAttachment->attachment)); @@ -273,28 +381,40 @@ namespace dawn_native { "depth stencil format"); } + // *sampleCount == 0 must only happen when there is no color attachment. In that case we + // do not need to validate the sample count of the depth stencil attachment. + const uint32_t depthStencilSampleCount = attachment->GetTexture()->GetSampleCount(); + if (*sampleCount != 0) { + if (depthStencilSampleCount != *sampleCount) { + return DAWN_VALIDATION_ERROR("Depth stencil attachment sample counts mismatch"); + } + } else { + *sampleCount = depthStencilSampleCount; + } + DAWN_TRY(ValidateAttachmentArrayLayersAndLevelCount(attachment)); DAWN_TRY(ValidateOrSetAttachmentSize(attachment, width, height)); return {}; } - MaybeError ValidateRenderPassDescriptorAndSetSize(const DeviceBase* device, - const RenderPassDescriptor* renderPass, - uint32_t* width, - uint32_t* height) { + MaybeError ValidateRenderPassDescriptor(const DeviceBase* device, + const RenderPassDescriptor* renderPass, + uint32_t* width, + uint32_t* height, + uint32_t* sampleCount) { if (renderPass->colorAttachmentCount > kMaxColorAttachments) { return DAWN_VALIDATION_ERROR("Setting color attachments out of bounds"); } for (uint32_t i = 0; i < renderPass->colorAttachmentCount; ++i) { DAWN_TRY(ValidateRenderPassColorAttachment(device, renderPass->colorAttachments[i], - width, height)); + width, height, sampleCount)); } if (renderPass->depthStencilAttachment != nullptr) { DAWN_TRY(ValidateRenderPassDepthStencilAttachment( - device, renderPass->depthStencilAttachment, width, height)); + device, renderPass->depthStencilAttachment, width, height, sampleCount)); } if (renderPass->colorAttachmentCount == 0 && @@ -440,6 +560,12 @@ namespace dawn_native { case dawn::BindingType::Sampler: break; + + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; } } } @@ -506,10 +632,14 @@ namespace dawn_native { uint32_t width = 0; uint32_t height = 0; - if (ConsumedError(ValidateRenderPassDescriptorAndSetSize(device, info, &width, &height))) { + uint32_t sampleCount = 0; + if (ConsumedError( + ValidateRenderPassDescriptor(device, info, &width, &height, &sampleCount))) { return RenderPassEncoderBase::MakeError(device, this); } + ASSERT(width > 0 && height > 0 && sampleCount > 0); + mEncodingState = EncodingState::RenderPass; BeginRenderPassCmd* cmd = mAllocator.Allocate<BeginRenderPassCmd>(Command::BeginRenderPass); @@ -541,15 +671,16 @@ namespace dawn_native { cmd->width = width; cmd->height = height; + cmd->sampleCount = sampleCount; return new RenderPassEncoderBase(device, this, &mAllocator); } void CommandEncoderBase::CopyBufferToBuffer(BufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) { + uint64_t destinationOffset, + uint64_t size) { if (ConsumedError(ValidateCanRecordTopLevelCommands())) { return; } @@ -646,8 +777,40 @@ namespace dawn_native { } } + void CommandEncoderBase::CopyTextureToTexture(const TextureCopyView* source, + const TextureCopyView* destination, + const Extent3D* copySize) { + if (ConsumedError(ValidateCanRecordTopLevelCommands())) { + return; + } + + if (ConsumedError(GetDevice()->ValidateObject(source->texture))) { + return; + } + + if (ConsumedError(GetDevice()->ValidateObject(destination->texture))) { + return; + } + + CopyTextureToTextureCmd* copy = + mAllocator.Allocate<CopyTextureToTextureCmd>(Command::CopyTextureToTexture); + new (copy) CopyTextureToTextureCmd; + copy->source.texture = source->texture; + copy->source.origin = source->origin; + copy->source.level = source->level; + copy->source.slice = source->slice; + copy->destination.texture = destination->texture; + copy->destination.origin = destination->origin; + copy->destination.level = destination->level; + copy->destination.slice = destination->slice; + copy->copySize = *copySize; + } + CommandBufferBase* CommandEncoderBase::Finish() { if (GetDevice()->ConsumedError(ValidateFinish())) { + // Even if finish validation fails, it is now invalid to call any encoding commands on + // this object, so we set its state to finished. + mEncodingState = EncodingState::Finished; return CommandBufferBase::MakeError(GetDevice()); } ASSERT(!IsError()); @@ -673,6 +836,11 @@ namespace dawn_native { } void CommandEncoderBase::PassEnded() { + // This function may still be called when the command encoder is finished, just do nothing. + if (mEncodingState == EncodingState::Finished) { + return; + } + if (mEncodingState == EncodingState::ComputePass) { mAllocator.Allocate<EndComputePassCmd>(Command::EndComputePass); } else { @@ -782,6 +950,25 @@ namespace dawn_native { mResourceUsages.topLevelBuffers.insert(copy->destination.buffer.Get()); } break; + case Command::CopyTextureToTexture: { + CopyTextureToTextureCmd* copy = + mIterator.NextCommand<CopyTextureToTextureCmd>(); + + DAWN_TRY(ValidateTextureToTextureCopyRestrictions( + copy->source, copy->destination, copy->copySize)); + + DAWN_TRY(ValidateCopySizeFitsInTexture(copy->source, copy->copySize)); + DAWN_TRY(ValidateCopySizeFitsInTexture(copy->destination, copy->copySize)); + + DAWN_TRY(ValidateCanUseAs(copy->source.texture.Get(), + dawn::TextureUsageBit::TransferSrc)); + DAWN_TRY(ValidateCanUseAs(copy->destination.texture.Get(), + dawn::TextureUsageBit::TransferDst)); + + mResourceUsages.topLevelTextures.insert(copy->source.texture.Get()); + mResourceUsages.topLevelTextures.insert(copy->destination.texture.Get()); + } break; + default: return DAWN_VALIDATION_ERROR("Command disallowed outside of a pass"); } @@ -871,6 +1058,12 @@ namespace dawn_native { RenderPassColorAttachmentInfo* colorAttachment = &renderPass->colorAttachments[i]; TextureBase* texture = colorAttachment->view->GetTexture(); usageTracker.TextureUsedAs(texture, dawn::TextureUsageBit::OutputAttachment); + + TextureViewBase* resolveTarget = colorAttachment->resolveTarget.Get(); + if (resolveTarget != nullptr) { + usageTracker.TextureUsedAs(resolveTarget->GetTexture(), + dawn::TextureUsageBit::OutputAttachment); + } } if (renderPass->hasDepthStencilAttachment) { @@ -972,7 +1165,7 @@ namespace dawn_native { case Command::SetVertexBuffers: { SetVertexBuffersCmd* cmd = mIterator.NextCommand<SetVertexBuffersCmd>(); auto buffers = mIterator.NextData<Ref<BufferBase>>(cmd->count); - mIterator.NextData<uint32_t>(cmd->count); + mIterator.NextData<uint64_t>(cmd->count); for (uint32_t i = 0; i < cmd->count; ++i) { usageTracker.BufferUsedAs(buffers[i].Get(), dawn::BufferUsageBit::Vertex); diff --git a/chromium/third_party/dawn/src/dawn_native/CommandEncoder.h b/chromium/third_party/dawn/src/dawn_native/CommandEncoder.h index 20d890103dd..a5e3c9be726 100644 --- a/chromium/third_party/dawn/src/dawn_native/CommandEncoder.h +++ b/chromium/third_party/dawn/src/dawn_native/CommandEncoder.h @@ -27,11 +27,7 @@ namespace dawn_native { struct BeginRenderPassCmd; - class CommandBufferBuilder; - // CommandEncoder is temporarily a wrapper around CommandBufferBuilder so the two can coexist - // while code is migrated to the new shiny CommandEncoder interface. It captures any command - // buffer builder error and defers to trigger a device error when "Finish" is called. class CommandEncoderBase : public ObjectBase { public: CommandEncoderBase(DeviceBase* device); @@ -44,16 +40,19 @@ namespace dawn_native { ComputePassEncoderBase* BeginComputePass(); RenderPassEncoderBase* BeginRenderPass(const RenderPassDescriptor* info); void CopyBufferToBuffer(BufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size); + uint64_t destinationOffset, + uint64_t size); void CopyBufferToTexture(const BufferCopyView* source, const TextureCopyView* destination, const Extent3D* copySize); void CopyTextureToBuffer(const TextureCopyView* source, const BufferCopyView* destination, const Extent3D* copySize); + void CopyTextureToTexture(const TextureCopyView* source, + const TextureCopyView* destination, + const Extent3D* copySize); CommandBufferBase* Finish(); // Functions to interact with the encoders diff --git a/chromium/third_party/dawn/src/dawn_native/Commands.cpp b/chromium/third_party/dawn/src/dawn_native/Commands.cpp index 816dd39e463..1bae0026491 100644 --- a/chromium/third_party/dawn/src/dawn_native/Commands.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Commands.cpp @@ -49,6 +49,11 @@ namespace dawn_native { CopyTextureToBufferCmd* copy = commands->NextCommand<CopyTextureToBufferCmd>(); copy->~CopyTextureToBufferCmd(); } break; + case Command::CopyTextureToTexture: { + CopyTextureToTextureCmd* copy = + commands->NextCommand<CopyTextureToTextureCmd>(); + copy->~CopyTextureToTextureCmd(); + } break; case Command::Dispatch: { DispatchCmd* dispatch = commands->NextCommand<DispatchCmd>(); dispatch->~DispatchCmd(); @@ -122,7 +127,7 @@ namespace dawn_native { for (size_t i = 0; i < cmd->count; ++i) { (&buffers[i])->~Ref<BufferBase>(); } - commands->NextData<uint32_t>(cmd->count); + commands->NextData<uint64_t>(cmd->count); cmd->~SetVertexBuffersCmd(); } break; } @@ -152,6 +157,10 @@ namespace dawn_native { commands->NextCommand<CopyTextureToBufferCmd>(); break; + case Command::CopyTextureToTexture: + commands->NextCommand<CopyTextureToTextureCmd>(); + break; + case Command::Dispatch: commands->NextCommand<DispatchCmd>(); break; @@ -222,7 +231,7 @@ namespace dawn_native { case Command::SetVertexBuffers: { auto* cmd = commands->NextCommand<SetVertexBuffersCmd>(); commands->NextData<Ref<BufferBase>>(cmd->count); - commands->NextData<uint32_t>(cmd->count); + commands->NextData<uint64_t>(cmd->count); } break; } } diff --git a/chromium/third_party/dawn/src/dawn_native/Commands.h b/chromium/third_party/dawn/src/dawn_native/Commands.h index 92913c04134..26e0b682ab2 100644 --- a/chromium/third_party/dawn/src/dawn_native/Commands.h +++ b/chromium/third_party/dawn/src/dawn_native/Commands.h @@ -36,6 +36,7 @@ namespace dawn_native { CopyBufferToBuffer, CopyBufferToTexture, CopyTextureToBuffer, + CopyTextureToTexture, Dispatch, Draw, DrawIndexed, @@ -81,14 +82,15 @@ namespace dawn_native { bool hasDepthStencilAttachment; RenderPassDepthStencilAttachmentInfo depthStencilAttachment; - // Cache the width and height of all attachments for convenience + // Cache the width, height and sample count of all attachments for convenience uint32_t width; uint32_t height; + uint32_t sampleCount; }; struct BufferCopy { Ref<BufferBase> buffer; - uint32_t offset; // Bytes + uint64_t offset; // Bytes uint32_t rowPitch; // Bytes uint32_t imageHeight; // Texels }; @@ -103,7 +105,7 @@ namespace dawn_native { struct CopyBufferToBufferCmd { BufferCopy source; BufferCopy destination; - uint32_t size; + uint64_t size; }; struct CopyBufferToTextureCmd { @@ -118,6 +120,12 @@ namespace dawn_native { Extent3D copySize; // Texels }; + struct CopyTextureToTextureCmd { + TextureCopy source; + TextureCopy destination; + Extent3D copySize; // Texels + }; + struct DispatchCmd { uint32_t x; uint32_t y; @@ -135,7 +143,7 @@ namespace dawn_native { uint32_t indexCount; uint32_t instanceCount; uint32_t firstIndex; - uint32_t baseVertex; + int32_t baseVertex; uint32_t firstInstance; }; @@ -186,7 +194,7 @@ namespace dawn_native { struct SetIndexBufferCmd { Ref<BufferBase> buffer; - uint32_t offset; + uint64_t offset; }; struct SetVertexBuffersCmd { diff --git a/chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp b/chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp index c95115b4587..a2fb60f6525 100644 --- a/chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp +++ b/chromium/third_party/dawn/src/dawn_native/ComputePipeline.cpp @@ -24,21 +24,9 @@ namespace dawn_native { return DAWN_VALIDATION_ERROR("nextInChain must be nullptr"); } - DAWN_TRY(device->ValidateObject(descriptor->module)); DAWN_TRY(device->ValidateObject(descriptor->layout)); - - if (descriptor->entryPoint != std::string("main")) { - return DAWN_VALIDATION_ERROR("Currently the entry point has to be main()"); - } - - if (descriptor->module->GetExecutionModel() != dawn::ShaderStage::Compute) { - return DAWN_VALIDATION_ERROR("Setting module with wrong execution model"); - } - - if (!descriptor->module->IsCompatibleWithPipelineLayout(descriptor->layout)) { - return DAWN_VALIDATION_ERROR("Stage not compatible with layout"); - } - + DAWN_TRY(ValidatePipelineStageDescriptor(device, descriptor->computeStage, + descriptor->layout, dawn::ShaderStage::Compute)); return {}; } @@ -47,7 +35,7 @@ namespace dawn_native { ComputePipelineBase::ComputePipelineBase(DeviceBase* device, const ComputePipelineDescriptor* descriptor) : PipelineBase(device, descriptor->layout, dawn::ShaderStageBit::Compute) { - ExtractModuleData(dawn::ShaderStage::Compute, descriptor->module); + ExtractModuleData(dawn::ShaderStage::Compute, descriptor->computeStage->module); } ComputePipelineBase::ComputePipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag) diff --git a/chromium/third_party/dawn/src/dawn_native/DawnNative.cpp b/chromium/third_party/dawn/src/dawn_native/DawnNative.cpp index 5464d0d77e0..7330f84cece 100644 --- a/chromium/third_party/dawn/src/dawn_native/DawnNative.cpp +++ b/chromium/third_party/dawn/src/dawn_native/DawnNative.cpp @@ -20,9 +20,9 @@ namespace dawn_native { - dawnProcTable GetProcsAutogen(); + DawnProcTable GetProcsAutogen(); - dawnProcTable GetProcs() { + DawnProcTable GetProcs() { return GetProcsAutogen(); } @@ -41,6 +41,10 @@ namespace dawn_native { return mImpl->GetBackendType(); } + DeviceType Adapter::GetDeviceType() const { + return mImpl->GetDeviceType(); + } + const PCIInfo& Adapter::GetPCIInfo() const { return mImpl->GetPCIInfo(); } @@ -49,8 +53,8 @@ namespace dawn_native { return mImpl != nullptr; } - dawnDevice Adapter::CreateDevice() { - return reinterpret_cast<dawnDevice>(mImpl->CreateDevice()); + DawnDevice Adapter::CreateDevice() { + return reinterpret_cast<DawnDevice>(mImpl->CreateDevice()); } // AdapterDiscoverOptionsBase diff --git a/chromium/third_party/dawn/src/dawn_native/Device.cpp b/chromium/third_party/dawn/src/dawn_native/Device.cpp index 0448464ab87..44be88a80af 100644 --- a/chromium/third_party/dawn/src/dawn_native/Device.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Device.cpp @@ -25,7 +25,6 @@ #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" #include "dawn_native/RenderPipeline.h" @@ -159,9 +158,6 @@ namespace dawn_native { return result; } - InputStateBuilder* DeviceBase::CreateInputStateBuilder() { - return new InputStateBuilder(this); - } PipelineLayoutBase* DeviceBase::CreatePipelineLayout( const PipelineLayoutDescriptor* descriptor) { PipelineLayoutBase* result = nullptr; diff --git a/chromium/third_party/dawn/src/dawn_native/Device.h b/chromium/third_party/dawn/src/dawn_native/Device.h index d1c73618f26..2561073a52c 100644 --- a/chromium/third_party/dawn/src/dawn_native/Device.h +++ b/chromium/third_party/dawn/src/dawn_native/Device.h @@ -30,7 +30,6 @@ namespace dawn_native { using ErrorCallback = void (*)(const char* errorMessage, void* userData); class AdapterBase; - class BufferBuilder; class FenceSignalTracker; class DynamicUploader; class StagingBufferBase; @@ -60,7 +59,6 @@ namespace dawn_native { FenceSignalTracker* GetFenceSignalTracker() const; virtual CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) = 0; - virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0; virtual Serial GetCompletedCommandSerial() const = 0; virtual Serial GetLastSubmittedCommandSerial() const = 0; @@ -68,7 +66,7 @@ namespace dawn_native { virtual void TickImpl() = 0; // Many Dawn objects are completely immutable once created which means that if two - // builders are given the same arguments, they can return the same object. Reusing + // creations are given the same arguments, they can return the same object. Reusing // objects will help make comparisons between objects by a single pointer comparison. // // Technically no object is immutable as they have a reference count, and an @@ -77,10 +75,10 @@ namespace dawn_native { // the client-server wire every creation will get a different proxy object, with a // different reference count. // - // When trying to create an object, we give both the builder and an example of what - // the built object will be, the "blueprint". The blueprint is just a FooBase object + // When trying to create an object, we give both the descriptor and an example of what + // the created object will be, the "blueprint". The blueprint is just a FooBase object // instead of a backend Foo object. If the blueprint doesn't match an object in the - // cache, then the builder is used to make a new object. + // cache, then the descriptor is used to make a new object. ResultOrError<BindGroupLayoutBase*> GetOrCreateBindGroupLayout( const BindGroupLayoutDescriptor* descriptor); void UncacheBindGroupLayout(BindGroupLayoutBase* obj); @@ -91,7 +89,6 @@ namespace dawn_native { BufferBase* CreateBuffer(const BufferDescriptor* descriptor); CommandEncoderBase* CreateCommandEncoder(); ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor); - InputStateBuilder* CreateInputStateBuilder(); PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor); QueueBase* CreateQueue(); RenderPipelineBase* CreateRenderPipeline(const RenderPipelineDescriptor* descriptor); @@ -108,17 +105,13 @@ namespace dawn_native { void Reference(); void Release(); - BufferBuilder* CreateBufferBuilderForTesting() { - return nullptr; - } - virtual ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer( size_t size) = 0; virtual MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) = 0; + uint64_t destinationOffset, + uint64_t size) = 0; ResultOrError<DynamicUploader*> GetDynamicUploader() const; diff --git a/chromium/third_party/dawn/src/dawn_native/Forward.h b/chromium/third_party/dawn/src/dawn_native/Forward.h index c11dc24530e..3f32c4a6410 100644 --- a/chromium/third_party/dawn/src/dawn_native/Forward.h +++ b/chromium/third_party/dawn/src/dawn_native/Forward.h @@ -28,8 +28,6 @@ namespace dawn_native { class CommandEncoderBase; class ComputePassEncoderBase; class FenceBase; - class InputStateBase; - class InputStateBuilder; class InstanceBase; class PipelineBase; class PipelineLayoutBase; diff --git a/chromium/third_party/dawn/src/dawn_native/InputState.cpp b/chromium/third_party/dawn/src/dawn_native/InputState.cpp deleted file mode 100644 index 64400690c22..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/InputState.cpp +++ /dev/null @@ -1,180 +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/InputState.h" - -#include "common/Assert.h" -#include "dawn_native/Device.h" -#include "dawn_native/ValidationUtils_autogen.h" - -namespace dawn_native { - - // InputState helpers - - size_t IndexFormatSize(dawn::IndexFormat format) { - switch (format) { - case dawn::IndexFormat::Uint16: - return sizeof(uint16_t); - case dawn::IndexFormat::Uint32: - return sizeof(uint32_t); - default: - UNREACHABLE(); - } - } - - uint32_t VertexFormatNumComponents(dawn::VertexFormat format) { - switch (format) { - case dawn::VertexFormat::FloatR32G32B32A32: - case dawn::VertexFormat::IntR32G32B32A32: - case dawn::VertexFormat::UshortR16G16B16A16: - case dawn::VertexFormat::UnormR8G8B8A8: - return 4; - case dawn::VertexFormat::FloatR32G32B32: - case dawn::VertexFormat::IntR32G32B32: - return 3; - case dawn::VertexFormat::FloatR32G32: - case dawn::VertexFormat::IntR32G32: - case dawn::VertexFormat::UshortR16G16: - case dawn::VertexFormat::UnormR8G8: - return 2; - case dawn::VertexFormat::FloatR32: - case dawn::VertexFormat::IntR32: - return 1; - default: - UNREACHABLE(); - } - } - - size_t VertexFormatComponentSize(dawn::VertexFormat format) { - switch (format) { - case dawn::VertexFormat::FloatR32G32B32A32: - case dawn::VertexFormat::FloatR32G32B32: - case dawn::VertexFormat::FloatR32G32: - case dawn::VertexFormat::FloatR32: - return sizeof(float); - case dawn::VertexFormat::IntR32G32B32A32: - case dawn::VertexFormat::IntR32G32B32: - case dawn::VertexFormat::IntR32G32: - case dawn::VertexFormat::IntR32: - return sizeof(int32_t); - case dawn::VertexFormat::UshortR16G16B16A16: - case dawn::VertexFormat::UshortR16G16: - return sizeof(uint16_t); - case dawn::VertexFormat::UnormR8G8B8A8: - case dawn::VertexFormat::UnormR8G8: - return sizeof(uint8_t); - default: - UNREACHABLE(); - } - } - - size_t VertexFormatSize(dawn::VertexFormat format) { - return VertexFormatNumComponents(format) * VertexFormatComponentSize(format); - } - - // InputStateBase - - InputStateBase::InputStateBase(InputStateBuilder* builder) : ObjectBase(builder->GetDevice()) { - mAttributesSetMask = builder->mAttributesSetMask; - mAttributeInfos = builder->mAttributeInfos; - mInputsSetMask = builder->mInputsSetMask; - mInputInfos = builder->mInputInfos; - } - - const std::bitset<kMaxVertexAttributes>& InputStateBase::GetAttributesSetMask() const { - return mAttributesSetMask; - } - - const VertexAttributeDescriptor& InputStateBase::GetAttribute(uint32_t location) const { - ASSERT(mAttributesSetMask[location]); - return mAttributeInfos[location]; - } - - const std::bitset<kMaxVertexInputs>& InputStateBase::GetInputsSetMask() const { - return mInputsSetMask; - } - - const VertexInputDescriptor& InputStateBase::GetInput(uint32_t slot) const { - ASSERT(mInputsSetMask[slot]); - return mInputInfos[slot]; - } - - // InputStateBuilder - - InputStateBuilder::InputStateBuilder(DeviceBase* device) : Builder(device) { - } - - InputStateBase* InputStateBuilder::GetResultImpl() { - for (uint32_t location = 0; location < kMaxVertexAttributes; ++location) { - if (mAttributesSetMask[location] && - !mInputsSetMask[mAttributeInfos[location].inputSlot]) { - HandleError("Attribute uses unset input"); - return nullptr; - } - } - - return GetDevice()->CreateInputState(this); - } - - void InputStateBuilder::SetAttribute(const VertexAttributeDescriptor* attribute) { - if (attribute->shaderLocation >= kMaxVertexAttributes) { - HandleError("Setting attribute out of bounds"); - return; - } - if (attribute->inputSlot >= kMaxVertexInputs) { - HandleError("Binding slot out of bounds"); - return; - } - if (GetDevice()->ConsumedError(ValidateVertexFormat(attribute->format))) { - return; - } - // If attribute->offset is close to 0xFFFFFFFF, the validation below to add - // attribute->offset and VertexFormatSize(attribute->format) might overflow on a - // 32bit machine, then it can pass the validation incorrectly. We need to catch it. - if (attribute->offset >= kMaxVertexAttributeEnd) { - HandleError("Setting attribute offset out of bounds"); - return; - } - if (attribute->offset + VertexFormatSize(attribute->format) > kMaxVertexAttributeEnd) { - HandleError("Setting attribute offset out of bounds"); - return; - } - if (mAttributesSetMask[attribute->shaderLocation]) { - HandleError("Setting already set attribute"); - return; - } - - mAttributesSetMask.set(attribute->shaderLocation); - mAttributeInfos[attribute->shaderLocation] = *attribute; - } - - void InputStateBuilder::SetInput(const VertexInputDescriptor* input) { - if (input->inputSlot >= kMaxVertexInputs) { - HandleError("Setting input out of bounds"); - return; - } - if (input->stride > kMaxVertexInputStride) { - HandleError("Setting input stride out of bounds"); - return; - } - if (mInputsSetMask[input->inputSlot]) { - HandleError("Setting already set input"); - return; - } - - mInputsSetMask.set(input->inputSlot); - mInputInfos[input->inputSlot] = *input; - } - -} // namespace dawn_native diff --git a/chromium/third_party/dawn/src/dawn_native/InputState.h b/chromium/third_party/dawn/src/dawn_native/InputState.h deleted file mode 100644 index adf5d9811f8..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/InputState.h +++ /dev/null @@ -1,72 +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_INPUTSTATE_H_ -#define DAWNNATIVE_INPUTSTATE_H_ - -#include "common/Constants.h" -#include "dawn_native/Builder.h" -#include "dawn_native/Forward.h" -#include "dawn_native/ObjectBase.h" - -#include "dawn_native/dawn_platform.h" - -#include <array> -#include <bitset> - -namespace dawn_native { - - size_t IndexFormatSize(dawn::IndexFormat format); - uint32_t VertexFormatNumComponents(dawn::VertexFormat format); - size_t VertexFormatComponentSize(dawn::VertexFormat format); - size_t VertexFormatSize(dawn::VertexFormat format); - - class InputStateBase : public ObjectBase { - public: - InputStateBase(InputStateBuilder* builder); - - const std::bitset<kMaxVertexAttributes>& GetAttributesSetMask() const; - const VertexAttributeDescriptor& GetAttribute(uint32_t location) const; - const std::bitset<kMaxVertexInputs>& GetInputsSetMask() const; - const VertexInputDescriptor& GetInput(uint32_t slot) const; - - private: - std::bitset<kMaxVertexAttributes> mAttributesSetMask; - std::array<VertexAttributeDescriptor, kMaxVertexAttributes> mAttributeInfos; - std::bitset<kMaxVertexInputs> mInputsSetMask; - std::array<VertexInputDescriptor, kMaxVertexInputs> mInputInfos; - }; - - class InputStateBuilder : public Builder<InputStateBase> { - public: - InputStateBuilder(DeviceBase* device); - - // Dawn API - void SetAttribute(const VertexAttributeDescriptor* attribute); - void SetInput(const VertexInputDescriptor* input); - - private: - friend class InputStateBase; - - InputStateBase* GetResultImpl() override; - - std::bitset<kMaxVertexAttributes> mAttributesSetMask; - std::array<VertexAttributeDescriptor, kMaxVertexAttributes> mAttributeInfos; - std::bitset<kMaxVertexInputs> mInputsSetMask; - std::array<VertexInputDescriptor, kMaxVertexInputs> mInputInfos; - }; - -} // namespace dawn_native - -#endif // DAWNNATIVE_INPUTSTATE_H_ diff --git a/chromium/third_party/dawn/src/dawn_native/Instance.cpp b/chromium/third_party/dawn/src/dawn_native/Instance.cpp index 6786f7f408a..9877264d434 100644 --- a/chromium/third_party/dawn/src/dawn_native/Instance.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Instance.cpp @@ -101,15 +101,15 @@ namespace dawn_native { #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) +#if defined(DAWN_ENABLE_BACKEND_OPENGL) + Register(opengl::Connect(this), BackendType::OpenGL); +#endif // defined(DAWN_ENABLE_BACKEND_OPENGL) +#if defined(DAWN_ENABLE_BACKEND_NULL) + Register(null::Connect(this), BackendType::Null); +#endif // defined(DAWN_ENABLE_BACKEND_NULL) mBackendsConnected = true; } diff --git a/chromium/third_party/dawn/src/dawn_native/Pipeline.cpp b/chromium/third_party/dawn/src/dawn_native/Pipeline.cpp index 6ddb7421437..e839b1b5b4d 100644 --- a/chromium/third_party/dawn/src/dawn_native/Pipeline.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Pipeline.cpp @@ -15,12 +15,29 @@ #include "dawn_native/Pipeline.h" #include "dawn_native/Device.h" -#include "dawn_native/InputState.h" #include "dawn_native/PipelineLayout.h" #include "dawn_native/ShaderModule.h" namespace dawn_native { + MaybeError ValidatePipelineStageDescriptor(DeviceBase* device, + const PipelineStageDescriptor* descriptor, + const PipelineLayoutBase* layout, + dawn::ShaderStage stage) { + DAWN_TRY(device->ValidateObject(descriptor->module)); + + 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 {}; + } + // PipelineBase PipelineBase::PipelineBase(DeviceBase* device, diff --git a/chromium/third_party/dawn/src/dawn_native/Pipeline.h b/chromium/third_party/dawn/src/dawn_native/Pipeline.h index cc1c542833f..c917125bd4b 100644 --- a/chromium/third_party/dawn/src/dawn_native/Pipeline.h +++ b/chromium/third_party/dawn/src/dawn_native/Pipeline.h @@ -15,7 +15,6 @@ #ifndef DAWNNATIVE_PIPELINE_H_ #define DAWNNATIVE_PIPELINE_H_ -#include "dawn_native/Builder.h" #include "dawn_native/Forward.h" #include "dawn_native/ObjectBase.h" #include "dawn_native/PerStage.h" @@ -35,6 +34,11 @@ namespace dawn_native { Float, }; + MaybeError ValidatePipelineStageDescriptor(DeviceBase* device, + const PipelineStageDescriptor* descriptor, + const PipelineLayoutBase* layout, + dawn::ShaderStage stage); + class PipelineBase : public ObjectBase { public: struct PushConstantInfo { diff --git a/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp b/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp index d5eaaa4914e..3c2b53a6233 100644 --- a/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp +++ b/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.cpp @@ -18,6 +18,7 @@ #include "dawn_native/CommandBuffer.h" #include "dawn_native/Commands.h" #include "dawn_native/Device.h" +#include "dawn_native/ValidationUtils_autogen.h" #include <string.h> @@ -81,7 +82,10 @@ namespace dawn_native { memcpy(label, groupLabel, cmd->length + 1); } - void ProgrammablePassEncoder::SetBindGroup(uint32_t groupIndex, BindGroupBase* group) { + void ProgrammablePassEncoder::SetBindGroup(uint32_t groupIndex, + BindGroupBase* group, + uint32_t dynamicOffsetCount, + const uint64_t* dynamicOffsets) { if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands()) || mTopLevelEncoder->ConsumedError(GetDevice()->ValidateObject(group))) { return; @@ -92,6 +96,12 @@ namespace dawn_native { return; } + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. + if (dynamicOffsetCount != 0) { + mTopLevelEncoder->HandleError("Dynamic Buffer Offset not supported yet"); + return; + } + SetBindGroupCmd* cmd = mAllocator->Allocate<SetBindGroupCmd>(Command::SetBindGroup); new (cmd) SetBindGroupCmd; cmd->index = groupIndex; @@ -106,6 +116,10 @@ namespace dawn_native { return; } + if (mTopLevelEncoder->ConsumedError(ValidateShaderStageBit(stages))) { + return; + } + // TODO(cwallez@chromium.org): check for overflows if (offset + count > kMaxPushConstants) { mTopLevelEncoder->HandleError("Setting too many push constants"); diff --git a/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.h b/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.h index ae7eb4638db..d37f9bec634 100644 --- a/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.h +++ b/chromium/third_party/dawn/src/dawn_native/ProgrammablePassEncoder.h @@ -39,7 +39,10 @@ namespace dawn_native { void PopDebugGroup(); void PushDebugGroup(const char* groupLabel); - void SetBindGroup(uint32_t groupIndex, BindGroupBase* group); + void SetBindGroup(uint32_t groupIndex, + BindGroupBase* group, + uint32_t dynamicOffsetCount, + const uint64_t* dynamicOffsets); void SetPushConstants(dawn::ShaderStageBit stages, uint32_t offset, uint32_t count, diff --git a/chromium/third_party/dawn/src/dawn_native/Queue.cpp b/chromium/third_party/dawn/src/dawn_native/Queue.cpp index eb483aa8d45..23cc91277f9 100644 --- a/chromium/third_party/dawn/src/dawn_native/Queue.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Queue.cpp @@ -60,12 +60,6 @@ namespace dawn_native { DAWN_TRY(GetDevice()->ValidateObject(this)); for (uint32_t i = 0; i < commandCount; ++i) { - // TODO(cwallez@chromium.org): Remove this once CommandBufferBuilder doesn't use the - // builder mechanism anymore. - if (commands[i] == nullptr) { - return DAWN_VALIDATION_ERROR("Command buffers cannot be null"); - } - DAWN_TRY(GetDevice()->ValidateObject(commands[i])); const CommandBufferResourceUsage& usages = commands[i]->GetResourceUsages(); diff --git a/chromium/third_party/dawn/src/dawn_native/Queue.h b/chromium/third_party/dawn/src/dawn_native/Queue.h index 3da2f0220c5..7b1031eab5a 100644 --- a/chromium/third_party/dawn/src/dawn_native/Queue.h +++ b/chromium/third_party/dawn/src/dawn_native/Queue.h @@ -15,7 +15,6 @@ #ifndef DAWNNATIVE_QUEUE_H_ #define DAWNNATIVE_QUEUE_H_ -#include "dawn_native/Builder.h" #include "dawn_native/Error.h" #include "dawn_native/Forward.h" #include "dawn_native/ObjectBase.h" diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp b/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp index 6bf0b8eda10..74700634877 100644 --- a/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp +++ b/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.cpp @@ -60,7 +60,7 @@ namespace dawn_native { void RenderPassEncoderBase::DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, - uint32_t baseVertex, + int32_t baseVertex, uint32_t firstInstance) { if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands())) { return; @@ -115,6 +115,10 @@ namespace dawn_native { if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands())) { return; } + if (width == 0 || height == 0) { + mTopLevelEncoder->HandleError("Width and height must be greater than 0."); + return; + } SetScissorRectCmd* cmd = mAllocator->Allocate<SetScissorRectCmd>(Command::SetScissorRect); new (cmd) SetScissorRectCmd; @@ -124,7 +128,7 @@ namespace dawn_native { cmd->height = height; } - void RenderPassEncoderBase::SetIndexBuffer(BufferBase* buffer, uint32_t offset) { + void RenderPassEncoderBase::SetIndexBuffer(BufferBase* buffer, uint64_t offset) { if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands()) || mTopLevelEncoder->ConsumedError(GetDevice()->ValidateObject(buffer))) { return; @@ -139,7 +143,7 @@ namespace dawn_native { void RenderPassEncoderBase::SetVertexBuffers(uint32_t startSlot, uint32_t count, BufferBase* const* buffers, - uint32_t const* offsets) { + uint64_t const* offsets) { if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands())) { return; } @@ -161,8 +165,8 @@ namespace dawn_native { new (&cmdBuffers[i]) Ref<BufferBase>(buffers[i]); } - uint32_t* cmdOffsets = mAllocator->AllocateData<uint32_t>(count); - memcpy(cmdOffsets, offsets, count * sizeof(uint32_t)); + uint64_t* cmdOffsets = mAllocator->AllocateData<uint64_t>(count); + memcpy(cmdOffsets, offsets, count * sizeof(uint64_t)); } } // namespace dawn_native diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h b/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h index 408cbe73fda..7e8243e26f9 100644 --- a/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h +++ b/chromium/third_party/dawn/src/dawn_native/RenderPassEncoder.h @@ -40,7 +40,7 @@ namespace dawn_native { void DrawIndexed(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstIndex, - uint32_t baseVertex, + int32_t baseVertex, uint32_t firstInstance); void SetPipeline(RenderPipelineBase* pipeline); @@ -53,7 +53,7 @@ namespace dawn_native { void SetVertexBuffers(uint32_t startSlot, uint32_t count, T* const* buffers, - uint32_t const* offsets) { + uint64_t const* offsets) { static_assert(std::is_base_of<BufferBase, T>::value, ""); SetVertexBuffers(startSlot, count, reinterpret_cast<BufferBase* const*>(buffers), offsets); @@ -61,8 +61,8 @@ namespace dawn_native { void SetVertexBuffers(uint32_t startSlot, uint32_t count, BufferBase* const* buffers, - uint32_t const* offsets); - void SetIndexBuffer(BufferBase* buffer, uint32_t offset); + uint64_t const* offsets); + void SetIndexBuffer(BufferBase* buffer, uint64_t offset); protected: RenderPassEncoderBase(DeviceBase* device, diff --git a/chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp b/chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp index 12531dcb04e..4aa206fd5d0 100644 --- a/chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp +++ b/chromium/third_party/dawn/src/dawn_native/RenderPipeline.cpp @@ -17,7 +17,6 @@ #include "common/BitSetIterator.h" #include "dawn_native/Commands.h" #include "dawn_native/Device.h" -#include "dawn_native/InputState.h" #include "dawn_native/Texture.h" #include "dawn_native/ValidationUtils_autogen.h" @@ -25,21 +24,86 @@ namespace dawn_native { // Helper functions namespace { - MaybeError ValidatePipelineStageDescriptor(DeviceBase* device, - const PipelineStageDescriptor* descriptor, - const PipelineLayoutBase* layout, - dawn::ShaderStage stage) { - DAWN_TRY(device->ValidateObject(descriptor->module)); + MaybeError ValidateVertexInputDescriptor(const VertexInputDescriptor* input, + std::bitset<kMaxVertexInputs>* inputsSetMask) { + DAWN_TRY(ValidateInputStepMode(input->stepMode)); + if (input->inputSlot >= kMaxVertexInputs) { + return DAWN_VALIDATION_ERROR("Setting input out of bounds"); + } + if (input->stride > kMaxVertexInputStride) { + return DAWN_VALIDATION_ERROR("Setting input stride out of bounds"); + } + if ((*inputsSetMask)[input->inputSlot]) { + return DAWN_VALIDATION_ERROR("Setting already set input"); + } + + inputsSetMask->set(input->inputSlot); + return {}; + } + + MaybeError ValidateVertexAttributeDescriptor( + const VertexAttributeDescriptor* attribute, + const std::bitset<kMaxVertexInputs>* inputsSetMask, + std::bitset<kMaxVertexAttributes>* attributesSetMask) { + DAWN_TRY(ValidateVertexFormat(attribute->format)); + + if (attribute->shaderLocation >= kMaxVertexAttributes) { + return DAWN_VALIDATION_ERROR("Setting attribute out of bounds"); + } + if (attribute->inputSlot >= kMaxVertexInputs) { + return DAWN_VALIDATION_ERROR("Binding slot out of bounds"); + } + ASSERT(kMaxVertexAttributeEnd >= VertexFormatSize(attribute->format)); + if (attribute->offset > kMaxVertexAttributeEnd - VertexFormatSize(attribute->format)) { + return DAWN_VALIDATION_ERROR("Setting attribute offset out of bounds"); + } + if ((*attributesSetMask)[attribute->shaderLocation]) { + return DAWN_VALIDATION_ERROR("Setting already set attribute"); + } + if (!(*inputsSetMask)[attribute->inputSlot]) { + return DAWN_VALIDATION_ERROR( + "Vertex attribute slot doesn't match any vertex input slot"); + } + + attributesSetMask->set(attribute->shaderLocation); + return {}; + } + + MaybeError ValidateInputStateDescriptor( + const InputStateDescriptor* descriptor, + std::bitset<kMaxVertexInputs>* inputsSetMask, + std::bitset<kMaxVertexAttributes>* attributesSetMask) { + if (descriptor->nextInChain != nullptr) { + return DAWN_VALIDATION_ERROR("nextInChain must be nullptr"); + } + DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat)); - if (descriptor->entryPoint != std::string("main")) { - return DAWN_VALIDATION_ERROR("Entry point must be \"main\""); + if (descriptor->numInputs > kMaxVertexInputs) { + return DAWN_VALIDATION_ERROR("Vertex Inputs number exceeds maximum"); } - if (descriptor->module->GetExecutionModel() != stage) { - return DAWN_VALIDATION_ERROR("Setting module with wrong stages"); + if (descriptor->numAttributes > kMaxVertexAttributes) { + return DAWN_VALIDATION_ERROR("Vertex Attributes number exceeds maximum"); } - if (!descriptor->module->IsCompatibleWithPipelineLayout(layout)) { - return DAWN_VALIDATION_ERROR("Stage not compatible with layout"); + + for (uint32_t i = 0; i < descriptor->numInputs; ++i) { + DAWN_TRY(ValidateVertexInputDescriptor(&descriptor->inputs[i], inputsSetMask)); + } + + for (uint32_t i = 0; i < descriptor->numAttributes; ++i) { + DAWN_TRY(ValidateVertexAttributeDescriptor(&descriptor->attributes[i], + inputsSetMask, attributesSetMask)); } + + return {}; + } + + MaybeError ValidateRasterizationStateDescriptor( + const RasterizationStateDescriptor* descriptor) { + if (descriptor->nextInChain != nullptr) { + return DAWN_VALIDATION_ERROR("nextInChain must be nullptr"); + } + DAWN_TRY(ValidateFrontFace(descriptor->frontFace)); + DAWN_TRY(ValidateCullMode(descriptor->cullMode)); return {}; } @@ -53,7 +117,7 @@ namespace dawn_native { DAWN_TRY(ValidateBlendOperation(descriptor->colorBlend.operation)); DAWN_TRY(ValidateBlendFactor(descriptor->colorBlend.srcFactor)); DAWN_TRY(ValidateBlendFactor(descriptor->colorBlend.dstFactor)); - DAWN_TRY(ValidateColorWriteMask(descriptor->colorWriteMask)); + DAWN_TRY(ValidateColorWriteMask(descriptor->writeMask)); dawn::TextureFormat format = descriptor->format; DAWN_TRY(ValidateTextureFormat(format)); @@ -91,6 +155,104 @@ namespace dawn_native { } // anonymous namespace + // Helper functions + size_t IndexFormatSize(dawn::IndexFormat format) { + switch (format) { + case dawn::IndexFormat::Uint16: + return sizeof(uint16_t); + case dawn::IndexFormat::Uint32: + return sizeof(uint32_t); + default: + UNREACHABLE(); + } + } + + uint32_t VertexFormatNumComponents(dawn::VertexFormat format) { + switch (format) { + case dawn::VertexFormat::UChar4: + case dawn::VertexFormat::Char4: + case dawn::VertexFormat::UChar4Norm: + case dawn::VertexFormat::Char4Norm: + case dawn::VertexFormat::UShort4: + case dawn::VertexFormat::Short4: + case dawn::VertexFormat::UShort4Norm: + case dawn::VertexFormat::Short4Norm: + case dawn::VertexFormat::Half4: + case dawn::VertexFormat::Float4: + case dawn::VertexFormat::UInt4: + case dawn::VertexFormat::Int4: + return 4; + case dawn::VertexFormat::Float3: + case dawn::VertexFormat::UInt3: + case dawn::VertexFormat::Int3: + return 3; + case dawn::VertexFormat::UChar2: + case dawn::VertexFormat::Char2: + case dawn::VertexFormat::UChar2Norm: + case dawn::VertexFormat::Char2Norm: + case dawn::VertexFormat::UShort2: + case dawn::VertexFormat::Short2: + case dawn::VertexFormat::UShort2Norm: + case dawn::VertexFormat::Short2Norm: + case dawn::VertexFormat::Half2: + case dawn::VertexFormat::Float2: + case dawn::VertexFormat::UInt2: + case dawn::VertexFormat::Int2: + return 2; + case dawn::VertexFormat::Float: + case dawn::VertexFormat::UInt: + case dawn::VertexFormat::Int: + return 1; + default: + UNREACHABLE(); + } + } + + size_t VertexFormatComponentSize(dawn::VertexFormat format) { + switch (format) { + case dawn::VertexFormat::UChar2: + case dawn::VertexFormat::UChar4: + case dawn::VertexFormat::Char2: + case dawn::VertexFormat::Char4: + case dawn::VertexFormat::UChar2Norm: + case dawn::VertexFormat::UChar4Norm: + case dawn::VertexFormat::Char2Norm: + case dawn::VertexFormat::Char4Norm: + return sizeof(char); + case dawn::VertexFormat::UShort2: + case dawn::VertexFormat::UShort4: + case dawn::VertexFormat::UShort2Norm: + case dawn::VertexFormat::UShort4Norm: + case dawn::VertexFormat::Short2: + case dawn::VertexFormat::Short4: + case dawn::VertexFormat::Short2Norm: + case dawn::VertexFormat::Short4Norm: + case dawn::VertexFormat::Half2: + case dawn::VertexFormat::Half4: + return sizeof(uint16_t); + case dawn::VertexFormat::Float: + case dawn::VertexFormat::Float2: + case dawn::VertexFormat::Float3: + case dawn::VertexFormat::Float4: + return sizeof(float); + case dawn::VertexFormat::UInt: + case dawn::VertexFormat::UInt2: + case dawn::VertexFormat::UInt3: + case dawn::VertexFormat::UInt4: + case dawn::VertexFormat::Int: + case dawn::VertexFormat::Int2: + case dawn::VertexFormat::Int3: + case dawn::VertexFormat::Int4: + return sizeof(int32_t); + default: + UNREACHABLE(); + } + } + + size_t VertexFormatSize(dawn::VertexFormat format) { + return VertexFormatNumComponents(format) * VertexFormatComponentSize(format); + } + MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device, const RenderPipelineDescriptor* descriptor) { if (descriptor->nextInChain != nullptr) { @@ -103,22 +265,25 @@ namespace dawn_native { return DAWN_VALIDATION_ERROR("Input state must not be null"); } - DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat)); + std::bitset<kMaxVertexInputs> inputsSetMask; + std::bitset<kMaxVertexAttributes> attributesSetMask; + DAWN_TRY(ValidateInputStateDescriptor(descriptor->inputState, &inputsSetMask, + &attributesSetMask)); DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology)); DAWN_TRY(ValidatePipelineStageDescriptor(device, descriptor->vertexStage, descriptor->layout, dawn::ShaderStage::Vertex)); DAWN_TRY(ValidatePipelineStageDescriptor(device, descriptor->fragmentStage, descriptor->layout, dawn::ShaderStage::Fragment)); + DAWN_TRY(ValidateRasterizationStateDescriptor(descriptor->rasterizationState)); - if ((descriptor->vertexStage->module->GetUsedVertexAttributes() & - ~descriptor->inputState->GetAttributesSetMask()) + if ((descriptor->vertexStage->module->GetUsedVertexAttributes() & ~attributesSetMask) .any()) { return DAWN_VALIDATION_ERROR( "Pipeline vertex stage uses inputs not in the input state"); } - if (descriptor->sampleCount != 1) { - return DAWN_VALIDATION_ERROR("Sample count must be one"); + if (!IsValidSampleCount(descriptor->sampleCount)) { + return DAWN_VALIDATION_ERROR("Sample count is not supported"); } if (descriptor->colorStateCount > kMaxColorAttachments) { @@ -167,10 +332,24 @@ namespace dawn_native { : PipelineBase(device, descriptor->layout, dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment), - mIndexFormat(descriptor->indexFormat), - mInputState(descriptor->inputState), + mInputState(*descriptor->inputState), mPrimitiveTopology(descriptor->primitiveTopology), - mHasDepthStencilAttachment(descriptor->depthStencilState != nullptr) { + mRasterizationState(*descriptor->rasterizationState), + mHasDepthStencilAttachment(descriptor->depthStencilState != nullptr), + mSampleCount(descriptor->sampleCount) { + uint32_t location = 0; + for (uint32_t i = 0; i < mInputState.numAttributes; ++i) { + location = mInputState.attributes[i].shaderLocation; + mAttributesSetMask.set(location); + mAttributeInfos[location] = mInputState.attributes[i]; + } + uint32_t slot = 0; + for (uint32_t i = 0; i < mInputState.numInputs; ++i) { + slot = mInputState.inputs[i].inputSlot; + mInputsSetMask.set(slot); + mInputInfos[slot] = mInputState.inputs[i]; + } + if (mHasDepthStencilAttachment) { mDepthStencilState = *descriptor->depthStencilState; } else { @@ -212,26 +391,43 @@ namespace dawn_native { return new RenderPipelineBase(device, ObjectBase::kError); } - const ColorStateDescriptor* RenderPipelineBase::GetColorStateDescriptor( - uint32_t attachmentSlot) { + const InputStateDescriptor* RenderPipelineBase::GetInputStateDescriptor() const { ASSERT(!IsError()); - ASSERT(attachmentSlot < mColorStates.size()); - return &mColorStates[attachmentSlot]; + return &mInputState; } - const DepthStencilStateDescriptor* RenderPipelineBase::GetDepthStencilStateDescriptor() { + const std::bitset<kMaxVertexAttributes>& RenderPipelineBase::GetAttributesSetMask() const { ASSERT(!IsError()); - return &mDepthStencilState; + return mAttributesSetMask; + } + + const VertexAttributeDescriptor& RenderPipelineBase::GetAttribute(uint32_t location) const { + ASSERT(!IsError()); + ASSERT(mAttributesSetMask[location]); + return mAttributeInfos[location]; + } + + const std::bitset<kMaxVertexInputs>& RenderPipelineBase::GetInputsSetMask() const { + ASSERT(!IsError()); + return mInputsSetMask; } - dawn::IndexFormat RenderPipelineBase::GetIndexFormat() const { + const VertexInputDescriptor& RenderPipelineBase::GetInput(uint32_t slot) const { + ASSERT(!IsError()); + ASSERT(mInputsSetMask[slot]); + return mInputInfos[slot]; + } + + const ColorStateDescriptor* RenderPipelineBase::GetColorStateDescriptor( + uint32_t attachmentSlot) { ASSERT(!IsError()); - return mIndexFormat; + ASSERT(attachmentSlot < mColorStates.size()); + return &mColorStates[attachmentSlot]; } - InputStateBase* RenderPipelineBase::GetInputState() { + const DepthStencilStateDescriptor* RenderPipelineBase::GetDepthStencilStateDescriptor() { ASSERT(!IsError()); - return mInputState.Get(); + return &mDepthStencilState; } dawn::PrimitiveTopology RenderPipelineBase::GetPrimitiveTopology() const { @@ -260,6 +456,11 @@ namespace dawn_native { return mDepthStencilState.format; } + uint32_t RenderPipelineBase::GetSampleCount() const { + ASSERT(!IsError()); + return mSampleCount; + } + bool RenderPipelineBase::IsCompatibleWith(const BeginRenderPassCmd* renderPass) const { ASSERT(!IsError()); // TODO(cwallez@chromium.org): This is called on every SetPipeline command. Optimize it for @@ -285,7 +486,17 @@ namespace dawn_native { return false; } + if (renderPass->sampleCount != mSampleCount) { + return false; + } + return true; } + std::bitset<kMaxVertexAttributes> RenderPipelineBase::GetAttributesUsingInput( + uint32_t slot) const { + ASSERT(!IsError()); + return attributesUsingInput[slot]; + } + } // 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 dd87945db6f..186de2c41f2 100644 --- a/chromium/third_party/dawn/src/dawn_native/RenderPipeline.h +++ b/chromium/third_party/dawn/src/dawn_native/RenderPipeline.h @@ -15,7 +15,6 @@ #ifndef DAWNNATIVE_RENDERPIPELINE_H_ #define DAWNNATIVE_RENDERPIPELINE_H_ -#include "dawn_native/InputState.h" #include "dawn_native/Pipeline.h" #include "dawn_native/dawn_platform.h" @@ -31,6 +30,11 @@ namespace dawn_native { MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device, const RenderPipelineDescriptor* descriptor); + size_t IndexFormatSize(dawn::IndexFormat format); + uint32_t VertexFormatNumComponents(dawn::VertexFormat format); + size_t VertexFormatComponentSize(dawn::VertexFormat format); + size_t VertexFormatSize(dawn::VertexFormat format); + bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState); bool BlendEnabled(const ColorStateDescriptor* mColorState); @@ -40,32 +44,45 @@ namespace dawn_native { static RenderPipelineBase* MakeError(DeviceBase* device); + const InputStateDescriptor* GetInputStateDescriptor() const; + const std::bitset<kMaxVertexAttributes>& GetAttributesSetMask() const; + const VertexAttributeDescriptor& GetAttribute(uint32_t location) const; + const std::bitset<kMaxVertexInputs>& GetInputsSetMask() const; + const VertexInputDescriptor& GetInput(uint32_t slot) const; + const ColorStateDescriptor* GetColorStateDescriptor(uint32_t attachmentSlot); const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor(); - dawn::IndexFormat GetIndexFormat() const; - InputStateBase* GetInputState(); dawn::PrimitiveTopology GetPrimitiveTopology() const; std::bitset<kMaxColorAttachments> GetColorAttachmentsMask() const; bool HasDepthStencilAttachment() const; dawn::TextureFormat GetColorAttachmentFormat(uint32_t attachment) const; dawn::TextureFormat GetDepthStencilFormat() const; + uint32_t GetSampleCount() const; // A pipeline can be used in a render pass if its attachment info matches the actual // attachments in the render pass. This returns whether it is the case. bool IsCompatibleWith(const BeginRenderPassCmd* renderPassCmd) const; + std::bitset<kMaxVertexAttributes> GetAttributesUsingInput(uint32_t slot) const; + std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexInputs> attributesUsingInput; private: RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag); - DepthStencilStateDescriptor mDepthStencilState; - dawn::IndexFormat mIndexFormat; - Ref<InputStateBase> mInputState; + InputStateDescriptor mInputState; + std::bitset<kMaxVertexAttributes> mAttributesSetMask; + std::array<VertexAttributeDescriptor, kMaxVertexAttributes> mAttributeInfos; + std::bitset<kMaxVertexInputs> mInputsSetMask; + std::array<VertexInputDescriptor, kMaxVertexInputs> mInputInfos; dawn::PrimitiveTopology mPrimitiveTopology; + RasterizationStateDescriptor mRasterizationState; + DepthStencilStateDescriptor mDepthStencilState; std::array<ColorStateDescriptor, kMaxColorAttachments> mColorStates; std::bitset<kMaxColorAttachments> mColorAttachmentsSet; bool mHasDepthStencilAttachment = false; + + uint32_t mSampleCount; }; } // namespace dawn_native diff --git a/chromium/third_party/dawn/src/dawn_native/Sampler.cpp b/chromium/third_party/dawn/src/dawn_native/Sampler.cpp index 4d462a58628..bbb224da750 100644 --- a/chromium/third_party/dawn/src/dawn_native/Sampler.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Sampler.cpp @@ -40,7 +40,6 @@ namespace dawn_native { 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/ShaderModule.cpp b/chromium/third_party/dawn/src/dawn_native/ShaderModule.cpp index d32899fd9ff..ca6548d2bcf 100644 --- a/chromium/third_party/dawn/src/dawn_native/ShaderModule.cpp +++ b/chromium/third_party/dawn/src/dawn_native/ShaderModule.cpp @@ -22,6 +22,8 @@ #include <spirv-cross/spirv_cross.hpp> #include <spirv-tools/libspirv.hpp> +#include <sstream> + namespace dawn_native { MaybeError ValidateShaderModuleDescriptor(DeviceBase*, @@ -82,7 +84,7 @@ namespace dawn_native { ASSERT(!IsError()); DeviceBase* device = GetDevice(); - // TODO(cwallez@chromium.org): make errors here builder-level + // TODO(cwallez@chromium.org): make errors here creation errors // currently errors here do not prevent the shadermodule from being used const auto& resources = compiler.get_shader_resources(); @@ -153,7 +155,8 @@ namespace dawn_native { } // Fill in bindingInfo with the SPIRV bindings - auto ExtractResourcesBinding = [this](const std::vector<spirv_cross::Resource>& resources, + auto ExtractResourcesBinding = [this](const spirv_cross::SmallVector<spirv_cross::Resource>& + resources, const spirv_cross::Compiler& compiler, dawn::BindingType bindingType) { for (const auto& resource : resources) { diff --git a/chromium/third_party/dawn/src/dawn_native/ShaderModule.h b/chromium/third_party/dawn/src/dawn_native/ShaderModule.h index dbeeb7be270..b8020f9b7b2 100644 --- a/chromium/third_party/dawn/src/dawn_native/ShaderModule.h +++ b/chromium/third_party/dawn/src/dawn_native/ShaderModule.h @@ -16,7 +16,6 @@ #define DAWNNATIVE_SHADERMODULE_H_ #include "common/Constants.h" -#include "dawn_native/Builder.h" #include "dawn_native/Error.h" #include "dawn_native/Forward.h" #include "dawn_native/ObjectBase.h" diff --git a/chromium/third_party/dawn/src/dawn_native/SwapChain.cpp b/chromium/third_party/dawn/src/dawn_native/SwapChain.cpp index 9832fc3a34a..3151c98de34 100644 --- a/chromium/third_party/dawn/src/dawn_native/SwapChain.cpp +++ b/chromium/third_party/dawn/src/dawn_native/SwapChain.cpp @@ -45,8 +45,8 @@ namespace dawn_native { return DAWN_VALIDATION_ERROR("Null implementation for the swapchain"); } - dawnSwapChainImplementation* impl = - reinterpret_cast<dawnSwapChainImplementation*>(descriptor->implementation); + DawnSwapChainImplementation* impl = + reinterpret_cast<DawnSwapChainImplementation*>(descriptor->implementation); if (!impl->Init || !impl->Destroy || !impl->Configure || !impl->GetNextTexture || !impl->Present) { @@ -61,7 +61,7 @@ namespace dawn_native { SwapChainBase::SwapChainBase(DeviceBase* device, const SwapChainDescriptor* descriptor) : ObjectBase(device), mImplementation( - *reinterpret_cast<dawnSwapChainImplementation*>(descriptor->implementation)) { + *reinterpret_cast<DawnSwapChainImplementation*>(descriptor->implementation)) { } SwapChainBase::SwapChainBase(DeviceBase* device, ObjectBase::ErrorTag tag) @@ -95,8 +95,8 @@ namespace dawn_native { mAllowedUsage = allowedUsage; mWidth = width; mHeight = height; - mImplementation.Configure(mImplementation.userData, static_cast<dawnTextureFormat>(format), - static_cast<dawnTextureUsageBit>(allowedUsage), width, height); + mImplementation.Configure(mImplementation.userData, static_cast<DawnTextureFormat>(format), + static_cast<DawnTextureUsageBit>(allowedUsage), width, height); } TextureBase* SwapChainBase::GetNextTexture() { @@ -132,7 +132,7 @@ namespace dawn_native { mImplementation.Present(mImplementation.userData); } - const dawnSwapChainImplementation& SwapChainBase::GetImplementation() { + const DawnSwapChainImplementation& SwapChainBase::GetImplementation() { ASSERT(!IsError()); return mImplementation; } diff --git a/chromium/third_party/dawn/src/dawn_native/SwapChain.h b/chromium/third_party/dawn/src/dawn_native/SwapChain.h index fa9f7102df6..c8479c6a157 100644 --- a/chromium/third_party/dawn/src/dawn_native/SwapChain.h +++ b/chromium/third_party/dawn/src/dawn_native/SwapChain.h @@ -15,7 +15,6 @@ #ifndef DAWNNATIVE_SWAPCHAIN_H_ #define DAWNNATIVE_SWAPCHAIN_H_ -#include "dawn_native/Builder.h" #include "dawn_native/Error.h" #include "dawn_native/Forward.h" #include "dawn_native/ObjectBase.h" @@ -46,7 +45,7 @@ namespace dawn_native { protected: SwapChainBase(DeviceBase* device, ObjectBase::ErrorTag tag); - const dawnSwapChainImplementation& GetImplementation(); + const DawnSwapChainImplementation& GetImplementation(); virtual TextureBase* GetNextTextureImpl(const TextureDescriptor*) = 0; virtual void OnBeforePresent(TextureBase* texture) = 0; @@ -58,7 +57,7 @@ namespace dawn_native { MaybeError ValidateGetNextTexture() const; MaybeError ValidatePresent(TextureBase* texture) const; - dawnSwapChainImplementation mImplementation = {}; + DawnSwapChainImplementation mImplementation = {}; dawn::TextureFormat mFormat = {}; dawn::TextureUsageBit mAllowedUsage; uint32_t mWidth = 0; diff --git a/chromium/third_party/dawn/src/dawn_native/Texture.cpp b/chromium/third_party/dawn/src/dawn_native/Texture.cpp index 5d21ad6b2d6..22a62e7d390 100644 --- a/chromium/third_party/dawn/src/dawn_native/Texture.cpp +++ b/chromium/third_party/dawn/src/dawn_native/Texture.cpp @@ -47,22 +47,6 @@ namespace dawn_native { } } - bool IsTextureViewDimensionCompatibleWithTextureSampleCount( - dawn::TextureViewDimension textureViewDimension, - const uint32_t sampleCount) { - switch (textureViewDimension) { - case dawn::TextureViewDimension::Cube: - case dawn::TextureViewDimension::CubeArray: - return sampleCount == 1; - case dawn::TextureViewDimension::e2D: - case dawn::TextureViewDimension::e2DArray: - return true; - default: - UNREACHABLE(); - return false; - } - } - // TODO(jiawei.shao@intel.com): support validation on all texture view dimensions bool IsArrayLayerValidForTextureViewDimension( dawn::TextureViewDimension textureViewDimension, @@ -100,18 +84,21 @@ namespace dawn_native { // TODO(jiawei.shao@intel.com): support more sample count. MaybeError ValidateSampleCount(const TextureDescriptor* descriptor) { - switch (descriptor->sampleCount) { - case 1: - break; - case 4: - if (descriptor->mipLevelCount > 1) { - return DAWN_VALIDATION_ERROR( - "The mipmap level count of a multisampled texture must be 1."); - } - break; - default: + if (!IsValidSampleCount(descriptor->sampleCount)) { + return DAWN_VALIDATION_ERROR("The sample count of the texture is not supported."); + } + + if (descriptor->sampleCount > 1) { + if (descriptor->mipLevelCount > 1) { return DAWN_VALIDATION_ERROR( - "The sample count of the texture is not supported."); + "The mipmap level count of a multisampled texture must be 1."); + } + + // Multisampled 2D array texture is not supported because on Metal it requires the + // version of macOS be greater than 10.14. + if (descriptor->arrayLayerCount > 1) { + return DAWN_VALIDATION_ERROR("Multisampled 2D array texture is not supported."); + } } return {}; @@ -133,13 +120,6 @@ namespace dawn_native { "original texture"); } - if (!IsTextureViewDimensionCompatibleWithTextureSampleCount( - descriptor->dimension, texture->GetSampleCount())) { - return DAWN_VALIDATION_ERROR( - "The dimension of the texture view is not compatible with the sample count of " - "the original texture"); - } - if (!IsTextureSizeValidForTextureViewDimension(descriptor->dimension, texture->GetSize())) { return DAWN_VALIDATION_ERROR( @@ -204,6 +184,10 @@ namespace dawn_native { } DAWN_TRY(device->ValidateObject(texture)); + if (texture->GetTextureState() == TextureBase::TextureState::Destroyed) { + return DAWN_VALIDATION_ERROR("Destroyed texture used to create texture view"); + } + DAWN_TRY(ValidateTextureViewDimension(descriptor->dimension)); DAWN_TRY(ValidateTextureFormat(descriptor->format)); @@ -314,9 +298,22 @@ namespace dawn_native { } } + bool IsValidSampleCount(uint32_t sampleCount) { + switch (sampleCount) { + case 1: + case 4: + return true; + + default: + return false; + } + } + // TextureBase - TextureBase::TextureBase(DeviceBase* device, const TextureDescriptor* descriptor) + TextureBase::TextureBase(DeviceBase* device, + const TextureDescriptor* descriptor, + TextureState state) : ObjectBase(device), mDimension(descriptor->dimension), mFormat(descriptor->format), @@ -324,7 +321,8 @@ namespace dawn_native { mArrayLayerCount(descriptor->arrayLayerCount), mMipLevelCount(descriptor->mipLevelCount), mSampleCount(descriptor->sampleCount), - mUsage(descriptor->usage) { + mUsage(descriptor->usage), + mState(state) { } TextureBase::TextureBase(DeviceBase* device, ObjectBase::ErrorTag tag) @@ -365,8 +363,16 @@ namespace dawn_native { return mUsage; } + TextureBase::TextureState TextureBase::GetTextureState() const { + ASSERT(!IsError()); + return mState; + } + MaybeError TextureBase::ValidateCanUseInSubmitNow() const { ASSERT(!IsError()); + if (mState == TextureState::Destroyed) { + return DAWN_VALIDATION_ERROR("Destroyed texture used in a submit"); + } return {}; } @@ -375,7 +381,7 @@ namespace dawn_native { return mSampleCount > 1; } - TextureViewBase* TextureBase::CreateDefaultTextureView() { + TextureViewBase* TextureBase::CreateDefaultView() { TextureViewDescriptor descriptor = {}; if (!IsError()) { @@ -385,10 +391,33 @@ namespace dawn_native { return GetDevice()->CreateTextureView(this, &descriptor); } - TextureViewBase* TextureBase::CreateTextureView(const TextureViewDescriptor* descriptor) { + TextureViewBase* TextureBase::CreateView(const TextureViewDescriptor* descriptor) { return GetDevice()->CreateTextureView(this, descriptor); } + void TextureBase::Destroy() { + if (GetDevice()->ConsumedError(ValidateDestroy())) { + return; + } + ASSERT(!IsError()); + DestroyInternal(); + } + + void TextureBase::DestroyImpl() { + } + + void TextureBase::DestroyInternal() { + if (mState == TextureState::OwnedInternal) { + DestroyImpl(); + } + mState = TextureState::Destroyed; + } + + MaybeError TextureBase::ValidateDestroy() const { + DAWN_TRY(GetDevice()->ValidateObject(this)); + return {}; + } + // TextureViewBase TextureViewBase::TextureViewBase(TextureBase* texture, const TextureViewDescriptor* descriptor) diff --git a/chromium/third_party/dawn/src/dawn_native/Texture.h b/chromium/third_party/dawn/src/dawn_native/Texture.h index 0c0222a9b70..abfce114d90 100644 --- a/chromium/third_party/dawn/src/dawn_native/Texture.h +++ b/chromium/third_party/dawn/src/dawn_native/Texture.h @@ -15,7 +15,6 @@ #ifndef DAWNNATIVE_TEXTURE_H_ #define DAWNNATIVE_TEXTURE_H_ -#include "dawn_native/Builder.h" #include "dawn_native/Error.h" #include "dawn_native/Forward.h" #include "dawn_native/ObjectBase.h" @@ -34,6 +33,7 @@ namespace dawn_native { bool TextureFormatHasDepthOrStencil(dawn::TextureFormat format); bool IsColorRenderableTextureFormat(dawn::TextureFormat format); bool IsDepthStencilRenderableTextureFormat(dawn::TextureFormat format); + bool IsValidSampleCount(uint32_t sampleCount); static constexpr dawn::TextureUsageBit kReadOnlyTextureUsages = dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::Sampled | @@ -45,7 +45,9 @@ namespace dawn_native { class TextureBase : public ObjectBase { public: - TextureBase(DeviceBase* device, const TextureDescriptor* descriptor); + enum class TextureState { OwnedInternal, OwnedExternal, Destroyed }; + + TextureBase(DeviceBase* device, const TextureDescriptor* descriptor, TextureState state); static TextureBase* MakeError(DeviceBase* device); @@ -56,18 +58,25 @@ namespace dawn_native { uint32_t GetNumMipLevels() const; uint32_t GetSampleCount() const; dawn::TextureUsageBit GetUsage() const; + TextureState GetTextureState() const; MaybeError ValidateCanUseInSubmitNow() const; bool IsMultisampledTexture() const; // Dawn API - TextureViewBase* CreateDefaultTextureView(); - TextureViewBase* CreateTextureView(const TextureViewDescriptor* descriptor); + TextureViewBase* CreateDefaultView(); + TextureViewBase* CreateView(const TextureViewDescriptor* descriptor); + void Destroy(); + + protected: + void DestroyInternal(); private: TextureBase(DeviceBase* device, ObjectBase::ErrorTag tag); + virtual void DestroyImpl(); + MaybeError ValidateDestroy() const; dawn::TextureDimension mDimension; dawn::TextureFormat mFormat; Extent3D mSize; @@ -75,6 +84,7 @@ namespace dawn_native { uint32_t mMipLevelCount; uint32_t mSampleCount; dawn::TextureUsageBit mUsage = dawn::TextureUsageBit::None; + TextureState mState; }; class TextureViewBase : public ObjectBase { diff --git a/chromium/third_party/dawn/src/dawn_native/ToBackend.h b/chromium/third_party/dawn/src/dawn_native/ToBackend.h index 1e09b1c913d..4f11fd45ae1 100644 --- a/chromium/third_party/dawn/src/dawn_native/ToBackend.h +++ b/chromium/third_party/dawn/src/dawn_native/ToBackend.h @@ -59,11 +59,6 @@ namespace dawn_native { }; template <typename BackendTraits> - struct ToBackendTraits<InputStateBase, BackendTraits> { - using BackendType = typename BackendTraits::InputStateType; - }; - - template <typename BackendTraits> struct ToBackendTraits<PipelineLayoutBase, BackendTraits> { using BackendType = typename BackendTraits::PipelineLayoutType; }; diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/AdapterD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/AdapterD3D12.cpp index 215bd460e56..61750c50472 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/AdapterD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/AdapterD3D12.cpp @@ -43,6 +43,13 @@ namespace dawn_native { namespace d3d12 { mPCIInfo.deviceId = adapterDesc.DeviceId; mPCIInfo.vendorId = adapterDesc.VendorId; + if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { + mDeviceType = DeviceType::CPU; + } else { + // TODO(cwallez@chromium.org): properly detect integrated vs. discrete. + mDeviceType = DeviceType::DiscreteGPU; + } + std::wstring_convert<DeletableFacet<std::codecvt<wchar_t, char, std::mbstate_t>>> converter( "Error converting"); mPCIInfo.name = converter.to_bytes(adapterDesc.Description); 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 b9ad9ba1198..36935184ac4 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupD3D12.cpp @@ -95,6 +95,12 @@ namespace dawn_native { namespace d3d12 { &samplerDesc, samplerHeapStart.GetCPUHandle(*samplerHeapOffset + bindingOffsets[bindingIndex])); } break; + + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; } } diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp index 7477e3fbf05..f97eebb3e78 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp @@ -37,6 +37,11 @@ namespace dawn_native { namespace d3d12 { case dawn::BindingType::Sampler: mBindingOffsets[binding] = mDescriptorCounts[Sampler]++; break; + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; } } @@ -95,6 +100,11 @@ namespace dawn_native { namespace d3d12 { case dawn::BindingType::Sampler: mBindingOffsets[binding] += descriptorOffsets[Sampler]; break; + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; } } } 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 307118d89fa..b0b5a1e49a6 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/BufferD3D12.cpp @@ -105,7 +105,7 @@ namespace dawn_native { namespace d3d12 { } Buffer::~Buffer() { - DestroyImpl(); + DestroyInternal(); } uint32_t Buffer::GetD3D12Size() const { 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 7d59f7d827d..b0603a22dbe 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.cpp @@ -23,7 +23,6 @@ #include "dawn_native/d3d12/ComputePipelineD3D12.h" #include "dawn_native/d3d12/DescriptorHeapAllocator.h" #include "dawn_native/d3d12/DeviceD3D12.h" -#include "dawn_native/d3d12/InputStateD3D12.h" #include "dawn_native/d3d12/PipelineLayoutD3D12.h" #include "dawn_native/d3d12/RenderPipelineD3D12.h" #include "dawn_native/d3d12/ResourceAllocator.h" @@ -44,6 +43,32 @@ namespace dawn_native { namespace d3d12 { UNREACHABLE(); } } + + D3D12_TEXTURE_COPY_LOCATION CreateTextureCopyLocationForTexture(const Texture& texture, + uint32_t level, + uint32_t slice) { + D3D12_TEXTURE_COPY_LOCATION copyLocation; + copyLocation.pResource = texture.GetD3D12Resource(); + copyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + copyLocation.SubresourceIndex = texture.GetSubresourceIndex(level, slice); + + return copyLocation; + } + + bool CanUseCopyResource(const uint32_t sourceNumMipLevels, + const Extent3D& srcSize, + const Extent3D& dstSize, + const Extent3D& copySize) { + if (sourceNumMipLevels == 1 && srcSize.width == dstSize.width && + srcSize.height == dstSize.height && srcSize.depth == dstSize.depth && + srcSize.width == copySize.width && srcSize.height == copySize.height && + srcSize.depth == copySize.depth) { + return true; + } + + return false; + } + } // anonymous namespace struct BindGroupStateTracker { @@ -321,6 +346,37 @@ namespace dawn_native { namespace d3d12 { } } + void ResolveMultisampledRenderPass(ComPtr<ID3D12GraphicsCommandList> commandList, + BeginRenderPassCmd* renderPass) { + ASSERT(renderPass != nullptr); + + for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) { + TextureViewBase* resolveTarget = + renderPass->colorAttachments[i].resolveTarget.Get(); + if (resolveTarget == nullptr) { + continue; + } + + Texture* colorTexture = + ToBackend(renderPass->colorAttachments[i].view->GetTexture()); + Texture* resolveTexture = ToBackend(resolveTarget->GetTexture()); + + // Transition the usages of the color attachment and resolve target. + colorTexture->TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_RESOLVE_SOURCE); + resolveTexture->TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_RESOLVE_DEST); + + // Do MSAA resolve with ResolveSubResource(). + ID3D12Resource* colorTextureHandle = colorTexture->GetD3D12Resource(); + ID3D12Resource* resolveTextureHandle = resolveTexture->GetD3D12Resource(); + const uint32_t resolveTextureSubresourceIndex = resolveTexture->GetSubresourceIndex( + resolveTarget->GetBaseMipLevel(), resolveTarget->GetBaseArrayLayer()); + constexpr uint32_t kColorTextureSubresourceIndex = 0; + commandList->ResolveSubresource( + resolveTextureHandle, resolveTextureSubresourceIndex, colorTextureHandle, + kColorTextureSubresourceIndex, colorTexture->GetD3D12Format()); + } + } + } // anonymous namespace CommandBuffer::CommandBuffer(Device* device, CommandEncoderBase* encoder) @@ -425,12 +481,9 @@ namespace dawn_native { namespace d3d12 { static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat())), copy->source.offset, copy->source.rowPitch, copy->source.imageHeight); - D3D12_TEXTURE_COPY_LOCATION textureLocation; - textureLocation.pResource = texture->GetD3D12Resource(); - textureLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - textureLocation.SubresourceIndex = - texture->GetNumMipLevels() * copy->destination.slice + - copy->destination.level; + D3D12_TEXTURE_COPY_LOCATION textureLocation = + CreateTextureCopyLocationForTexture(*texture, copy->destination.level, + copy->destination.slice); for (uint32_t i = 0; i < copySplit.count; ++i) { auto& info = copySplit.copies[i]; @@ -473,11 +526,9 @@ namespace dawn_native { namespace d3d12 { copy->destination.offset, copy->destination.rowPitch, copy->destination.imageHeight); - D3D12_TEXTURE_COPY_LOCATION textureLocation; - textureLocation.pResource = texture->GetD3D12Resource(); - textureLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - textureLocation.SubresourceIndex = - texture->GetNumMipLevels() * copy->source.slice + copy->source.level; + D3D12_TEXTURE_COPY_LOCATION textureLocation = + CreateTextureCopyLocationForTexture(*texture, copy->source.level, + copy->source.slice); for (uint32_t i = 0; i < copySplit.count; ++i) { auto& info = copySplit.copies[i]; @@ -507,6 +558,45 @@ namespace dawn_native { namespace d3d12 { } } break; + case Command::CopyTextureToTexture: { + CopyTextureToTextureCmd* copy = + mCommands.NextCommand<CopyTextureToTextureCmd>(); + + Texture* source = ToBackend(copy->source.texture.Get()); + Texture* destination = ToBackend(copy->destination.texture.Get()); + + source->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferSrc); + destination->TransitionUsageNow(commandList, + dawn::TextureUsageBit::TransferDst); + + if (CanUseCopyResource(source->GetNumMipLevels(), source->GetSize(), + destination->GetSize(), copy->copySize)) { + commandList->CopyResource(destination->GetD3D12Resource(), + source->GetD3D12Resource()); + + } else { + D3D12_TEXTURE_COPY_LOCATION srcLocation = + CreateTextureCopyLocationForTexture(*source, copy->source.level, + copy->source.slice); + + D3D12_TEXTURE_COPY_LOCATION dstLocation = + CreateTextureCopyLocationForTexture( + *destination, copy->destination.level, copy->destination.slice); + + D3D12_BOX sourceRegion; + sourceRegion.left = copy->source.origin.x; + sourceRegion.top = copy->source.origin.y; + sourceRegion.front = copy->source.origin.z; + sourceRegion.right = copy->source.origin.x + copy->copySize.width; + sourceRegion.bottom = copy->source.origin.y + copy->copySize.height; + sourceRegion.back = copy->source.origin.z + copy->copySize.depth; + + commandList->CopyTextureRegion( + &dstLocation, copy->destination.origin.x, copy->destination.origin.y, + copy->destination.origin.z, &srcLocation, &sourceRegion); + } + } break; + default: { UNREACHABLE(); } break; } } @@ -516,11 +606,11 @@ namespace dawn_native { namespace d3d12 { void CommandBuffer::FlushSetVertexBuffers(ComPtr<ID3D12GraphicsCommandList> commandList, VertexBuffersInfo* vertexBuffersInfo, - const InputState* inputState) { + const RenderPipeline* renderPipeline) { DAWN_ASSERT(vertexBuffersInfo != nullptr); - DAWN_ASSERT(inputState != nullptr); + DAWN_ASSERT(renderPipeline != nullptr); - auto inputsMask = inputState->GetInputsSetMask(); + auto inputsMask = renderPipeline->GetInputsSetMask(); uint32_t startSlot = vertexBuffersInfo->startSlot; uint32_t endSlot = vertexBuffersInfo->endSlot; @@ -528,14 +618,14 @@ namespace dawn_native { namespace d3d12 { // 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; + if (vertexBuffersInfo->lastRenderPipeline != renderPipeline) { + vertexBuffersInfo->lastRenderPipeline = renderPipeline; 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; + renderPipeline->GetInput(slot).stride; } } @@ -668,7 +758,6 @@ namespace dawn_native { namespace d3d12 { RenderPipeline* lastPipeline = nullptr; PipelineLayout* lastLayout = nullptr; - InputState* lastInputState = nullptr; VertexBuffersInfo vertexBuffersInfo = {}; Command type; @@ -676,13 +765,19 @@ namespace dawn_native { namespace d3d12 { switch (type) { case Command::EndRenderPass: { mCommands.NextCommand<EndRenderPassCmd>(); + + // TODO(brandon1.jones@intel.com): avoid calling this function and enable MSAA + // resolve in D3D12 render pass on the platforms that support this feature. + if (renderPass->sampleCount > 1) { + ResolveMultisampledRenderPass(commandList, renderPass); + } return; } break; case Command::Draw: { DrawCmd* draw = mCommands.NextCommand<DrawCmd>(); - FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastInputState); + FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline); commandList->DrawInstanced(draw->vertexCount, draw->instanceCount, draw->firstVertex, draw->firstInstance); } break; @@ -690,7 +785,7 @@ namespace dawn_native { namespace d3d12 { case Command::DrawIndexed: { DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>(); - FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastInputState); + FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline); commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount, draw->firstIndex, draw->baseVertex, draw->firstInstance); @@ -708,7 +803,6 @@ namespace dawn_native { namespace d3d12 { 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()); @@ -718,7 +812,6 @@ namespace dawn_native { namespace d3d12 { lastPipeline = pipeline; lastLayout = layout; - lastInputState = inputState; } break; case Command::SetStencilReference: { @@ -759,7 +852,8 @@ namespace dawn_native { namespace d3d12 { // TODO(cwallez@chromium.org): Make index buffers lazily applied, right now // this will break if the pipeline is changed for one with a different index // format after SetIndexBuffer - bufferView.Format = DXGIIndexFormat(lastPipeline->GetIndexFormat()); + bufferView.Format = + DXGIIndexFormat(lastPipeline->GetInputStateDescriptor()->indexFormat); commandList->IASetIndexBuffer(&bufferView); } break; @@ -767,7 +861,7 @@ namespace dawn_native { namespace d3d12 { case Command::SetVertexBuffers: { SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>(); auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count); - auto offsets = mCommands.NextData<uint32_t>(cmd->count); + auto offsets = mCommands.NextData<uint64_t>(cmd->count); vertexBuffersInfo.startSlot = std::min(vertexBuffersInfo.startSlot, cmd->startSlot); 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 e7aee326211..5a958016d4c 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.h +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/CommandBufferD3D12.h @@ -15,13 +15,15 @@ #ifndef DAWNNATIVE_D3D12_COMMANDBUFFERD3D12_H_ #define DAWNNATIVE_D3D12_COMMANDBUFFERD3D12_H_ +#include "common/Constants.h" #include "dawn_native/CommandAllocator.h" #include "dawn_native/CommandBuffer.h" #include "dawn_native/d3d12/Forward.h" -#include "dawn_native/d3d12/InputStateD3D12.h" #include "dawn_native/d3d12/d3d12_platform.h" +#include <array> + namespace dawn_native { struct BeginRenderPassCmd; } // namespace dawn_native @@ -30,6 +32,7 @@ namespace dawn_native { namespace d3d12 { class Device; class RenderPassDescriptorHeapTracker; + class RenderPipeline; struct BindGroupStateTracker; @@ -38,7 +41,7 @@ namespace dawn_native { namespace d3d12 { // 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; + const RenderPipeline* lastRenderPipeline = nullptr; uint32_t startSlot = kMaxVertexInputs; uint32_t endSlot = 0; std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexInputs> d3d12BufferViews = {}; @@ -54,7 +57,7 @@ namespace dawn_native { namespace d3d12 { private: void FlushSetVertexBuffers(ComPtr<ID3D12GraphicsCommandList> commandList, VertexBuffersInfo* vertexBuffersInfo, - const InputState* inputState); + const RenderPipeline* lastRenderPipeline); void RecordComputePass(ComPtr<ID3D12GraphicsCommandList> commandList, BindGroupStateTracker* bindingTracker); void RecordRenderPass(ComPtr<ID3D12GraphicsCommandList> commandList, diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/ComputePipelineD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/ComputePipelineD3D12.cpp index 67f4cbc4748..d70846ea099 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/ComputePipelineD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/ComputePipelineD3D12.cpp @@ -32,7 +32,7 @@ namespace dawn_native { namespace d3d12 { // SPRIV-cross does matrix multiplication expecting row major matrices compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; - const ShaderModule* module = ToBackend(descriptor->module); + const ShaderModule* module = ToBackend(descriptor->computeStage->module); const std::string& hlslSource = module->GetHLSLSource(ToBackend(GetLayout())); ComPtr<ID3DBlob> compiledShader; @@ -40,8 +40,8 @@ namespace dawn_native { namespace d3d12 { const PlatformFunctions* functions = device->GetFunctions(); if (FAILED(functions->d3dCompile(hlslSource.c_str(), hlslSource.length(), nullptr, nullptr, - nullptr, descriptor->entryPoint, "cs_5_1", compileFlags, 0, - &compiledShader, &errors))) { + nullptr, descriptor->computeStage->entryPoint, "cs_5_1", + compileFlags, 0, &compiledShader, &errors))) { printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer())); ASSERT(false); } diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/D3D12Backend.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/D3D12Backend.cpp index 0f09bbe87c0..36e766151dc 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/D3D12Backend.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/D3D12Backend.cpp @@ -23,20 +23,20 @@ namespace dawn_native { namespace d3d12 { - dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, HWND window) { + DawnSwapChainImplementation CreateNativeSwapChainImpl(DawnDevice device, HWND window) { Device* backendDevice = reinterpret_cast<Device*>(device); - dawnSwapChainImplementation impl; + DawnSwapChainImplementation impl; impl = CreateSwapChainImplementation(new NativeSwapChainImpl(backendDevice, window)); impl.textureUsage = DAWN_TEXTURE_USAGE_BIT_PRESENT; return impl; } - dawnTextureFormat GetNativeSwapChainPreferredFormat( - const dawnSwapChainImplementation* swapChain) { + DawnTextureFormat GetNativeSwapChainPreferredFormat( + const DawnSwapChainImplementation* swapChain) { NativeSwapChainImpl* impl = reinterpret_cast<NativeSwapChainImpl*>(swapChain->userData); - return static_cast<dawnTextureFormat>(impl->GetPreferredFormat()); + return static_cast<DawnTextureFormat>(impl->GetPreferredFormat()); } }} // 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 6366e81a39b..bd30f25d861 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.cpp @@ -26,7 +26,6 @@ #include "dawn_native/d3d12/CommandBufferD3D12.h" #include "dawn_native/d3d12/ComputePipelineD3D12.h" #include "dawn_native/d3d12/DescriptorHeapAllocator.h" -#include "dawn_native/d3d12/InputStateD3D12.h" #include "dawn_native/d3d12/PipelineLayoutD3D12.h" #include "dawn_native/d3d12/PlatformFunctions.h" #include "dawn_native/d3d12/QueueD3D12.h" @@ -216,9 +215,6 @@ namespace dawn_native { namespace d3d12 { 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); @@ -257,10 +253,10 @@ namespace dawn_native { namespace d3d12 { } MaybeError Device::CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) { + uint64_t destinationOffset, + uint64_t size) { ToBackend(destination) ->TransitionUsageNow(GetPendingCommandList(), dawn::BufferUsageBit::TransferDst); 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 98118ea4aca..a73ca6b6693 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.h +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/DeviceD3D12.h @@ -41,7 +41,6 @@ namespace dawn_native { namespace d3d12 { ~Device(); CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override; - InputStateBase* CreateInputState(InputStateBuilder* builder) override; Serial GetCompletedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override; @@ -70,10 +69,10 @@ namespace dawn_native { namespace d3d12 { ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override; MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) override; + uint64_t destinationOffset, + uint64_t size) override; private: ResultOrError<BindGroupBase*> CreateBindGroupImpl( 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 e93b61158bd..ade12e3ac86 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/Forward.h +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/Forward.h @@ -26,7 +26,6 @@ namespace dawn_native { namespace d3d12 { class CommandBuffer; class ComputePipeline; class Device; - class InputState; class PipelineLayout; class Queue; class RenderPipeline; @@ -45,7 +44,6 @@ namespace dawn_native { namespace d3d12 { using CommandBufferType = CommandBuffer; using ComputePipelineType = ComputePipeline; using DeviceType = Device; - using InputStateType = InputState; using PipelineLayoutType = PipelineLayout; using QueueType = Queue; using RenderPipelineType = RenderPipeline; diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/InputStateD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/InputStateD3D12.cpp deleted file mode 100644 index edeb4c0feed..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/InputStateD3D12.cpp +++ /dev/null @@ -1,103 +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/InputStateD3D12.h" - -#include "common/BitSetIterator.h" - -namespace dawn_native { namespace d3d12 { - - static DXGI_FORMAT VertexFormatType(dawn::VertexFormat format) { - switch (format) { - case dawn::VertexFormat::FloatR32G32B32A32: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - case dawn::VertexFormat::FloatR32G32B32: - return DXGI_FORMAT_R32G32B32_FLOAT; - case dawn::VertexFormat::FloatR32G32: - return DXGI_FORMAT_R32G32_FLOAT; - case dawn::VertexFormat::FloatR32: - return DXGI_FORMAT_R32_FLOAT; - case dawn::VertexFormat::IntR32G32B32A32: - return DXGI_FORMAT_R32G32B32A32_SINT; - case dawn::VertexFormat::IntR32G32B32: - return DXGI_FORMAT_R32G32B32_SINT; - case dawn::VertexFormat::IntR32G32: - return DXGI_FORMAT_R32G32_SINT; - case dawn::VertexFormat::IntR32: - return DXGI_FORMAT_R32_SINT; - case dawn::VertexFormat::UshortR16G16B16A16: - return DXGI_FORMAT_R16G16B16A16_UINT; - case dawn::VertexFormat::UshortR16G16: - return DXGI_FORMAT_R16G16_UINT; - case dawn::VertexFormat::UnormR8G8B8A8: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case dawn::VertexFormat::UnormR8G8: - return DXGI_FORMAT_R8G8_UNORM; - default: - UNREACHABLE(); - } - } - - static D3D12_INPUT_CLASSIFICATION InputStepModeFunction(dawn::InputStepMode mode) { - switch (mode) { - case dawn::InputStepMode::Vertex: - return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; - case dawn::InputStepMode::Instance: - return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; - default: - UNREACHABLE(); - } - } - - InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) { - const auto& attributesSetMask = GetAttributesSetMask(); - - unsigned int count = 0; - for (auto i : IterateBitSet(attributesSetMask)) { - if (!attributesSetMask[i]) { - continue; - } - - D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = mInputElementDescriptors[count++]; - - const VertexAttributeDescriptor& attribute = GetAttribute(i); - - // If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the - // SemanticIndex N - inputElementDescriptor.SemanticName = "TEXCOORD"; - inputElementDescriptor.SemanticIndex = static_cast<uint32_t>(i); - inputElementDescriptor.Format = VertexFormatType(attribute.format); - inputElementDescriptor.InputSlot = attribute.inputSlot; - - const VertexInputDescriptor& input = GetInput(attribute.inputSlot); - - inputElementDescriptor.AlignedByteOffset = attribute.offset; - inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode); - if (inputElementDescriptor.InputSlotClass == - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) { - inputElementDescriptor.InstanceDataStepRate = 0; - } else { - inputElementDescriptor.InstanceDataStepRate = 1; - } - } - - mInputLayoutDescriptor.pInputElementDescs = mInputElementDescriptors; - mInputLayoutDescriptor.NumElements = count; - } - - const D3D12_INPUT_LAYOUT_DESC& InputState::GetD3D12InputLayoutDescriptor() const { - return mInputLayoutDescriptor; - } - -}} // namespace dawn_native::d3d12 diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/InputStateD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/InputStateD3D12.h deleted file mode 100644 index f42b74734e7..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/InputStateD3D12.h +++ /dev/null @@ -1,39 +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_INPUTSTATED3D12_H_ -#define DAWNNATIVE_D3D12_INPUTSTATED3D12_H_ - -#include "dawn_native/InputState.h" - -#include "dawn_native/d3d12/d3d12_platform.h" - -namespace dawn_native { namespace d3d12 { - - class Device; - - class InputState : public InputStateBase { - public: - InputState(InputStateBuilder* builder); - - const D3D12_INPUT_LAYOUT_DESC& GetD3D12InputLayoutDescriptor() const; - - private: - D3D12_INPUT_LAYOUT_DESC mInputLayoutDescriptor; - D3D12_INPUT_ELEMENT_DESC mInputElementDescriptors[kMaxVertexAttributes]; - }; - -}} // namespace dawn_native::d3d12 - -#endif // DAWNNATIVE_D3D12_INPUTSTATED3D12_H_ 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 577d8fa2bc7..50d006f5b91 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.cpp @@ -21,7 +21,7 @@ namespace dawn_native { namespace d3d12 { namespace { - DXGI_USAGE D3D12SwapChainBufferUsage(dawnTextureUsageBit allowedUsages) { + DXGI_USAGE D3D12SwapChainBufferUsage(DawnTextureUsageBit allowedUsages) { DXGI_USAGE usage = DXGI_CPU_ACCESS_NONE; if (allowedUsages & DAWN_TEXTURE_USAGE_BIT_SAMPLED) { usage |= DXGI_USAGE_SHADER_INPUT; @@ -45,16 +45,16 @@ namespace dawn_native { namespace d3d12 { NativeSwapChainImpl::~NativeSwapChainImpl() { } - void NativeSwapChainImpl::Init(dawnWSIContextD3D12* /*context*/) { + void NativeSwapChainImpl::Init(DawnWSIContextD3D12* /*context*/) { } - dawnSwapChainError NativeSwapChainImpl::Configure(dawnTextureFormat format, - dawnTextureUsageBit usage, + DawnSwapChainError NativeSwapChainImpl::Configure(DawnTextureFormat format, + DawnTextureUsageBit usage, uint32_t width, uint32_t height) { ASSERT(width > 0); ASSERT(height > 0); - ASSERT(format == static_cast<dawnTextureFormat>(GetPreferredFormat())); + ASSERT(format == static_cast<DawnTextureFormat>(GetPreferredFormat())); ComPtr<IDXGIFactory4> factory = mDevice->GetFactory(); ComPtr<ID3D12CommandQueue> queue = mDevice->GetCommandQueue(); @@ -89,7 +89,7 @@ namespace dawn_native { namespace d3d12 { return DAWN_SWAP_CHAIN_NO_ERROR; } - dawnSwapChainError NativeSwapChainImpl::GetNextTexture(dawnSwapChainNextTexture* nextTexture) { + DawnSwapChainError NativeSwapChainImpl::GetNextTexture(DawnSwapChainNextTexture* nextTexture) { mCurrentBuffer = mSwapChain->GetCurrentBackBufferIndex(); nextTexture->texture.ptr = mBuffers[mCurrentBuffer].Get(); @@ -100,7 +100,7 @@ namespace dawn_native { namespace d3d12 { return DAWN_SWAP_CHAIN_NO_ERROR; } - dawnSwapChainError NativeSwapChainImpl::Present() { + DawnSwapChainError NativeSwapChainImpl::Present() { // This assumes the texture has already been transition to the PRESENT state. ASSERT_SUCCESS(mSwapChain->Present(1, 0)); diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.h index f953da5e62b..f2fa847b97f 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.h +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/NativeSwapChainImplD3D12.h @@ -28,18 +28,18 @@ namespace dawn_native { namespace d3d12 { class NativeSwapChainImpl { public: - using WSIContext = dawnWSIContextD3D12; + using WSIContext = DawnWSIContextD3D12; NativeSwapChainImpl(Device* device, HWND window); ~NativeSwapChainImpl(); - void Init(dawnWSIContextD3D12* context); - dawnSwapChainError Configure(dawnTextureFormat format, - dawnTextureUsageBit, + void Init(DawnWSIContextD3D12* context); + DawnSwapChainError Configure(DawnTextureFormat format, + DawnTextureUsageBit, uint32_t width, uint32_t height); - dawnSwapChainError GetNextTexture(dawnSwapChainNextTexture* nextTexture); - dawnSwapChainError Present(); + DawnSwapChainError GetNextTexture(DawnSwapChainNextTexture* nextTexture); + DawnSwapChainError Present(); dawn::TextureFormat GetPreferredFormat() const; 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 4e4127d3187..5df00b1a5e6 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.cpp @@ -16,7 +16,6 @@ #include "common/Assert.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" @@ -28,6 +27,84 @@ namespace dawn_native { namespace d3d12 { namespace { + DXGI_FORMAT VertexFormatType(dawn::VertexFormat format) { + switch (format) { + case dawn::VertexFormat::UChar2: + return DXGI_FORMAT_R8G8_UINT; + case dawn::VertexFormat::UChar4: + return DXGI_FORMAT_R8G8B8A8_UINT; + case dawn::VertexFormat::Char2: + return DXGI_FORMAT_R8G8_SINT; + case dawn::VertexFormat::Char4: + return DXGI_FORMAT_R8G8B8A8_SINT; + case dawn::VertexFormat::UChar2Norm: + return DXGI_FORMAT_R8G8_UNORM; + case dawn::VertexFormat::UChar4Norm: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case dawn::VertexFormat::Char2Norm: + return DXGI_FORMAT_R8G8_SNORM; + case dawn::VertexFormat::Char4Norm: + return DXGI_FORMAT_R8G8B8A8_SNORM; + case dawn::VertexFormat::UShort2: + return DXGI_FORMAT_R16G16_UINT; + case dawn::VertexFormat::UShort4: + return DXGI_FORMAT_R16G16B16A16_UINT; + case dawn::VertexFormat::Short2: + return DXGI_FORMAT_R16G16_SINT; + case dawn::VertexFormat::Short4: + return DXGI_FORMAT_R16G16B16A16_SINT; + case dawn::VertexFormat::UShort2Norm: + return DXGI_FORMAT_R16G16_UNORM; + case dawn::VertexFormat::UShort4Norm: + return DXGI_FORMAT_R16G16B16A16_UNORM; + case dawn::VertexFormat::Short2Norm: + return DXGI_FORMAT_R16G16_SNORM; + case dawn::VertexFormat::Short4Norm: + return DXGI_FORMAT_R16G16B16A16_SNORM; + case dawn::VertexFormat::Half2: + return DXGI_FORMAT_R16G16_FLOAT; + case dawn::VertexFormat::Half4: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case dawn::VertexFormat::Float: + return DXGI_FORMAT_R32_FLOAT; + case dawn::VertexFormat::Float2: + return DXGI_FORMAT_R32G32_FLOAT; + case dawn::VertexFormat::Float3: + return DXGI_FORMAT_R32G32B32_FLOAT; + case dawn::VertexFormat::Float4: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + case dawn::VertexFormat::UInt: + return DXGI_FORMAT_R32_UINT; + case dawn::VertexFormat::UInt2: + return DXGI_FORMAT_R32G32_UINT; + case dawn::VertexFormat::UInt3: + return DXGI_FORMAT_R32G32B32_UINT; + case dawn::VertexFormat::UInt4: + return DXGI_FORMAT_R32G32B32A32_UINT; + case dawn::VertexFormat::Int: + return DXGI_FORMAT_R32_SINT; + case dawn::VertexFormat::Int2: + return DXGI_FORMAT_R32G32_SINT; + case dawn::VertexFormat::Int3: + return DXGI_FORMAT_R32G32B32_SINT; + case dawn::VertexFormat::Int4: + return DXGI_FORMAT_R32G32B32A32_SINT; + default: + UNREACHABLE(); + } + } + + D3D12_INPUT_CLASSIFICATION InputStepModeFunction(dawn::InputStepMode mode) { + switch (mode) { + case dawn::InputStepMode::Vertex: + return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; + case dawn::InputStepMode::Instance: + return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; + default: + UNREACHABLE(); + } + } + D3D12_PRIMITIVE_TOPOLOGY D3D12PrimitiveTopology(dawn::PrimitiveTopology primitiveTopology) { switch (primitiveTopology) { case dawn::PrimitiveTopology::PointList: @@ -111,7 +188,7 @@ namespace dawn_native { namespace d3d12 { } } - uint8_t D3D12RenderTargetWriteMask(dawn::ColorWriteMask colorWriteMask) { + uint8_t D3D12RenderTargetWriteMask(dawn::ColorWriteMask writeMask) { static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(dawn::ColorWriteMask::Red) == D3D12_COLOR_WRITE_ENABLE_RED, "ColorWriteMask values must match"); @@ -124,7 +201,7 @@ namespace dawn_native { namespace d3d12 { 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); + return static_cast<uint8_t>(writeMask); } D3D12_RENDER_TARGET_BLEND_DESC ComputeColorDesc(const ColorStateDescriptor* descriptor) { @@ -136,8 +213,7 @@ namespace dawn_native { namespace d3d12 { blendDesc.SrcBlendAlpha = D3D12Blend(descriptor->alphaBlend.srcFactor); blendDesc.DestBlendAlpha = D3D12Blend(descriptor->alphaBlend.dstFactor); blendDesc.BlendOpAlpha = D3D12BlendOperation(descriptor->alphaBlend.operation); - blendDesc.RenderTargetWriteMask = - D3D12RenderTargetWriteMask(descriptor->colorWriteMask); + blendDesc.RenderTargetWriteMask = D3D12RenderTargetWriteMask(descriptor->writeMask); blendDesc.LogicOpEnable = false; blendDesc.LogicOp = D3D12_LOGIC_OP_NOOP; return blendDesc; @@ -261,9 +337,9 @@ namespace dawn_native { namespace d3d12 { descriptorD3D12.pRootSignature = layout->GetRootSignature().Get(); // D3D12 logs warnings if any empty input state is used - InputState* inputState = ToBackend(GetInputState()); - if (inputState->GetAttributesSetMask().any()) { - descriptorD3D12.InputLayout = inputState->GetD3D12InputLayoutDescriptor(); + std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes> inputElementDescriptors; + if (GetAttributesSetMask().any()) { + descriptorD3D12.InputLayout = ComputeInputLayout(&inputElementDescriptors); } descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; @@ -274,7 +350,7 @@ namespace dawn_native { namespace d3d12 { descriptorD3D12.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; descriptorD3D12.RasterizerState.DepthClipEnable = TRUE; - descriptorD3D12.RasterizerState.MultisampleEnable = FALSE; + descriptorD3D12.RasterizerState.MultisampleEnable = (GetSampleCount() > 1) ? TRUE : FALSE; descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE; descriptorD3D12.RasterizerState.ForcedSampleCount = 0; descriptorD3D12.RasterizerState.ConservativeRaster = @@ -299,7 +375,8 @@ namespace dawn_native { namespace d3d12 { descriptorD3D12.SampleMask = UINT_MAX; descriptorD3D12.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology()); - descriptorD3D12.SampleDesc.Count = 1; + descriptorD3D12.SampleDesc.Count = GetSampleCount(); + descriptorD3D12.SampleDesc.Quality = 0; ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState( &descriptorD3D12, IID_PPV_ARGS(&mPipelineState))); @@ -317,4 +394,37 @@ namespace dawn_native { namespace d3d12 { return mPipelineState; } + D3D12_INPUT_LAYOUT_DESC RenderPipeline::ComputeInputLayout( + std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors) { + unsigned int count = 0; + for (auto i : IterateBitSet(GetAttributesSetMask())) { + D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = (*inputElementDescriptors)[count++]; + + const VertexAttributeDescriptor& attribute = GetAttribute(i); + + // If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the + // SemanticIndex N + inputElementDescriptor.SemanticName = "TEXCOORD"; + inputElementDescriptor.SemanticIndex = static_cast<uint32_t>(i); + inputElementDescriptor.Format = VertexFormatType(attribute.format); + inputElementDescriptor.InputSlot = attribute.inputSlot; + + const VertexInputDescriptor& input = GetInput(attribute.inputSlot); + + inputElementDescriptor.AlignedByteOffset = attribute.offset; + inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode); + if (inputElementDescriptor.InputSlotClass == + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) { + inputElementDescriptor.InstanceDataStepRate = 0; + } else { + inputElementDescriptor.InstanceDataStepRate = 1; + } + } + + D3D12_INPUT_LAYOUT_DESC inputLayoutDescriptor; + inputLayoutDescriptor.pInputElementDescs = &(*inputElementDescriptors)[0]; + inputLayoutDescriptor.NumElements = count; + return inputLayoutDescriptor; + } + }} // namespace dawn_native::d3d12 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 20502bb2cc8..b9c9029eef0 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.h +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/RenderPipelineD3D12.h @@ -32,6 +32,9 @@ namespace dawn_native { namespace d3d12 { ComPtr<ID3D12PipelineState> GetPipelineState(); private: + D3D12_INPUT_LAYOUT_DESC ComputeInputLayout( + std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors); + D3D12_PRIMITIVE_TOPOLOGY mD3d12PrimitiveTopology; ComPtr<ID3D12PipelineState> mPipelineState; }; 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 4b78c6cd233..68afa1ac8a7 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.cpp @@ -28,8 +28,6 @@ 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(); } @@ -88,24 +86,6 @@ namespace dawn_native { namespace d3d12 { 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/SamplerD3D12.h b/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.h index 46e82b5852a..0c52716b44e 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.h +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/SamplerD3D12.h @@ -30,7 +30,7 @@ namespace dawn_native { namespace d3d12 { const D3D12_SAMPLER_DESC& GetSamplerDescriptor() const; private: - D3D12_SAMPLER_DESC mSamplerDesc; + D3D12_SAMPLER_DESC mSamplerDesc = {}; }; }} // namespace dawn_native::d3d12 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 b9ec960d2cf..2973bb244da 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/ShaderModuleD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/ShaderModuleD3D12.cpp @@ -37,7 +37,6 @@ namespace dawn_native { namespace d3d12 { // If these options are changed, the values in DawnSPIRVCrossHLSLFastFuzzer.cpp need to be // updated. spirv_cross::CompilerGLSL::Options options_glsl; - options_glsl.vertex.fixup_clipspace = true; options_glsl.vertex.flip_vert_y = true; compiler.set_common_options(options_glsl); diff --git a/chromium/third_party/dawn/src/dawn_native/d3d12/SwapChainD3D12.cpp b/chromium/third_party/dawn/src/dawn_native/d3d12/SwapChainD3D12.cpp index cabc12b25b4..2bfa789161f 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/SwapChainD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/SwapChainD3D12.cpp @@ -24,8 +24,8 @@ namespace dawn_native { namespace d3d12 { SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor) : SwapChainBase(device, descriptor) { const auto& im = GetImplementation(); - dawnWSIContextD3D12 wsiContext = {}; - wsiContext.device = reinterpret_cast<dawnDevice>(GetDevice()); + DawnWSIContextD3D12 wsiContext = {}; + wsiContext.device = reinterpret_cast<DawnDevice>(GetDevice()); im.Init(im.userData, &wsiContext); ASSERT(im.textureUsage != DAWN_TEXTURE_USAGE_BIT_NONE); @@ -37,8 +37,8 @@ namespace dawn_native { namespace d3d12 { TextureBase* SwapChain::GetNextTextureImpl(const TextureDescriptor* descriptor) { const auto& im = GetImplementation(); - dawnSwapChainNextTexture next = {}; - dawnSwapChainError error = im.GetNextTexture(im.userData, &next); + DawnSwapChainNextTexture next = {}; + DawnSwapChainError error = im.GetNextTexture(im.userData, &next); if (error) { GetDevice()->HandleError(error); return nullptr; 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 5e58cbcba91..201c4634b0f 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.cpp @@ -39,14 +39,15 @@ namespace dawn_native { namespace d3d12 { TextureCopySplit ComputeTextureCopySplit(Origin3D origin, Extent3D copySize, uint32_t texelSize, - uint32_t offset, + uint64_t offset, uint32_t rowPitch, uint32_t imageHeight) { TextureCopySplit copy; ASSERT(rowPitch % texelSize == 0); - uint32_t alignedOffset = offset & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1); + uint64_t alignedOffset = + offset & ~static_cast<uint64_t>(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1); copy.offset = alignedOffset; if (offset == alignedOffset) { @@ -67,10 +68,11 @@ namespace dawn_native { namespace d3d12 { } ASSERT(alignedOffset < offset); + ASSERT(offset - alignedOffset < D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); Origin3D texelOffset; - ComputeTexelOffsets(offset - alignedOffset, rowPitch, rowPitch * imageHeight, texelSize, - &texelOffset); + ComputeTexelOffsets(static_cast<uint32_t>(offset - alignedOffset), rowPitch, + rowPitch * imageHeight, texelSize, &texelOffset); uint32_t rowPitchInTexels = rowPitch / texelSize; 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 e468fc67993..e70a0e15766 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.h +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureCopySplitter.h @@ -32,7 +32,7 @@ namespace dawn_native { namespace d3d12 { Extent3D copySize; }; - uint32_t offset = 0; + uint64_t offset = 0; uint32_t count = 0; std::array<CopyInfo, kMaxTextureCopyRegions> copies; }; @@ -40,7 +40,7 @@ namespace dawn_native { namespace d3d12 { TextureCopySplit ComputeTextureCopySplit(Origin3D origin, Extent3D copySize, uint32_t texelSize, - uint32_t offset, + uint64_t offset, uint32_t rowPitch, uint32_t imageHeight); }} // namespace dawn_native::d3d12 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 eb4228f75c7..5e9a63b7658 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.cpp +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.cpp @@ -54,13 +54,19 @@ namespace dawn_native { namespace d3d12 { } D3D12_RESOURCE_FLAGS D3D12ResourceFlags(dawn::TextureUsageBit usage, - dawn::TextureFormat format) { + dawn::TextureFormat format, + bool isMultisampledTexture) { D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE; if (usage & dawn::TextureUsageBit::Storage) { flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; } - if (usage & dawn::TextureUsageBit::OutputAttachment) { + + // A multisampled resource must have either D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET or + // D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL set in D3D12_RESOURCE_DESC::Flags. + // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_resource + // _desc + if ((usage & dawn::TextureUsageBit::OutputAttachment) || isMultisampledTexture) { if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) { flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; } else { @@ -108,7 +114,7 @@ namespace dawn_native { namespace d3d12 { } Texture::Texture(Device* device, const TextureDescriptor* descriptor) - : TextureBase(device, descriptor) { + : TextureBase(device, descriptor, TextureState::OwnedInternal) { D3D12_RESOURCE_DESC resourceDescriptor; resourceDescriptor.Dimension = D3D12TextureDimension(GetDimension()); resourceDescriptor.Alignment = 0; @@ -120,10 +126,12 @@ namespace dawn_native { namespace d3d12 { resourceDescriptor.DepthOrArraySize = GetDepthOrArraySize(); resourceDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels()); resourceDescriptor.Format = D3D12TextureFormat(GetFormat()); - resourceDescriptor.SampleDesc.Count = 1; + resourceDescriptor.SampleDesc.Count = descriptor->sampleCount; + // TODO(bryan.bernhart@intel.com): investigate how to specify standard MSAA sample pattern. resourceDescriptor.SampleDesc.Quality = 0; resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - resourceDescriptor.Flags = D3D12ResourceFlags(GetUsage(), GetFormat()); + resourceDescriptor.Flags = + D3D12ResourceFlags(GetUsage(), GetFormat(), IsMultisampledTexture()); mResource = ToBackend(GetDevice()) ->GetResourceAllocator() @@ -136,21 +144,25 @@ namespace dawn_native { namespace d3d12 { Texture::Texture(Device* device, const TextureDescriptor* descriptor, ID3D12Resource* nativeTexture) - : TextureBase(device, descriptor), mResourcePtr(nativeTexture) { + : TextureBase(device, descriptor, TextureState::OwnedExternal), + mResourcePtr(nativeTexture) { } Texture::~Texture() { - if (mResource) { - // If we own the resource, release it. - ToBackend(GetDevice())->GetResourceAllocator()->Release(mResource); - } + DestroyInternal(); + } + + void Texture::DestroyImpl() { + // If we own the resource, release it. + ToBackend(GetDevice())->GetResourceAllocator()->Release(mResource); + mResource = nullptr; } DXGI_FORMAT Texture::GetD3D12Format() const { return D3D12TextureFormat(GetFormat()); } - ID3D12Resource* Texture::GetD3D12Resource() { + ID3D12Resource* Texture::GetD3D12Resource() const { return mResourcePtr; } @@ -165,26 +177,32 @@ namespace dawn_native { namespace d3d12 { void Texture::TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList, dawn::TextureUsageBit usage) { + TransitionUsageNow(commandList, D3D12TextureUsage(usage, GetFormat())); + } + + void Texture::TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList, + D3D12_RESOURCE_STATES newState) { // Avoid transitioning the texture when it isn't needed. // TODO(cwallez@chromium.org): Need some form of UAV barriers at some point. - if (usage == mLastUsage) { + if (mLastState == newState) { return; } - D3D12_RESOURCE_STATES lastState = D3D12TextureUsage(mLastUsage, GetFormat()); - D3D12_RESOURCE_STATES newState = D3D12TextureUsage(usage, GetFormat()); - D3D12_RESOURCE_BARRIER barrier; barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; barrier.Transition.pResource = mResourcePtr; - barrier.Transition.StateBefore = lastState; + barrier.Transition.StateBefore = mLastState; barrier.Transition.StateAfter = newState; barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; commandList->ResourceBarrier(1, &barrier); - mLastUsage = usage; + mLastState = newState; + } + + uint32_t Texture::GetSubresourceIndex(uint32_t mipmapLevel, uint32_t arraySlice) const { + return GetNumMipLevels() * arraySlice + mipmapLevel; } TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor) @@ -198,6 +216,7 @@ namespace dawn_native { namespace d3d12 { // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_srv // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array_srv // TODO(jiawei.shao@intel.com): support more texture view dimensions. + // TODO(jiawei.shao@intel.com): support creating SRV on multisampled textures. switch (descriptor->dimension) { case dawn::TextureViewDimension::e2D: case dawn::TextureViewDimension::e2DArray: @@ -238,26 +257,43 @@ namespace dawn_native { namespace d3d12 { ASSERT(GetTexture()->GetDimension() == dawn::TextureDimension::e2D); D3D12_RENDER_TARGET_VIEW_DESC rtvDesc; 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; + if (GetTexture()->IsMultisampledTexture()) { + ASSERT(GetTexture()->GetArrayLayers() == 1 && GetTexture()->GetNumMipLevels() == 1 && + GetBaseArrayLayer() == 0 && GetBaseMipLevel() == 0); + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; + } else { + // 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() const { D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc; dsvDesc.Format = ToBackend(GetTexture())->GetD3D12Format(); - dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = D3D12_DSV_FLAG_NONE; + + // TODO(jiawei.shao@intel.com): support rendering into a layer of a texture. + ASSERT(GetTexture()->GetArrayLayers() == 1 && GetTexture()->GetNumMipLevels() == 1 && + GetBaseArrayLayer() == 0 && GetBaseMipLevel() == 0); + + if (GetTexture()->IsMultisampledTexture()) { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS; + } else { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = 0; + } + return dsvDesc; } 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 2edfb7ce44a..33b6be35bdf 100644 --- a/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.h +++ b/chromium/third_party/dawn/src/dawn_native/d3d12/TextureD3D12.h @@ -32,17 +32,24 @@ namespace dawn_native { namespace d3d12 { ~Texture(); DXGI_FORMAT GetD3D12Format() const; - ID3D12Resource* GetD3D12Resource(); + ID3D12Resource* GetD3D12Resource() const; void TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList, dawn::TextureUsageBit usage); + void TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList, + D3D12_RESOURCE_STATES newState); + + uint32_t GetSubresourceIndex(uint32_t mipmapLevel, uint32_t arraySlice) const; private: + // Dawn API + void DestroyImpl() override; + UINT16 GetDepthOrArraySize(); ComPtr<ID3D12Resource> mResource = {}; ID3D12Resource* mResourcePtr = nullptr; - dawn::TextureUsageBit mLastUsage = dawn::TextureUsageBit::None; + D3D12_RESOURCE_STATES mLastState = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COMMON; }; class TextureView : public TextureViewBase { diff --git a/chromium/third_party/dawn/src/dawn_native/dawn_platform.h b/chromium/third_party/dawn/src/dawn_native/dawn_platform.h index 795c371225c..d456d326db7 100644 --- a/chromium/third_party/dawn/src/dawn_native/dawn_platform.h +++ b/chromium/third_party/dawn/src/dawn_native/dawn_platform.h @@ -15,7 +15,7 @@ #ifndef DAWNNATIVE_DAWNPLATFORM_H_ #define DAWNNATIVE_DAWNPLATFORM_H_ -// Use dawncpp to have the enum and bitfield definitions +// Use cawncpp to have the enum and bitfield definitions #include <dawn/dawncpp.h> // Use our autogenerated version of the dawn structures that point to dawn_native object types diff --git a/chromium/third_party/dawn/src/dawn_native/metal/BackendMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/BackendMTL.mm index 9e89ed1818a..2b2f6e28050 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/BackendMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/BackendMTL.mm @@ -104,6 +104,12 @@ namespace dawn_native { namespace metal { return value; } + + bool IsMetalSupported() { + // Metal was first introduced in macOS 10.11 + NSOperatingSystemVersion macOS10_11 = {10, 11, 0}; + return [NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:macOS10_11]; + } } // anonymous namespace // The Metal backend's Adapter. @@ -123,6 +129,12 @@ namespace dawn_native { namespace metal { mPCIInfo.deviceId = GetEntryProperty(entry, CFSTR("device-id")); IOObjectRelease(entry); } + + if ([device isLowPower]) { + mDeviceType = DeviceType::IntegratedGPU; + } else { + mDeviceType = DeviceType::DiscreteGPU; + } } ~Adapter() override { @@ -155,6 +167,9 @@ namespace dawn_native { namespace metal { } BackendConnection* Connect(InstanceBase* instance) { + if (!IsMetalSupported()) { + return nullptr; + } return new Backend(instance); } 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 3e91b43fcc4..1d0828aa4b7 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/BufferMTL.mm @@ -31,7 +31,7 @@ namespace dawn_native { namespace metal { } Buffer::~Buffer() { - DestroyImpl(); + DestroyInternal(); } id<MTLBuffer> Buffer::GetMTLBuffer() { 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 bb76ca24a69..9f3a5aee28e 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/CommandBufferMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/CommandBufferMTL.mm @@ -20,7 +20,6 @@ #include "dawn_native/metal/BufferMTL.h" #include "dawn_native/metal/ComputePipelineMTL.h" #include "dawn_native/metal/DeviceMTL.h" -#include "dawn_native/metal/InputStateMTL.h" #include "dawn_native/metal/PipelineLayoutMTL.h" #include "dawn_native/metal/RenderPipelineMTL.h" #include "dawn_native/metal/SamplerMTL.h" @@ -68,7 +67,21 @@ namespace dawn_native { namespace metal { descriptor.colorAttachments[i].level = attachmentInfo.view->GetBaseMipLevel(); descriptor.colorAttachments[i].slice = attachmentInfo.view->GetBaseArrayLayer(); - descriptor.colorAttachments[i].storeAction = MTLStoreActionStore; + ASSERT(attachmentInfo.storeOp == dawn::StoreOp::Store); + // TODO(jiawei.shao@intel.com): emulate MTLStoreActionStoreAndMultisampleResolve on + // the platforms that do not support this store action. + if (attachmentInfo.resolveTarget.Get() != nullptr) { + descriptor.colorAttachments[i].resolveTexture = + ToBackend(attachmentInfo.resolveTarget->GetTexture())->GetMTLTexture(); + descriptor.colorAttachments[i].resolveLevel = + attachmentInfo.resolveTarget->GetBaseMipLevel(); + descriptor.colorAttachments[i].resolveSlice = + attachmentInfo.resolveTarget->GetBaseArrayLayer(); + descriptor.colorAttachments[i].storeAction = + MTLStoreActionStoreAndMultisampleResolve; + } else { + descriptor.colorAttachments[i].storeAction = MTLStoreActionStore; + } } if (renderPass->hasDepthStencilAttachment) { @@ -199,6 +212,12 @@ namespace dawn_native { namespace metal { [compute setTexture:textureView->GetMTLTexture() atIndex:computeIndex]; } } break; + + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; } } } @@ -302,7 +321,7 @@ namespace dawn_native { namespace metal { break; } - uint32_t offset = src.offset; + uint64_t offset = src.offset; // Doing all the copy except the last image. if (size.depth > 1) { @@ -414,7 +433,7 @@ namespace dawn_native { namespace metal { break; } - uint32_t offset = dst.offset; + uint64_t offset = dst.offset; // Doing all the copy except the last image. if (size.depth > 1) { @@ -470,6 +489,40 @@ namespace dawn_native { namespace metal { destinationBytesPerImage:lastRowDataSize]; } break; + case Command::CopyTextureToTexture: { + CopyTextureToTextureCmd* copy = + mCommands.NextCommand<CopyTextureToTextureCmd>(); + Texture* srcTexture = ToBackend(copy->source.texture.Get()); + Texture* dstTexture = ToBackend(copy->destination.texture.Get()); + + MTLOrigin srcOrigin; + srcOrigin.x = copy->source.origin.x; + srcOrigin.y = copy->source.origin.y; + srcOrigin.z = copy->source.origin.z; + + MTLOrigin dstOrigin; + dstOrigin.x = copy->destination.origin.x; + dstOrigin.y = copy->destination.origin.y; + dstOrigin.z = copy->destination.origin.z; + + MTLSize size; + size.width = copy->copySize.width; + size.height = copy->copySize.height; + size.depth = copy->copySize.depth; + + encoders.EnsureBlit(commandBuffer); + + [encoders.blit copyFromTexture:srcTexture->GetMTLTexture() + sourceSlice:copy->source.slice + sourceLevel:copy->source.level + sourceOrigin:srcOrigin + sourceSize:size + toTexture:dstTexture->GetMTLTexture() + destinationSlice:copy->destination.slice + destinationLevel:copy->destination.level + destinationOrigin:dstOrigin]; + } break; + default: { UNREACHABLE(); } break; } } @@ -585,7 +638,8 @@ namespace dawn_native { namespace metal { case Command::DrawIndexed: { DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>(); - size_t formatSize = IndexFormatSize(lastPipeline->GetIndexFormat()); + size_t formatSize = + IndexFormatSize(lastPipeline->GetInputStateDescriptor()->indexFormat); // The index and instance count must be non-zero, otherwise no-op if (draw->indexCount != 0 && draw->instanceCount != 0) { @@ -667,6 +721,15 @@ namespace dawn_native { namespace metal { rect.width = cmd->width; rect.height = cmd->height; + // The scissor rect x + width must be <= render pass width + if ((rect.x + rect.width) > renderPassCmd->width) { + rect.width = renderPassCmd->width - rect.x; + } + // The scissor rect y + height must be <= render pass height + if ((rect.y + rect.height > renderPassCmd->height)) { + rect.height = renderPassCmd->height - rect.y; + } + [encoder setScissorRect:rect]; } break; @@ -694,7 +757,7 @@ namespace dawn_native { namespace metal { case Command::SetVertexBuffers: { SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>(); auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count); - auto offsets = mCommands.NextData<uint32_t>(cmd->count); + auto offsets = mCommands.NextData<uint64_t>(cmd->count); std::array<id<MTLBuffer>, kMaxVertexInputs> mtlBuffers; std::array<NSUInteger, kMaxVertexInputs> mtlOffsets; diff --git a/chromium/third_party/dawn/src/dawn_native/metal/ComputePipelineMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/ComputePipelineMTL.mm index 5c6eaa62f49..fc76ee195c0 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/ComputePipelineMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/ComputePipelineMTL.mm @@ -23,15 +23,14 @@ namespace dawn_native { namespace metal { : ComputePipelineBase(device, descriptor) { auto mtlDevice = ToBackend(GetDevice())->GetMTLDevice(); - const auto& module = ToBackend(descriptor->module); - const char* entryPoint = descriptor->entryPoint; - - auto compilationData = - module->GetFunction(entryPoint, dawn::ShaderStage::Compute, ToBackend(GetLayout())); + const ShaderModule* computeModule = ToBackend(descriptor->computeStage->module); + const char* computeEntryPoint = descriptor->computeStage->entryPoint; + ShaderModule::MetalFunctionData computeData = computeModule->GetFunction( + computeEntryPoint, dawn::ShaderStage::Compute, ToBackend(GetLayout())); NSError* error = nil; mMtlComputePipelineState = - [mtlDevice newComputePipelineStateWithFunction:compilationData.function error:&error]; + [mtlDevice newComputePipelineStateWithFunction:computeData.function error:&error]; if (error != nil) { NSLog(@" error => %@", error); GetDevice()->HandleError("Error creating pipeline state"); @@ -39,7 +38,7 @@ namespace dawn_native { namespace metal { } // Copy over the local workgroup size as it is passed to dispatch explicitly in Metal - mLocalWorkgroupSize = compilationData.localWorkgroupSize; + mLocalWorkgroupSize = computeData.localWorkgroupSize; } ComputePipeline::~ComputePipeline() { 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 9bcbf2f5772..87eec00a387 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.h +++ b/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.h @@ -24,8 +24,9 @@ #import <Metal/Metal.h> #import <QuartzCore/CAMetalLayer.h> +#include <atomic> #include <memory> -#include <type_traits> +#include <mutex> namespace dawn_native { namespace metal { @@ -37,7 +38,6 @@ namespace dawn_native { namespace metal { ~Device(); CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override; - InputStateBase* CreateInputState(InputStateBuilder* builder) override; Serial GetCompletedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override; @@ -54,13 +54,14 @@ namespace dawn_native { namespace metal { TextureBase* CreateTextureWrappingIOSurface(const TextureDescriptor* descriptor, IOSurfaceRef ioSurface, uint32_t plane); + void WaitForCommandsToBeScheduled(); ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override; MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) override; + uint64_t destinationOffset, + uint64_t size) override; private: ResultOrError<BindGroupBase*> CreateBindGroupImpl( @@ -85,15 +86,21 @@ namespace dawn_native { namespace metal { TextureBase* texture, const TextureViewDescriptor* descriptor) override; - void OnCompletedHandler(); - id<MTLDevice> mMtlDevice = nil; id<MTLCommandQueue> mCommandQueue = nil; std::unique_ptr<MapRequestTracker> mMapTracker; - Serial mCompletedSerial = 0; Serial mLastSubmittedSerial = 0; id<MTLCommandBuffer> mPendingCommands = nil; + + // The completed serial is updated in a Metal completion handler that can be fired on a + // different thread, so it needs to be atomic. + std::atomic<uint64_t> mCompletedSerial; + + // mLastSubmittedCommands will be accessed in a Metal schedule handler that can be fired on + // a different thread so we guard access to it with a mutex. + std::mutex mLastSubmittedCommandsMutex; + id<MTLCommandBuffer> mLastSubmittedCommands = nil; }; }} // namespace dawn_native::metal 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 3a5fa1a9f12..c53e6622b87 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/DeviceMTL.mm @@ -21,7 +21,6 @@ #include "dawn_native/metal/BufferMTL.h" #include "dawn_native/metal/CommandBufferMTL.h" #include "dawn_native/metal/ComputePipelineMTL.h" -#include "dawn_native/metal/InputStateMTL.h" #include "dawn_native/metal/PipelineLayoutMTL.h" #include "dawn_native/metal/QueueMTL.h" #include "dawn_native/metal/RenderPipelineMTL.h" @@ -31,12 +30,15 @@ #include "dawn_native/metal/SwapChainMTL.h" #include "dawn_native/metal/TextureMTL.h" +#include <type_traits> + namespace dawn_native { namespace metal { Device::Device(AdapterBase* adapter, id<MTLDevice> mtlDevice) : DeviceBase(adapter), mMtlDevice([mtlDevice retain]), - mMapTracker(new MapRequestTracker(this)) { + mMapTracker(new MapRequestTracker(this)), + mCompletedSerial(0) { [mMtlDevice retain]; mCommandQueue = [mMtlDevice newCommandQueue]; } @@ -47,7 +49,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 (mCompletedSerial != mLastSubmittedSerial) { + while (GetCompletedCommandSerial() != mLastSubmittedSerial) { usleep(100); } Tick(); @@ -83,9 +85,6 @@ namespace dawn_native { namespace metal { 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); @@ -118,7 +117,8 @@ namespace dawn_native { namespace metal { } Serial Device::GetCompletedCommandSerial() const { - return mCompletedSerial; + static_assert(std::is_same<Serial, uint64_t>::value, ""); + return mCompletedSerial.load(); } Serial Device::GetLastSubmittedCommandSerial() const { @@ -130,12 +130,14 @@ namespace dawn_native { namespace metal { } void Device::TickImpl() { - mDynamicUploader->Tick(mCompletedSerial); - mMapTracker->Tick(mCompletedSerial); + Serial completedSerial = GetCompletedCommandSerial(); + + mDynamicUploader->Tick(completedSerial); + mMapTracker->Tick(completedSerial); if (mPendingCommands != nil) { SubmitPendingCommandBuffer(); - } else if (mCompletedSerial == mLastSubmittedSerial) { + } else if (completedSerial == 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++; @@ -160,18 +162,45 @@ namespace dawn_native { namespace metal { return; } - // Ok, ObjC blocks are weird. My understanding is that local variables are captured by value - // 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. mLastSubmittedSerial++; + + // Replace mLastSubmittedCommands with the mutex held so we avoid races between the + // schedule handler and this code. + { + std::lock_guard<std::mutex> lock(mLastSubmittedCommandsMutex); + [mLastSubmittedCommands release]; + mLastSubmittedCommands = mPendingCommands; + } + + // Ok, ObjC blocks are weird. My understanding is that local variables are captured by + // value so this-> works as expected. However it is unclear how members are captured, (are + // they captured using this-> or by value?). To be safe we copy members to local variables + // to ensure they are captured "by value". + + // Free mLastSubmittedCommands as soon as it is scheduled so that it doesn't hold + // references to its resources. Make a local copy of pendingCommands first so it is + // captured "by-value" by the block. + id<MTLCommandBuffer> pendingCommands = mPendingCommands; + + [mPendingCommands addScheduledHandler:^(id<MTLCommandBuffer>) { + // This is DRF because we hold the mutex for mLastSubmittedCommands and pendingCommands + // is a local value (and not the member itself). + std::lock_guard<std::mutex> lock(mLastSubmittedCommandsMutex); + if (this->mLastSubmittedCommands == pendingCommands) { + [this->mLastSubmittedCommands release]; + this->mLastSubmittedCommands = nil; + } + }]; + + // Update the completed serial once the completed handler is fired. Make a local copy of + // mLastSubmittedSerial so it is captured by value. Serial pendingSerial = mLastSubmittedSerial; [mPendingCommands addCompletedHandler:^(id<MTLCommandBuffer>) { + ASSERT(pendingSerial > mCompletedSerial.load()); this->mCompletedSerial = pendingSerial; }]; [mPendingCommands commit]; - [mPendingCommands release]; mPendingCommands = nil; } @@ -186,10 +215,10 @@ namespace dawn_native { namespace metal { } MaybeError Device::CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) { + uint64_t destinationOffset, + uint64_t size) { id<MTLBuffer> uploadBuffer = ToBackend(source)->GetBufferHandle(); id<MTLBuffer> buffer = ToBackend(destination)->GetMTLBuffer(); id<MTLCommandBuffer> commandBuffer = GetPendingCommandBuffer(); @@ -216,4 +245,10 @@ namespace dawn_native { namespace metal { return new Texture(this, descriptor, ioSurface, plane); } + + void Device::WaitForCommandsToBeScheduled() { + SubmitPendingCommandBuffer(); + [mLastSubmittedCommands waitUntilScheduled]; + } + }} // namespace dawn_native::metal 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 f2a2e3ce4ea..4e889cddec5 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/Forward.h +++ b/chromium/third_party/dawn/src/dawn_native/metal/Forward.h @@ -32,7 +32,6 @@ namespace dawn_native { namespace metal { class ComputePipeline; class Device; class Framebuffer; - class InputState; class PipelineLayout; class Queue; class RenderPipeline; @@ -51,7 +50,6 @@ namespace dawn_native { namespace metal { using CommandBufferType = CommandBuffer; using ComputePipelineType = ComputePipeline; using DeviceType = Device; - using InputStateType = InputState; using PipelineLayoutType = PipelineLayout; using QueueType = Queue; using RenderPipelineType = RenderPipeline; diff --git a/chromium/third_party/dawn/src/dawn_native/metal/InputStateMTL.h b/chromium/third_party/dawn/src/dawn_native/metal/InputStateMTL.h deleted file mode 100644 index 496e6eae274..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/metal/InputStateMTL.h +++ /dev/null @@ -1,37 +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_METAL_INPUTSTATEMTL_H_ -#define DAWNNATIVE_METAL_INPUTSTATEMTL_H_ - -#include "dawn_native/InputState.h" - -#import <Metal/Metal.h> - -namespace dawn_native { namespace metal { - - class InputState : public InputStateBase { - public: - InputState(InputStateBuilder* builder); - ~InputState(); - - MTLVertexDescriptor* GetMTLVertexDescriptor(); - - private: - MTLVertexDescriptor* mMtlVertexDescriptor = nil; - }; - -}} // namespace dawn_native::metal - -#endif // DAWNNATIVE_METAL_COMMANDINPUTSTATEMTL_H_ diff --git a/chromium/third_party/dawn/src/dawn_native/metal/InputStateMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/InputStateMTL.mm deleted file mode 100644 index 02a0c8ab2a2..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/metal/InputStateMTL.mm +++ /dev/null @@ -1,111 +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/InputStateMTL.h" - -#include "common/BitSetIterator.h" - -namespace dawn_native { namespace metal { - - namespace { - MTLVertexFormat VertexFormatType(dawn::VertexFormat format) { - switch (format) { - case dawn::VertexFormat::FloatR32G32B32A32: - return MTLVertexFormatFloat4; - case dawn::VertexFormat::FloatR32G32B32: - return MTLVertexFormatFloat3; - case dawn::VertexFormat::FloatR32G32: - return MTLVertexFormatFloat2; - case dawn::VertexFormat::FloatR32: - return MTLVertexFormatFloat; - case dawn::VertexFormat::IntR32G32B32A32: - return MTLVertexFormatInt4; - case dawn::VertexFormat::IntR32G32B32: - return MTLVertexFormatInt3; - case dawn::VertexFormat::IntR32G32: - return MTLVertexFormatInt2; - case dawn::VertexFormat::IntR32: - return MTLVertexFormatInt; - case dawn::VertexFormat::UshortR16G16B16A16: - return MTLVertexFormatUShort4; - case dawn::VertexFormat::UshortR16G16: - return MTLVertexFormatUShort2; - case dawn::VertexFormat::UnormR8G8B8A8: - return MTLVertexFormatUChar4Normalized; - case dawn::VertexFormat::UnormR8G8: - return MTLVertexFormatUChar2Normalized; - } - } - - MTLVertexStepFunction InputStepModeFunction(dawn::InputStepMode mode) { - switch (mode) { - case dawn::InputStepMode::Vertex: - return MTLVertexStepFunctionPerVertex; - case dawn::InputStepMode::Instance: - return MTLVertexStepFunctionPerInstance; - } - } - } - - InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) { - mMtlVertexDescriptor = [MTLVertexDescriptor new]; - - const auto& attributesSetMask = GetAttributesSetMask(); - for (uint32_t i = 0; i < attributesSetMask.size(); ++i) { - if (!attributesSetMask[i]) { - continue; - } - const VertexAttributeDescriptor& info = GetAttribute(i); - - auto attribDesc = [MTLVertexAttributeDescriptor new]; - attribDesc.format = VertexFormatType(info.format); - attribDesc.offset = info.offset; - attribDesc.bufferIndex = kMaxBindingsPerGroup + info.inputSlot; - mMtlVertexDescriptor.attributes[i] = attribDesc; - [attribDesc release]; - } - - for (uint32_t i : IterateBitSet(GetInputsSetMask())) { - const VertexInputDescriptor& info = GetInput(i); - - auto layoutDesc = [MTLVertexBufferLayoutDescriptor new]; - if (info.stride == 0) { - // For MTLVertexStepFunctionConstant, the stepRate must be 0, - // but the stride must NOT be 0, so I made up a value (256). - // TODO(cwallez@chromium.org): the made up value will need to be at least - // max(attrib.offset + sizeof(attrib) for each attrib) - layoutDesc.stepFunction = MTLVertexStepFunctionConstant; - layoutDesc.stepRate = 0; - layoutDesc.stride = 256; - } else { - layoutDesc.stepFunction = InputStepModeFunction(info.stepMode); - layoutDesc.stepRate = 1; - layoutDesc.stride = info.stride; - } - // TODO(cwallez@chromium.org): make the offset depend on the pipeline layout - mMtlVertexDescriptor.layouts[kMaxBindingsPerGroup + i] = layoutDesc; - [layoutDesc release]; - } - } - - InputState::~InputState() { - [mMtlVertexDescriptor release]; - mMtlVertexDescriptor = nil; - } - - MTLVertexDescriptor* InputState::GetMTLVertexDescriptor() { - return mMtlVertexDescriptor; - } - -}} // namespace dawn_native::metal diff --git a/chromium/third_party/dawn/src/dawn_native/metal/MetalBackend.mm b/chromium/third_party/dawn/src/dawn_native/metal/MetalBackend.mm index 7f6274740f1..e5c88673fff 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/MetalBackend.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/MetalBackend.mm @@ -22,20 +22,25 @@ namespace dawn_native { namespace metal { - id<MTLDevice> GetMetalDevice(dawnDevice cDevice) { + id<MTLDevice> GetMetalDevice(DawnDevice cDevice) { Device* device = reinterpret_cast<Device*>(cDevice); return device->GetMTLDevice(); } - dawnTexture WrapIOSurface(dawnDevice cDevice, - const dawnTextureDescriptor* cDescriptor, + DawnTexture WrapIOSurface(DawnDevice cDevice, + const DawnTextureDescriptor* cDescriptor, IOSurfaceRef ioSurface, uint32_t plane) { Device* device = reinterpret_cast<Device*>(cDevice); const TextureDescriptor* descriptor = reinterpret_cast<const TextureDescriptor*>(cDescriptor); TextureBase* texture = device->CreateTextureWrappingIOSurface(descriptor, ioSurface, plane); - return reinterpret_cast<dawnTexture>(texture); + return reinterpret_cast<DawnTexture>(texture); + } + + void WaitForCommandsToBeScheduled(DawnDevice cDevice) { + Device* device = reinterpret_cast<Device*>(cDevice); + device->WaitForCommandsToBeScheduled(); } }} // namespace dawn_native::metal diff --git a/chromium/third_party/dawn/src/dawn_native/metal/PipelineLayoutMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/PipelineLayoutMTL.mm index 9912f94de26..4b6bb29d181 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/PipelineLayoutMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/PipelineLayoutMTL.mm @@ -53,6 +53,11 @@ namespace dawn_native { namespace metal { mIndexInfo[stage][group][binding] = textureIndex; textureIndex++; break; + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; } } } 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 6da06e2f4b0..1edf434db75 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.h +++ b/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.h @@ -36,6 +36,8 @@ namespace dawn_native { namespace metal { id<MTLDepthStencilState> GetMTLDepthStencilState(); private: + MTLVertexDescriptor* MakeVertexDesc(); + MTLIndexType mMtlIndexType; MTLPrimitiveType mMtlPrimitiveTopology; id<MTLRenderPipelineState> mMtlRenderPipelineState = nil; 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 45437a80422..fa72c797f59 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/RenderPipelineMTL.mm @@ -15,7 +15,6 @@ #include "dawn_native/metal/RenderPipelineMTL.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" @@ -24,6 +23,80 @@ namespace dawn_native { namespace metal { namespace { + MTLVertexFormat VertexFormatType(dawn::VertexFormat format) { + switch (format) { + case dawn::VertexFormat::UChar2: + return MTLVertexFormatUChar2; + case dawn::VertexFormat::UChar4: + return MTLVertexFormatUChar4; + case dawn::VertexFormat::Char2: + return MTLVertexFormatChar2; + case dawn::VertexFormat::Char4: + return MTLVertexFormatChar4; + case dawn::VertexFormat::UChar2Norm: + return MTLVertexFormatUChar2Normalized; + case dawn::VertexFormat::UChar4Norm: + return MTLVertexFormatUChar4Normalized; + case dawn::VertexFormat::Char2Norm: + return MTLVertexFormatChar2Normalized; + case dawn::VertexFormat::Char4Norm: + return MTLVertexFormatChar4Normalized; + case dawn::VertexFormat::UShort2: + return MTLVertexFormatUShort2; + case dawn::VertexFormat::UShort4: + return MTLVertexFormatUShort4; + case dawn::VertexFormat::Short2: + return MTLVertexFormatShort2; + case dawn::VertexFormat::Short4: + return MTLVertexFormatShort4; + case dawn::VertexFormat::UShort2Norm: + return MTLVertexFormatUShort2Normalized; + case dawn::VertexFormat::UShort4Norm: + return MTLVertexFormatUShort4Normalized; + case dawn::VertexFormat::Short2Norm: + return MTLVertexFormatShort2Normalized; + case dawn::VertexFormat::Short4Norm: + return MTLVertexFormatShort4Normalized; + case dawn::VertexFormat::Half2: + return MTLVertexFormatHalf2; + case dawn::VertexFormat::Half4: + return MTLVertexFormatHalf4; + case dawn::VertexFormat::Float: + return MTLVertexFormatFloat; + case dawn::VertexFormat::Float2: + return MTLVertexFormatFloat2; + case dawn::VertexFormat::Float3: + return MTLVertexFormatFloat3; + case dawn::VertexFormat::Float4: + return MTLVertexFormatFloat4; + case dawn::VertexFormat::UInt: + return MTLVertexFormatUInt; + case dawn::VertexFormat::UInt2: + return MTLVertexFormatUInt2; + case dawn::VertexFormat::UInt3: + return MTLVertexFormatUInt3; + case dawn::VertexFormat::UInt4: + return MTLVertexFormatUInt4; + case dawn::VertexFormat::Int: + return MTLVertexFormatInt; + case dawn::VertexFormat::Int2: + return MTLVertexFormatInt2; + case dawn::VertexFormat::Int3: + return MTLVertexFormatInt3; + case dawn::VertexFormat::Int4: + return MTLVertexFormatInt4; + } + } + + MTLVertexStepFunction InputStepModeFunction(dawn::InputStepMode mode) { + switch (mode) { + case dawn::InputStepMode::Vertex: + return MTLVertexStepFunctionPerVertex; + case dawn::InputStepMode::Instance: + return MTLVertexStepFunctionPerInstance; + } + } + MTLPrimitiveType MTLPrimitiveTopology(dawn::PrimitiveTopology primitiveTopology) { switch (primitiveTopology) { case dawn::PrimitiveTopology::PointList: @@ -109,19 +182,19 @@ namespace dawn_native { namespace metal { } } - MTLColorWriteMask MetalColorWriteMask(dawn::ColorWriteMask colorWriteMask) { + MTLColorWriteMask MetalColorWriteMask(dawn::ColorWriteMask writeMask) { MTLColorWriteMask mask = MTLColorWriteMaskNone; - if (colorWriteMask & dawn::ColorWriteMask::Red) { + if (writeMask & dawn::ColorWriteMask::Red) { mask |= MTLColorWriteMaskRed; } - if (colorWriteMask & dawn::ColorWriteMask::Green) { + if (writeMask & dawn::ColorWriteMask::Green) { mask |= MTLColorWriteMaskGreen; } - if (colorWriteMask & dawn::ColorWriteMask::Blue) { + if (writeMask & dawn::ColorWriteMask::Blue) { mask |= MTLColorWriteMaskBlue; } - if (colorWriteMask & dawn::ColorWriteMask::Alpha) { + if (writeMask & dawn::ColorWriteMask::Alpha) { mask |= MTLColorWriteMaskAlpha; } @@ -141,7 +214,7 @@ namespace dawn_native { namespace metal { attachment.destinationAlphaBlendFactor = MetalBlendFactor(descriptor->alphaBlend.dstFactor, true); attachment.alphaBlendOperation = MetalBlendOperation(descriptor->alphaBlend.operation); - attachment.writeMask = MetalColorWriteMask(descriptor->colorWriteMask); + attachment.writeMask = MetalColorWriteMask(descriptor->writeMask); } MTLStencilOperation MetalStencilOperation(dawn::StencilOperation stencilOperation) { @@ -165,17 +238,17 @@ namespace dawn_native { namespace metal { } } - MTLDepthStencilDescriptor* ComputeDepthStencilDesc( + MTLDepthStencilDescriptor* MakeDepthStencilDesc( const DepthStencilStateDescriptor* descriptor) { - MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = - [[MTLDepthStencilDescriptor new] autorelease]; + MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = [MTLDepthStencilDescriptor new]; + mtlDepthStencilDescriptor.depthCompareFunction = ToMetalCompareFunction(descriptor->depthCompare); mtlDepthStencilDescriptor.depthWriteEnabled = descriptor->depthWriteEnabled; if (StencilTestEnabled(descriptor)) { - MTLStencilDescriptor* backFaceStencil = [[MTLStencilDescriptor new] autorelease]; - MTLStencilDescriptor* frontFaceStencil = [[MTLStencilDescriptor new] autorelease]; + MTLStencilDescriptor* backFaceStencil = [MTLStencilDescriptor new]; + MTLStencilDescriptor* frontFaceStencil = [MTLStencilDescriptor new]; backFaceStencil.stencilCompareFunction = ToMetalCompareFunction(descriptor->stencilBack.compare); @@ -201,7 +274,11 @@ namespace dawn_native { namespace metal { mtlDepthStencilDescriptor.backFaceStencil = backFaceStencil; mtlDepthStencilDescriptor.frontFaceStencil = frontFaceStencil; + + [backFaceStencil release]; + [frontFaceStencil release]; } + return mtlDepthStencilDescriptor; } @@ -209,7 +286,7 @@ namespace dawn_native { namespace metal { RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor) : RenderPipelineBase(device, descriptor), - mMtlIndexType(MTLIndexFormat(GetIndexFormat())), + mMtlIndexType(MTLIndexFormat(GetInputStateDescriptor()->indexFormat)), mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) { auto mtlDevice = device->GetMTLDevice(); @@ -243,8 +320,11 @@ namespace dawn_native { namespace metal { descriptorMTL.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology()); - InputState* inputState = ToBackend(GetInputState()); - descriptorMTL.vertexDescriptor = inputState->GetMTLVertexDescriptor(); + MTLVertexDescriptor* vertexDesc = MakeVertexDesc(); + descriptorMTL.vertexDescriptor = vertexDesc; + [vertexDesc release]; + + descriptorMTL.sampleCount = GetSampleCount(); // TODO(kainino@chromium.org): push constants, textures, samplers @@ -260,12 +340,13 @@ namespace dawn_native { namespace metal { } } - // 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 + // Create depth stencil state and cache it, fetch the cached depth stencil state when we + // call setDepthStencilState() for a given render pipeline in CommandEncoder, in order to // improve performance. - mMtlDepthStencilState = - [mtlDevice newDepthStencilStateWithDescriptor:ComputeDepthStencilDesc( - GetDepthStencilStateDescriptor())]; + MTLDepthStencilDescriptor* depthStencilDesc = + MakeDepthStencilDesc(GetDepthStencilStateDescriptor()); + mMtlDepthStencilState = [mtlDevice newDepthStencilStateWithDescriptor:depthStencilDesc]; + [depthStencilDesc release]; } RenderPipeline::~RenderPipeline() { @@ -289,4 +370,42 @@ namespace dawn_native { namespace metal { return mMtlDepthStencilState; } + MTLVertexDescriptor* RenderPipeline::MakeVertexDesc() { + MTLVertexDescriptor* mtlVertexDescriptor = [MTLVertexDescriptor new]; + + for (uint32_t i : IterateBitSet(GetAttributesSetMask())) { + const VertexAttributeDescriptor& info = GetAttribute(i); + + auto attribDesc = [MTLVertexAttributeDescriptor new]; + attribDesc.format = VertexFormatType(info.format); + attribDesc.offset = info.offset; + attribDesc.bufferIndex = kMaxBindingsPerGroup + info.inputSlot; + mtlVertexDescriptor.attributes[i] = attribDesc; + [attribDesc release]; + } + + for (uint32_t i : IterateBitSet(GetInputsSetMask())) { + const VertexInputDescriptor& info = GetInput(i); + + auto layoutDesc = [MTLVertexBufferLayoutDescriptor new]; + if (info.stride == 0) { + // For MTLVertexStepFunctionConstant, the stepRate must be 0, + // but the stride must NOT be 0, so I made up a value (256). + // TODO(cwallez@chromium.org): the made up value will need to be at least + // max(attrib.offset + sizeof(attrib) for each attrib) + layoutDesc.stepFunction = MTLVertexStepFunctionConstant; + layoutDesc.stepRate = 0; + layoutDesc.stride = 256; + } else { + layoutDesc.stepFunction = InputStepModeFunction(info.stepMode); + layoutDesc.stepRate = 1; + layoutDesc.stride = info.stride; + } + // TODO(cwallez@chromium.org): make the offset depend on the pipeline layout + mtlVertexDescriptor.layouts[kMaxBindingsPerGroup + i] = layoutDesc; + [layoutDesc release]; + } + return mtlVertexDescriptor; + } + }} // 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 19d374b8bc3..eff9c35c45e 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/SamplerMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/SamplerMTL.mm @@ -46,19 +46,6 @@ 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; } } } @@ -66,7 +53,7 @@ namespace dawn_native { namespace metal { Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor) : SamplerBase(device, descriptor) { MTLSamplerDescriptor* mtlDesc = [MTLSamplerDescriptor new]; - [mtlDesc autorelease]; + mtlDesc.minFilter = FilterModeToMinMagFilter(descriptor->minFilter); mtlDesc.magFilter = FilterModeToMinMagFilter(descriptor->magFilter); mtlDesc.mipFilter = FilterModeToMipFilter(descriptor->mipmapFilter); @@ -78,9 +65,10 @@ namespace dawn_native { namespace metal { mtlDesc.lodMinClamp = descriptor->lodMinClamp; mtlDesc.lodMaxClamp = descriptor->lodMaxClamp; mtlDesc.compareFunction = ToMetalCompareFunction(descriptor->compareFunction); - mtlDesc.borderColor = BorderColor(descriptor->borderColor); mMtlSamplerState = [device->GetMTLDevice() newSamplerStateWithDescriptor:mtlDesc]; + + [mtlDesc release]; } Sampler::~Sampler() { diff --git a/chromium/third_party/dawn/src/dawn_native/metal/ShaderModuleMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/ShaderModuleMTL.mm index 2d38d1854f6..28cff586a82 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/ShaderModuleMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/ShaderModuleMTL.mm @@ -60,8 +60,7 @@ namespace dawn_native { namespace metal { // By default SPIRV-Cross will give MSL resources indices in increasing order. // To make the MSL indices match the indices chosen in the PipelineLayout, we build - // a table of MSLResourceBinding to give to SPIRV-Cross - std::vector<spirv_cross::MSLResourceBinding> mslBindings; + // a table of MSLResourceBinding to give to SPIRV-Cross. // Reserve index 0 for buffers for the push constants buffer. for (auto stage : IterateStages(kAllStages)) { @@ -71,7 +70,7 @@ namespace dawn_native { namespace metal { binding.binding = spirv_cross::kPushConstBinding; binding.msl_buffer = 0; - mslBindings.push_back(binding); + compiler.add_msl_resource_binding(binding); } // Create one resource binding entry per stage per binding. @@ -87,7 +86,7 @@ namespace dawn_native { namespace metal { mslBinding.binding = binding; mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler = index; - mslBindings.push_back(mslBinding); + compiler.add_msl_resource_binding(mslBinding); } } } @@ -103,7 +102,7 @@ namespace dawn_native { namespace metal { { // SPIRV-Cross also supports re-ordering attributes but it seems to do the correct thing // by default. - std::string msl = compiler.compile(nullptr, &mslBindings); + std::string msl = compiler.compile(); NSString* mslSource = [NSString stringWithFormat:@"%s", msl.c_str()]; auto mtlDevice = ToBackend(GetDevice())->GetMTLDevice(); diff --git a/chromium/third_party/dawn/src/dawn_native/metal/SwapChainMTL.mm b/chromium/third_party/dawn/src/dawn_native/metal/SwapChainMTL.mm index e1a636d0754..094e35ac79e 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/SwapChainMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/SwapChainMTL.mm @@ -24,7 +24,7 @@ namespace dawn_native { namespace metal { SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor) : SwapChainBase(device, descriptor) { const auto& im = GetImplementation(); - dawnWSIContextMetal wsiContext = {}; + DawnWSIContextMetal wsiContext = {}; wsiContext.device = ToBackend(GetDevice())->GetMTLDevice(); im.Init(im.userData, &wsiContext); } @@ -34,8 +34,8 @@ namespace dawn_native { namespace metal { TextureBase* SwapChain::GetNextTextureImpl(const TextureDescriptor* descriptor) { const auto& im = GetImplementation(); - dawnSwapChainNextTexture next = {}; - dawnSwapChainError error = im.GetNextTexture(im.userData, &next); + DawnSwapChainNextTexture next = {}; + DawnSwapChainError error = im.GetNextTexture(im.userData, &next); if (error) { GetDevice()->HandleError(error); return nullptr; diff --git a/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.h b/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.h index 51951f67ac7..d4feb5bfc47 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.h +++ b/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.h @@ -42,6 +42,8 @@ namespace dawn_native { namespace metal { id<MTLTexture> GetMTLTexture(); private: + void DestroyImpl() override; + id<MTLTexture> mMtlTexture = nil; }; 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 607b00e1a64..7de816489be 100644 --- a/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.mm +++ b/chromium/third_party/dawn/src/dawn_native/metal/TextureMTL.mm @@ -50,17 +50,24 @@ namespace dawn_native { namespace metal { } MTLTextureType MetalTextureType(dawn::TextureDimension dimension, - unsigned int arrayLayers) { + unsigned int arrayLayers, + unsigned int sampleCount) { switch (dimension) { case dawn::TextureDimension::e2D: - return (arrayLayers > 1) ? MTLTextureType2DArray : MTLTextureType2D; + if (sampleCount > 1) { + ASSERT(arrayLayers == 1); + return MTLTextureType2DMultisample; + } else { + return (arrayLayers > 1) ? MTLTextureType2DArray : MTLTextureType2D; + } } } - MTLTextureType MetalTextureViewType(dawn::TextureViewDimension dimension) { + MTLTextureType MetalTextureViewType(dawn::TextureViewDimension dimension, + unsigned int sampleCount) { switch (dimension) { case dawn::TextureViewDimension::e2D: - return MTLTextureType2D; + return (sampleCount > 1) ? MTLTextureType2DMultisample : MTLTextureType2D; case dawn::TextureViewDimension::e2DArray: return MTLTextureType2DArray; case dawn::TextureViewDimension::Cube: @@ -178,7 +185,8 @@ namespace dawn_native { namespace metal { MTLTextureDescriptor* CreateMetalTextureDescriptor(const TextureDescriptor* descriptor) { MTLTextureDescriptor* mtlDesc = [MTLTextureDescriptor new]; - mtlDesc.textureType = MetalTextureType(descriptor->dimension, descriptor->arrayLayerCount); + mtlDesc.textureType = MetalTextureType(descriptor->dimension, descriptor->arrayLayerCount, + descriptor->sampleCount); mtlDesc.usage = MetalTextureUsage(descriptor->usage); mtlDesc.pixelFormat = MetalPixelFormat(descriptor->format); @@ -190,18 +198,20 @@ namespace dawn_native { namespace metal { mtlDesc.arrayLength = descriptor->arrayLayerCount; mtlDesc.storageMode = MTLStorageModePrivate; + mtlDesc.sampleCount = descriptor->sampleCount; + return mtlDesc; } Texture::Texture(Device* device, const TextureDescriptor* descriptor) - : TextureBase(device, descriptor) { + : TextureBase(device, descriptor, TextureState::OwnedInternal) { MTLTextureDescriptor* mtlDesc = CreateMetalTextureDescriptor(descriptor); mMtlTexture = [device->GetMTLDevice() newTextureWithDescriptor:mtlDesc]; [mtlDesc release]; } Texture::Texture(Device* device, const TextureDescriptor* descriptor, id<MTLTexture> mtlTexture) - : TextureBase(device, descriptor), mMtlTexture(mtlTexture) { + : TextureBase(device, descriptor, TextureState::OwnedInternal), mMtlTexture(mtlTexture) { [mMtlTexture retain]; } @@ -209,8 +219,9 @@ namespace dawn_native { namespace metal { const TextureDescriptor* descriptor, IOSurfaceRef ioSurface, uint32_t plane) - : TextureBase(device, descriptor) { + : TextureBase(device, descriptor, TextureState::OwnedInternal) { MTLTextureDescriptor* mtlDesc = CreateMetalTextureDescriptor(descriptor); + mtlDesc.storageMode = MTLStorageModeManaged; mMtlTexture = [device->GetMTLDevice() newTextureWithDescriptor:mtlDesc iosurface:ioSurface plane:plane]; @@ -218,7 +229,12 @@ namespace dawn_native { namespace metal { } Texture::~Texture() { + DestroyInternal(); + } + + void Texture::DestroyImpl() { [mMtlTexture release]; + mMtlTexture = nil; } id<MTLTexture> Texture::GetMTLTexture() { @@ -235,7 +251,8 @@ namespace dawn_native { namespace metal { mMtlTextureView = [mtlTexture retain]; } else { MTLPixelFormat format = MetalPixelFormat(descriptor->format); - MTLTextureType textureViewType = MetalTextureViewType(descriptor->dimension); + MTLTextureType textureViewType = + MetalTextureViewType(descriptor->dimension, texture->GetSampleCount()); auto mipLevelRange = NSMakeRange(descriptor->baseMipLevel, descriptor->mipLevelCount); auto arrayLayerRange = NSMakeRange(descriptor->baseArrayLayer, descriptor->arrayLayerCount); diff --git a/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.cpp b/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.cpp index 9cf38245aff..3476f1ab0b5 100644 --- a/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.cpp +++ b/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.cpp @@ -28,6 +28,7 @@ namespace dawn_native { namespace null { public: Adapter(InstanceBase* instance) : AdapterBase(instance, BackendType::Null) { mPCIInfo.name = "Null backend"; + mDeviceType = DeviceType::CPU; } virtual ~Adapter() = default; @@ -82,9 +83,6 @@ namespace dawn_native { namespace null { 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); @@ -113,7 +111,7 @@ namespace dawn_native { namespace null { return new SwapChain(this, descriptor); } ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) { - return new Texture(this, descriptor); + return new Texture(this, descriptor, TextureBase::TextureState::OwnedInternal); } ResultOrError<TextureViewBase*> Device::CreateTextureViewImpl( TextureBase* texture, @@ -128,10 +126,10 @@ namespace dawn_native { namespace null { } MaybeError Device::CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) { + uint64_t destinationOffset, + uint64_t size) { return DAWN_UNIMPLEMENTED_ERROR("Device unable to copy from staging buffer."); } @@ -274,18 +272,18 @@ namespace dawn_native { namespace null { void NativeSwapChainImpl::Init(WSIContext* context) { } - dawnSwapChainError NativeSwapChainImpl::Configure(dawnTextureFormat format, - dawnTextureUsageBit, + DawnSwapChainError NativeSwapChainImpl::Configure(DawnTextureFormat format, + DawnTextureUsageBit, uint32_t width, uint32_t height) { return DAWN_SWAP_CHAIN_NO_ERROR; } - dawnSwapChainError NativeSwapChainImpl::GetNextTexture(dawnSwapChainNextTexture* nextTexture) { + DawnSwapChainError NativeSwapChainImpl::GetNextTexture(DawnSwapChainNextTexture* nextTexture) { return DAWN_SWAP_CHAIN_NO_ERROR; } - dawnSwapChainError NativeSwapChainImpl::Present() { + DawnSwapChainError NativeSwapChainImpl::Present() { return DAWN_SWAP_CHAIN_NO_ERROR; } diff --git a/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.h b/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.h index e38f88eb1cd..5450b4b80bc 100644 --- a/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.h +++ b/chromium/third_party/dawn/src/dawn_native/null/DeviceNull.h @@ -22,7 +22,6 @@ #include "dawn_native/CommandEncoder.h" #include "dawn_native/ComputePipeline.h" #include "dawn_native/Device.h" -#include "dawn_native/InputState.h" #include "dawn_native/PipelineLayout.h" #include "dawn_native/Queue.h" #include "dawn_native/RenderPipeline.h" @@ -44,7 +43,6 @@ namespace dawn_native { namespace null { class CommandBuffer; using ComputePipeline = ComputePipelineBase; class Device; - using InputState = InputStateBase; using PipelineLayout = PipelineLayoutBase; class Queue; using RenderPipeline = RenderPipelineBase; @@ -62,7 +60,6 @@ namespace dawn_native { namespace null { using CommandBufferType = CommandBuffer; using ComputePipelineType = ComputePipeline; using DeviceType = Device; - using InputStateType = InputState; using PipelineLayoutType = PipelineLayout; using QueueType = Queue; using RenderPipelineType = RenderPipeline; @@ -89,7 +86,6 @@ namespace dawn_native { namespace null { ~Device(); CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override; - InputStateBase* CreateInputState(InputStateBuilder* builder) override; Serial GetCompletedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override; @@ -101,10 +97,10 @@ namespace dawn_native { namespace null { ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override; MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) override; + uint64_t destinationOffset, + uint64_t size) override; private: ResultOrError<BindGroupBase*> CreateBindGroupImpl( @@ -185,12 +181,12 @@ namespace dawn_native { namespace null { public: using WSIContext = struct {}; void Init(WSIContext* context); - dawnSwapChainError Configure(dawnTextureFormat format, - dawnTextureUsageBit, + DawnSwapChainError Configure(DawnTextureFormat format, + DawnTextureUsageBit, uint32_t width, uint32_t height); - dawnSwapChainError GetNextTexture(dawnSwapChainNextTexture* nextTexture); - dawnSwapChainError Present(); + DawnSwapChainError GetNextTexture(DawnSwapChainNextTexture* nextTexture); + DawnSwapChainError Present(); dawn::TextureFormat GetPreferredFormat() const; }; 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 7f66df0242a..ef1bbe49388 100644 --- a/chromium/third_party/dawn/src/dawn_native/null/NullBackend.cpp +++ b/chromium/third_party/dawn/src/dawn_native/null/NullBackend.cpp @@ -22,8 +22,8 @@ namespace dawn_native { namespace null { - dawnSwapChainImplementation CreateNativeSwapChainImpl() { - dawnSwapChainImplementation impl; + DawnSwapChainImplementation CreateNativeSwapChainImpl() { + DawnSwapChainImplementation impl; impl = CreateSwapChainImplementation(new NativeSwapChainImpl()); impl.textureUsage = DAWN_TEXTURE_USAGE_BIT_PRESENT; return impl; diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.cpp index 1b80d678e5f..1d69a4a3379 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/BackendGL.cpp @@ -32,6 +32,7 @@ namespace dawn_native { namespace opengl { glEnable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); + glEnable(GL_MULTISAMPLE); mPCIInfo.name = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); } 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 50e2d0b0f4a..225a5834add 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/BufferGL.cpp @@ -28,7 +28,7 @@ namespace dawn_native { namespace opengl { } Buffer::~Buffer() { - DestroyImpl(); + DestroyInternal(); } GLuint Buffer::GetHandle() const { 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 ea66e2c65fa..b2fecc4b7c6 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/CommandBufferGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/CommandBufferGL.cpp @@ -21,7 +21,6 @@ #include "dawn_native/opengl/ComputePipelineGL.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/PipelineLayoutGL.h" #include "dawn_native/opengl/RenderPipelineGL.h" @@ -47,22 +46,44 @@ namespace dawn_native { namespace opengl { GLenum VertexFormatType(dawn::VertexFormat format) { switch (format) { - case dawn::VertexFormat::FloatR32G32B32A32: - case dawn::VertexFormat::FloatR32G32B32: - case dawn::VertexFormat::FloatR32G32: - case dawn::VertexFormat::FloatR32: + case dawn::VertexFormat::UChar2: + case dawn::VertexFormat::UChar4: + case dawn::VertexFormat::UChar2Norm: + case dawn::VertexFormat::UChar4Norm: + return GL_UNSIGNED_BYTE; + case dawn::VertexFormat::Char2: + case dawn::VertexFormat::Char4: + case dawn::VertexFormat::Char2Norm: + case dawn::VertexFormat::Char4Norm: + return GL_BYTE; + case dawn::VertexFormat::UShort2: + case dawn::VertexFormat::UShort4: + case dawn::VertexFormat::UShort2Norm: + case dawn::VertexFormat::UShort4Norm: + return GL_UNSIGNED_SHORT; + case dawn::VertexFormat::Short2: + case dawn::VertexFormat::Short4: + case dawn::VertexFormat::Short2Norm: + case dawn::VertexFormat::Short4Norm: + return GL_SHORT; + case dawn::VertexFormat::Half2: + case dawn::VertexFormat::Half4: + return GL_HALF_FLOAT; + case dawn::VertexFormat::Float: + case dawn::VertexFormat::Float2: + case dawn::VertexFormat::Float3: + case dawn::VertexFormat::Float4: return GL_FLOAT; - case dawn::VertexFormat::IntR32G32B32A32: - case dawn::VertexFormat::IntR32G32B32: - case dawn::VertexFormat::IntR32G32: - case dawn::VertexFormat::IntR32: + case dawn::VertexFormat::UInt: + case dawn::VertexFormat::UInt2: + case dawn::VertexFormat::UInt3: + case dawn::VertexFormat::UInt4: + return GL_UNSIGNED_INT; + case dawn::VertexFormat::Int: + case dawn::VertexFormat::Int2: + case dawn::VertexFormat::Int3: + case dawn::VertexFormat::Int4: return GL_INT; - case dawn::VertexFormat::UshortR16G16B16A16: - case dawn::VertexFormat::UshortR16G16: - return GL_UNSIGNED_SHORT; - case dawn::VertexFormat::UnormR8G8B8A8: - case dawn::VertexFormat::UnormR8G8: - return GL_UNSIGNED_BYTE; default: UNREACHABLE(); } @@ -70,14 +91,29 @@ namespace dawn_native { namespace opengl { GLboolean VertexFormatIsNormalized(dawn::VertexFormat format) { switch (format) { - case dawn::VertexFormat::UnormR8G8B8A8: - case dawn::VertexFormat::UnormR8G8: + case dawn::VertexFormat::UChar2Norm: + case dawn::VertexFormat::UChar4Norm: + case dawn::VertexFormat::Char2Norm: + case dawn::VertexFormat::Char4Norm: + case dawn::VertexFormat::UShort2Norm: + case dawn::VertexFormat::UShort4Norm: + case dawn::VertexFormat::Short2Norm: + case dawn::VertexFormat::Short4Norm: return GL_TRUE; default: return GL_FALSE; } } + GLint GetStencilMaskFromStencilFormat(dawn::TextureFormat depthStencilFormat) { + switch (depthStencilFormat) { + case dawn::TextureFormat::D32FloatS8Uint: + return 0xFF; + default: + UNREACHABLE(); + } + } + // Push constants are implemented using OpenGL uniforms, however they aren't part of the // global OpenGL state but are part of the program state instead. This means that we have to // reapply push constants on pipeline change. @@ -162,7 +198,7 @@ namespace dawn_native { namespace opengl { void OnSetVertexBuffers(uint32_t startSlot, uint32_t count, Ref<BufferBase>* buffers, - uint32_t* offsets) { + uint64_t* offsets) { for (uint32_t i = 0; i < count; ++i) { uint32_t slot = startSlot + i; mVertexBuffers[slot] = ToBackend(buffers[i].Get()); @@ -175,15 +211,14 @@ namespace dawn_native { namespace opengl { } void OnSetPipeline(RenderPipelineBase* pipeline) { - InputStateBase* inputState = pipeline->GetInputState(); - if (mLastInputState == inputState) { + if (mLastPipeline == pipeline) { return; } mIndexBufferDirty = true; - mDirtyVertexBuffers |= inputState->GetInputsSetMask(); + mDirtyVertexBuffers |= pipeline->GetInputsSetMask(); - mLastInputState = ToBackend(inputState); + mLastPipeline = pipeline; } void Apply() { @@ -193,15 +228,15 @@ namespace dawn_native { namespace opengl { } for (uint32_t slot : - IterateBitSet(mDirtyVertexBuffers & mLastInputState->GetInputsSetMask())) { + IterateBitSet(mDirtyVertexBuffers & mLastPipeline->GetInputsSetMask())) { for (uint32_t location : - IterateBitSet(mLastInputState->GetAttributesUsingInput(slot))) { - auto attribute = mLastInputState->GetAttribute(location); + IterateBitSet(mLastPipeline->GetAttributesUsingInput(slot))) { + auto attribute = mLastPipeline->GetAttribute(location); GLuint buffer = mVertexBuffers[slot]->GetHandle(); - uint32_t offset = mVertexBufferOffsets[slot]; + uint64_t offset = mVertexBufferOffsets[slot]; - auto input = mLastInputState->GetInput(slot); + auto input = mLastPipeline->GetInput(slot); auto components = VertexFormatNumComponents(attribute.format); auto formatType = VertexFormatType(attribute.format); @@ -223,9 +258,9 @@ namespace dawn_native { namespace opengl { std::bitset<kMaxVertexInputs> mDirtyVertexBuffers; std::array<Buffer*, kMaxVertexInputs> mVertexBuffers; - std::array<uint32_t, kMaxVertexInputs> mVertexBufferOffsets; + std::array<uint64_t, kMaxVertexInputs> mVertexBufferOffsets; - InputState* mLastInputState = nullptr; + RenderPipelineBase* mLastPipeline = nullptr; }; // Handles SetBindGroup commands with the specifics of translating to OpenGL texture and @@ -278,8 +313,67 @@ namespace dawn_native { namespace opengl { glBindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer, binding.offset, binding.size); } break; + + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; + } + } + } + + void ResolveMultisampledRenderTargets(const BeginRenderPassCmd* renderPass) { + ASSERT(renderPass != nullptr); + + GLuint readFbo = 0; + GLuint writeFbo = 0; + + for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) { + if (renderPass->colorAttachments[i].resolveTarget.Get() != nullptr) { + if (readFbo == 0) { + ASSERT(writeFbo == 0); + glGenFramebuffers(1, &readFbo); + glGenFramebuffers(1, &writeFbo); + } + + const TextureBase* colorTexture = + renderPass->colorAttachments[i].view->GetTexture(); + ASSERT(colorTexture->IsMultisampledTexture()); + ASSERT(colorTexture->GetArrayLayers() == 1); + ASSERT(renderPass->colorAttachments[i].view->GetBaseMipLevel() == 0); + + GLuint colorHandle = ToBackend(colorTexture)->GetHandle(); + glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + ToBackend(colorTexture)->GetGLTarget(), colorHandle, 0); + + const TextureBase* resolveTexture = + renderPass->colorAttachments[i].resolveTarget->GetTexture(); + GLuint resolveTextureHandle = ToBackend(resolveTexture)->GetHandle(); + GLuint resolveTargetMipmapLevel = + renderPass->colorAttachments[i].resolveTarget->GetBaseMipLevel(); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, writeFbo); + if (resolveTexture->GetArrayLayers() == 1) { + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, resolveTextureHandle, + resolveTargetMipmapLevel); + } else { + GLuint resolveTargetArrayLayer = + renderPass->colorAttachments[i].resolveTarget->GetBaseArrayLayer(); + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + resolveTextureHandle, resolveTargetMipmapLevel, + resolveTargetArrayLayer); + } + + glBlitFramebuffer(0, 0, renderPass->width, renderPass->height, 0, 0, + renderPass->width, renderPass->height, GL_COLOR_BUFFER_BIT, + GL_NEAREST); } } + + glDeleteFramebuffers(1, &readFbo); + glDeleteFramebuffers(1, &writeFbo); } } // namespace @@ -409,6 +503,22 @@ namespace dawn_native { namespace opengl { glDeleteFramebuffers(1, &readFBO); } break; + case Command::CopyTextureToTexture: { + CopyTextureToTextureCmd* copy = + mCommands.NextCommand<CopyTextureToTextureCmd>(); + auto& src = copy->source; + auto& dst = copy->destination; + auto& copySize = copy->copySize; + Texture* srcTexture = ToBackend(src.texture.Get()); + Texture* dstTexture = ToBackend(dst.texture.Get()); + + glCopyImageSubData(srcTexture->GetHandle(), srcTexture->GetGLTarget(), + src.level, src.origin.x, src.origin.y, src.slice, + dstTexture->GetHandle(), dstTexture->GetGLTarget(), + dst.level, dst.origin.x, dst.origin.y, dst.slice, + copySize.width, copySize.height, 1); + } break; + default: { UNREACHABLE(); } break; } } @@ -491,8 +601,9 @@ namespace dawn_native { namespace opengl { // Attach color buffers. if (textureView->GetTexture()->GetArrayLayers() == 1) { - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_TEXTURE_2D, texture, textureView->GetBaseMipLevel()); + GLenum target = ToBackend(textureView->GetTexture())->GetGLTarget(); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, target, + texture, textureView->GetBaseMipLevel()); } else { glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, texture, textureView->GetBaseMipLevel(), @@ -530,8 +641,8 @@ namespace dawn_native { namespace opengl { glAttachment = GL_STENCIL_ATTACHMENT; } - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, GL_TEXTURE_2D, texture, - 0); + GLenum target = ToBackend(textureView->GetTexture())->GetGLTarget(); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, target, texture, 0); // TODO(kainino@chromium.org): the depth/stencil clears (later in // this function) may be undefined for other texture formats. @@ -546,6 +657,7 @@ namespace dawn_native { namespace opengl { // Load op - color if (attachmentInfo.loadOp == dawn::LoadOp::Clear) { + glColorMaski(i, true, true, true, true); glClearBufferfv(GL_COLOR, i, &attachmentInfo.clearColor.r); } } @@ -560,6 +672,14 @@ namespace dawn_native { namespace opengl { (attachmentInfo.depthLoadOp == dawn::LoadOp::Clear); bool doStencilClear = TextureFormatHasStencil(attachmentFormat) && (attachmentInfo.stencilLoadOp == dawn::LoadOp::Clear); + + if (doDepthClear) { + glDepthMask(GL_TRUE); + } + if (doStencilClear) { + glStencilMask(GetStencilMaskFromStencilFormat(attachmentFormat)); + } + if (doDepthClear && doStencilClear) { glClearBufferfi(GL_DEPTH_STENCIL, 0, attachmentInfo.clearDepth, attachmentInfo.clearStencil); @@ -573,7 +693,7 @@ namespace dawn_native { namespace opengl { } RenderPipeline* lastPipeline = nullptr; - uint32_t indexBufferBaseOffset = 0; + uint64_t indexBufferBaseOffset = 0; PersistentPipelineState persistentPipelineState; @@ -591,6 +711,11 @@ namespace dawn_native { namespace opengl { switch (type) { case Command::EndRenderPass: { mCommands.NextCommand<EndRenderPassCmd>(); + + if (renderPass->sampleCount > 1) { + ResolveMultisampledRenderTargets(renderPass); + } + glDeleteFramebuffers(1, &fbo); return; } break; @@ -617,23 +742,24 @@ namespace dawn_native { namespace opengl { pushConstants.Apply(lastPipeline, lastPipeline); inputBuffers.Apply(); - dawn::IndexFormat indexFormat = lastPipeline->GetIndexFormat(); + dawn::IndexFormat indexFormat = + lastPipeline->GetInputStateDescriptor()->indexFormat; size_t formatSize = IndexFormatSize(indexFormat); GLenum formatType = IndexFormatType(indexFormat); if (draw->firstInstance > 0) { - glDrawElementsInstancedBaseInstance( + glDrawElementsInstancedBaseVertexBaseInstance( lastPipeline->GetGLPrimitiveTopology(), draw->indexCount, formatType, reinterpret_cast<void*>(draw->firstIndex * formatSize + indexBufferBaseOffset), - draw->instanceCount, draw->firstInstance); + draw->instanceCount, draw->baseVertex, draw->firstInstance); } else { // This branch is only needed on OpenGL < 4.2 - glDrawElementsInstanced( + glDrawElementsInstancedBaseVertex( lastPipeline->GetGLPrimitiveTopology(), draw->indexCount, formatType, reinterpret_cast<void*>(draw->firstIndex * formatSize + indexBufferBaseOffset), - draw->instanceCount); + draw->instanceCount, draw->baseVertex); } } break; @@ -690,7 +816,7 @@ namespace dawn_native { namespace opengl { case Command::SetVertexBuffers: { SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>(); auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count); - auto offsets = mCommands.NextData<uint32_t>(cmd->count); + auto offsets = mCommands.NextData<uint64_t>(cmd->count); inputBuffers.OnSetVertexBuffers(cmd->startSlot, cmd->count, buffers, offsets); } break; diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/ComputePipelineGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/ComputePipelineGL.cpp index 815e4d7499f..2cbad4efcf8 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/ComputePipelineGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/ComputePipelineGL.cpp @@ -21,7 +21,7 @@ namespace dawn_native { namespace opengl { ComputePipeline::ComputePipeline(Device* device, const ComputePipelineDescriptor* descriptor) : ComputePipelineBase(device, descriptor) { PerStage<const ShaderModule*> modules(nullptr); - modules[dawn::ShaderStage::Compute] = ToBackend(descriptor->module); + modules[dawn::ShaderStage::Compute] = ToBackend(descriptor->computeStage->module); PipelineGL::Initialize(ToBackend(descriptor->layout), modules); } 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 f2a3edf0564..7dd761b0961 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.cpp @@ -21,7 +21,6 @@ #include "dawn_native/opengl/BufferGL.h" #include "dawn_native/opengl/CommandBufferGL.h" #include "dawn_native/opengl/ComputePipelineGL.h" -#include "dawn_native/opengl/InputStateGL.h" #include "dawn_native/opengl/PipelineLayoutGL.h" #include "dawn_native/opengl/QueueGL.h" #include "dawn_native/opengl/RenderPipelineGL.h" @@ -67,9 +66,6 @@ namespace dawn_native { namespace opengl { 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); @@ -153,10 +149,10 @@ namespace dawn_native { namespace opengl { } MaybeError Device::CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) { + uint64_t destinationOffset, + uint64_t size) { return DAWN_UNIMPLEMENTED_ERROR("Device unable to copy from staging buffer."); } 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 43fdf6537fa..5725a8ef6db 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.h +++ b/chromium/third_party/dawn/src/dawn_native/opengl/DeviceGL.h @@ -41,7 +41,6 @@ namespace dawn_native { namespace opengl { // Dawn API CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override; - InputStateBase* CreateInputState(InputStateBuilder* builder) override; Serial GetCompletedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override; @@ -50,10 +49,10 @@ namespace dawn_native { namespace opengl { ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override; MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) override; + uint64_t destinationOffset, + uint64_t size) override; private: ResultOrError<BindGroupBase*> CreateBindGroupImpl( 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 d4bfac6c18f..6542ff90299 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/Forward.h +++ b/chromium/third_party/dawn/src/dawn_native/opengl/Forward.h @@ -32,7 +32,6 @@ namespace dawn_native { namespace opengl { class CommandBuffer; class ComputePipeline; class Device; - class InputState; class PersistentPipelineState; class PipelineLayout; class Queue; @@ -51,7 +50,6 @@ namespace dawn_native { namespace opengl { using CommandBufferType = CommandBuffer; using ComputePipelineType = ComputePipeline; using DeviceType = Device; - using InputStateType = InputState; using PipelineLayoutType = PipelineLayout; using QueueType = Queue; using RenderPipelineType = RenderPipeline; diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/InputStateGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/InputStateGL.cpp deleted file mode 100644 index f9052e2d3ad..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/opengl/InputStateGL.cpp +++ /dev/null @@ -1,61 +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/InputStateGL.h" - -#include "common/Assert.h" - -namespace dawn_native { namespace opengl { - - InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) { - glGenVertexArrays(1, &mVertexArrayObject); - glBindVertexArray(mVertexArrayObject); - auto& attributesSetMask = GetAttributesSetMask(); - for (uint32_t location = 0; location < attributesSetMask.size(); ++location) { - if (!attributesSetMask[location]) { - continue; - } - auto attribute = GetAttribute(location); - glEnableVertexAttribArray(location); - - attributesUsingInput[attribute.inputSlot][location] = true; - auto input = GetInput(attribute.inputSlot); - - if (input.stride == 0) { - // Emulate a stride of zero (constant vertex attribute) by - // setting the attribute instance divisor to a huge number. - glVertexAttribDivisor(location, 0xffffffff); - } else { - switch (input.stepMode) { - case dawn::InputStepMode::Vertex: - break; - case dawn::InputStepMode::Instance: - glVertexAttribDivisor(location, 1); - break; - default: - UNREACHABLE(); - } - } - } - } - - std::bitset<kMaxVertexAttributes> InputState::GetAttributesUsingInput(uint32_t slot) const { - return attributesUsingInput[slot]; - } - - GLuint InputState::GetVAO() { - return mVertexArrayObject; - } - -}} // namespace dawn_native::opengl diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/InputStateGL.h b/chromium/third_party/dawn/src/dawn_native/opengl/InputStateGL.h deleted file mode 100644 index dbdd84b07b9..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/opengl/InputStateGL.h +++ /dev/null @@ -1,40 +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_OPENGL_INPUTSTATEGL_H_ -#define DAWNNATIVE_OPENGL_INPUTSTATEGL_H_ - -#include "dawn_native/InputState.h" - -#include "glad/glad.h" - -namespace dawn_native { namespace opengl { - - class Device; - - class InputState : public InputStateBase { - public: - InputState(InputStateBuilder* builder); - - std::bitset<kMaxVertexAttributes> GetAttributesUsingInput(uint32_t slot) const; - GLuint GetVAO(); - - private: - GLuint mVertexArrayObject; - std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexInputs> attributesUsingInput; - }; - -}} // namespace dawn_native::opengl - -#endif // DAWNNATIVE_OPENGL_INPUTSTATEGL_H_ diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/PipelineGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/PipelineGL.cpp index f03ab8778db..11cb5b9dfdf 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/PipelineGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/PipelineGL.cpp @@ -159,6 +159,12 @@ namespace dawn_native { namespace opengl { // These binding types are handled in the separate sampler and texture // emulation break; + + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; } } } diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/PipelineLayoutGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/PipelineLayoutGL.cpp index 8f2cdaaf969..e646feff93b 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/PipelineLayoutGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/PipelineLayoutGL.cpp @@ -53,6 +53,12 @@ namespace dawn_native { namespace opengl { mIndexInfo[group][binding] = ssboIndex; ssboIndex++; break; + + // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; } } } 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 830fa407c09..ada39b21bcf 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.cpp @@ -16,13 +16,13 @@ #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 { namespace { + GLenum GLPrimitiveTopology(dawn::PrimitiveTopology primitiveTopology) { switch (primitiveTopology) { case dawn::PrimitiveTopology::PointList: @@ -103,10 +103,10 @@ namespace dawn_native { namespace opengl { } 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); + glColorMaski(attachment, descriptor->writeMask & dawn::ColorWriteMask::Red, + descriptor->writeMask & dawn::ColorWriteMask::Green, + descriptor->writeMask & dawn::ColorWriteMask::Blue, + descriptor->writeMask & dawn::ColorWriteMask::Alpha); } GLuint OpenGLStencilOperation(dawn::StencilOperation stencilOperation) { @@ -175,23 +175,58 @@ namespace dawn_native { namespace opengl { RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor) : RenderPipelineBase(device, descriptor), + mVertexArrayObject(0), mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) { PerStage<const ShaderModule*> modules(nullptr); modules[dawn::ShaderStage::Vertex] = ToBackend(descriptor->vertexStage->module); modules[dawn::ShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module); PipelineGL::Initialize(ToBackend(GetLayout()), modules); + CreateVAOForInputState(descriptor->inputState); + } + + RenderPipeline::~RenderPipeline() { + glDeleteVertexArrays(1, &mVertexArrayObject); + glBindVertexArray(0); } GLenum RenderPipeline::GetGLPrimitiveTopology() const { return mGlPrimitiveTopology; } + void RenderPipeline::CreateVAOForInputState(const InputStateDescriptor* inputState) { + glGenVertexArrays(1, &mVertexArrayObject); + glBindVertexArray(mVertexArrayObject); + for (uint32_t location : IterateBitSet(GetAttributesSetMask())) { + const auto& attribute = GetAttribute(location); + glEnableVertexAttribArray(location); + + attributesUsingInput[attribute.inputSlot][location] = true; + auto input = GetInput(attribute.inputSlot); + + if (input.stride == 0) { + // Emulate a stride of zero (constant vertex attribute) by + // setting the attribute instance divisor to a huge number. + glVertexAttribDivisor(location, 0xffffffff); + } else { + switch (input.stepMode) { + case dawn::InputStepMode::Vertex: + break; + case dawn::InputStepMode::Instance: + glVertexAttribDivisor(location, 1); + break; + default: + UNREACHABLE(); + } + } + } + } + void RenderPipeline::ApplyNow(PersistentPipelineState& persistentPipelineState) { PipelineGL::ApplyNow(); - auto inputState = ToBackend(GetInputState()); - glBindVertexArray(inputState->GetVAO()); + ASSERT(mVertexArrayObject); + glBindVertexArray(mVertexArrayObject); ApplyDepthStencilState(GetDepthStencilStateDescriptor(), &persistentPipelineState); 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 28458e0f125..dc51f6f9e82 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.h +++ b/chromium/third_party/dawn/src/dawn_native/opengl/RenderPipelineGL.h @@ -31,12 +31,17 @@ namespace dawn_native { namespace opengl { class RenderPipeline : public RenderPipelineBase, public PipelineGL { public: RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor); + ~RenderPipeline(); GLenum GetGLPrimitiveTopology() const; void ApplyNow(PersistentPipelineState& persistentPipelineState); private: + void CreateVAOForInputState(const InputStateDescriptor* inputState); + + // TODO(yunchao.he@intel.com): vao need to be deduplicated between pipelines. + GLuint mVertexArrayObject; GLenum mGlPrimitiveTopology; }; 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 cb2e0df08b7..6500e42a757 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/SamplerGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/SamplerGL.cpp @@ -65,17 +65,11 @@ 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) @@ -96,20 +90,6 @@ namespace dawn_native { namespace opengl { 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/ShaderModuleGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/ShaderModuleGL.cpp index ab24940bd0a..ae3d1f9ba2a 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/ShaderModuleGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/ShaderModuleGL.cpp @@ -54,6 +54,12 @@ namespace dawn_native { namespace opengl { // updated. spirv_cross::CompilerGLSL::Options options; + // The range of Z-coordinate in the clipping volume of OpenGL is [-w, w], while it is [0, w] + // in D3D12, Metal and Vulkan, so we should normalize it in shaders in all backends. + // See the documentation of spirv_cross::CompilerGLSL::Options::vertex::fixup_clipspace for + // more details. + options.vertex.fixup_clipspace = true; + // TODO(cwallez@chromium.org): discover the backing context version and use that. #if defined(DAWN_PLATFORM_APPLE) options.version = 410; diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/SwapChainGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/SwapChainGL.cpp index fa8e46fc5c6..2a9fe294d55 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/SwapChainGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/SwapChainGL.cpp @@ -33,14 +33,15 @@ namespace dawn_native { namespace opengl { TextureBase* SwapChain::GetNextTextureImpl(const TextureDescriptor* descriptor) { const auto& im = GetImplementation(); - dawnSwapChainNextTexture next = {}; - dawnSwapChainError error = im.GetNextTexture(im.userData, &next); + DawnSwapChainNextTexture next = {}; + DawnSwapChainError error = im.GetNextTexture(im.userData, &next); if (error) { GetDevice()->HandleError(error); return nullptr; } GLuint nativeTexture = next.texture.u32; - return new Texture(ToBackend(GetDevice()), descriptor, nativeTexture); + return new Texture(ToBackend(GetDevice()), descriptor, nativeTexture, + TextureBase::TextureState::OwnedExternal); } void SwapChain::OnBeforePresent(TextureBase*) { diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/TextureGL.cpp b/chromium/third_party/dawn/src/dawn_native/opengl/TextureGL.cpp index 8d36bd2f43c..34fa9f3af8b 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/TextureGL.cpp +++ b/chromium/third_party/dawn/src/dawn_native/opengl/TextureGL.cpp @@ -24,22 +24,33 @@ namespace dawn_native { namespace opengl { namespace { - GLenum TargetForDimensionAndArrayLayers(dawn::TextureDimension dimension, - uint32_t arrayLayerCount) { - switch (dimension) { + GLenum TargetForTexture(const TextureDescriptor* descriptor) { + switch (descriptor->dimension) { case dawn::TextureDimension::e2D: - return (arrayLayerCount > 1) ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; + if (descriptor->arrayLayerCount > 1) { + ASSERT(descriptor->sampleCount == 1); + return GL_TEXTURE_2D_ARRAY; + } else { + if (descriptor->sampleCount > 1) { + return GL_TEXTURE_2D_MULTISAMPLE; + } else { + return GL_TEXTURE_2D; + } + } + default: UNREACHABLE(); return GL_TEXTURE_2D; } } - GLenum TargetForTextureViewDimension(dawn::TextureViewDimension dimension) { + GLenum TargetForTextureViewDimension(dawn::TextureViewDimension dimension, + uint32_t sampleCount) { switch (dimension) { case dawn::TextureViewDimension::e2D: - return GL_TEXTURE_2D; + return (sampleCount > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; case dawn::TextureViewDimension::e2DArray: + ASSERT(sampleCount == 1); return GL_TEXTURE_2D_ARRAY; case dawn::TextureViewDimension::Cube: return GL_TEXTURE_CUBE_MAP; @@ -83,26 +94,52 @@ namespace dawn_native { namespace opengl { return handle; } + bool UsageNeedsTextureView(dawn::TextureUsageBit usage) { + constexpr dawn::TextureUsageBit kUsageNeedingTextureView = + dawn::TextureUsageBit::Storage | dawn::TextureUsageBit::Sampled; + return usage & kUsageNeedingTextureView; + } + + bool RequiresCreatingNewTextureView(const TextureBase* texture, + const TextureViewDescriptor* textureViewDescriptor) { + if (texture->GetFormat() != textureViewDescriptor->format) { + return true; + } + + if (texture->GetArrayLayers() != textureViewDescriptor->arrayLayerCount) { + return true; + } + + if (texture->GetNumMipLevels() != textureViewDescriptor->mipLevelCount) { + return true; + } + + switch (textureViewDescriptor->dimension) { + case dawn::TextureViewDimension::Cube: + case dawn::TextureViewDimension::CubeArray: + return true; + default: + break; + } + + return false; + } + } // namespace // Texture Texture::Texture(Device* device, const TextureDescriptor* descriptor) - : Texture(device, descriptor, GenTexture()) { - } - - Texture::Texture(Device* device, const TextureDescriptor* descriptor, GLuint handle) - : TextureBase(device, descriptor), mHandle(handle) { - mTarget = TargetForDimensionAndArrayLayers(GetDimension(), GetArrayLayers()); - + : Texture(device, descriptor, GenTexture(), TextureState::OwnedInternal) { uint32_t width = GetSize().width; uint32_t height = GetSize().height; uint32_t levels = GetNumMipLevels(); uint32_t arrayLayers = GetArrayLayers(); + uint32_t sampleCount = GetSampleCount(); auto formatInfo = GetGLFormatInfo(GetFormat()); - glBindTexture(mTarget, handle); + glBindTexture(mTarget, mHandle); // glTextureView() requires the value of GL_TEXTURE_IMMUTABLE_FORMAT for origtexture to be // GL_TRUE, so the storage of the texture must be allocated with glTexStorage*D. @@ -110,10 +147,16 @@ namespace dawn_native { namespace opengl { switch (GetDimension()) { case dawn::TextureDimension::e2D: if (arrayLayers > 1) { + ASSERT(!IsMultisampledTexture()); glTexStorage3D(mTarget, levels, formatInfo.internalFormat, width, height, arrayLayers); } else { - glTexStorage2D(mTarget, levels, formatInfo.internalFormat, width, height); + if (IsMultisampledTexture()) { + glTexStorage2DMultisample(mTarget, sampleCount, formatInfo.internalFormat, + width, height, true); + } else { + glTexStorage2D(mTarget, levels, formatInfo.internalFormat, width, height); + } } break; default: @@ -125,9 +168,21 @@ namespace dawn_native { namespace opengl { glTexParameteri(mTarget, GL_TEXTURE_MAX_LEVEL, levels - 1); } + Texture::Texture(Device* device, + const TextureDescriptor* descriptor, + GLuint handle, + TextureState state) + : TextureBase(device, descriptor, state), mHandle(handle) { + mTarget = TargetForTexture(descriptor); + } + Texture::~Texture() { - // TODO(kainino@chromium.org): delete texture (but only when not using the native texture - // constructor?) + DestroyInternal(); + } + + void Texture::DestroyImpl() { + glDeleteTextures(1, &mHandle); + mHandle = 0; } GLuint Texture::GetHandle() const { @@ -145,24 +200,35 @@ namespace dawn_native { namespace opengl { // TextureView TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor) - : TextureViewBase(texture, descriptor) { - mTarget = TargetForTextureViewDimension(descriptor->dimension); - - // glTextureView() is supported on OpenGL version >= 4.3 - // TODO(jiawei.shao@intel.com): support texture view on OpenGL version <= 4.2 - mHandle = GenTexture(); - const Texture* textureGL = ToBackend(texture); - TextureFormatInfo textureViewFormat = GetGLFormatInfo(descriptor->format); - glTextureView(mHandle, mTarget, textureGL->GetHandle(), textureViewFormat.internalFormat, - descriptor->baseMipLevel, descriptor->mipLevelCount, - descriptor->baseArrayLayer, descriptor->arrayLayerCount); + : TextureViewBase(texture, descriptor), mOwnsHandle(false) { + mTarget = TargetForTextureViewDimension(descriptor->dimension, texture->GetSampleCount()); + + if (!UsageNeedsTextureView(texture->GetUsage())) { + mHandle = 0; + } else if (!RequiresCreatingNewTextureView(texture, descriptor)) { + mHandle = ToBackend(texture)->GetHandle(); + } else { + // glTextureView() is supported on OpenGL version >= 4.3 + // TODO(jiawei.shao@intel.com): support texture view on OpenGL version <= 4.2 + mHandle = GenTexture(); + const Texture* textureGL = ToBackend(texture); + TextureFormatInfo textureViewFormat = GetGLFormatInfo(descriptor->format); + glTextureView(mHandle, mTarget, textureGL->GetHandle(), + textureViewFormat.internalFormat, descriptor->baseMipLevel, + descriptor->mipLevelCount, descriptor->baseArrayLayer, + descriptor->arrayLayerCount); + mOwnsHandle = true; + } } TextureView::~TextureView() { - glDeleteTextures(1, &mHandle); + if (mOwnsHandle) { + glDeleteTextures(1, &mHandle); + } } GLuint TextureView::GetHandle() const { + ASSERT(mHandle != 0); return mHandle; } diff --git a/chromium/third_party/dawn/src/dawn_native/opengl/TextureGL.h b/chromium/third_party/dawn/src/dawn_native/opengl/TextureGL.h index 5b12da5eccf..1dacd179ab3 100644 --- a/chromium/third_party/dawn/src/dawn_native/opengl/TextureGL.h +++ b/chromium/third_party/dawn/src/dawn_native/opengl/TextureGL.h @@ -32,7 +32,10 @@ namespace dawn_native { namespace opengl { class Texture : public TextureBase { public: Texture(Device* device, const TextureDescriptor* descriptor); - Texture(Device* device, const TextureDescriptor* descriptor, GLuint handle); + Texture(Device* device, + const TextureDescriptor* descriptor, + GLuint handle, + TextureState state); ~Texture(); GLuint GetHandle() const; @@ -40,6 +43,8 @@ namespace dawn_native { namespace opengl { TextureFormatInfo GetGLFormat() const; private: + void DestroyImpl() override; + GLuint mHandle; GLenum mTarget; }; @@ -55,6 +60,7 @@ namespace dawn_native { namespace opengl { private: GLuint mHandle; GLenum mTarget; + bool mOwnsHandle; }; }} // namespace dawn_native::opengl diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/AdapterVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/AdapterVk.cpp index 60c350a4a24..d87fdcc029b 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/AdapterVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/AdapterVk.cpp @@ -44,6 +44,21 @@ namespace dawn_native { namespace vulkan { mPCIInfo.vendorId = mDeviceInfo.properties.vendorID; mPCIInfo.name = mDeviceInfo.properties.deviceName; + switch (mDeviceInfo.properties.deviceType) { + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + mDeviceType = DeviceType::IntegratedGPU; + break; + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + mDeviceType = DeviceType::DiscreteGPU; + break; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + mDeviceType = DeviceType::CPU; + break; + default: + mDeviceType = DeviceType::Unknown; + break; + } + return {}; } diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupLayoutVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupLayoutVk.cpp index 94a3429184a..c6ea3f9991e 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupLayoutVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupLayoutVk.cpp @@ -49,6 +49,9 @@ namespace dawn_native { namespace vulkan { return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; case dawn::BindingType::StorageBuffer: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); default: UNREACHABLE(); } @@ -125,6 +128,9 @@ namespace dawn_native { namespace vulkan { return SAMPLED_IMAGE; case dawn::BindingType::StorageBuffer: return STORAGE_BUFFER; + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); default: UNREACHABLE(); } 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 c8c92175516..1fb8a7ccbf5 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/BindGroupVk.cpp @@ -108,6 +108,11 @@ namespace dawn_native { namespace vulkan { write.pImageInfo = &writeImageInfo[numWrites]; } break; + + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: + UNREACHABLE(); + break; default: UNREACHABLE(); } 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 e38a716ac90..137f1ad7872 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/BufferVk.cpp @@ -137,7 +137,7 @@ namespace dawn_native { namespace vulkan { } Buffer::~Buffer() { - DestroyImpl(); + DestroyInternal(); } void Buffer::OnMapReadCommandSerialFinished(uint32_t mapSerial, const void* data) { 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 3e8d79426ea..e65f5377995 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/CommandBufferVk.cpp @@ -70,6 +70,39 @@ namespace dawn_native { namespace vulkan { return region; } + VkImageCopy ComputeImageCopyRegion(const TextureCopy& srcCopy, + const TextureCopy& dstCopy, + const Extent3D& copySize) { + const Texture* srcTexture = ToBackend(srcCopy.texture.Get()); + const Texture* dstTexture = ToBackend(dstCopy.texture.Get()); + + VkImageCopy region; + + region.srcSubresource.aspectMask = srcTexture->GetVkAspectMask(); + region.srcSubresource.mipLevel = srcCopy.level; + region.srcSubresource.baseArrayLayer = srcCopy.slice; + region.srcSubresource.layerCount = 1; + + region.srcOffset.x = srcCopy.origin.x; + region.srcOffset.y = srcCopy.origin.y; + region.srcOffset.z = srcCopy.origin.z; + + region.dstSubresource.aspectMask = dstTexture->GetVkAspectMask(); + region.dstSubresource.mipLevel = dstCopy.level; + region.dstSubresource.baseArrayLayer = dstCopy.slice; + region.dstSubresource.layerCount = 1; + + region.dstOffset.x = dstCopy.origin.x; + region.dstOffset.y = dstCopy.origin.y; + region.dstOffset.z = dstCopy.origin.z; + + region.extent.width = copySize.width; + region.extent.height = copySize.height; + region.extent.depth = copySize.depth; + + return region; + } + class DescriptorSetTracker { public: void OnSetBindGroup(uint32_t index, VkDescriptorSet set) { @@ -121,7 +154,9 @@ namespace dawn_native { namespace vulkan { for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) { const auto& attachmentInfo = renderPass->colorAttachments[i]; - query.SetColor(i, attachmentInfo.view->GetFormat(), attachmentInfo.loadOp); + bool hasResolveTarget = attachmentInfo.resolveTarget.Get() != nullptr; + query.SetColor(i, attachmentInfo.view->GetFormat(), attachmentInfo.loadOp, + hasResolveTarget); } if (renderPass->hasDepthStencilAttachment) { @@ -130,6 +165,8 @@ namespace dawn_native { namespace vulkan { attachmentInfo.depthLoadOp, attachmentInfo.stencilLoadOp); } + query.SetSampleCount(renderPass->sampleCount); + renderPassVK = device->GetRenderPassCache()->GetRenderPass(query); } @@ -140,7 +177,7 @@ namespace dawn_native { namespace vulkan { uint32_t attachmentCount = 0; { // Fill in the attachment info that will be chained in the framebuffer create info. - std::array<VkImageView, kMaxColorAttachments + 1> attachments; + std::array<VkImageView, kMaxColorAttachments * 2 + 1> attachments; for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) { auto& attachmentInfo = renderPass->colorAttachments[i]; @@ -168,6 +205,17 @@ namespace dawn_native { namespace vulkan { attachmentCount++; } + for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) { + if (renderPass->colorAttachments[i].resolveTarget.Get() != nullptr) { + TextureView* view = + ToBackend(renderPass->colorAttachments[i].resolveTarget.Get()); + + attachments[attachmentCount] = view->GetHandle(); + + attachmentCount++; + } + } + // Chain attachments and create the framebuffer VkFramebufferCreateInfo createInfo; createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; @@ -299,6 +347,28 @@ namespace dawn_native { namespace vulkan { dstBuffer, 1, ®ion); } break; + case Command::CopyTextureToTexture: { + CopyTextureToTextureCmd* copy = + mCommands.NextCommand<CopyTextureToTextureCmd>(); + TextureCopy& src = copy->source; + TextureCopy& dst = copy->destination; + + ToBackend(src.texture) + ->TransitionUsageNow(commands, dawn::TextureUsageBit::TransferSrc); + ToBackend(dst.texture) + ->TransitionUsageNow(commands, dawn::TextureUsageBit::TransferDst); + + VkImage srcImage = ToBackend(src.texture)->GetHandle(); + VkImage dstImage = ToBackend(dst.texture)->GetHandle(); + + VkImageCopy region = ComputeImageCopyRegion(src, dst, copy->copySize); + + // The dstImage is written to so the Dawn guarantees make sure it is in the + // TRANSFER_DST_OPTIMAL layout + device->fn.CmdCopyImage(commands, srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + } break; + case Command::BeginRenderPass: { BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>(); @@ -504,7 +574,8 @@ namespace dawn_native { namespace vulkan { // TODO(cwallez@chromium.org): get the index type from the last render pipeline // and rebind if needed on pipeline change ASSERT(lastPipeline != nullptr); - VkIndexType indexType = VulkanIndexType(lastPipeline->GetIndexFormat()); + VkIndexType indexType = + VulkanIndexType(lastPipeline->GetInputStateDescriptor()->indexFormat); device->fn.CmdBindIndexBuffer( commands, indexBuffer, static_cast<VkDeviceSize>(cmd->offset), indexType); } break; @@ -540,7 +611,7 @@ namespace dawn_native { namespace vulkan { case Command::SetVertexBuffers: { SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>(); auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count); - auto offsets = mCommands.NextData<uint32_t>(cmd->count); + auto offsets = mCommands.NextData<uint64_t>(cmd->count); std::array<VkBuffer, kMaxVertexInputs> vkBuffers; std::array<VkDeviceSize, kMaxVertexInputs> vkOffsets; diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/ComputePipelineVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/ComputePipelineVk.cpp index 06948b35a87..8e7c7aa746d 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/ComputePipelineVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/ComputePipelineVk.cpp @@ -35,8 +35,8 @@ namespace dawn_native { namespace vulkan { createInfo.stage.pNext = nullptr; createInfo.stage.flags = 0; createInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; - createInfo.stage.module = ToBackend(descriptor->module)->GetHandle(); - createInfo.stage.pName = descriptor->entryPoint; + createInfo.stage.module = ToBackend(descriptor->computeStage->module)->GetHandle(); + createInfo.stage.pName = descriptor->computeStage->entryPoint; createInfo.stage.pSpecializationInfo = nullptr; if (device->fn.CreateComputePipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1, &createInfo, 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 aad6e2f4e28..212adb076bd 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.cpp @@ -27,7 +27,6 @@ #include "dawn_native/vulkan/CommandBufferVk.h" #include "dawn_native/vulkan/ComputePipelineVk.h" #include "dawn_native/vulkan/FencedDeleter.h" -#include "dawn_native/vulkan/InputStateVk.h" #include "dawn_native/vulkan/PipelineLayoutVk.h" #include "dawn_native/vulkan/QueueVk.h" #include "dawn_native/vulkan/RenderPassCache.h" @@ -152,9 +151,6 @@ namespace dawn_native { namespace vulkan { 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); @@ -506,10 +502,10 @@ namespace dawn_native { namespace vulkan { } MaybeError Device::CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) { + uint64_t destinationOffset, + uint64_t size) { // Insert memory barrier to ensure host write operations are made visible before // copying from the staging buffer. However, this barrier can be removed (see note below). // 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 95cdc5479b1..699aefd755e 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.h +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/DeviceVk.h @@ -65,7 +65,6 @@ namespace dawn_native { namespace vulkan { // Dawn API CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override; - InputStateBase* CreateInputState(InputStateBuilder* builder) override; Serial GetCompletedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override; @@ -73,10 +72,11 @@ namespace dawn_native { namespace vulkan { ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override; MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, - uint32_t sourceOffset, + uint64_t sourceOffset, BufferBase* destination, - uint32_t destinationOffset, - uint32_t size) override; + uint64_t destinationOffset, + uint64_t size) override; + private: ResultOrError<BindGroupBase*> CreateBindGroupImpl( const BindGroupDescriptor* descriptor) override; 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 99cc23a7852..344678a20c2 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/Forward.h +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/Forward.h @@ -26,7 +26,6 @@ namespace dawn_native { namespace vulkan { class CommandBuffer; class ComputePipeline; class Device; - class InputState; class PipelineLayout; class Queue; class RenderPipeline; @@ -45,7 +44,6 @@ namespace dawn_native { namespace vulkan { using CommandBufferType = CommandBuffer; using ComputePipelineType = ComputePipeline; using DeviceType = Device; - using InputStateType = InputState; using PipelineLayoutType = PipelineLayout; using QueueType = Queue; using RenderPipelineType = RenderPipeline; diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/InputStateVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/InputStateVk.cpp deleted file mode 100644 index 2e8b5f5b9b4..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/InputStateVk.cpp +++ /dev/null @@ -1,109 +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/InputStateVk.h" - -#include "common/BitSetIterator.h" - -namespace dawn_native { namespace vulkan { - - namespace { - - VkVertexInputRate VulkanInputRate(dawn::InputStepMode stepMode) { - switch (stepMode) { - case dawn::InputStepMode::Vertex: - return VK_VERTEX_INPUT_RATE_VERTEX; - case dawn::InputStepMode::Instance: - return VK_VERTEX_INPUT_RATE_INSTANCE; - default: - UNREACHABLE(); - } - } - - VkFormat VulkanVertexFormat(dawn::VertexFormat format) { - switch (format) { - case dawn::VertexFormat::FloatR32G32B32A32: - return VK_FORMAT_R32G32B32A32_SFLOAT; - case dawn::VertexFormat::FloatR32G32B32: - return VK_FORMAT_R32G32B32_SFLOAT; - case dawn::VertexFormat::FloatR32G32: - return VK_FORMAT_R32G32_SFLOAT; - case dawn::VertexFormat::FloatR32: - return VK_FORMAT_R32_SFLOAT; - case dawn::VertexFormat::IntR32G32B32A32: - return VK_FORMAT_R32G32B32A32_SINT; - case dawn::VertexFormat::IntR32G32B32: - return VK_FORMAT_R32G32B32_SINT; - case dawn::VertexFormat::IntR32G32: - return VK_FORMAT_R32G32_SINT; - case dawn::VertexFormat::IntR32: - return VK_FORMAT_R32_SINT; - case dawn::VertexFormat::UshortR16G16B16A16: - return VK_FORMAT_R16G16B16A16_UINT; - case dawn::VertexFormat::UshortR16G16: - return VK_FORMAT_R16G16_UINT; - case dawn::VertexFormat::UnormR8G8B8A8: - return VK_FORMAT_R8G8B8A8_UNORM; - case dawn::VertexFormat::UnormR8G8: - return VK_FORMAT_R8G8_UNORM; - default: - UNREACHABLE(); - } - } - - } // anonymous namespace - - InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) { - // Fill in the "binding info" that will be chained in the create info - uint32_t bindingCount = 0; - for (uint32_t i : IterateBitSet(GetInputsSetMask())) { - const auto& bindingInfo = GetInput(i); - - auto& bindingDesc = mBindings[bindingCount]; - bindingDesc.binding = i; - bindingDesc.stride = bindingInfo.stride; - bindingDesc.inputRate = VulkanInputRate(bindingInfo.stepMode); - - bindingCount++; - } - - // Fill in the "attribute info" that will be chained in the create info - uint32_t attributeCount = 0; - for (uint32_t i : IterateBitSet(GetAttributesSetMask())) { - const auto& attributeInfo = GetAttribute(i); - - auto& attributeDesc = mAttributes[attributeCount]; - attributeDesc.location = i; - attributeDesc.binding = attributeInfo.inputSlot; - attributeDesc.format = VulkanVertexFormat(attributeInfo.format); - attributeDesc.offset = attributeInfo.offset; - - attributeCount++; - } - - // Build the create info - mCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - mCreateInfo.pNext = nullptr; - mCreateInfo.flags = 0; - mCreateInfo.vertexBindingDescriptionCount = bindingCount; - mCreateInfo.pVertexBindingDescriptions = mBindings.data(); - mCreateInfo.vertexAttributeDescriptionCount = attributeCount; - mCreateInfo.pVertexAttributeDescriptions = mAttributes.data(); - } - - const VkPipelineVertexInputStateCreateInfo* InputState::GetCreateInfo() const { - return &mCreateInfo; - } - -}} // namespace dawn_native::vulkan diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/InputStateVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/InputStateVk.h deleted file mode 100644 index b44c08ad1cb..00000000000 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/InputStateVk.h +++ /dev/null @@ -1,41 +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. - -#ifndef DAWNNATIVE_VULKAN_INPUTSTATEVK_H_ -#define DAWNNATIVE_VULKAN_INPUTSTATEVK_H_ - -#include "dawn_native/InputState.h" - -#include "common/vulkan_platform.h" - -namespace dawn_native { namespace vulkan { - - class Device; - - // Pre-computes the input state configuration to give to a graphics pipeline create info. - class InputState : public InputStateBase { - public: - InputState(InputStateBuilder* builder); - - const VkPipelineVertexInputStateCreateInfo* GetCreateInfo() const; - - private: - VkPipelineVertexInputStateCreateInfo mCreateInfo; - std::array<VkVertexInputBindingDescription, kMaxVertexInputs> mBindings; - std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes> mAttributes; - }; - -}} // namespace dawn_native::vulkan - -#endif // DAWNNATIVE_VULKAN_INPUTSTATEVK_H_ 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 e0121e527c5..cc80ed47042 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp @@ -57,7 +57,7 @@ namespace dawn_native { namespace vulkan { } } - void NativeSwapChainImpl::Init(dawnWSIContextVulkan* /*context*/) { + void NativeSwapChainImpl::Init(DawnWSIContextVulkan* /*context*/) { if (mDevice->ConsumedError( GatherSurfaceInfo(*ToBackend(mDevice->GetAdapter()), mSurface, &mInfo))) { ASSERT(false); @@ -68,8 +68,8 @@ namespace dawn_native { namespace vulkan { } } - dawnSwapChainError NativeSwapChainImpl::Configure(dawnTextureFormat format, - dawnTextureUsageBit usage, + DawnSwapChainError NativeSwapChainImpl::Configure(DawnTextureFormat format, + DawnTextureUsageBit usage, uint32_t width, uint32_t height) { ASSERT(mInfo.capabilities.minImageExtent.width <= width); @@ -77,7 +77,7 @@ namespace dawn_native { namespace vulkan { ASSERT(mInfo.capabilities.minImageExtent.height <= height); ASSERT(mInfo.capabilities.maxImageExtent.height >= height); - ASSERT(format == static_cast<dawnTextureFormat>(GetPreferredFormat())); + ASSERT(format == static_cast<DawnTextureFormat>(GetPreferredFormat())); // TODO(cwallez@chromium.org): need to check usage works too // Create the swapchain with the configuration we chose @@ -151,7 +151,7 @@ namespace dawn_native { namespace vulkan { return DAWN_SWAP_CHAIN_NO_ERROR; } - dawnSwapChainError NativeSwapChainImpl::GetNextTexture(dawnSwapChainNextTexture* nextTexture) { + DawnSwapChainError NativeSwapChainImpl::GetNextTexture(DawnSwapChainNextTexture* nextTexture) { // Transiently create a semaphore that will be signaled when the presentation engine is done // with the swapchain image. Further operations on the image will wait for this semaphore. VkSemaphore semaphore = VK_NULL_HANDLE; @@ -178,7 +178,7 @@ namespace dawn_native { namespace vulkan { return DAWN_SWAP_CHAIN_NO_ERROR; } - dawnSwapChainError NativeSwapChainImpl::Present() { + DawnSwapChainError NativeSwapChainImpl::Present() { // This assumes that the image has already been transitioned to the PRESENT layout and // writes were made available to the stage. diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.h index 114439afb3f..f5dc27d3f88 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.h +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/NativeSwapChainImplVk.h @@ -26,18 +26,18 @@ namespace dawn_native { namespace vulkan { class NativeSwapChainImpl { public: - using WSIContext = dawnWSIContextVulkan; + using WSIContext = DawnWSIContextVulkan; NativeSwapChainImpl(Device* device, VkSurfaceKHR surface); ~NativeSwapChainImpl(); - void Init(dawnWSIContextVulkan* context); - dawnSwapChainError Configure(dawnTextureFormat format, - dawnTextureUsageBit, + void Init(DawnWSIContextVulkan* context); + DawnSwapChainError Configure(DawnTextureFormat format, + DawnTextureUsageBit, uint32_t width, uint32_t height); - dawnSwapChainError GetNextTexture(dawnSwapChainNextTexture* nextTexture); - dawnSwapChainError Present(); + DawnSwapChainError GetNextTexture(DawnSwapChainNextTexture* nextTexture); + DawnSwapChainError Present(); dawn::TextureFormat GetPreferredFormat() const; diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPassCache.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPassCache.cpp index 76e35f5d090..daeb5a43ab1 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPassCache.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPassCache.cpp @@ -38,10 +38,12 @@ namespace dawn_native { namespace vulkan { void RenderPassCacheQuery::SetColor(uint32_t index, dawn::TextureFormat format, - dawn::LoadOp loadOp) { + dawn::LoadOp loadOp, + bool hasResolveTarget) { colorMask.set(index); colorFormats[index] = format; colorLoadOp[index] = loadOp; + resolveTargetMask[index] = hasResolveTarget; } void RenderPassCacheQuery::SetDepthStencil(dawn::TextureFormat format, @@ -53,6 +55,10 @@ namespace dawn_native { namespace vulkan { this->stencilLoadOp = stencilLoadOp; } + void RenderPassCacheQuery::SetSampleCount(uint32_t sampleCount) { + this->sampleCount = sampleCount; + } + // RenderPassCache RenderPassCache::RenderPassCache(Device* device) : mDevice(device) { @@ -80,44 +86,49 @@ namespace dawn_native { namespace vulkan { const RenderPassCacheQuery& query) const { // The Vulkan subpasses want to know the layout of the attachments with VkAttachmentRef. // Precompute them as they must be pointer-chained in VkSubpassDescription - std::array<VkAttachmentReference, kMaxColorAttachments + 1> attachmentRefs; + std::array<VkAttachmentReference, kMaxColorAttachments> colorAttachmentRefs; + std::array<VkAttachmentReference, kMaxColorAttachments> resolveAttachmentRefs; + VkAttachmentReference depthStencilAttachmentRef; // Contains the attachment description that will be chained in the create info - std::array<VkAttachmentDescription, kMaxColorAttachments + 1> attachmentDescs = {}; + // The order of all attachments in attachmentDescs is "color-depthstencil-resolve". + constexpr uint32_t kMaxAttachmentCount = kMaxColorAttachments * 2 + 1; + std::array<VkAttachmentDescription, kMaxAttachmentCount> attachmentDescs = {}; - uint32_t attachmentCount = 0; + VkSampleCountFlagBits vkSampleCount = VulkanSampleCount(query.sampleCount); + + uint32_t colorAttachmentIndex = 0; for (uint32_t i : IterateBitSet(query.colorMask)) { - auto& attachmentRef = attachmentRefs[attachmentCount]; - auto& attachmentDesc = attachmentDescs[attachmentCount]; + auto& attachmentRef = colorAttachmentRefs[colorAttachmentIndex]; + auto& attachmentDesc = attachmentDescs[colorAttachmentIndex]; - attachmentRef.attachment = attachmentCount; + attachmentRef.attachment = colorAttachmentIndex; attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachmentDesc.flags = 0; attachmentDesc.format = VulkanImageFormat(query.colorFormats[i]); - attachmentDesc.samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDesc.samples = vkSampleCount; attachmentDesc.loadOp = VulkanAttachmentLoadOp(query.colorLoadOp[i]); attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachmentCount++; + ++colorAttachmentIndex; } - uint32_t colorAttachmentCount = attachmentCount; + uint32_t attachmentCount = colorAttachmentIndex; VkAttachmentReference* depthStencilAttachment = nullptr; if (query.hasDepthStencil) { - auto& attachmentRef = attachmentRefs[attachmentCount]; auto& attachmentDesc = attachmentDescs[attachmentCount]; - depthStencilAttachment = &attachmentRefs[attachmentCount]; + depthStencilAttachment = &depthStencilAttachmentRef; - attachmentRef.attachment = attachmentCount; - attachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthStencilAttachmentRef.attachment = attachmentCount; + depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachmentDesc.flags = 0; attachmentDesc.format = VulkanImageFormat(query.depthStencilFormat); - attachmentDesc.samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDesc.samples = vkSampleCount; attachmentDesc.loadOp = VulkanAttachmentLoadOp(query.depthLoadOp); attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachmentDesc.stencilLoadOp = VulkanAttachmentLoadOp(query.stencilLoadOp); @@ -125,18 +136,41 @@ namespace dawn_native { namespace vulkan { attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - attachmentCount++; + ++attachmentCount; } + uint32_t resolveAttachmentIndex = 0; + for (uint32_t i : IterateBitSet(query.resolveTargetMask)) { + auto& attachmentRef = resolveAttachmentRefs[resolveAttachmentIndex]; + auto& attachmentDesc = attachmentDescs[attachmentCount]; + + attachmentRef.attachment = attachmentCount; + attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + attachmentDesc.flags = 0; + attachmentDesc.format = VulkanImageFormat(query.colorFormats[i]); + attachmentDesc.samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + ++attachmentCount; + ++resolveAttachmentIndex; + } + + VkAttachmentReference* resolveTargetAttachmentRefs = + query.resolveTargetMask.any() ? resolveAttachmentRefs.data() : nullptr; + // Create the VkSubpassDescription that will be chained in the VkRenderPassCreateInfo VkSubpassDescription subpassDesc; subpassDesc.flags = 0; subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpassDesc.inputAttachmentCount = 0; subpassDesc.pInputAttachments = nullptr; - subpassDesc.colorAttachmentCount = colorAttachmentCount; - subpassDesc.pColorAttachments = attachmentRefs.data(); - subpassDesc.pResolveAttachments = nullptr; + subpassDesc.colorAttachmentCount = colorAttachmentIndex; + subpassDesc.pColorAttachments = colorAttachmentRefs.data(); + subpassDesc.pResolveAttachments = resolveTargetAttachmentRefs; subpassDesc.pDepthStencilAttachment = depthStencilAttachment; subpassDesc.preserveAttachmentCount = 0; subpassDesc.pPreserveAttachments = nullptr; @@ -168,6 +202,8 @@ namespace dawn_native { namespace vulkan { size_t RenderPassCache::CacheFuncs::operator()(const RenderPassCacheQuery& query) const { size_t hash = Hash(query.colorMask); + HashCombine(&hash, Hash(query.resolveTargetMask)); + for (uint32_t i : IterateBitSet(query.colorMask)) { HashCombine(&hash, query.colorFormats[i], query.colorLoadOp[i]); } @@ -177,6 +213,8 @@ namespace dawn_native { namespace vulkan { HashCombine(&hash, query.depthStencilFormat, query.depthLoadOp, query.stencilLoadOp); } + HashCombine(&hash, query.sampleCount); + return hash; } @@ -186,6 +224,14 @@ namespace dawn_native { namespace vulkan { return false; } + if (a.resolveTargetMask != b.resolveTargetMask) { + return false; + } + + if (a.sampleCount != b.sampleCount) { + return false; + } + for (uint32_t i : IterateBitSet(a.colorMask)) { if ((a.colorFormats[i] != b.colorFormats[i]) || (a.colorLoadOp[i] != b.colorLoadOp[i])) { diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPassCache.h b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPassCache.h index 9f678a5a46a..8410cea0fa0 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPassCache.h +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPassCache.h @@ -34,12 +34,17 @@ namespace dawn_native { namespace vulkan { struct RenderPassCacheQuery { // Use these helpers to build the query, they make sure all relevant data is initialized and // masks set. - void SetColor(uint32_t index, dawn::TextureFormat format, dawn::LoadOp loadOp); + void SetColor(uint32_t index, + dawn::TextureFormat format, + dawn::LoadOp loadOp, + bool hasResolveTarget); void SetDepthStencil(dawn::TextureFormat format, dawn::LoadOp depthLoadOp, dawn::LoadOp stencilLoadOp); + void SetSampleCount(uint32_t sampleCount); std::bitset<kMaxColorAttachments> colorMask; + std::bitset<kMaxColorAttachments> resolveTargetMask; std::array<dawn::TextureFormat, kMaxColorAttachments> colorFormats; std::array<dawn::LoadOp, kMaxColorAttachments> colorLoadOp; @@ -47,10 +52,14 @@ namespace dawn_native { namespace vulkan { dawn::TextureFormat depthStencilFormat; dawn::LoadOp depthLoadOp; dawn::LoadOp stencilLoadOp; + + uint32_t sampleCount; }; // Caches VkRenderPasses so that we don't create duplicate ones for every RenderPipeline or - // render pass. + // render pass. We always arrange the order of attachments in "color-depthstencil-resolve" order + // when creating render pass and framebuffer so that we can always make sure the order of + // attachments in the rendering pipeline matches the one of the framebuffer. // TODO(cwallez@chromium.org): Make it an LRU cache somehow? class RenderPassCache { public: 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 81b73b5bc55..e2cbca93d1b 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.cpp @@ -16,16 +16,94 @@ #include "dawn_native/vulkan/DeviceVk.h" #include "dawn_native/vulkan/FencedDeleter.h" -#include "dawn_native/vulkan/InputStateVk.h" #include "dawn_native/vulkan/PipelineLayoutVk.h" #include "dawn_native/vulkan/RenderPassCache.h" #include "dawn_native/vulkan/ShaderModuleVk.h" +#include "dawn_native/vulkan/TextureVk.h" #include "dawn_native/vulkan/UtilsVulkan.h" namespace dawn_native { namespace vulkan { namespace { + VkVertexInputRate VulkanInputRate(dawn::InputStepMode stepMode) { + switch (stepMode) { + case dawn::InputStepMode::Vertex: + return VK_VERTEX_INPUT_RATE_VERTEX; + case dawn::InputStepMode::Instance: + return VK_VERTEX_INPUT_RATE_INSTANCE; + default: + UNREACHABLE(); + } + } + + VkFormat VulkanVertexFormat(dawn::VertexFormat format) { + switch (format) { + case dawn::VertexFormat::UChar2: + return VK_FORMAT_R8G8_UINT; + case dawn::VertexFormat::UChar4: + return VK_FORMAT_R8G8B8A8_UINT; + case dawn::VertexFormat::Char2: + return VK_FORMAT_R8G8_SINT; + case dawn::VertexFormat::Char4: + return VK_FORMAT_R8G8B8A8_SINT; + case dawn::VertexFormat::UChar2Norm: + return VK_FORMAT_R8G8_UNORM; + case dawn::VertexFormat::UChar4Norm: + return VK_FORMAT_R8G8B8A8_UNORM; + case dawn::VertexFormat::Char2Norm: + return VK_FORMAT_R8G8_SNORM; + case dawn::VertexFormat::Char4Norm: + return VK_FORMAT_R8G8B8A8_SNORM; + case dawn::VertexFormat::UShort2: + return VK_FORMAT_R16G16_UINT; + case dawn::VertexFormat::UShort4: + return VK_FORMAT_R16G16B16A16_UINT; + case dawn::VertexFormat::Short2: + return VK_FORMAT_R16G16_SINT; + case dawn::VertexFormat::Short4: + return VK_FORMAT_R16G16B16A16_SINT; + case dawn::VertexFormat::UShort2Norm: + return VK_FORMAT_R16G16_UNORM; + case dawn::VertexFormat::UShort4Norm: + return VK_FORMAT_R16G16B16A16_UNORM; + case dawn::VertexFormat::Short2Norm: + return VK_FORMAT_R16G16_SNORM; + case dawn::VertexFormat::Short4Norm: + return VK_FORMAT_R16G16B16A16_SNORM; + case dawn::VertexFormat::Half2: + return VK_FORMAT_R16G16_SFLOAT; + case dawn::VertexFormat::Half4: + return VK_FORMAT_R16G16B16A16_SFLOAT; + case dawn::VertexFormat::Float: + return VK_FORMAT_R32_SFLOAT; + case dawn::VertexFormat::Float2: + return VK_FORMAT_R32G32_SFLOAT; + case dawn::VertexFormat::Float3: + return VK_FORMAT_R32G32B32_SFLOAT; + case dawn::VertexFormat::Float4: + return VK_FORMAT_R32G32B32A32_SFLOAT; + case dawn::VertexFormat::UInt: + return VK_FORMAT_R32_UINT; + case dawn::VertexFormat::UInt2: + return VK_FORMAT_R32G32_UINT; + case dawn::VertexFormat::UInt3: + return VK_FORMAT_R32G32B32_UINT; + case dawn::VertexFormat::UInt4: + return VK_FORMAT_R32G32B32A32_UINT; + case dawn::VertexFormat::Int: + return VK_FORMAT_R32_SINT; + case dawn::VertexFormat::Int2: + return VK_FORMAT_R32G32_SINT; + case dawn::VertexFormat::Int3: + return VK_FORMAT_R32G32B32_SINT; + case dawn::VertexFormat::Int4: + return VK_FORMAT_R32G32B32A32_SINT; + default: + UNREACHABLE(); + } + } + VkPrimitiveTopology VulkanPrimitiveTopology(dawn::PrimitiveTopology topology) { switch (topology) { case dawn::PrimitiveTopology::PointList: @@ -121,7 +199,7 @@ namespace dawn_native { namespace vulkan { attachment.srcAlphaBlendFactor = VulkanBlendFactor(descriptor->alphaBlend.srcFactor); attachment.dstAlphaBlendFactor = VulkanBlendFactor(descriptor->alphaBlend.dstFactor); attachment.alphaBlendOp = VulkanBlendOperation(descriptor->alphaBlend.operation); - attachment.colorWriteMask = VulkanColorWriteMask(descriptor->colorWriteMask); + attachment.colorWriteMask = VulkanColorWriteMask(descriptor->writeMask); return attachment; } @@ -218,6 +296,12 @@ namespace dawn_native { namespace vulkan { shaderStages[1].pName = descriptor->fragmentStage->entryPoint; } + std::array<VkVertexInputBindingDescription, kMaxVertexInputs> mBindings; + std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes> mAttributes; + const InputStateDescriptor* inputState = GetInputStateDescriptor(); + VkPipelineVertexInputStateCreateInfo inputStateCreateInfo = + ComputeInputStateDesc(inputState, &mBindings, &mAttributes); + VkPipelineInputAssemblyStateCreateInfo inputAssembly; inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; inputAssembly.pNext = nullptr; @@ -268,7 +352,7 @@ namespace dawn_native { namespace vulkan { multisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisample.pNext = nullptr; multisample.flags = 0; - multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + multisample.rasterizationSamples = VulkanSampleCount(GetSampleCount()); multisample.sampleShadingEnable = VK_FALSE; multisample.minSampleShading = 0.0f; multisample.pSampleMask = nullptr; @@ -322,7 +406,7 @@ namespace dawn_native { namespace vulkan { RenderPassCacheQuery query; for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { - query.SetColor(i, GetColorAttachmentFormat(i), dawn::LoadOp::Load); + query.SetColor(i, GetColorAttachmentFormat(i), dawn::LoadOp::Load, false); } if (HasDepthStencilAttachment()) { @@ -330,6 +414,8 @@ namespace dawn_native { namespace vulkan { dawn::LoadOp::Load); } + query.SetSampleCount(GetSampleCount()); + renderPass = device->GetRenderPassCache()->GetRenderPass(query); } @@ -341,7 +427,7 @@ namespace dawn_native { namespace vulkan { createInfo.flags = 0; createInfo.stageCount = 2; createInfo.pStages = shaderStages; - createInfo.pVertexInputState = ToBackend(GetInputState())->GetCreateInfo(); + createInfo.pVertexInputState = &inputStateCreateInfo; createInfo.pInputAssemblyState = &inputAssembly; createInfo.pTessellationState = nullptr; createInfo.pViewportState = &viewport; @@ -362,6 +448,49 @@ namespace dawn_native { namespace vulkan { } } + VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeInputStateDesc( + const InputStateDescriptor* inputState, + std::array<VkVertexInputBindingDescription, kMaxVertexInputs>* mBindings, + std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes>* mAttributes) { + // Fill in the "binding info" that will be chained in the create info + uint32_t bindingCount = 0; + for (uint32_t i : IterateBitSet(GetInputsSetMask())) { + const auto& bindingInfo = GetInput(i); + + auto& bindingDesc = (*mBindings)[bindingCount]; + bindingDesc.binding = i; + bindingDesc.stride = bindingInfo.stride; + bindingDesc.inputRate = VulkanInputRate(bindingInfo.stepMode); + + bindingCount++; + } + + // Fill in the "attribute info" that will be chained in the create info + uint32_t attributeCount = 0; + for (uint32_t i : IterateBitSet(GetAttributesSetMask())) { + const auto& attributeInfo = GetAttribute(i); + + auto& attributeDesc = (*mAttributes)[attributeCount]; + attributeDesc.location = i; + attributeDesc.binding = attributeInfo.inputSlot; + attributeDesc.format = VulkanVertexFormat(attributeInfo.format); + attributeDesc.offset = attributeInfo.offset; + + attributeCount++; + } + + // Build the create info + VkPipelineVertexInputStateCreateInfo mCreateInfo; + mCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + mCreateInfo.pNext = nullptr; + mCreateInfo.flags = 0; + mCreateInfo.vertexBindingDescriptionCount = bindingCount; + mCreateInfo.pVertexBindingDescriptions = &(*mBindings)[0]; + mCreateInfo.vertexAttributeDescriptionCount = attributeCount; + mCreateInfo.pVertexAttributeDescriptions = &(*mAttributes)[0]; + return mCreateInfo; + } + RenderPipeline::~RenderPipeline() { if (mHandle != VK_NULL_HANDLE) { ToBackend(GetDevice())->GetFencedDeleter()->DeleteWhenUnused(mHandle); 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 744772d6966..5d58fa73975 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.h +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/RenderPipelineVk.h @@ -31,6 +31,11 @@ namespace dawn_native { namespace vulkan { VkPipeline GetHandle() const; private: + VkPipelineVertexInputStateCreateInfo ComputeInputStateDesc( + const InputStateDescriptor* inputState, + std::array<VkVertexInputBindingDescription, kMaxVertexInputs>* mBindings, + std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes>* mAttributes); + VkPipeline mHandle = VK_NULL_HANDLE; }; 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 aa23b3c1bd8..7f242d834f2 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/SamplerVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/SamplerVk.cpp @@ -29,8 +29,6 @@ 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(); } @@ -57,24 +55,11 @@ 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) : SamplerBase(device, descriptor), mDevice(device) { - VkSamplerCreateInfo createInfo; + VkSamplerCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; createInfo.pNext = nullptr; createInfo.flags = 0; @@ -91,7 +76,6 @@ namespace dawn_native { namespace vulkan { 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/SwapChainVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/SwapChainVk.cpp index 6028444b567..f4e857d4d85 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/SwapChainVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/SwapChainVk.cpp @@ -22,7 +22,7 @@ namespace dawn_native { namespace vulkan { SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor) : SwapChainBase(device, descriptor) { const auto& im = GetImplementation(); - dawnWSIContextVulkan wsiContext = {}; + DawnWSIContextVulkan wsiContext = {}; im.Init(im.userData, &wsiContext); ASSERT(im.textureUsage != DAWN_TEXTURE_USAGE_BIT_NONE); @@ -34,8 +34,8 @@ namespace dawn_native { namespace vulkan { TextureBase* SwapChain::GetNextTextureImpl(const TextureDescriptor* descriptor) { const auto& im = GetImplementation(); - dawnSwapChainNextTexture next = {}; - dawnSwapChainError error = im.GetNextTexture(im.userData, &next); + DawnSwapChainNextTexture next = {}; + DawnSwapChainError error = im.GetNextTexture(im.userData, &next); if (error) { GetDevice()->HandleError(error); diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/TextureVk.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/TextureVk.cpp index f57d359f314..70064ec1e97 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/TextureVk.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/TextureVk.cpp @@ -14,6 +14,7 @@ #include "dawn_native/vulkan/TextureVk.h" +#include "dawn_native/vulkan/AdapterVk.h" #include "dawn_native/vulkan/DeviceVk.h" #include "dawn_native/vulkan/FencedDeleter.h" @@ -191,6 +192,22 @@ namespace dawn_native { namespace vulkan { return {extent.width, extent.height, extent.depth}; } + bool IsSampleCountSupported(const dawn_native::vulkan::Device* device, + const VkImageCreateInfo& imageCreateInfo) { + ASSERT(device); + + VkPhysicalDevice physicalDevice = ToBackend(device->GetAdapter())->GetPhysicalDevice(); + VkImageFormatProperties properties; + if (device->fn.GetPhysicalDeviceImageFormatProperties( + physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, + imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags, + &properties) != VK_SUCCESS) { + UNREACHABLE(); + } + + return properties.sampleCounts & imageCreateInfo.samples; + } + } // namespace // Converts Dawn texture format to Vulkan formats. @@ -245,8 +262,19 @@ namespace dawn_native { namespace vulkan { return flags; } + VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount) { + switch (sampleCount) { + case 1: + return VK_SAMPLE_COUNT_1_BIT; + case 4: + return VK_SAMPLE_COUNT_4_BIT; + default: + UNREACHABLE(); + } + } + Texture::Texture(Device* device, const TextureDescriptor* descriptor) - : TextureBase(device, descriptor) { + : TextureBase(device, descriptor, TextureState::OwnedInternal) { // Create the Vulkan image "container". We don't need to check that the format supports the // combination of sample, usage etc. because validation should have been done in the Dawn // frontend already based on the minimum supported formats in the Vulkan spec @@ -259,7 +287,7 @@ namespace dawn_native { namespace vulkan { createInfo.extent = VulkanExtent3D(GetSize()); createInfo.mipLevels = GetNumMipLevels(); createInfo.arrayLayers = GetArrayLayers(); - createInfo.samples = VK_SAMPLE_COUNT_1_BIT; + createInfo.samples = VulkanSampleCount(GetSampleCount()); createInfo.tiling = VK_IMAGE_TILING_OPTIMAL; createInfo.usage = VulkanImageUsage(GetUsage(), GetFormat()); createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; @@ -267,6 +295,8 @@ namespace dawn_native { namespace vulkan { createInfo.pQueueFamilyIndices = nullptr; createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + ASSERT(IsSampleCountSupported(device, createInfo)); + if (GetArrayLayers() >= 6 && GetSize().width == GetSize().height) { createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; } @@ -291,17 +321,23 @@ namespace dawn_native { namespace vulkan { } } + // With this constructor, the lifetime of the resource is externally managed. Texture::Texture(Device* device, const TextureDescriptor* descriptor, VkImage nativeImage) - : TextureBase(device, descriptor), mHandle(nativeImage) { + : TextureBase(device, descriptor, TextureState::OwnedExternal), mHandle(nativeImage) { } Texture::~Texture() { + DestroyInternal(); + } + + void Texture::DestroyImpl() { Device* device = ToBackend(GetDevice()); // If we own the resource, release it. if (mMemoryAllocation.GetMemory() != VK_NULL_HANDLE) { - // We need to free both the memory allocation and the container. Memory should be freed - // after the VkImage is destroyed and this is taken care of by the FencedDeleter. + // We need to free both the memory allocation and the container. Memory should be + // freed after the VkImage is destroyed and this is taken care of by the + // FencedDeleter. device->GetMemoryAllocator()->Free(&mMemoryAllocation); if (mHandle != VK_NULL_HANDLE) { diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/TextureVk.h b/chromium/third_party/dawn/src/dawn_native/vulkan/TextureVk.h index e17ebb2eee4..3909be0ff08 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/TextureVk.h +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/TextureVk.h @@ -24,6 +24,7 @@ namespace dawn_native { namespace vulkan { VkFormat VulkanImageFormat(dawn::TextureFormat format); VkImageUsageFlags VulkanImageUsage(dawn::TextureUsageBit usage, dawn::TextureFormat format); + VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount); class Texture : public TextureBase { public: @@ -40,6 +41,8 @@ namespace dawn_native { namespace vulkan { void TransitionUsageNow(VkCommandBuffer commands, dawn::TextureUsageBit usage); private: + void DestroyImpl() override; + VkImage mHandle = VK_NULL_HANDLE; DeviceMemoryAllocation mMemoryAllocation; diff --git a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanBackend.cpp b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanBackend.cpp index 4880e75f9b5..acc624a618a 100644 --- a/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanBackend.cpp +++ b/chromium/third_party/dawn/src/dawn_native/vulkan/VulkanBackend.cpp @@ -27,29 +27,29 @@ namespace dawn_native { namespace vulkan { - VkInstance GetInstance(dawnDevice device) { + VkInstance GetInstance(DawnDevice device) { Device* backendDevice = reinterpret_cast<Device*>(device); return backendDevice->GetVkInstance(); } // Explicitly export this function because it uses the "native" type for surfaces while the // header as seen in this file uses the wrapped type. - DAWN_NATIVE_EXPORT dawnSwapChainImplementation - CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHRNative surfaceNative) { + DAWN_NATIVE_EXPORT DawnSwapChainImplementation + CreateNativeSwapChainImpl(DawnDevice device, VkSurfaceKHRNative surfaceNative) { Device* backendDevice = reinterpret_cast<Device*>(device); VkSurfaceKHR surface = VkSurfaceKHR::CreateFromHandle(surfaceNative); - dawnSwapChainImplementation impl; + DawnSwapChainImplementation impl; impl = CreateSwapChainImplementation(new NativeSwapChainImpl(backendDevice, surface)); impl.textureUsage = DAWN_TEXTURE_USAGE_BIT_PRESENT; return impl; } - dawnTextureFormat GetNativeSwapChainPreferredFormat( - const dawnSwapChainImplementation* swapChain) { + DawnTextureFormat GetNativeSwapChainPreferredFormat( + const DawnSwapChainImplementation* swapChain) { NativeSwapChainImpl* impl = reinterpret_cast<NativeSwapChainImpl*>(swapChain->userData); - return static_cast<dawnTextureFormat>(impl->GetPreferredFormat()); + return static_cast<DawnTextureFormat>(impl->GetPreferredFormat()); } }} // namespace dawn_native::vulkan |