Typeify ColorAttachmentIndex

Also moves BindingNumber, BindGroupIndex, and BindingIndex to
IntegerTypes.h. Future TypedIntegers should be declared here.

Bug: dawn:442
Change-Id: I5ba8de3412fb48b7957b67e7c413a5097f8ec00f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/27880
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng 2020-09-09 00:08:38 +00:00 committed by Commit Bot service account
parent 22e5e179fa
commit 7b7e098b11
28 changed files with 208 additions and 128 deletions

View File

@ -29,7 +29,7 @@ static constexpr uint32_t kMaxVertexAttributeEnd = 2048u;
static constexpr uint32_t kMaxVertexBuffers = 16u; static constexpr uint32_t kMaxVertexBuffers = 16u;
static constexpr uint32_t kMaxVertexBufferStride = 2048u; static constexpr uint32_t kMaxVertexBufferStride = 2048u;
static constexpr uint32_t kNumStages = 3; static constexpr uint32_t kNumStages = 3;
static constexpr uint32_t kMaxColorAttachments = 4u; static constexpr uint8_t kMaxColorAttachments = 4u;
static constexpr uint32_t kTextureBytesPerRowAlignment = 256u; static constexpr uint32_t kTextureBytesPerRowAlignment = 256u;
// Dynamic buffer offsets require offset to be divisible by 256 // Dynamic buffer offsets require offset to be divisible by 256
static constexpr uint64_t kMinDynamicBufferOffsetAlignment = 256u; static constexpr uint64_t kMinDynamicBufferOffsetAlignment = 256u;

View File

@ -88,6 +88,7 @@ namespace ityp {
using Base::back; using Base::back;
using Base::data; using Base::data;
using Base::empty; using Base::empty;
using Base::fill;
using Base::front; using Base::front;
}; };

View File

@ -24,18 +24,22 @@ namespace dawn_native {
AttachmentStateBlueprint::AttachmentStateBlueprint( AttachmentStateBlueprint::AttachmentStateBlueprint(
const RenderBundleEncoderDescriptor* descriptor) const RenderBundleEncoderDescriptor* descriptor)
: mSampleCount(descriptor->sampleCount) { : mSampleCount(descriptor->sampleCount) {
for (uint32_t i = 0; i < descriptor->colorFormatsCount; ++i) { ASSERT(descriptor->colorFormatsCount <= kMaxColorAttachments);
for (ColorAttachmentIndex i(uint8_t(0));
i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->colorFormatsCount)); ++i) {
mColorAttachmentsSet.set(i); mColorAttachmentsSet.set(i);
mColorFormats[i] = descriptor->colorFormats[i]; mColorFormats[i] = descriptor->colorFormats[static_cast<uint8_t>(i)];
} }
mDepthStencilFormat = descriptor->depthStencilFormat; mDepthStencilFormat = descriptor->depthStencilFormat;
} }
AttachmentStateBlueprint::AttachmentStateBlueprint(const RenderPipelineDescriptor* descriptor) AttachmentStateBlueprint::AttachmentStateBlueprint(const RenderPipelineDescriptor* descriptor)
: mSampleCount(descriptor->sampleCount) { : mSampleCount(descriptor->sampleCount) {
for (uint32_t i = 0; i < descriptor->colorStateCount; ++i) { ASSERT(descriptor->colorStateCount <= kMaxColorAttachments);
for (ColorAttachmentIndex i(uint8_t(0));
i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->colorStateCount)); ++i) {
mColorAttachmentsSet.set(i); mColorAttachmentsSet.set(i);
mColorFormats[i] = descriptor->colorStates[i].format; mColorFormats[i] = descriptor->colorStates[static_cast<uint8_t>(i)].format;
} }
if (descriptor->depthStencilState != nullptr) { if (descriptor->depthStencilState != nullptr) {
mDepthStencilFormat = descriptor->depthStencilState->format; mDepthStencilFormat = descriptor->depthStencilState->format;
@ -43,8 +47,11 @@ namespace dawn_native {
} }
AttachmentStateBlueprint::AttachmentStateBlueprint(const RenderPassDescriptor* descriptor) { AttachmentStateBlueprint::AttachmentStateBlueprint(const RenderPassDescriptor* descriptor) {
for (uint32_t i = 0; i < descriptor->colorAttachmentCount; ++i) { for (ColorAttachmentIndex i(uint8_t(0));
TextureViewBase* attachment = descriptor->colorAttachments[i].attachment; i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->colorAttachmentCount));
++i) {
TextureViewBase* attachment =
descriptor->colorAttachments[static_cast<uint8_t>(i)].attachment;
mColorAttachmentsSet.set(i); mColorAttachmentsSet.set(i);
mColorFormats[i] = attachment->GetFormat().format; mColorFormats[i] = attachment->GetFormat().format;
if (mSampleCount == 0) { if (mSampleCount == 0) {
@ -74,7 +81,7 @@ namespace dawn_native {
// Hash color formats // Hash color formats
HashCombine(&hash, attachmentState->mColorAttachmentsSet); HashCombine(&hash, attachmentState->mColorAttachmentsSet);
for (uint32_t i : IterateBitSet(attachmentState->mColorAttachmentsSet)) { for (ColorAttachmentIndex i : IterateBitSet(attachmentState->mColorAttachmentsSet)) {
HashCombine(&hash, attachmentState->mColorFormats[i]); HashCombine(&hash, attachmentState->mColorFormats[i]);
} }
@ -96,7 +103,7 @@ namespace dawn_native {
} }
// Check color formats // Check color formats
for (uint32_t i : IterateBitSet(a->mColorAttachmentsSet)) { for (ColorAttachmentIndex i : IterateBitSet(a->mColorAttachmentsSet)) {
if (a->mColorFormats[i] != b->mColorFormats[i]) { if (a->mColorFormats[i] != b->mColorFormats[i]) {
return false; return false;
} }
@ -123,11 +130,13 @@ namespace dawn_native {
GetDevice()->UncacheAttachmentState(this); GetDevice()->UncacheAttachmentState(this);
} }
std::bitset<kMaxColorAttachments> AttachmentState::GetColorAttachmentsMask() const { ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
AttachmentState::GetColorAttachmentsMask() const {
return mColorAttachmentsSet; return mColorAttachmentsSet;
} }
wgpu::TextureFormat AttachmentState::GetColorAttachmentFormat(uint32_t index) const { wgpu::TextureFormat AttachmentState::GetColorAttachmentFormat(
ColorAttachmentIndex index) const {
ASSERT(mColorAttachmentsSet[index]); ASSERT(mColorAttachmentsSet[index]);
return mColorFormats[index]; return mColorFormats[index];
} }

View File

@ -16,7 +16,10 @@
#define DAWNNATIVE_ATTACHMENTSTATE_H_ #define DAWNNATIVE_ATTACHMENTSTATE_H_
#include "common/Constants.h" #include "common/Constants.h"
#include "common/ityp_array.h"
#include "common/ityp_bitset.h"
#include "dawn_native/CachedObject.h" #include "dawn_native/CachedObject.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
@ -49,8 +52,8 @@ namespace dawn_native {
}; };
protected: protected:
std::bitset<kMaxColorAttachments> mColorAttachmentsSet; ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> mColorAttachmentsSet;
std::array<wgpu::TextureFormat, kMaxColorAttachments> mColorFormats; ityp::array<ColorAttachmentIndex, wgpu::TextureFormat, kMaxColorAttachments> mColorFormats;
// Default (texture format Undefined) indicates there is no depth stencil attachment. // Default (texture format Undefined) indicates there is no depth stencil attachment.
wgpu::TextureFormat mDepthStencilFormat = wgpu::TextureFormat::Undefined; wgpu::TextureFormat mDepthStencilFormat = wgpu::TextureFormat::Undefined;
uint32_t mSampleCount = 0; uint32_t mSampleCount = 0;
@ -60,8 +63,8 @@ namespace dawn_native {
public: public:
AttachmentState(DeviceBase* device, const AttachmentStateBlueprint& blueprint); AttachmentState(DeviceBase* device, const AttachmentStateBlueprint& blueprint);
std::bitset<kMaxColorAttachments> GetColorAttachmentsMask() const; ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> GetColorAttachmentsMask() const;
wgpu::TextureFormat GetColorAttachmentFormat(uint32_t index) const; wgpu::TextureFormat GetColorAttachmentFormat(ColorAttachmentIndex index) const;
bool HasDepthStencilAttachment() const; bool HasDepthStencilAttachment() const;
wgpu::TextureFormat GetDepthStencilFormat() const; wgpu::TextureFormat GetDepthStencilFormat() const;
uint32_t GetSampleCount() const; uint32_t GetSampleCount() const;

View File

@ -212,6 +212,7 @@ source_set("dawn_native_sources") {
"Forward.h", "Forward.h",
"Instance.cpp", "Instance.cpp",
"Instance.h", "Instance.h",
"IntegerTypes.h",
"MapRequestTracker.cpp", "MapRequestTracker.cpp",
"MapRequestTracker.h", "MapRequestTracker.h",
"ObjectBase.cpp", "ObjectBase.cpp",

View File

@ -16,10 +16,10 @@
#define DAWNNATIVE_BINDINGINFO_H_ #define DAWNNATIVE_BINDINGINFO_H_
#include "common/Constants.h" #include "common/Constants.h"
#include "common/TypedInteger.h"
#include "common/ityp_array.h" #include "common/ityp_array.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/Format.h" #include "dawn_native/Format.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/PerStage.h" #include "dawn_native/PerStage.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
@ -28,16 +28,6 @@
namespace dawn_native { namespace dawn_native {
// Binding numbers in the shader and BindGroup/BindGroupLayoutDescriptors
using BindingNumber = TypedInteger<struct BindingNumberT, uint32_t>;
// Binding numbers get mapped to a packed range of indices
using BindingIndex = TypedInteger<struct BindingIndexT, uint32_t>;
using BindGroupIndex = TypedInteger<struct BindGroupIndexT, uint32_t>;
static constexpr BindGroupIndex kMaxBindGroupsTyped = BindGroupIndex(kMaxBindGroups);
// Not a real WebGPU limit, but the sum of the two limits is useful for internal optimizations. // Not a real WebGPU limit, but the sum of the two limits is useful for internal optimizations.
static constexpr uint32_t kMaxDynamicBuffersPerPipelineLayout = static constexpr uint32_t kMaxDynamicBuffersPerPipelineLayout =
kMaxDynamicUniformBuffersPerPipelineLayout + kMaxDynamicStorageBuffersPerPipelineLayout; kMaxDynamicUniformBuffersPerPipelineLayout + kMaxDynamicStorageBuffersPerPipelineLayout;

View File

@ -90,6 +90,7 @@ target_sources(dawn_native PRIVATE
"Forward.h" "Forward.h"
"Instance.cpp" "Instance.cpp"
"Instance.h" "Instance.h"
"IntegerTypes.h"
"MapRequestTracker.cpp" "MapRequestTracker.cpp"
"MapRequestTracker.h" "MapRequestTracker.h"
"ObjectBase.cpp" "ObjectBase.cpp"

View File

@ -85,7 +85,8 @@ namespace dawn_native {
} }
void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass) { void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass) {
for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { for (ColorAttachmentIndex i :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
auto& attachmentInfo = renderPass->colorAttachments[i]; auto& attachmentInfo = renderPass->colorAttachments[i];
TextureViewBase* view = attachmentInfo.view.Get(); TextureViewBase* view = attachmentInfo.view.Get();
bool hasResolveTarget = attachmentInfo.resolveTarget.Get() != nullptr; bool hasResolveTarget = attachmentInfo.resolveTarget.Get() != nullptr;

View File

@ -514,15 +514,17 @@ namespace dawn_native {
cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor); cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor);
for (uint32_t i : IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) { for (ColorAttachmentIndex index :
IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
uint8_t i = static_cast<uint8_t>(index);
TextureViewBase* view = descriptor->colorAttachments[i].attachment; TextureViewBase* view = descriptor->colorAttachments[i].attachment;
TextureViewBase* resolveTarget = descriptor->colorAttachments[i].resolveTarget; TextureViewBase* resolveTarget = descriptor->colorAttachments[i].resolveTarget;
cmd->colorAttachments[i].view = view; cmd->colorAttachments[index].view = view;
cmd->colorAttachments[i].resolveTarget = resolveTarget; cmd->colorAttachments[index].resolveTarget = resolveTarget;
cmd->colorAttachments[i].loadOp = descriptor->colorAttachments[i].loadOp; cmd->colorAttachments[index].loadOp = descriptor->colorAttachments[i].loadOp;
cmd->colorAttachments[i].storeOp = descriptor->colorAttachments[i].storeOp; cmd->colorAttachments[index].storeOp = descriptor->colorAttachments[i].storeOp;
cmd->colorAttachments[i].clearColor = cmd->colorAttachments[index].clearColor =
descriptor->colorAttachments[i].clearColor; descriptor->colorAttachments[i].clearColor;
usageTracker.TextureViewUsedAs(view, wgpu::TextureUsage::OutputAttachment); usageTracker.TextureViewUsedAs(view, wgpu::TextureUsage::OutputAttachment);

View File

@ -86,7 +86,8 @@ namespace dawn_native {
struct BeginRenderPassCmd { struct BeginRenderPassCmd {
Ref<AttachmentState> attachmentState; Ref<AttachmentState> attachmentState;
RenderPassColorAttachmentInfo colorAttachments[kMaxColorAttachments]; ityp::array<ColorAttachmentIndex, RenderPassColorAttachmentInfo, kMaxColorAttachments>
colorAttachments;
RenderPassDepthStencilAttachmentInfo depthStencilAttachment; RenderPassDepthStencilAttachmentInfo depthStencilAttachment;
// Cache the width and height of all attachments for convenience // Cache the width and height of all attachments for convenience

View File

@ -0,0 +1,41 @@
// Copyright 2020 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_INTEGERTYPES_H_
#define DAWNNATIVE_INTEGERTYPES_H_
#include "common/Constants.h"
#include "common/TypedInteger.h"
#include <cstdint>
namespace dawn_native {
// Binding numbers in the shader and BindGroup/BindGroupLayoutDescriptors
using BindingNumber = TypedInteger<struct BindingNumberT, uint32_t>;
// Binding numbers get mapped to a packed range of indices
using BindingIndex = TypedInteger<struct BindingIndexT, uint32_t>;
using BindGroupIndex = TypedInteger<struct BindGroupIndexT, uint32_t>;
static constexpr BindGroupIndex kMaxBindGroupsTyped = BindGroupIndex(kMaxBindGroups);
using ColorAttachmentIndex = TypedInteger<struct ColorAttachmentIndexT, uint8_t>;
constexpr ColorAttachmentIndex kMaxColorAttachmentsTyped =
ColorAttachmentIndex(kMaxColorAttachments);
} // namespace dawn_native
#endif // DAWNNATIVE_INTEGERTYPES_H_

View File

@ -356,10 +356,11 @@ namespace dawn_native {
const EntryPointMetadata& fragmentMetadata = const EntryPointMetadata& fragmentMetadata =
descriptor->fragmentStage->module->GetEntryPoint(descriptor->fragmentStage->entryPoint, descriptor->fragmentStage->module->GetEntryPoint(descriptor->fragmentStage->entryPoint,
SingleShaderStage::Fragment); SingleShaderStage::Fragment);
for (uint32_t i = 0; i < descriptor->colorStateCount; ++i) { for (ColorAttachmentIndex i(uint8_t(0));
DAWN_TRY( i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->colorStateCount)); ++i) {
ValidateColorStateDescriptor(device, descriptor->colorStates[i], DAWN_TRY(ValidateColorStateDescriptor(
fragmentMetadata.fragmentOutputFormatBaseTypes[i])); device, descriptor->colorStates[static_cast<uint8_t>(i)],
fragmentMetadata.fragmentOutputFormatBaseTypes[i]));
} }
if (descriptor->depthStencilState) { if (descriptor->depthStencilState) {
@ -460,8 +461,8 @@ namespace dawn_native {
mDepthStencilState.stencilWriteMask = 0xff; mDepthStencilState.stencilWriteMask = 0xff;
} }
for (uint32_t i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
mColorStates[i] = descriptor->colorStates[i]; mColorStates[i] = descriptor->colorStates[static_cast<uint8_t>(i)];
} }
// TODO(cwallez@chromium.org): Check against the shader module that the correct color // TODO(cwallez@chromium.org): Check against the shader module that the correct color
@ -511,7 +512,7 @@ namespace dawn_native {
} }
const ColorStateDescriptor* RenderPipelineBase::GetColorStateDescriptor( const ColorStateDescriptor* RenderPipelineBase::GetColorStateDescriptor(
uint32_t attachmentSlot) const { ColorAttachmentIndex attachmentSlot) const {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(attachmentSlot < mColorStates.size()); ASSERT(attachmentSlot < mColorStates.size());
return &mColorStates[attachmentSlot]; return &mColorStates[attachmentSlot];
@ -537,7 +538,8 @@ namespace dawn_native {
return mRasterizationState.frontFace; return mRasterizationState.frontFace;
} }
std::bitset<kMaxColorAttachments> RenderPipelineBase::GetColorAttachmentsMask() const { ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
RenderPipelineBase::GetColorAttachmentsMask() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mAttachmentState->GetColorAttachmentsMask(); return mAttachmentState->GetColorAttachmentsMask();
} }
@ -547,7 +549,8 @@ namespace dawn_native {
return mAttachmentState->HasDepthStencilAttachment(); return mAttachmentState->HasDepthStencilAttachment();
} }
wgpu::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(uint32_t attachment) const { wgpu::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(
ColorAttachmentIndex attachment) const {
ASSERT(!IsError()); ASSERT(!IsError());
return mColorStates[attachment].format; return mColorStates[attachment].format;
} }
@ -594,7 +597,8 @@ namespace dawn_native {
HashCombine(&hash, pipeline->mAttachmentState.Get()); HashCombine(&hash, pipeline->mAttachmentState.Get());
// Hash attachments // Hash attachments
for (uint32_t i : IterateBitSet(pipeline->mAttachmentState->GetColorAttachmentsMask())) { for (ColorAttachmentIndex i :
IterateBitSet(pipeline->mAttachmentState->GetColorAttachmentsMask())) {
const ColorStateDescriptor& desc = *pipeline->GetColorStateDescriptor(i); const ColorStateDescriptor& desc = *pipeline->GetColorStateDescriptor(i);
HashCombine(&hash, desc.writeMask); HashCombine(&hash, desc.writeMask);
HashCombine(&hash, desc.colorBlend.operation, desc.colorBlend.srcFactor, HashCombine(&hash, desc.colorBlend.operation, desc.colorBlend.srcFactor,
@ -656,7 +660,8 @@ namespace dawn_native {
return false; return false;
} }
for (uint32_t i : IterateBitSet(a->mAttachmentState->GetColorAttachmentsMask())) { for (ColorAttachmentIndex i :
IterateBitSet(a->mAttachmentState->GetColorAttachmentsMask())) {
const ColorStateDescriptor& descA = *a->GetColorStateDescriptor(i); const ColorStateDescriptor& descA = *a->GetColorStateDescriptor(i);
const ColorStateDescriptor& descB = *b->GetColorStateDescriptor(i); const ColorStateDescriptor& descB = *b->GetColorStateDescriptor(i);
if (descA.writeMask != descB.writeMask) { if (descA.writeMask != descB.writeMask) {

View File

@ -67,15 +67,16 @@ namespace dawn_native {
const std::bitset<kMaxVertexBuffers>& GetVertexBufferSlotsUsed() const; const std::bitset<kMaxVertexBuffers>& GetVertexBufferSlotsUsed() const;
const VertexBufferInfo& GetVertexBuffer(uint32_t slot) const; const VertexBufferInfo& GetVertexBuffer(uint32_t slot) const;
const ColorStateDescriptor* GetColorStateDescriptor(uint32_t attachmentSlot) const; const ColorStateDescriptor* GetColorStateDescriptor(
ColorAttachmentIndex attachmentSlot) const;
const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor() const; const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor() const;
wgpu::PrimitiveTopology GetPrimitiveTopology() const; wgpu::PrimitiveTopology GetPrimitiveTopology() const;
wgpu::CullMode GetCullMode() const; wgpu::CullMode GetCullMode() const;
wgpu::FrontFace GetFrontFace() const; wgpu::FrontFace GetFrontFace() const;
std::bitset<kMaxColorAttachments> GetColorAttachmentsMask() const; ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> GetColorAttachmentsMask() const;
bool HasDepthStencilAttachment() const; bool HasDepthStencilAttachment() const;
wgpu::TextureFormat GetColorAttachmentFormat(uint32_t attachment) const; wgpu::TextureFormat GetColorAttachmentFormat(ColorAttachmentIndex attachment) const;
wgpu::TextureFormat GetDepthStencilFormat() const; wgpu::TextureFormat GetDepthStencilFormat() const;
uint32_t GetSampleCount() const; uint32_t GetSampleCount() const;
uint32_t GetSampleMask() const; uint32_t GetSampleMask() const;
@ -108,7 +109,7 @@ namespace dawn_native {
// Attachments // Attachments
Ref<AttachmentState> mAttachmentState; Ref<AttachmentState> mAttachmentState;
DepthStencilStateDescriptor mDepthStencilState; DepthStencilStateDescriptor mDepthStencilState;
std::array<ColorStateDescriptor, kMaxColorAttachments> mColorStates; ityp::array<ColorAttachmentIndex, ColorStateDescriptor, kMaxColorAttachments> mColorStates;
// Other state // Other state
wgpu::PrimitiveTopology mPrimitiveTopology; wgpu::PrimitiveTopology mPrimitiveTopology;

View File

@ -872,12 +872,14 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"Unable to find Location decoration for Fragment output"); "Unable to find Location decoration for Fragment output");
} }
uint32_t location = uint32_t unsanitizedAttachment =
compiler.get_decoration(fragmentOutput.id, spv::DecorationLocation); compiler.get_decoration(fragmentOutput.id, spv::DecorationLocation);
if (location >= kMaxColorAttachments) { if (unsanitizedAttachment >= kMaxColorAttachments) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"Fragment output location over limits in the SPIRV"); "Fragment output attachment index must be less than max number of color "
"attachments");
} }
ColorAttachmentIndex attachment(static_cast<uint8_t>(unsanitizedAttachment));
spirv_cross::SPIRType::BaseType shaderFragmentOutputBaseType = spirv_cross::SPIRType::BaseType shaderFragmentOutputBaseType =
compiler.get_type(fragmentOutput.base_type_id).basetype; compiler.get_type(fragmentOutput.base_type_id).basetype;
@ -886,7 +888,7 @@ namespace dawn_native {
if (formatType == Format::Type::Other) { if (formatType == Format::Type::Other) {
return DAWN_VALIDATION_ERROR("Unexpected Fragment output type"); return DAWN_VALIDATION_ERROR("Unexpected Fragment output type");
} }
metadata->fragmentOutputFormatBaseTypes[location] = formatType; metadata->fragmentOutputFormatBaseTypes[attachment] = formatType;
} }
} }

View File

@ -22,6 +22,7 @@
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/Format.h" #include "dawn_native/Format.h"
#include "dawn_native/Forward.h" #include "dawn_native/Forward.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/PerStage.h" #include "dawn_native/PerStage.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
@ -77,7 +78,8 @@ namespace dawn_native {
// An array to record the basic types (float, int and uint) of the fragment shader outputs // An array to record the basic types (float, int and uint) of the fragment shader outputs
// or Format::Type::Other means the fragment shader output is unused. // or Format::Type::Other means the fragment shader output is unused.
using FragmentOutputBaseTypes = std::array<Format::Type, kMaxColorAttachments>; using FragmentOutputBaseTypes =
ityp::array<ColorAttachmentIndex, Format::Type, kMaxColorAttachments>;
FragmentOutputBaseTypes fragmentOutputFormatBaseTypes; FragmentOutputBaseTypes fragmentOutputFormatBaseTypes;
// The shader stage for this binding, TODO(dawn:216): can likely be removed once we // The shader stage for this binding, TODO(dawn:216): can likely be removed once we

View File

@ -522,7 +522,7 @@ namespace dawn_native { namespace d3d12 {
BeginRenderPassCmd* renderPass) { BeginRenderPassCmd* renderPass) {
ASSERT(renderPass != nullptr); ASSERT(renderPass != nullptr);
for (uint32_t i : for (ColorAttachmentIndex i :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
TextureViewBase* resolveTarget = TextureViewBase* resolveTarget =
renderPass->colorAttachments[i].resolveTarget.Get(); renderPass->colorAttachments[i].resolveTarget.Get();
@ -993,7 +993,8 @@ namespace dawn_native { namespace d3d12 {
RenderPassBuilder* renderPassBuilder) { RenderPassBuilder* renderPassBuilder) {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { for (ColorAttachmentIndex i :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
RenderPassColorAttachmentInfo& attachmentInfo = renderPass->colorAttachments[i]; RenderPassColorAttachmentInfo& attachmentInfo = renderPass->colorAttachments[i];
TextureView* view = ToBackend(attachmentInfo.view.Get()); TextureView* view = ToBackend(attachmentInfo.view.Get());
@ -1084,7 +1085,8 @@ namespace dawn_native { namespace d3d12 {
// Clear framebuffer attachments as needed. // Clear framebuffer attachments as needed.
{ {
for (uint32_t i = 0; i < renderPassBuilder->GetColorAttachmentCount(); i++) { for (ColorAttachmentIndex i(uint8_t(0));
i < renderPassBuilder->GetColorAttachmentCount(); i++) {
// Load op - color // Load op - color
if (renderPassBuilder->GetRenderPassRenderTargetDescriptors()[i] if (renderPassBuilder->GetRenderPassRenderTargetDescriptors()[i]
.BeginningAccess.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR) { .BeginningAccess.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR) {
@ -1128,8 +1130,8 @@ namespace dawn_native { namespace d3d12 {
} }
commandList->OMSetRenderTargets( commandList->OMSetRenderTargets(
renderPassBuilder->GetColorAttachmentCount(), renderPassBuilder->GetRenderTargetViews(), static_cast<uint8_t>(renderPassBuilder->GetColorAttachmentCount()),
FALSE, renderPassBuilder->GetRenderTargetViews(), FALSE,
renderPassBuilder->HasDepth() renderPassBuilder->HasDepth()
? &renderPassBuilder->GetRenderPassDepthStencilDescriptor()->cpuDescriptor ? &renderPassBuilder->GetRenderPassDepthStencilDescriptor()->cpuDescriptor
: nullptr); : nullptr);
@ -1153,8 +1155,8 @@ namespace dawn_native { namespace d3d12 {
// beginning and ending access operations. // beginning and ending access operations.
if (useRenderPass) { if (useRenderPass) {
commandContext->GetCommandList4()->BeginRenderPass( commandContext->GetCommandList4()->BeginRenderPass(
renderPassBuilder.GetColorAttachmentCount(), static_cast<uint8_t>(renderPassBuilder.GetColorAttachmentCount()),
renderPassBuilder.GetRenderPassRenderTargetDescriptors(), renderPassBuilder.GetRenderPassRenderTargetDescriptors().data(),
renderPassBuilder.HasDepth() renderPassBuilder.HasDepth()
? renderPassBuilder.GetRenderPassDepthStencilDescriptor() ? renderPassBuilder.GetRenderPassDepthStencilDescriptor()
: nullptr, : nullptr,

View File

@ -110,9 +110,9 @@ namespace dawn_native { namespace d3d12 {
} }
} }
void RenderPassBuilder::SetRenderTargetView(uint32_t attachmentIndex, void RenderPassBuilder::SetRenderTargetView(ColorAttachmentIndex attachmentIndex,
D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor) { D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor) {
ASSERT(mColorAttachmentCount < kMaxColorAttachments); ASSERT(mColorAttachmentCount < kMaxColorAttachmentsTyped);
mRenderTargetViews[attachmentIndex] = baseDescriptor; mRenderTargetViews[attachmentIndex] = baseDescriptor;
mRenderPassRenderTargetDescriptors[attachmentIndex].cpuDescriptor = baseDescriptor; mRenderPassRenderTargetDescriptors[attachmentIndex].cpuDescriptor = baseDescriptor;
mColorAttachmentCount++; mColorAttachmentCount++;
@ -122,7 +122,7 @@ namespace dawn_native { namespace d3d12 {
mRenderPassDepthStencilDesc.cpuDescriptor = baseDescriptor; mRenderPassDepthStencilDesc.cpuDescriptor = baseDescriptor;
} }
uint32_t RenderPassBuilder::GetColorAttachmentCount() const { ColorAttachmentIndex RenderPassBuilder::GetColorAttachmentCount() const {
return mColorAttachmentCount; return mColorAttachmentCount;
} }
@ -130,9 +130,9 @@ namespace dawn_native { namespace d3d12 {
return mHasDepth; return mHasDepth;
} }
const D3D12_RENDER_PASS_RENDER_TARGET_DESC* ityp::span<ColorAttachmentIndex, const D3D12_RENDER_PASS_RENDER_TARGET_DESC>
RenderPassBuilder::GetRenderPassRenderTargetDescriptors() const { RenderPassBuilder::GetRenderPassRenderTargetDescriptors() const {
return mRenderPassRenderTargetDescriptors.data(); return {mRenderPassRenderTargetDescriptors.data(), mColorAttachmentCount};
} }
const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC*
@ -148,7 +148,7 @@ namespace dawn_native { namespace d3d12 {
return mRenderTargetViews.data(); return mRenderTargetViews.data();
} }
void RenderPassBuilder::SetRenderTargetBeginningAccess(uint32_t attachment, void RenderPassBuilder::SetRenderTargetBeginningAccess(ColorAttachmentIndex attachment,
wgpu::LoadOp loadOp, wgpu::LoadOp loadOp,
dawn_native::Color clearColor, dawn_native::Color clearColor,
DXGI_FORMAT format) { DXGI_FORMAT format) {
@ -168,13 +168,13 @@ namespace dawn_native { namespace d3d12 {
} }
} }
void RenderPassBuilder::SetRenderTargetEndingAccess(uint32_t attachment, void RenderPassBuilder::SetRenderTargetEndingAccess(ColorAttachmentIndex attachment,
wgpu::StoreOp storeOp) { wgpu::StoreOp storeOp) {
mRenderPassRenderTargetDescriptors[attachment].EndingAccess.Type = mRenderPassRenderTargetDescriptors[attachment].EndingAccess.Type =
D3D12EndingAccessType(storeOp); D3D12EndingAccessType(storeOp);
} }
void RenderPassBuilder::SetRenderTargetEndingAccessResolve(uint32_t attachment, void RenderPassBuilder::SetRenderTargetEndingAccessResolve(ColorAttachmentIndex attachment,
wgpu::StoreOp storeOp, wgpu::StoreOp storeOp,
TextureView* resolveSource, TextureView* resolveSource,
TextureView* resolveDestination) { TextureView* resolveDestination) {

View File

@ -16,6 +16,9 @@
#define DAWNNATIVE_D3D12_RENDERPASSBUILDERD3D12_H_ #define DAWNNATIVE_D3D12_RENDERPASSBUILDERD3D12_H_
#include "common/Constants.h" #include "common/Constants.h"
#include "common/ityp_array.h"
#include "common/ityp_span.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/d3d12/d3d12_platform.h" #include "dawn_native/d3d12/d3d12_platform.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
@ -34,11 +37,12 @@ namespace dawn_native { namespace d3d12 {
public: public:
RenderPassBuilder(bool hasUAV); RenderPassBuilder(bool hasUAV);
uint32_t GetColorAttachmentCount() const; ColorAttachmentIndex GetColorAttachmentCount() const;
// Returns descriptors that are fed directly to BeginRenderPass, or are used as parameter // Returns descriptors that are fed directly to BeginRenderPass, or are used as parameter
// storage if D3D12 render pass API is unavailable. // storage if D3D12 render pass API is unavailable.
const D3D12_RENDER_PASS_RENDER_TARGET_DESC* GetRenderPassRenderTargetDescriptors() const; ityp::span<ColorAttachmentIndex, const D3D12_RENDER_PASS_RENDER_TARGET_DESC>
GetRenderPassRenderTargetDescriptors() const;
const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* GetRenderPassDepthStencilDescriptor() const; const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* GetRenderPassDepthStencilDescriptor() const;
D3D12_RENDER_PASS_FLAGS GetRenderPassFlags() const; D3D12_RENDER_PASS_FLAGS GetRenderPassFlags() const;
@ -55,12 +59,12 @@ namespace dawn_native { namespace d3d12 {
DXGI_FORMAT format); DXGI_FORMAT format);
void SetDepthNoAccess(); void SetDepthNoAccess();
void SetDepthStencilNoAccess(); void SetDepthStencilNoAccess();
void SetRenderTargetBeginningAccess(uint32_t attachment, void SetRenderTargetBeginningAccess(ColorAttachmentIndex attachment,
wgpu::LoadOp loadOp, wgpu::LoadOp loadOp,
dawn_native::Color clearColor, dawn_native::Color clearColor,
DXGI_FORMAT format); DXGI_FORMAT format);
void SetRenderTargetEndingAccess(uint32_t attachment, wgpu::StoreOp storeOp); void SetRenderTargetEndingAccess(ColorAttachmentIndex attachment, wgpu::StoreOp storeOp);
void SetRenderTargetEndingAccessResolve(uint32_t attachment, void SetRenderTargetEndingAccessResolve(ColorAttachmentIndex attachment,
wgpu::StoreOp storeOp, wgpu::StoreOp storeOp,
TextureView* resolveSource, TextureView* resolveSource,
TextureView* resolveDestination); TextureView* resolveDestination);
@ -70,20 +74,23 @@ namespace dawn_native { namespace d3d12 {
DXGI_FORMAT format); DXGI_FORMAT format);
void SetStencilNoAccess(); void SetStencilNoAccess();
void SetRenderTargetView(uint32_t attachmentIndex, void SetRenderTargetView(ColorAttachmentIndex attachmentIndex,
D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor); D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor);
void SetDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor); void SetDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor);
private: private:
uint32_t mColorAttachmentCount = 0; ColorAttachmentIndex mColorAttachmentCount{uint8_t(0)};
bool mHasDepth = false; bool mHasDepth = false;
D3D12_RENDER_PASS_FLAGS mRenderPassFlags = D3D12_RENDER_PASS_FLAG_NONE; D3D12_RENDER_PASS_FLAGS mRenderPassFlags = D3D12_RENDER_PASS_FLAG_NONE;
D3D12_RENDER_PASS_DEPTH_STENCIL_DESC mRenderPassDepthStencilDesc; D3D12_RENDER_PASS_DEPTH_STENCIL_DESC mRenderPassDepthStencilDesc;
std::array<D3D12_RENDER_PASS_RENDER_TARGET_DESC, kMaxColorAttachments> ityp::
mRenderPassRenderTargetDescriptors; array<ColorAttachmentIndex, D3D12_RENDER_PASS_RENDER_TARGET_DESC, kMaxColorAttachments>
std::array<D3D12_CPU_DESCRIPTOR_HANDLE, kMaxColorAttachments> mRenderTargetViews; mRenderPassRenderTargetDescriptors;
std::array<D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS, ityp::array<ColorAttachmentIndex, D3D12_CPU_DESCRIPTOR_HANDLE, kMaxColorAttachments>
kMaxColorAttachments> mRenderTargetViews;
ityp::array<ColorAttachmentIndex,
D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS,
kMaxColorAttachments>
mSubresourceParams; mSubresourceParams;
}; };
}} // namespace dawn_native::d3d12 }} // namespace dawn_native::d3d12

View File

@ -376,9 +376,10 @@ namespace dawn_native { namespace d3d12 {
descriptorD3D12.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat()); descriptorD3D12.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat());
} }
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
descriptorD3D12.RTVFormats[i] = D3D12TextureFormat(GetColorAttachmentFormat(i)); descriptorD3D12.RTVFormats[static_cast<uint8_t>(i)] =
descriptorD3D12.BlendState.RenderTarget[i] = D3D12TextureFormat(GetColorAttachmentFormat(i));
descriptorD3D12.BlendState.RenderTarget[static_cast<uint8_t>(i)] =
ComputeColorDesc(GetColorStateDescriptor(i)); ComputeColorDesc(GetColorStateDescriptor(i));
} }
descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count()); descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());

View File

@ -56,9 +56,10 @@ namespace dawn_native { namespace metal {
MTLRenderPassDescriptor* CreateMTLRenderPassDescriptor(BeginRenderPassCmd* renderPass) { MTLRenderPassDescriptor* CreateMTLRenderPassDescriptor(BeginRenderPassCmd* renderPass) {
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor]; MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
for (uint32_t i : for (ColorAttachmentIndex attachment :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
auto& attachmentInfo = renderPass->colorAttachments[i]; uint8_t i = static_cast<uint8_t>(attachment);
auto& attachmentInfo = renderPass->colorAttachments[attachment];
switch (attachmentInfo.loadOp) { switch (attachmentInfo.loadOp) {
case wgpu::LoadOp::Clear: case wgpu::LoadOp::Clear:

View File

@ -370,12 +370,12 @@ namespace dawn_native { namespace metal {
const EntryPointMetadata::FragmentOutputBaseTypes& fragmentOutputBaseTypes = const EntryPointMetadata::FragmentOutputBaseTypes& fragmentOutputBaseTypes =
GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputFormatBaseTypes; GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputFormatBaseTypes;
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
descriptorMTL.colorAttachments[i].pixelFormat = descriptorMTL.colorAttachments[static_cast<uint8_t>(i)].pixelFormat =
MetalPixelFormat(GetColorAttachmentFormat(i)); MetalPixelFormat(GetColorAttachmentFormat(i));
const ColorStateDescriptor* descriptor = GetColorStateDescriptor(i); const ColorStateDescriptor* descriptor = GetColorStateDescriptor(i);
bool isDeclaredInFragmentShader = fragmentOutputBaseTypes[i] != Format::Type::Other; bool isDeclaredInFragmentShader = fragmentOutputBaseTypes[i] != Format::Type::Other;
ComputeBlendDesc(descriptorMTL.colorAttachments[i], descriptor, ComputeBlendDesc(descriptorMTL.colorAttachments[static_cast<uint8_t>(i)], descriptor,
isDeclaredInFragmentShader); isDeclaredInFragmentShader);
} }

View File

@ -370,7 +370,7 @@ namespace dawn_native { namespace opengl {
GLuint readFbo = 0; GLuint readFbo = 0;
GLuint writeFbo = 0; GLuint writeFbo = 0;
for (uint32_t i : for (ColorAttachmentIndex i :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
if (renderPass->colorAttachments[i].resolveTarget.Get() != nullptr) { if (renderPass->colorAttachments[i].resolveTarget.Get() != nullptr) {
if (readFbo == 0) { if (readFbo == 0) {
@ -854,30 +854,33 @@ namespace dawn_native { namespace opengl {
// Mapping from attachmentSlot to GL framebuffer attachment points. Defaults to zero // Mapping from attachmentSlot to GL framebuffer attachment points. Defaults to zero
// (GL_NONE). // (GL_NONE).
std::array<GLenum, kMaxColorAttachments> drawBuffers = {}; ityp::array<ColorAttachmentIndex, GLenum, kMaxColorAttachments> drawBuffers = {};
// Construct GL framebuffer // Construct GL framebuffer
unsigned int attachmentCount = 0; ColorAttachmentIndex attachmentCount(uint8_t(0));
for (uint32_t i : for (ColorAttachmentIndex i :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
TextureViewBase* textureView = renderPass->colorAttachments[i].view.Get(); TextureViewBase* textureView = renderPass->colorAttachments[i].view.Get();
GLuint texture = ToBackend(textureView->GetTexture())->GetHandle(); GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
GLenum glAttachment = GL_COLOR_ATTACHMENT0 + static_cast<uint8_t>(i);
// Attach color buffers. // Attach color buffers.
if (textureView->GetTexture()->GetArrayLayers() == 1) { if (textureView->GetTexture()->GetArrayLayers() == 1) {
GLenum target = ToBackend(textureView->GetTexture())->GetGLTarget(); GLenum target = ToBackend(textureView->GetTexture())->GetGLTarget();
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, target, gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, target, texture,
texture, textureView->GetBaseMipLevel()); textureView->GetBaseMipLevel());
} else { } else {
gl.FramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, gl.FramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, glAttachment, texture,
texture, textureView->GetBaseMipLevel(), textureView->GetBaseMipLevel(),
textureView->GetBaseArrayLayer()); textureView->GetBaseArrayLayer());
} }
drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i; drawBuffers[i] = glAttachment;
attachmentCount = i + 1; attachmentCount = i;
attachmentCount++;
} }
gl.DrawBuffers(attachmentCount, drawBuffers.data()); gl.DrawBuffers(static_cast<uint8_t>(attachmentCount), drawBuffers.data());
if (renderPass->attachmentState->HasDepthStencilAttachment()) { if (renderPass->attachmentState->HasDepthStencilAttachment()) {
TextureViewBase* textureView = renderPass->depthStencilAttachment.view.Get(); TextureViewBase* textureView = renderPass->depthStencilAttachment.view.Get();
@ -922,9 +925,10 @@ namespace dawn_native { namespace opengl {
// Clear framebuffer attachments as needed // Clear framebuffer attachments as needed
{ {
for (uint32_t i : for (ColorAttachmentIndex index :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
auto* attachmentInfo = &renderPass->colorAttachments[i]; uint8_t i = static_cast<uint8_t>(index);
auto* attachmentInfo = &renderPass->colorAttachments[index];
// Load op - color // Load op - color
if (attachmentInfo->loadOp == wgpu::LoadOp::Clear) { if (attachmentInfo->loadOp == wgpu::LoadOp::Clear) {

View File

@ -109,21 +109,23 @@ namespace dawn_native { namespace opengl {
} }
void ApplyColorState(const OpenGLFunctions& gl, void ApplyColorState(const OpenGLFunctions& gl,
uint32_t attachment, ColorAttachmentIndex attachment,
const ColorStateDescriptor* descriptor) { const ColorStateDescriptor* descriptor) {
GLuint colorBuffer = static_cast<GLuint>(static_cast<uint8_t>(attachment));
if (BlendEnabled(descriptor)) { if (BlendEnabled(descriptor)) {
gl.Enablei(GL_BLEND, attachment); gl.Enablei(GL_BLEND, colorBuffer);
gl.BlendEquationSeparatei(attachment, GLBlendMode(descriptor->colorBlend.operation), gl.BlendEquationSeparatei(colorBuffer,
GLBlendMode(descriptor->colorBlend.operation),
GLBlendMode(descriptor->alphaBlend.operation)); GLBlendMode(descriptor->alphaBlend.operation));
gl.BlendFuncSeparatei(attachment, gl.BlendFuncSeparatei(colorBuffer,
GLBlendFactor(descriptor->colorBlend.srcFactor, false), GLBlendFactor(descriptor->colorBlend.srcFactor, false),
GLBlendFactor(descriptor->colorBlend.dstFactor, false), GLBlendFactor(descriptor->colorBlend.dstFactor, false),
GLBlendFactor(descriptor->alphaBlend.srcFactor, true), GLBlendFactor(descriptor->alphaBlend.srcFactor, true),
GLBlendFactor(descriptor->alphaBlend.dstFactor, true)); GLBlendFactor(descriptor->alphaBlend.dstFactor, true));
} else { } else {
gl.Disablei(GL_BLEND, attachment); gl.Disablei(GL_BLEND, colorBuffer);
} }
gl.ColorMaski(attachment, descriptor->writeMask & wgpu::ColorWriteMask::Red, gl.ColorMaski(colorBuffer, descriptor->writeMask & wgpu::ColorWriteMask::Red,
descriptor->writeMask & wgpu::ColorWriteMask::Green, descriptor->writeMask & wgpu::ColorWriteMask::Green,
descriptor->writeMask & wgpu::ColorWriteMask::Blue, descriptor->writeMask & wgpu::ColorWriteMask::Blue,
descriptor->writeMask & wgpu::ColorWriteMask::Alpha); descriptor->writeMask & wgpu::ColorWriteMask::Alpha);
@ -265,7 +267,7 @@ namespace dawn_native { namespace opengl {
gl.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE); gl.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
} }
for (uint32_t attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
ApplyColorState(gl, attachmentSlot, GetColorStateDescriptor(attachmentSlot)); ApplyColorState(gl, attachmentSlot, GetColorStateDescriptor(attachmentSlot));
} }
} }

View File

@ -232,7 +232,7 @@ namespace dawn_native { namespace vulkan {
{ {
RenderPassCacheQuery query; RenderPassCacheQuery query;
for (uint32_t i : for (ColorAttachmentIndex i :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
const auto& attachmentInfo = renderPass->colorAttachments[i]; const auto& attachmentInfo = renderPass->colorAttachments[i];
@ -264,7 +264,7 @@ namespace dawn_native { namespace vulkan {
// Fill in the attachment info that will be chained in the framebuffer create info. // Fill in the attachment info that will be chained in the framebuffer create info.
std::array<VkImageView, kMaxColorAttachments * 2 + 1> attachments; std::array<VkImageView, kMaxColorAttachments * 2 + 1> attachments;
for (uint32_t i : for (ColorAttachmentIndex i :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
auto& attachmentInfo = renderPass->colorAttachments[i]; auto& attachmentInfo = renderPass->colorAttachments[i];
TextureView* view = ToBackend(attachmentInfo.view.Get()); TextureView* view = ToBackend(attachmentInfo.view.Get());
@ -308,7 +308,7 @@ namespace dawn_native { namespace vulkan {
attachmentCount++; attachmentCount++;
} }
for (uint32_t i : for (ColorAttachmentIndex i :
IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
if (renderPass->colorAttachments[i].resolveTarget.Get() != nullptr) { if (renderPass->colorAttachments[i].resolveTarget.Get() != nullptr) {
TextureView* view = TextureView* view =

View File

@ -37,7 +37,7 @@ namespace dawn_native { namespace vulkan {
// RenderPassCacheQuery // RenderPassCacheQuery
void RenderPassCacheQuery::SetColor(uint32_t index, void RenderPassCacheQuery::SetColor(ColorAttachmentIndex index,
wgpu::TextureFormat format, wgpu::TextureFormat format,
wgpu::LoadOp loadOp, wgpu::LoadOp loadOp,
bool hasResolveTarget) { bool hasResolveTarget) {
@ -94,13 +94,13 @@ namespace dawn_native { namespace vulkan {
// Contains the attachment description that will be chained in the create info // Contains the attachment description that will be chained in the create info
// The order of all attachments in attachmentDescs is "color-depthstencil-resolve". // The order of all attachments in attachmentDescs is "color-depthstencil-resolve".
constexpr uint32_t kMaxAttachmentCount = kMaxColorAttachments * 2 + 1; constexpr uint8_t kMaxAttachmentCount = kMaxColorAttachments * 2 + 1;
std::array<VkAttachmentDescription, kMaxAttachmentCount> attachmentDescs = {}; std::array<VkAttachmentDescription, kMaxAttachmentCount> attachmentDescs = {};
VkSampleCountFlagBits vkSampleCount = VulkanSampleCount(query.sampleCount); VkSampleCountFlagBits vkSampleCount = VulkanSampleCount(query.sampleCount);
uint32_t colorAttachmentIndex = 0; uint32_t colorAttachmentIndex = 0;
for (uint32_t i : IterateBitSet(query.colorMask)) { for (ColorAttachmentIndex i : IterateBitSet(query.colorMask)) {
auto& attachmentRef = colorAttachmentRefs[colorAttachmentIndex]; auto& attachmentRef = colorAttachmentRefs[colorAttachmentIndex];
auto& attachmentDesc = attachmentDescs[colorAttachmentIndex]; auto& attachmentDesc = attachmentDescs[colorAttachmentIndex];
@ -142,7 +142,7 @@ namespace dawn_native { namespace vulkan {
} }
uint32_t resolveAttachmentIndex = 0; uint32_t resolveAttachmentIndex = 0;
for (uint32_t i : IterateBitSet(query.resolveTargetMask)) { for (ColorAttachmentIndex i : IterateBitSet(query.resolveTargetMask)) {
auto& attachmentRef = resolveAttachmentRefs[resolveAttachmentIndex]; auto& attachmentRef = resolveAttachmentRefs[resolveAttachmentIndex];
auto& attachmentDesc = attachmentDescs[attachmentCount]; auto& attachmentDesc = attachmentDescs[attachmentCount];
@ -211,7 +211,7 @@ namespace dawn_native { namespace vulkan {
HashCombine(&hash, Hash(query.resolveTargetMask)); HashCombine(&hash, Hash(query.resolveTargetMask));
for (uint32_t i : IterateBitSet(query.colorMask)) { for (ColorAttachmentIndex i : IterateBitSet(query.colorMask)) {
HashCombine(&hash, query.colorFormats[i], query.colorLoadOp[i]); HashCombine(&hash, query.colorFormats[i], query.colorLoadOp[i]);
} }
@ -239,7 +239,7 @@ namespace dawn_native { namespace vulkan {
return false; return false;
} }
for (uint32_t i : IterateBitSet(a.colorMask)) { for (ColorAttachmentIndex i : IterateBitSet(a.colorMask)) {
if ((a.colorFormats[i] != b.colorFormats[i]) || if ((a.colorFormats[i] != b.colorFormats[i]) ||
(a.colorLoadOp[i] != b.colorLoadOp[i])) { (a.colorLoadOp[i] != b.colorLoadOp[i])) {
return false; return false;

View File

@ -16,8 +16,11 @@
#define DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_ #define DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_
#include "common/Constants.h" #include "common/Constants.h"
#include "common/ityp_array.h"
#include "common/ityp_bitset.h"
#include "common/vulkan_platform.h" #include "common/vulkan_platform.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
#include <array> #include <array>
@ -34,7 +37,7 @@ namespace dawn_native { namespace vulkan {
struct RenderPassCacheQuery { struct RenderPassCacheQuery {
// Use these helpers to build the query, they make sure all relevant data is initialized and // Use these helpers to build the query, they make sure all relevant data is initialized and
// masks set. // masks set.
void SetColor(uint32_t index, void SetColor(ColorAttachmentIndex index,
wgpu::TextureFormat format, wgpu::TextureFormat format,
wgpu::LoadOp loadOp, wgpu::LoadOp loadOp,
bool hasResolveTarget); bool hasResolveTarget);
@ -43,10 +46,10 @@ namespace dawn_native { namespace vulkan {
wgpu::LoadOp stencilLoadOp); wgpu::LoadOp stencilLoadOp);
void SetSampleCount(uint32_t sampleCount); void SetSampleCount(uint32_t sampleCount);
std::bitset<kMaxColorAttachments> colorMask; ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> colorMask;
std::bitset<kMaxColorAttachments> resolveTargetMask; ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> resolveTargetMask;
std::array<wgpu::TextureFormat, kMaxColorAttachments> colorFormats; ityp::array<ColorAttachmentIndex, wgpu::TextureFormat, kMaxColorAttachments> colorFormats;
std::array<wgpu::LoadOp, kMaxColorAttachments> colorLoadOp; ityp::array<ColorAttachmentIndex, wgpu::LoadOp, kMaxColorAttachments> colorLoadOp;
bool hasDepthStencil = false; bool hasDepthStencil = false;
wgpu::TextureFormat depthStencilFormat; wgpu::TextureFormat depthStencilFormat;

View File

@ -424,10 +424,11 @@ namespace dawn_native { namespace vulkan {
// Initialize the "blend state info" that will be chained in the "create info" from the data // Initialize the "blend state info" that will be chained in the "create info" from the data
// pre-computed in the ColorState // pre-computed in the ColorState
std::array<VkPipelineColorBlendAttachmentState, kMaxColorAttachments> colorBlendAttachments; ityp::array<ColorAttachmentIndex, VkPipelineColorBlendAttachmentState, kMaxColorAttachments>
colorBlendAttachments;
const EntryPointMetadata::FragmentOutputBaseTypes& fragmentOutputBaseTypes = const EntryPointMetadata::FragmentOutputBaseTypes& fragmentOutputBaseTypes =
GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputFormatBaseTypes; GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputFormatBaseTypes;
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
const ColorStateDescriptor* colorStateDescriptor = GetColorStateDescriptor(i); const ColorStateDescriptor* colorStateDescriptor = GetColorStateDescriptor(i);
bool isDeclaredInFragmentShader = fragmentOutputBaseTypes[i] != Format::Type::Other; bool isDeclaredInFragmentShader = fragmentOutputBaseTypes[i] != Format::Type::Other;
colorBlendAttachments[i] = colorBlendAttachments[i] =
@ -469,7 +470,7 @@ namespace dawn_native { namespace vulkan {
{ {
RenderPassCacheQuery query; RenderPassCacheQuery query;
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
query.SetColor(i, GetColorAttachmentFormat(i), wgpu::LoadOp::Load, false); query.SetColor(i, GetColorAttachmentFormat(i), wgpu::LoadOp::Load, false);
} }

View File

@ -99,11 +99,10 @@ TEST_F(ShaderModuleValidationTest, FragmentOutputLocationExceedsMaxColorAttachme
std::ostringstream stream; std::ostringstream stream;
stream << R"(#version 450 stream << R"(#version 450
layout(location = )" layout(location = )"
<< kMaxColorAttachments << R"() out vec4 fragColor; << static_cast<unsigned>(kMaxColorAttachments) << R"() out vec4 fragColor;
void main() { void main() {
fragColor = vec4(0.0, 1.0, 0.0, 1.0); fragColor = vec4(0.0, 1.0, 0.0, 1.0);
})"; })";
ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment,
stream.str().c_str())); stream.str().c_str()));
} }