Update RenderPipelineBase to stop depending on deprecated struct types

Bug: dawn:642
Change-Id: Ibc9d8f87735864dcafb3ec68013e4590602af855
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/45360
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Brandon Jones 2021-03-22 22:17:26 +00:00 committed by Commit Bot service account
parent a9439199b7
commit 97da45c373
10 changed files with 337 additions and 264 deletions

View File

@ -127,10 +127,8 @@ namespace dawn_native {
} }
if (aspects[VALIDATION_ASPECT_INDEX_BUFFER] && mIndexBufferSet) { if (aspects[VALIDATION_ASPECT_INDEX_BUFFER] && mIndexBufferSet) {
wgpu::IndexFormat pipelineIndexFormat =
mLastRenderPipeline->GetVertexStateDescriptor()->indexFormat;
if (!IsStripPrimitiveTopology(mLastRenderPipeline->GetPrimitiveTopology()) || if (!IsStripPrimitiveTopology(mLastRenderPipeline->GetPrimitiveTopology()) ||
mIndexFormat == pipelineIndexFormat) { mIndexFormat == mLastRenderPipeline->GetStripIndexFormat()) {
mAspects.set(VALIDATION_ASPECT_INDEX_BUFFER); mAspects.set(VALIDATION_ASPECT_INDEX_BUFFER);
} }
} }
@ -142,8 +140,7 @@ namespace dawn_native {
} }
if (aspects[VALIDATION_ASPECT_INDEX_BUFFER]) { if (aspects[VALIDATION_ASPECT_INDEX_BUFFER]) {
wgpu::IndexFormat pipelineIndexFormat = wgpu::IndexFormat pipelineIndexFormat = mLastRenderPipeline->GetStripIndexFormat();
mLastRenderPipeline->GetVertexStateDescriptor()->indexFormat;
if (!mIndexBufferSet) { if (!mIndexBufferSet) {
return DAWN_VALIDATION_ERROR("Missing index buffer"); return DAWN_VALIDATION_ERROR("Missing index buffer");
} else if (IsStripPrimitiveTopology(mLastRenderPipeline->GetPrimitiveTopology()) && } else if (IsStripPrimitiveTopology(mLastRenderPipeline->GetPrimitiveTopology()) &&

View File

@ -302,15 +302,15 @@ namespace dawn_native {
return {}; return {};
} }
bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState) { bool StencilTestEnabled(const DepthStencilState* mDepthStencil) {
return mDepthStencilState->stencilBack.compare != wgpu::CompareFunction::Always || return mDepthStencil->stencilBack.compare != wgpu::CompareFunction::Always ||
mDepthStencilState->stencilBack.failOp != wgpu::StencilOperation::Keep || mDepthStencil->stencilBack.failOp != wgpu::StencilOperation::Keep ||
mDepthStencilState->stencilBack.depthFailOp != wgpu::StencilOperation::Keep || mDepthStencil->stencilBack.depthFailOp != wgpu::StencilOperation::Keep ||
mDepthStencilState->stencilBack.passOp != wgpu::StencilOperation::Keep || mDepthStencil->stencilBack.passOp != wgpu::StencilOperation::Keep ||
mDepthStencilState->stencilFront.compare != wgpu::CompareFunction::Always || mDepthStencil->stencilFront.compare != wgpu::CompareFunction::Always ||
mDepthStencilState->stencilFront.failOp != wgpu::StencilOperation::Keep || mDepthStencil->stencilFront.failOp != wgpu::StencilOperation::Keep ||
mDepthStencilState->stencilFront.depthFailOp != wgpu::StencilOperation::Keep || mDepthStencil->stencilFront.depthFailOp != wgpu::StencilOperation::Keep ||
mDepthStencilState->stencilFront.passOp != wgpu::StencilOperation::Keep; mDepthStencil->stencilFront.passOp != wgpu::StencilOperation::Keep;
} }
bool BlendEnabled(const ColorStateDescriptor* mColorState) { bool BlendEnabled(const ColorStateDescriptor* mColorState) {
@ -330,71 +330,104 @@ namespace dawn_native {
descriptor->layout, descriptor->layout,
{{SingleShaderStage::Vertex, &descriptor->vertexStage}, {{SingleShaderStage::Vertex, &descriptor->vertexStage},
{SingleShaderStage::Fragment, descriptor->fragmentStage}}), {SingleShaderStage::Fragment, descriptor->fragmentStage}}),
mAttachmentState(device->GetOrCreateAttachmentState(descriptor)), mAttachmentState(device->GetOrCreateAttachmentState(descriptor)) {
mPrimitiveTopology(descriptor->primitiveTopology), mPrimitive.topology = descriptor->primitiveTopology;
mSampleMask(descriptor->sampleMask),
mAlphaToCoverageEnabled(descriptor->alphaToCoverageEnabled) { mMultisample.count = descriptor->sampleCount;
mMultisample.mask = descriptor->sampleMask;
mMultisample.alphaToCoverageEnabled = descriptor->alphaToCoverageEnabled;
if (descriptor->vertexState != nullptr) { if (descriptor->vertexState != nullptr) {
mVertexState = *descriptor->vertexState; const VertexStateDescriptor& vertexState = *descriptor->vertexState;
} else { mVertexBufferCount = vertexState.vertexBufferCount;
mVertexState = VertexStateDescriptor(); mPrimitive.stripIndexFormat = vertexState.indexFormat;
}
for (uint8_t slot = 0; slot < mVertexState.vertexBufferCount; ++slot) { for (uint8_t slot = 0; slot < mVertexBufferCount; ++slot) {
if (mVertexState.vertexBuffers[slot].attributeCount == 0) { if (vertexState.vertexBuffers[slot].attributeCount == 0) {
continue; continue;
}
VertexBufferSlot typedSlot(slot);
mVertexBufferSlotsUsed.set(typedSlot);
mVertexBufferInfos[typedSlot].arrayStride =
vertexState.vertexBuffers[slot].arrayStride;
mVertexBufferInfos[typedSlot].stepMode = vertexState.vertexBuffers[slot].stepMode;
for (uint32_t i = 0; i < vertexState.vertexBuffers[slot].attributeCount; ++i) {
VertexAttributeLocation location = VertexAttributeLocation(static_cast<uint8_t>(
vertexState.vertexBuffers[slot].attributes[i].shaderLocation));
mAttributeLocationsUsed.set(location);
mAttributeInfos[location].shaderLocation = location;
mAttributeInfos[location].vertexBufferSlot = typedSlot;
mAttributeInfos[location].offset =
vertexState.vertexBuffers[slot].attributes[i].offset;
mAttributeInfos[location].format = dawn::NormalizeVertexFormat(
vertexState.vertexBuffers[slot].attributes[i].format);
}
} }
VertexBufferSlot typedSlot(slot);
mVertexBufferSlotsUsed.set(typedSlot);
mVertexBufferInfos[typedSlot].arrayStride =
mVertexState.vertexBuffers[slot].arrayStride;
mVertexBufferInfos[typedSlot].stepMode = mVertexState.vertexBuffers[slot].stepMode;
for (uint32_t i = 0; i < mVertexState.vertexBuffers[slot].attributeCount; ++i) {
VertexAttributeLocation location = VertexAttributeLocation(static_cast<uint8_t>(
mVertexState.vertexBuffers[slot].attributes[i].shaderLocation));
mAttributeLocationsUsed.set(location);
mAttributeInfos[location].shaderLocation = location;
mAttributeInfos[location].vertexBufferSlot = typedSlot;
mAttributeInfos[location].offset =
mVertexState.vertexBuffers[slot].attributes[i].offset;
mAttributeInfos[location].format = dawn::NormalizeVertexFormat(
mVertexState.vertexBuffers[slot].attributes[i].format);
}
}
if (descriptor->rasterizationState != nullptr) {
mRasterizationState = *descriptor->rasterizationState;
} else { } else {
mRasterizationState = RasterizationStateDescriptor(); mVertexBufferCount = 0;
mPrimitive.stripIndexFormat = wgpu::IndexFormat::Undefined;
} }
if (mAttachmentState->HasDepthStencilAttachment()) { if (mAttachmentState->HasDepthStencilAttachment()) {
mDepthStencilState = *descriptor->depthStencilState; const DepthStencilStateDescriptor& depthStencil = *descriptor->depthStencilState;
mDepthStencil.format = depthStencil.format;
mDepthStencil.depthWriteEnabled = depthStencil.depthWriteEnabled;
mDepthStencil.depthCompare = depthStencil.depthCompare;
mDepthStencil.stencilBack = depthStencil.stencilBack;
mDepthStencil.stencilFront = depthStencil.stencilFront;
mDepthStencil.stencilReadMask = depthStencil.stencilReadMask;
mDepthStencil.stencilWriteMask = depthStencil.stencilWriteMask;
} else { } else {
// These default values below are useful for backends to fill information. // These default values below are useful for backends to fill information.
// The values indicate that depth and stencil test are disabled when backends // The values indicate that depth and stencil test are disabled when backends
// set their own depth stencil states/descriptors according to the values in // set their own depth stencil states/descriptors according to the values in
// mDepthStencilState. // mDepthStencil.
mDepthStencilState.depthCompare = wgpu::CompareFunction::Always; mDepthStencil.format = wgpu::TextureFormat::Undefined;
mDepthStencilState.depthWriteEnabled = false; mDepthStencil.depthWriteEnabled = false;
mDepthStencilState.stencilBack.compare = wgpu::CompareFunction::Always; mDepthStencil.depthCompare = wgpu::CompareFunction::Always;
mDepthStencilState.stencilBack.failOp = wgpu::StencilOperation::Keep; mDepthStencil.stencilBack.compare = wgpu::CompareFunction::Always;
mDepthStencilState.stencilBack.depthFailOp = wgpu::StencilOperation::Keep; mDepthStencil.stencilBack.failOp = wgpu::StencilOperation::Keep;
mDepthStencilState.stencilBack.passOp = wgpu::StencilOperation::Keep; mDepthStencil.stencilBack.depthFailOp = wgpu::StencilOperation::Keep;
mDepthStencilState.stencilFront.compare = wgpu::CompareFunction::Always; mDepthStencil.stencilBack.passOp = wgpu::StencilOperation::Keep;
mDepthStencilState.stencilFront.failOp = wgpu::StencilOperation::Keep; mDepthStencil.stencilFront.compare = wgpu::CompareFunction::Always;
mDepthStencilState.stencilFront.depthFailOp = wgpu::StencilOperation::Keep; mDepthStencil.stencilFront.failOp = wgpu::StencilOperation::Keep;
mDepthStencilState.stencilFront.passOp = wgpu::StencilOperation::Keep; mDepthStencil.stencilFront.depthFailOp = wgpu::StencilOperation::Keep;
mDepthStencilState.stencilReadMask = 0xff; mDepthStencil.stencilFront.passOp = wgpu::StencilOperation::Keep;
mDepthStencilState.stencilWriteMask = 0xff; mDepthStencil.stencilReadMask = 0xff;
mDepthStencil.stencilWriteMask = 0xff;
}
if (descriptor->rasterizationState != nullptr) {
mPrimitive.frontFace = descriptor->rasterizationState->frontFace;
mPrimitive.cullMode = descriptor->rasterizationState->cullMode;
mDepthStencil.depthBias = descriptor->rasterizationState->depthBias;
mDepthStencil.depthBiasSlopeScale = descriptor->rasterizationState->depthBiasSlopeScale;
mDepthStencil.depthBiasClamp = descriptor->rasterizationState->depthBiasClamp;
} else {
mPrimitive.frontFace = wgpu::FrontFace::CCW;
mPrimitive.cullMode = wgpu::CullMode::None;
mDepthStencil.depthBias = 0;
mDepthStencil.depthBiasSlopeScale = 0.0f;
mDepthStencil.depthBiasClamp = 0.0f;
} }
for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
mColorStates[i] = descriptor->colorStates[static_cast<uint8_t>(i)]; const ColorStateDescriptor* colorState =
&descriptor->colorStates[static_cast<uint8_t>(i)];
mTargets[i].format = colorState->format;
mTargets[i].writeMask = colorState->writeMask;
if (BlendEnabled(colorState)) {
mTargetBlend[i].color = colorState->colorBlend;
mTargetBlend[i].alpha = colorState->alphaBlend;
mTargets[i].blend = &mTargetBlend[i];
} else {
mTargets[i].blend = nullptr;
}
} }
// 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
@ -416,11 +449,6 @@ namespace dawn_native {
} }
} }
const VertexStateDescriptor* RenderPipelineBase::GetVertexStateDescriptor() const {
ASSERT(!IsError());
return &mVertexState;
}
const ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes>& const ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes>&
RenderPipelineBase::GetAttributeLocationsUsed() const { RenderPipelineBase::GetAttributeLocationsUsed() const {
ASSERT(!IsError()); ASSERT(!IsError());
@ -446,51 +474,61 @@ namespace dawn_native {
return mVertexBufferInfos[slot]; return mVertexBufferInfos[slot];
} }
const ColorStateDescriptor* RenderPipelineBase::GetColorStateDescriptor( uint32_t RenderPipelineBase::GetVertexBufferCount() const {
ColorAttachmentIndex attachmentSlot) const {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(attachmentSlot < mColorStates.size()); return mVertexBufferCount;
return &mColorStates[attachmentSlot];
} }
const DepthStencilStateDescriptor* RenderPipelineBase::GetDepthStencilStateDescriptor() const { const ColorTargetState* RenderPipelineBase::GetColorTargetState(
ColorAttachmentIndex attachmentSlot) const {
ASSERT(!IsError()); ASSERT(!IsError());
return &mDepthStencilState; ASSERT(attachmentSlot < mTargets.size());
return &mTargets[attachmentSlot];
}
const DepthStencilState* RenderPipelineBase::GetDepthStencilState() const {
ASSERT(!IsError());
return &mDepthStencil;
} }
wgpu::PrimitiveTopology RenderPipelineBase::GetPrimitiveTopology() const { wgpu::PrimitiveTopology RenderPipelineBase::GetPrimitiveTopology() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mPrimitiveTopology; return mPrimitive.topology;
}
wgpu::IndexFormat RenderPipelineBase::GetStripIndexFormat() const {
ASSERT(!IsError());
return mPrimitive.stripIndexFormat;
} }
wgpu::CullMode RenderPipelineBase::GetCullMode() const { wgpu::CullMode RenderPipelineBase::GetCullMode() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mRasterizationState.cullMode; return mPrimitive.cullMode;
} }
wgpu::FrontFace RenderPipelineBase::GetFrontFace() const { wgpu::FrontFace RenderPipelineBase::GetFrontFace() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mRasterizationState.frontFace; return mPrimitive.frontFace;
} }
bool RenderPipelineBase::IsDepthBiasEnabled() const { bool RenderPipelineBase::IsDepthBiasEnabled() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mRasterizationState.depthBias != 0 || mRasterizationState.depthBiasSlopeScale != 0; return mDepthStencil.depthBias != 0 || mDepthStencil.depthBiasSlopeScale != 0;
} }
int32_t RenderPipelineBase::GetDepthBias() const { int32_t RenderPipelineBase::GetDepthBias() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mRasterizationState.depthBias; return mDepthStencil.depthBias;
} }
float RenderPipelineBase::GetDepthBiasSlopeScale() const { float RenderPipelineBase::GetDepthBiasSlopeScale() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mRasterizationState.depthBiasSlopeScale; return mDepthStencil.depthBiasSlopeScale;
} }
float RenderPipelineBase::GetDepthBiasClamp() const { float RenderPipelineBase::GetDepthBiasClamp() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mRasterizationState.depthBiasClamp; return mDepthStencil.depthBiasClamp;
} }
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
@ -507,13 +545,13 @@ namespace dawn_native {
wgpu::TextureFormat RenderPipelineBase::GetColorAttachmentFormat( wgpu::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(
ColorAttachmentIndex attachment) const { ColorAttachmentIndex attachment) const {
ASSERT(!IsError()); ASSERT(!IsError());
return mColorStates[attachment].format; return mTargets[attachment].format;
} }
wgpu::TextureFormat RenderPipelineBase::GetDepthStencilFormat() const { wgpu::TextureFormat RenderPipelineBase::GetDepthStencilFormat() const {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(mAttachmentState->HasDepthStencilAttachment()); ASSERT(mAttachmentState->HasDepthStencilAttachment());
return mDepthStencilState.format; return mDepthStencil.format;
} }
uint32_t RenderPipelineBase::GetSampleCount() const { uint32_t RenderPipelineBase::GetSampleCount() const {
@ -523,12 +561,12 @@ namespace dawn_native {
uint32_t RenderPipelineBase::GetSampleMask() const { uint32_t RenderPipelineBase::GetSampleMask() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mSampleMask; return mMultisample.mask;
} }
bool RenderPipelineBase::IsAlphaToCoverageEnabled() const { bool RenderPipelineBase::IsAlphaToCoverageEnabled() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mAlphaToCoverageEnabled; return mMultisample.alphaToCoverageEnabled;
} }
const AttachmentState* RenderPipelineBase::GetAttachmentState() const { const AttachmentState* RenderPipelineBase::GetAttachmentState() const {
@ -549,22 +587,25 @@ namespace dawn_native {
// Record attachments // Record attachments
for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
const ColorStateDescriptor& desc = *GetColorStateDescriptor(i); const ColorTargetState& desc = *GetColorTargetState(i);
recorder.Record(desc.writeMask); recorder.Record(desc.writeMask);
recorder.Record(desc.colorBlend.operation, desc.colorBlend.srcFactor, if (desc.blend != nullptr) {
desc.colorBlend.dstFactor); recorder.Record(desc.blend->color.operation, desc.blend->color.srcFactor,
recorder.Record(desc.alphaBlend.operation, desc.alphaBlend.srcFactor, desc.blend->color.dstFactor);
desc.alphaBlend.dstFactor); recorder.Record(desc.blend->alpha.operation, desc.blend->alpha.srcFactor,
desc.blend->alpha.dstFactor);
}
} }
if (mAttachmentState->HasDepthStencilAttachment()) { if (mAttachmentState->HasDepthStencilAttachment()) {
const DepthStencilStateDescriptor& desc = mDepthStencilState; const DepthStencilState& desc = mDepthStencil;
recorder.Record(desc.depthWriteEnabled, desc.depthCompare); recorder.Record(desc.depthWriteEnabled, desc.depthCompare);
recorder.Record(desc.stencilReadMask, desc.stencilWriteMask); recorder.Record(desc.stencilReadMask, desc.stencilWriteMask);
recorder.Record(desc.stencilFront.compare, desc.stencilFront.failOp, recorder.Record(desc.stencilFront.compare, desc.stencilFront.failOp,
desc.stencilFront.depthFailOp, desc.stencilFront.passOp); desc.stencilFront.depthFailOp, desc.stencilFront.passOp);
recorder.Record(desc.stencilBack.compare, desc.stencilBack.failOp, recorder.Record(desc.stencilBack.compare, desc.stencilBack.failOp,
desc.stencilBack.depthFailOp, desc.stencilBack.passOp); desc.stencilBack.depthFailOp, desc.stencilBack.passOp);
recorder.Record(desc.depthBias, desc.depthBiasSlopeScale, desc.depthBiasClamp);
} }
// Record vertex state // Record vertex state
@ -580,17 +621,13 @@ namespace dawn_native {
recorder.Record(desc.arrayStride, desc.stepMode); recorder.Record(desc.arrayStride, desc.stepMode);
} }
recorder.Record(mVertexState.indexFormat); // Record primitive state
recorder.Record(mPrimitive.topology, mPrimitive.stripIndexFormat, mPrimitive.frontFace,
mPrimitive.cullMode);
// Record rasterization state // Record multisample state
{ // Sample count hashed as part of the attachment state
const RasterizationStateDescriptor& desc = mRasterizationState; recorder.Record(mMultisample.mask, mMultisample.alphaToCoverageEnabled);
recorder.Record(desc.frontFace, desc.cullMode);
recorder.Record(desc.depthBias, desc.depthBiasSlopeScale, desc.depthBiasClamp);
}
// Record other state
recorder.Record(mPrimitiveTopology, mSampleMask, mAlphaToCoverageEnabled);
return recorder.GetContentHash(); return recorder.GetContentHash();
} }
@ -610,44 +647,59 @@ namespace dawn_native {
for (ColorAttachmentIndex i : for (ColorAttachmentIndex i :
IterateBitSet(a->mAttachmentState->GetColorAttachmentsMask())) { IterateBitSet(a->mAttachmentState->GetColorAttachmentsMask())) {
const ColorStateDescriptor& descA = *a->GetColorStateDescriptor(i); const ColorTargetState& descA = *a->GetColorTargetState(i);
const ColorStateDescriptor& descB = *b->GetColorStateDescriptor(i); const ColorTargetState& descB = *b->GetColorTargetState(i);
if (descA.writeMask != descB.writeMask) { if (descA.writeMask != descB.writeMask) {
return false; return false;
} }
if (descA.colorBlend.operation != descB.colorBlend.operation || if ((descA.blend == nullptr) != (descB.blend == nullptr)) {
descA.colorBlend.srcFactor != descB.colorBlend.srcFactor ||
descA.colorBlend.dstFactor != descB.colorBlend.dstFactor) {
return false; return false;
} }
if (descA.alphaBlend.operation != descB.alphaBlend.operation || if (descA.blend != nullptr) {
descA.alphaBlend.srcFactor != descB.alphaBlend.srcFactor || if (descA.blend->color.operation != descB.blend->color.operation ||
descA.alphaBlend.dstFactor != descB.alphaBlend.dstFactor) { descA.blend->color.srcFactor != descB.blend->color.srcFactor ||
return false; descA.blend->color.dstFactor != descB.blend->color.dstFactor) {
return false;
}
if (descA.blend->alpha.operation != descB.blend->alpha.operation ||
descA.blend->alpha.srcFactor != descB.blend->alpha.srcFactor ||
descA.blend->alpha.dstFactor != descB.blend->alpha.dstFactor) {
return false;
}
} }
} }
// Check depth/stencil state
if (a->mAttachmentState->HasDepthStencilAttachment()) { if (a->mAttachmentState->HasDepthStencilAttachment()) {
const DepthStencilStateDescriptor& descA = a->mDepthStencilState; const DepthStencilState& stateA = a->mDepthStencil;
const DepthStencilStateDescriptor& descB = b->mDepthStencilState; const DepthStencilState& stateB = b->mDepthStencil;
if (descA.depthWriteEnabled != descB.depthWriteEnabled ||
descA.depthCompare != descB.depthCompare) { ASSERT(!std::isnan(stateA.depthBiasSlopeScale));
ASSERT(!std::isnan(stateB.depthBiasSlopeScale));
ASSERT(!std::isnan(stateA.depthBiasClamp));
ASSERT(!std::isnan(stateB.depthBiasClamp));
if (stateA.depthWriteEnabled != stateB.depthWriteEnabled ||
stateA.depthCompare != stateB.depthCompare ||
stateA.depthBias != stateB.depthBias ||
stateA.depthBiasSlopeScale != stateB.depthBiasSlopeScale ||
stateA.depthBiasClamp != stateB.depthBiasClamp) {
return false; return false;
} }
if (descA.stencilReadMask != descB.stencilReadMask || if (stateA.stencilFront.compare != stateB.stencilFront.compare ||
descA.stencilWriteMask != descB.stencilWriteMask) { stateA.stencilFront.failOp != stateB.stencilFront.failOp ||
stateA.stencilFront.depthFailOp != stateB.stencilFront.depthFailOp ||
stateA.stencilFront.passOp != stateB.stencilFront.passOp) {
return false; return false;
} }
if (descA.stencilFront.compare != descB.stencilFront.compare || if (stateA.stencilBack.compare != stateB.stencilBack.compare ||
descA.stencilFront.failOp != descB.stencilFront.failOp || stateA.stencilBack.failOp != stateB.stencilBack.failOp ||
descA.stencilFront.depthFailOp != descB.stencilFront.depthFailOp || stateA.stencilBack.depthFailOp != stateB.stencilBack.depthFailOp ||
descA.stencilFront.passOp != descB.stencilFront.passOp) { stateA.stencilBack.passOp != stateB.stencilBack.passOp) {
return false; return false;
} }
if (descA.stencilBack.compare != descB.stencilBack.compare || if (stateA.stencilReadMask != stateB.stencilReadMask ||
descA.stencilBack.failOp != descB.stencilBack.failOp || stateA.stencilWriteMask != stateB.stencilWriteMask) {
descA.stencilBack.depthFailOp != descB.stencilBack.depthFailOp ||
descA.stencilBack.passOp != descB.stencilBack.passOp) {
return false; return false;
} }
} }
@ -679,34 +731,26 @@ namespace dawn_native {
} }
} }
if (a->mVertexState.indexFormat != b->mVertexState.indexFormat) { // Check primitive state
return false;
}
// Check rasterization state
{ {
const RasterizationStateDescriptor& descA = a->mRasterizationState; const PrimitiveState& stateA = a->mPrimitive;
const RasterizationStateDescriptor& descB = b->mRasterizationState; const PrimitiveState& stateB = b->mPrimitive;
if (descA.frontFace != descB.frontFace || descA.cullMode != descB.cullMode) { if (stateA.topology != stateB.topology ||
return false; stateA.stripIndexFormat != stateB.stripIndexFormat ||
} stateA.frontFace != stateB.frontFace || stateA.cullMode != stateB.cullMode) {
ASSERT(!std::isnan(descA.depthBiasSlopeScale));
ASSERT(!std::isnan(descB.depthBiasSlopeScale));
ASSERT(!std::isnan(descA.depthBiasClamp));
ASSERT(!std::isnan(descB.depthBiasClamp));
if (descA.depthBias != descB.depthBias ||
descA.depthBiasSlopeScale != descB.depthBiasSlopeScale ||
descA.depthBiasClamp != descB.depthBiasClamp) {
return false; return false;
} }
} }
// Check other state // Check multisample state
if (a->mPrimitiveTopology != b->mPrimitiveTopology || a->mSampleMask != b->mSampleMask || {
a->mAlphaToCoverageEnabled != b->mAlphaToCoverageEnabled) { const MultisampleState& stateA = a->mMultisample;
return false; const MultisampleState& stateB = b->mMultisample;
// Sample count already checked as part of the attachment state.
if (stateA.mask != stateB.mask ||
stateA.alphaToCoverageEnabled != stateB.alphaToCoverageEnabled) {
return false;
}
} }
return true; return true;

View File

@ -35,8 +35,7 @@ namespace dawn_native {
bool IsStripPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology); bool IsStripPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology);
bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState); bool StencilTestEnabled(const DepthStencilState* mDepthStencil);
bool BlendEnabled(const ColorStateDescriptor* mColorState);
struct VertexAttributeInfo { struct VertexAttributeInfo {
wgpu::VertexFormat format; wgpu::VertexFormat format;
@ -57,17 +56,17 @@ namespace dawn_native {
static RenderPipelineBase* MakeError(DeviceBase* device); static RenderPipelineBase* MakeError(DeviceBase* device);
const VertexStateDescriptor* GetVertexStateDescriptor() const;
const ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes>& const ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes>&
GetAttributeLocationsUsed() const; GetAttributeLocationsUsed() const;
const VertexAttributeInfo& GetAttribute(VertexAttributeLocation location) const; const VertexAttributeInfo& GetAttribute(VertexAttributeLocation location) const;
const ityp::bitset<VertexBufferSlot, kMaxVertexBuffers>& GetVertexBufferSlotsUsed() const; const ityp::bitset<VertexBufferSlot, kMaxVertexBuffers>& GetVertexBufferSlotsUsed() const;
const VertexBufferInfo& GetVertexBuffer(VertexBufferSlot slot) const; const VertexBufferInfo& GetVertexBuffer(VertexBufferSlot slot) const;
uint32_t GetVertexBufferCount() const;
const ColorStateDescriptor* GetColorStateDescriptor( const ColorTargetState* GetColorTargetState(ColorAttachmentIndex attachmentSlot) const;
ColorAttachmentIndex attachmentSlot) const; const DepthStencilState* GetDepthStencilState() const;
const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor() const;
wgpu::PrimitiveTopology GetPrimitiveTopology() const; wgpu::PrimitiveTopology GetPrimitiveTopology() const;
wgpu::IndexFormat GetStripIndexFormat() const;
wgpu::CullMode GetCullMode() const; wgpu::CullMode GetCullMode() const;
wgpu::FrontFace GetFrontFace() const; wgpu::FrontFace GetFrontFace() const;
bool IsDepthBiasEnabled() const; bool IsDepthBiasEnabled() const;
@ -96,7 +95,7 @@ namespace dawn_native {
RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag); RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag);
// Vertex state // Vertex state
VertexStateDescriptor mVertexState; uint32_t mVertexBufferCount;
ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes> mAttributeLocationsUsed; ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes> mAttributeLocationsUsed;
ityp::array<VertexAttributeLocation, VertexAttributeInfo, kMaxVertexAttributes> ityp::array<VertexAttributeLocation, VertexAttributeInfo, kMaxVertexAttributes>
mAttributeInfos; mAttributeInfos;
@ -105,14 +104,13 @@ namespace dawn_native {
// Attachments // Attachments
Ref<AttachmentState> mAttachmentState; Ref<AttachmentState> mAttachmentState;
DepthStencilStateDescriptor mDepthStencilState; ityp::array<ColorAttachmentIndex, ColorTargetState, kMaxColorAttachments> mTargets;
ityp::array<ColorAttachmentIndex, ColorStateDescriptor, kMaxColorAttachments> mColorStates; ityp::array<ColorAttachmentIndex, BlendState, kMaxColorAttachments> mTargetBlend;
// Other state // Other state
wgpu::PrimitiveTopology mPrimitiveTopology; PrimitiveState mPrimitive;
RasterizationStateDescriptor mRasterizationState; DepthStencilState mDepthStencil;
uint32_t mSampleMask; MultisampleState mMultisample;
bool mAlphaToCoverageEnabled;
}; };
} // namespace dawn_native } // namespace dawn_native

View File

@ -207,16 +207,18 @@ namespace dawn_native { namespace d3d12 {
return static_cast<uint8_t>(writeMask); return static_cast<uint8_t>(writeMask);
} }
D3D12_RENDER_TARGET_BLEND_DESC ComputeColorDesc(const ColorStateDescriptor* descriptor) { D3D12_RENDER_TARGET_BLEND_DESC ComputeColorDesc(const ColorTargetState* state) {
D3D12_RENDER_TARGET_BLEND_DESC blendDesc; D3D12_RENDER_TARGET_BLEND_DESC blendDesc;
blendDesc.BlendEnable = BlendEnabled(descriptor); blendDesc.BlendEnable = state->blend != nullptr;
blendDesc.SrcBlend = D3D12Blend(descriptor->colorBlend.srcFactor); if (blendDesc.BlendEnable) {
blendDesc.DestBlend = D3D12Blend(descriptor->colorBlend.dstFactor); blendDesc.SrcBlend = D3D12Blend(state->blend->color.srcFactor);
blendDesc.BlendOp = D3D12BlendOperation(descriptor->colorBlend.operation); blendDesc.DestBlend = D3D12Blend(state->blend->color.dstFactor);
blendDesc.SrcBlendAlpha = D3D12Blend(descriptor->alphaBlend.srcFactor); blendDesc.BlendOp = D3D12BlendOperation(state->blend->color.operation);
blendDesc.DestBlendAlpha = D3D12Blend(descriptor->alphaBlend.dstFactor); blendDesc.SrcBlendAlpha = D3D12Blend(state->blend->alpha.srcFactor);
blendDesc.BlendOpAlpha = D3D12BlendOperation(descriptor->alphaBlend.operation); blendDesc.DestBlendAlpha = D3D12Blend(state->blend->alpha.dstFactor);
blendDesc.RenderTargetWriteMask = D3D12RenderTargetWriteMask(descriptor->writeMask); blendDesc.BlendOpAlpha = D3D12BlendOperation(state->blend->alpha.operation);
}
blendDesc.RenderTargetWriteMask = D3D12RenderTargetWriteMask(state->writeMask);
blendDesc.LogicOpEnable = false; blendDesc.LogicOpEnable = false;
blendDesc.LogicOp = D3D12_LOGIC_OP_NOOP; blendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
return blendDesc; return blendDesc;
@ -254,8 +256,7 @@ namespace dawn_native { namespace d3d12 {
return desc; return desc;
} }
D3D12_DEPTH_STENCIL_DESC ComputeDepthStencilDesc( D3D12_DEPTH_STENCIL_DESC ComputeDepthStencilDesc(const DepthStencilState* descriptor) {
const DepthStencilStateDescriptor* descriptor) {
D3D12_DEPTH_STENCIL_DESC mDepthStencilDescriptor; D3D12_DEPTH_STENCIL_DESC mDepthStencilDescriptor;
mDepthStencilDescriptor.DepthEnable = TRUE; mDepthStencilDescriptor.DepthEnable = TRUE;
mDepthStencilDescriptor.DepthWriteMask = descriptor->depthWriteEnabled mDepthStencilDescriptor.DepthWriteMask = descriptor->depthWriteEnabled
@ -347,8 +348,8 @@ namespace dawn_native { namespace d3d12 {
descriptorD3D12.InputLayout = ComputeInputLayout(&inputElementDescriptors); descriptorD3D12.InputLayout = ComputeInputLayout(&inputElementDescriptors);
} }
descriptorD3D12.IBStripCutValue = ComputeIndexBufferStripCutValue( descriptorD3D12.IBStripCutValue =
GetPrimitiveTopology(), GetVertexStateDescriptor()->indexFormat); ComputeIndexBufferStripCutValue(GetPrimitiveTopology(), GetStripIndexFormat());
descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
descriptorD3D12.RasterizerState.CullMode = D3D12CullMode(GetCullMode()); descriptorD3D12.RasterizerState.CullMode = D3D12CullMode(GetCullMode());
@ -372,15 +373,14 @@ namespace dawn_native { namespace d3d12 {
descriptorD3D12.RTVFormats[static_cast<uint8_t>(i)] = descriptorD3D12.RTVFormats[static_cast<uint8_t>(i)] =
D3D12TextureFormat(GetColorAttachmentFormat(i)); D3D12TextureFormat(GetColorAttachmentFormat(i));
descriptorD3D12.BlendState.RenderTarget[static_cast<uint8_t>(i)] = descriptorD3D12.BlendState.RenderTarget[static_cast<uint8_t>(i)] =
ComputeColorDesc(GetColorStateDescriptor(i)); ComputeColorDesc(GetColorTargetState(i));
} }
descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count()); descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());
descriptorD3D12.BlendState.AlphaToCoverageEnable = descriptor->alphaToCoverageEnabled; descriptorD3D12.BlendState.AlphaToCoverageEnable = descriptor->alphaToCoverageEnabled;
descriptorD3D12.BlendState.IndependentBlendEnable = TRUE; descriptorD3D12.BlendState.IndependentBlendEnable = TRUE;
descriptorD3D12.DepthStencilState = descriptorD3D12.DepthStencilState = ComputeDepthStencilDesc(GetDepthStencilState());
ComputeDepthStencilDesc(GetDepthStencilStateDescriptor());
descriptorD3D12.SampleMask = GetSampleMask(); descriptorD3D12.SampleMask = GetSampleMask();
descriptorD3D12.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology()); descriptorD3D12.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology());

View File

@ -284,7 +284,7 @@ namespace dawn_native { namespace metal {
->GetBufferBindingCount(SingleShaderStage::Vertex); ->GetBufferBindingCount(SingleShaderStage::Vertex);
if (enableVertexPulling) { if (enableVertexPulling) {
bufferCount += pipeline->GetVertexStateDescriptor()->vertexBufferCount; bufferCount += pipeline->GetVertexBufferCount();
} }
[render setVertexBytes:data[SingleShaderStage::Vertex].data() [render setVertexBytes:data[SingleShaderStage::Vertex].data()

View File

@ -201,21 +201,23 @@ namespace dawn_native { namespace metal {
} }
void ComputeBlendDesc(MTLRenderPipelineColorAttachmentDescriptor* attachment, void ComputeBlendDesc(MTLRenderPipelineColorAttachmentDescriptor* attachment,
const ColorStateDescriptor* descriptor, const ColorTargetState* state,
bool isDeclaredInFragmentShader) { bool isDeclaredInFragmentShader) {
attachment.blendingEnabled = BlendEnabled(descriptor); attachment.blendingEnabled = state->blend != nullptr;
attachment.sourceRGBBlendFactor = if (attachment.blendingEnabled) {
MetalBlendFactor(descriptor->colorBlend.srcFactor, false); attachment.sourceRGBBlendFactor =
attachment.destinationRGBBlendFactor = MetalBlendFactor(state->blend->color.srcFactor, false);
MetalBlendFactor(descriptor->colorBlend.dstFactor, false); attachment.destinationRGBBlendFactor =
attachment.rgbBlendOperation = MetalBlendOperation(descriptor->colorBlend.operation); MetalBlendFactor(state->blend->color.dstFactor, false);
attachment.sourceAlphaBlendFactor = attachment.rgbBlendOperation = MetalBlendOperation(state->blend->color.operation);
MetalBlendFactor(descriptor->alphaBlend.srcFactor, true); attachment.sourceAlphaBlendFactor =
attachment.destinationAlphaBlendFactor = MetalBlendFactor(state->blend->alpha.srcFactor, true);
MetalBlendFactor(descriptor->alphaBlend.dstFactor, true); attachment.destinationAlphaBlendFactor =
attachment.alphaBlendOperation = MetalBlendOperation(descriptor->alphaBlend.operation); MetalBlendFactor(state->blend->alpha.dstFactor, true);
attachment.alphaBlendOperation = MetalBlendOperation(state->blend->alpha.operation);
}
attachment.writeMask = attachment.writeMask =
MetalColorWriteMask(descriptor->writeMask, isDeclaredInFragmentShader); MetalColorWriteMask(state->writeMask, isDeclaredInFragmentShader);
} }
MTLStencilOperation MetalStencilOperation(wgpu::StencilOperation stencilOperation) { MTLStencilOperation MetalStencilOperation(wgpu::StencilOperation stencilOperation) {
@ -239,8 +241,7 @@ namespace dawn_native { namespace metal {
} }
} }
NSRef<MTLDepthStencilDescriptor> MakeDepthStencilDesc( NSRef<MTLDepthStencilDescriptor> MakeDepthStencilDesc(const DepthStencilState* descriptor) {
const DepthStencilStateDescriptor* descriptor) {
NSRef<MTLDepthStencilDescriptor> mtlDepthStencilDescRef = NSRef<MTLDepthStencilDescriptor> mtlDepthStencilDescRef =
AcquireNSRef([MTLDepthStencilDescriptor new]); AcquireNSRef([MTLDepthStencilDescriptor new]);
MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = mtlDepthStencilDescRef.Get(); MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = mtlDepthStencilDescRef.Get();
@ -340,9 +341,17 @@ namespace dawn_native { namespace metal {
ShaderModule* vertexModule = ToBackend(descriptor->vertexStage.module); ShaderModule* vertexModule = ToBackend(descriptor->vertexStage.module);
const char* vertexEntryPoint = descriptor->vertexStage.entryPoint; const char* vertexEntryPoint = descriptor->vertexStage.entryPoint;
ShaderModule::MetalFunctionData vertexData; ShaderModule::MetalFunctionData vertexData;
const VertexStateDescriptor* vertexStatePtr = descriptor->vertexState;
VertexStateDescriptor vertexState;
if (vertexStatePtr == nullptr) {
vertexState = {};
vertexStatePtr = &vertexState;
}
DAWN_TRY(vertexModule->CreateFunction(vertexEntryPoint, SingleShaderStage::Vertex, DAWN_TRY(vertexModule->CreateFunction(vertexEntryPoint, SingleShaderStage::Vertex,
ToBackend(GetLayout()), &vertexData, 0xFFFFFFFF, ToBackend(GetLayout()), &vertexData, 0xFFFFFFFF, this,
this)); vertexStatePtr));
descriptorMTL.vertexFunction = vertexData.function.Get(); descriptorMTL.vertexFunction = vertexData.function.Get();
if (vertexData.needsStorageBufferLength) { if (vertexData.needsStorageBufferLength) {
@ -379,7 +388,7 @@ namespace dawn_native { namespace metal {
for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
descriptorMTL.colorAttachments[static_cast<uint8_t>(i)].pixelFormat = descriptorMTL.colorAttachments[static_cast<uint8_t>(i)].pixelFormat =
MetalPixelFormat(GetColorAttachmentFormat(i)); MetalPixelFormat(GetColorAttachmentFormat(i));
const ColorStateDescriptor* descriptor = GetColorStateDescriptor(i); const ColorTargetState* descriptor = GetColorTargetState(i);
ComputeBlendDesc(descriptorMTL.colorAttachments[static_cast<uint8_t>(i)], descriptor, ComputeBlendDesc(descriptorMTL.colorAttachments[static_cast<uint8_t>(i)], descriptor,
fragmentOutputsWritten[i]); fragmentOutputsWritten[i]);
} }
@ -403,7 +412,7 @@ namespace dawn_native { namespace metal {
// call setDepthStencilState() for a given render pipeline in CommandEncoder, in order to // call setDepthStencilState() for a given render pipeline in CommandEncoder, in order to
// improve performance. // improve performance.
NSRef<MTLDepthStencilDescriptor> depthStencilDesc = NSRef<MTLDepthStencilDescriptor> depthStencilDesc =
MakeDepthStencilDesc(GetDepthStencilStateDescriptor()); MakeDepthStencilDesc(GetDepthStencilState());
mMtlDepthStencilState = mMtlDepthStencilState =
AcquireNSPRef([mtlDevice newDepthStencilStateWithDescriptor:depthStencilDesc.Get()]); AcquireNSPRef([mtlDevice newDepthStencilStateWithDescriptor:depthStencilDesc.Get()]);

View File

@ -47,7 +47,8 @@ namespace dawn_native { namespace metal {
const PipelineLayout* layout, const PipelineLayout* layout,
MetalFunctionData* out, MetalFunctionData* out,
uint32_t sampleMask = 0xFFFFFFFF, uint32_t sampleMask = 0xFFFFFFFF,
const RenderPipeline* renderPipeline = nullptr); const RenderPipeline* renderPipeline = nullptr,
const VertexStateDescriptor* vertexState = nullptr);
private: private:
ResultOrError<std::string> TranslateToMSLWithTint(const char* entryPointName, ResultOrError<std::string> TranslateToMSLWithTint(const char* entryPointName,
@ -55,6 +56,7 @@ namespace dawn_native { namespace metal {
const PipelineLayout* layout, const PipelineLayout* layout,
uint32_t sampleMask, uint32_t sampleMask,
const RenderPipeline* renderPipeline, const RenderPipeline* renderPipeline,
const VertexStateDescriptor* vertexState,
std::string* remappedEntryPointName, std::string* remappedEntryPointName,
bool* needsStorageBufferLength); bool* needsStorageBufferLength);
ResultOrError<std::string> TranslateToMSLWithSPIRVCross( ResultOrError<std::string> TranslateToMSLWithSPIRVCross(
@ -63,6 +65,7 @@ namespace dawn_native { namespace metal {
const PipelineLayout* layout, const PipelineLayout* layout,
uint32_t sampleMask, uint32_t sampleMask,
const RenderPipeline* renderPipeline, const RenderPipeline* renderPipeline,
const VertexStateDescriptor* vertexState,
std::string* remappedEntryPointName, std::string* remappedEntryPointName,
bool* needsStorageBufferLength); bool* needsStorageBufferLength);

View File

@ -56,6 +56,7 @@ namespace dawn_native { namespace metal {
// TODO(crbug.com/tint/387): AND in a fixed sample mask in the shader. // TODO(crbug.com/tint/387): AND in a fixed sample mask in the shader.
uint32_t sampleMask, uint32_t sampleMask,
const RenderPipeline* renderPipeline, const RenderPipeline* renderPipeline,
const VertexStateDescriptor* vertexState,
std::string* remappedEntryPointName, std::string* remappedEntryPointName,
bool* needsStorageBufferLength) { bool* needsStorageBufferLength) {
// TODO(crbug.com/tint/256): Set this accordingly if arrayLength(..) is used. // TODO(crbug.com/tint/256): Set this accordingly if arrayLength(..) is used.
@ -68,8 +69,7 @@ namespace dawn_native { namespace metal {
if (stage == SingleShaderStage::Vertex && if (stage == SingleShaderStage::Vertex &&
GetDevice()->IsToggleEnabled(Toggle::MetalEnableVertexPulling)) { GetDevice()->IsToggleEnabled(Toggle::MetalEnableVertexPulling)) {
transformManager.append( transformManager.append(
MakeVertexPullingTransform(*renderPipeline->GetVertexStateDescriptor(), MakeVertexPullingTransform(*vertexState, entryPointName, kPullingBufferBindingSet));
entryPointName, kPullingBufferBindingSet));
for (VertexBufferSlot slot : for (VertexBufferSlot slot :
IterateBitSet(renderPipeline->GetVertexBufferSlotsUsed())) { IterateBitSet(renderPipeline->GetVertexBufferSlotsUsed())) {
@ -118,6 +118,7 @@ namespace dawn_native { namespace metal {
const PipelineLayout* layout, const PipelineLayout* layout,
uint32_t sampleMask, uint32_t sampleMask,
const RenderPipeline* renderPipeline, const RenderPipeline* renderPipeline,
const VertexStateDescriptor* vertexState,
std::string* remappedEntryPointName, std::string* remappedEntryPointName,
bool* needsStorageBufferLength) { bool* needsStorageBufferLength) {
const std::vector<uint32_t>* spirv = &GetSpirv(); const std::vector<uint32_t>* spirv = &GetSpirv();
@ -128,14 +129,12 @@ namespace dawn_native { namespace metal {
stage == SingleShaderStage::Vertex) { stage == SingleShaderStage::Vertex) {
if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) { if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) {
DAWN_TRY_ASSIGN(pullingSpirv, DAWN_TRY_ASSIGN(pullingSpirv,
GeneratePullingSpirv(GetTintProgram(), GeneratePullingSpirv(GetTintProgram(), *vertexState, entryPointName,
*renderPipeline->GetVertexStateDescriptor(), kPullingBufferBindingSet));
entryPointName, kPullingBufferBindingSet));
} else { } else {
DAWN_TRY_ASSIGN( DAWN_TRY_ASSIGN(pullingSpirv,
pullingSpirv, GeneratePullingSpirv(GetSpirv(), *vertexState, entryPointName,
GeneratePullingSpirv(GetSpirv(), *renderPipeline->GetVertexStateDescriptor(), kPullingBufferBindingSet));
entryPointName, kPullingBufferBindingSet));
} }
spirv = &pullingSpirv; spirv = &pullingSpirv;
} }
@ -228,20 +227,29 @@ namespace dawn_native { namespace metal {
const PipelineLayout* layout, const PipelineLayout* layout,
ShaderModule::MetalFunctionData* out, ShaderModule::MetalFunctionData* out,
uint32_t sampleMask, uint32_t sampleMask,
const RenderPipeline* renderPipeline) { const RenderPipeline* renderPipeline,
const VertexStateDescriptor* vertexState) {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(out); ASSERT(out);
// Vertex stages must specify a renderPipeline and vertexState
if (stage == SingleShaderStage::Vertex) {
ASSERT(renderPipeline != nullptr);
ASSERT(vertexState != nullptr);
}
std::string remappedEntryPointName; std::string remappedEntryPointName;
std::string msl; std::string msl;
if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) { if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) {
DAWN_TRY_ASSIGN(msl, TranslateToMSLWithTint(entryPointName, stage, layout, sampleMask, DAWN_TRY_ASSIGN(
renderPipeline, &remappedEntryPointName, msl, TranslateToMSLWithTint(entryPointName, stage, layout, sampleMask,
&out->needsStorageBufferLength)); renderPipeline, vertexState, &remappedEntryPointName,
&out->needsStorageBufferLength));
} else { } else {
DAWN_TRY_ASSIGN(msl, TranslateToMSLWithSPIRVCross( DAWN_TRY_ASSIGN(msl, TranslateToMSLWithSPIRVCross(entryPointName, stage, layout,
entryPointName, stage, layout, sampleMask, renderPipeline, sampleMask, renderPipeline,
&remappedEntryPointName, &out->needsStorageBufferLength)); vertexState, &remappedEntryPointName,
&out->needsStorageBufferLength));
} }
// Metal uses Clang to compile the shader as C++14. Disable everything in the -Wall // Metal uses Clang to compile the shader as C++14. Disable everything in the -Wall

View File

@ -104,43 +104,42 @@ namespace dawn_native { namespace opengl {
void ApplyColorState(const OpenGLFunctions& gl, void ApplyColorState(const OpenGLFunctions& gl,
ColorAttachmentIndex attachment, ColorAttachmentIndex attachment,
const ColorStateDescriptor* descriptor) { const ColorTargetState* state) {
GLuint colorBuffer = static_cast<GLuint>(static_cast<uint8_t>(attachment)); GLuint colorBuffer = static_cast<GLuint>(static_cast<uint8_t>(attachment));
if (BlendEnabled(descriptor)) { if (state->blend != nullptr) {
gl.Enablei(GL_BLEND, colorBuffer); gl.Enablei(GL_BLEND, colorBuffer);
gl.BlendEquationSeparatei(colorBuffer, gl.BlendEquationSeparatei(colorBuffer, GLBlendMode(state->blend->color.operation),
GLBlendMode(descriptor->colorBlend.operation), GLBlendMode(state->blend->alpha.operation));
GLBlendMode(descriptor->alphaBlend.operation));
gl.BlendFuncSeparatei(colorBuffer, gl.BlendFuncSeparatei(colorBuffer,
GLBlendFactor(descriptor->colorBlend.srcFactor, false), GLBlendFactor(state->blend->color.srcFactor, false),
GLBlendFactor(descriptor->colorBlend.dstFactor, false), GLBlendFactor(state->blend->color.dstFactor, false),
GLBlendFactor(descriptor->alphaBlend.srcFactor, true), GLBlendFactor(state->blend->alpha.srcFactor, true),
GLBlendFactor(descriptor->alphaBlend.dstFactor, true)); GLBlendFactor(state->blend->alpha.dstFactor, true));
} else { } else {
gl.Disablei(GL_BLEND, colorBuffer); gl.Disablei(GL_BLEND, colorBuffer);
} }
gl.ColorMaski(colorBuffer, descriptor->writeMask & wgpu::ColorWriteMask::Red, gl.ColorMaski(colorBuffer, state->writeMask & wgpu::ColorWriteMask::Red,
descriptor->writeMask & wgpu::ColorWriteMask::Green, state->writeMask & wgpu::ColorWriteMask::Green,
descriptor->writeMask & wgpu::ColorWriteMask::Blue, state->writeMask & wgpu::ColorWriteMask::Blue,
descriptor->writeMask & wgpu::ColorWriteMask::Alpha); state->writeMask & wgpu::ColorWriteMask::Alpha);
} }
void ApplyColorState(const OpenGLFunctions& gl, const ColorStateDescriptor* descriptor) { void ApplyColorState(const OpenGLFunctions& gl, const ColorTargetState* state) {
if (BlendEnabled(descriptor)) { if (state->blend != nullptr) {
gl.Enable(GL_BLEND); gl.Enable(GL_BLEND);
gl.BlendEquationSeparate(GLBlendMode(descriptor->colorBlend.operation), gl.BlendEquationSeparate(GLBlendMode(state->blend->color.operation),
GLBlendMode(descriptor->alphaBlend.operation)); GLBlendMode(state->blend->alpha.operation));
gl.BlendFuncSeparate(GLBlendFactor(descriptor->colorBlend.srcFactor, false), gl.BlendFuncSeparate(GLBlendFactor(state->blend->color.srcFactor, false),
GLBlendFactor(descriptor->colorBlend.dstFactor, false), GLBlendFactor(state->blend->color.dstFactor, false),
GLBlendFactor(descriptor->alphaBlend.srcFactor, true), GLBlendFactor(state->blend->alpha.srcFactor, true),
GLBlendFactor(descriptor->alphaBlend.dstFactor, true)); GLBlendFactor(state->blend->alpha.dstFactor, true));
} else { } else {
gl.Disable(GL_BLEND); gl.Disable(GL_BLEND);
} }
gl.ColorMask(descriptor->writeMask & wgpu::ColorWriteMask::Red, gl.ColorMask(state->writeMask & wgpu::ColorWriteMask::Red,
descriptor->writeMask & wgpu::ColorWriteMask::Green, state->writeMask & wgpu::ColorWriteMask::Green,
descriptor->writeMask & wgpu::ColorWriteMask::Blue, state->writeMask & wgpu::ColorWriteMask::Blue,
descriptor->writeMask & wgpu::ColorWriteMask::Alpha); state->writeMask & wgpu::ColorWriteMask::Alpha);
} }
bool Equal(const BlendDescriptor& lhs, const BlendDescriptor& rhs) { bool Equal(const BlendDescriptor& lhs, const BlendDescriptor& rhs) {
@ -170,7 +169,7 @@ namespace dawn_native { namespace opengl {
} }
void ApplyDepthStencilState(const OpenGLFunctions& gl, void ApplyDepthStencilState(const OpenGLFunctions& gl,
const DepthStencilStateDescriptor* descriptor, const DepthStencilState* descriptor,
PersistentPipelineState* persistentPipelineState) { PersistentPipelineState* persistentPipelineState) {
// Depth writes only occur if depth is enabled // Depth writes only occur if depth is enabled
if (descriptor->depthCompare == wgpu::CompareFunction::Always && if (descriptor->depthCompare == wgpu::CompareFunction::Always &&
@ -278,7 +277,7 @@ namespace dawn_native { namespace opengl {
ApplyFrontFaceAndCulling(gl, GetFrontFace(), GetCullMode()); ApplyFrontFaceAndCulling(gl, GetFrontFace(), GetCullMode());
ApplyDepthStencilState(gl, GetDepthStencilStateDescriptor(), &persistentPipelineState); ApplyDepthStencilState(gl, GetDepthStencilState(), &persistentPipelineState);
gl.SampleMaski(0, GetSampleMask()); gl.SampleMaski(0, GetSampleMask());
if (IsAlphaToCoverageEnabled()) { if (IsAlphaToCoverageEnabled()) {
@ -302,21 +301,26 @@ namespace dawn_native { namespace opengl {
if (!GetDevice()->IsToggleEnabled(Toggle::DisableIndexedDrawBuffers)) { if (!GetDevice()->IsToggleEnabled(Toggle::DisableIndexedDrawBuffers)) {
for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
ApplyColorState(gl, attachmentSlot, GetColorStateDescriptor(attachmentSlot)); ApplyColorState(gl, attachmentSlot, GetColorTargetState(attachmentSlot));
} }
} else { } else {
const ColorStateDescriptor* prevDescriptor = nullptr; const ColorTargetState* prevDescriptor = nullptr;
for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
const ColorStateDescriptor* descriptor = GetColorStateDescriptor(attachmentSlot); const ColorTargetState* descriptor = GetColorTargetState(attachmentSlot);
if (!prevDescriptor) { if (!prevDescriptor) {
ApplyColorState(gl, descriptor); ApplyColorState(gl, descriptor);
prevDescriptor = descriptor; prevDescriptor = descriptor;
} else if (!Equal(descriptor->alphaBlend, prevDescriptor->alphaBlend) || } else if ((descriptor->blend == nullptr) != (prevDescriptor->blend == nullptr)) {
!Equal(descriptor->colorBlend, prevDescriptor->colorBlend) || // TODO(crbug.com/dawn/582): GLES < 3.2 does not support different blend states
descriptor->writeMask != prevDescriptor->writeMask) { // per color target. Add validation to prevent this as it is not.
// TODO(crbug.com/dawn/582): Add validation to prevent this as it is not
// supported on GLES < 3.2.
ASSERT(false); ASSERT(false);
} else if (descriptor->blend != nullptr) {
if (!Equal(descriptor->blend->alpha, prevDescriptor->blend->alpha) ||
!Equal(descriptor->blend->color, prevDescriptor->blend->color) ||
descriptor->writeMask != prevDescriptor->writeMask) {
// TODO(crbug.com/dawn/582)
ASSERT(false);
}
} }
} }
} }

View File

@ -222,18 +222,29 @@ namespace dawn_native { namespace vulkan {
: static_cast<VkColorComponentFlags>(0); : static_cast<VkColorComponentFlags>(0);
} }
VkPipelineColorBlendAttachmentState ComputeColorDesc(const ColorStateDescriptor* descriptor, VkPipelineColorBlendAttachmentState ComputeColorDesc(const ColorTargetState* state,
bool isDeclaredInFragmentShader) { bool isDeclaredInFragmentShader) {
VkPipelineColorBlendAttachmentState attachment; VkPipelineColorBlendAttachmentState attachment;
attachment.blendEnable = BlendEnabled(descriptor) ? VK_TRUE : VK_FALSE; attachment.blendEnable = state->blend != nullptr ? VK_TRUE : VK_FALSE;
attachment.srcColorBlendFactor = VulkanBlendFactor(descriptor->colorBlend.srcFactor); if (attachment.blendEnable) {
attachment.dstColorBlendFactor = VulkanBlendFactor(descriptor->colorBlend.dstFactor); attachment.srcColorBlendFactor = VulkanBlendFactor(state->blend->color.srcFactor);
attachment.colorBlendOp = VulkanBlendOperation(descriptor->colorBlend.operation); attachment.dstColorBlendFactor = VulkanBlendFactor(state->blend->color.dstFactor);
attachment.srcAlphaBlendFactor = VulkanBlendFactor(descriptor->alphaBlend.srcFactor); attachment.colorBlendOp = VulkanBlendOperation(state->blend->color.operation);
attachment.dstAlphaBlendFactor = VulkanBlendFactor(descriptor->alphaBlend.dstFactor); attachment.srcAlphaBlendFactor = VulkanBlendFactor(state->blend->alpha.srcFactor);
attachment.alphaBlendOp = VulkanBlendOperation(descriptor->alphaBlend.operation); attachment.dstAlphaBlendFactor = VulkanBlendFactor(state->blend->alpha.dstFactor);
attachment.alphaBlendOp = VulkanBlendOperation(state->blend->alpha.operation);
} else {
// Swiftshader's Vulkan implementation appears to expect these values to be valid
// even when blending is not enabled.
attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
attachment.colorBlendOp = VK_BLEND_OP_ADD;
attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
attachment.alphaBlendOp = VK_BLEND_OP_ADD;
}
attachment.colorWriteMask = attachment.colorWriteMask =
VulkanColorWriteMask(descriptor->writeMask, isDeclaredInFragmentShader); VulkanColorWriteMask(state->writeMask, isDeclaredInFragmentShader);
return attachment; return attachment;
} }
@ -259,7 +270,7 @@ namespace dawn_native { namespace vulkan {
} }
VkPipelineDepthStencilStateCreateInfo ComputeDepthStencilDesc( VkPipelineDepthStencilStateCreateInfo ComputeDepthStencilDesc(
const DepthStencilStateDescriptor* descriptor) { const DepthStencilState* descriptor) {
VkPipelineDepthStencilStateCreateInfo depthStencilState; VkPipelineDepthStencilStateCreateInfo depthStencilState;
depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencilState.pNext = nullptr; depthStencilState.pNext = nullptr;
@ -404,7 +415,7 @@ namespace dawn_native { namespace vulkan {
multisample.alphaToOneEnable = VK_FALSE; multisample.alphaToOneEnable = VK_FALSE;
VkPipelineDepthStencilStateCreateInfo depthStencilState = VkPipelineDepthStencilStateCreateInfo depthStencilState =
ComputeDepthStencilDesc(GetDepthStencilStateDescriptor()); ComputeDepthStencilDesc(GetDepthStencilState());
// 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
@ -413,9 +424,8 @@ namespace dawn_native { namespace vulkan {
const auto& fragmentOutputsWritten = const auto& fragmentOutputsWritten =
GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputsWritten; GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputsWritten;
for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) { for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
const ColorStateDescriptor* colorStateDescriptor = GetColorStateDescriptor(i); const ColorTargetState* target = GetColorTargetState(i);
colorBlendAttachments[i] = colorBlendAttachments[i] = ComputeColorDesc(target, fragmentOutputsWritten[i]);
ComputeColorDesc(colorStateDescriptor, fragmentOutputsWritten[i]);
} }
VkPipelineColorBlendStateCreateInfo colorBlend; VkPipelineColorBlendStateCreateInfo colorBlend;
colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;