Create RenderPipeline blueprints w/ RenderPipelineDescriptor2

This is another incremental change towards using the new render
pipeline descriptor throughout the entire stack. Creates blueprints for
hashing with the new descriptor when provided before then converting it
to the old format for the native backend creation.

BUG: dawn:642
Change-Id: I1927b12fd02b2fedf25ef4428f07e339fa666715
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/46541
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Brandon Jones 2021-04-01 01:28:52 +00:00 committed by Commit Bot service account
parent 984e72dbf9
commit 3ceb65443c
6 changed files with 209 additions and 80 deletions

View File

@ -46,6 +46,20 @@ namespace dawn_native {
}
}
AttachmentStateBlueprint::AttachmentStateBlueprint(const RenderPipelineDescriptor2* descriptor)
: mSampleCount(descriptor->multisample.count) {
ASSERT(descriptor->fragment->targetCount <= kMaxColorAttachments);
for (ColorAttachmentIndex i(uint8_t(0));
i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->fragment->targetCount));
++i) {
mColorAttachmentsSet.set(i);
mColorFormats[i] = descriptor->fragment->targets[static_cast<uint8_t>(i)].format;
}
if (descriptor->depthStencil != nullptr) {
mDepthStencilFormat = descriptor->depthStencil->format;
}
}
AttachmentStateBlueprint::AttachmentStateBlueprint(const RenderPassDescriptor* descriptor) {
for (ColorAttachmentIndex i(uint8_t(0));
i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->colorAttachmentCount));

View File

@ -38,6 +38,7 @@ namespace dawn_native {
// Note: Descriptors must be validated before the AttachmentState is constructed.
explicit AttachmentStateBlueprint(const RenderBundleEncoderDescriptor* descriptor);
explicit AttachmentStateBlueprint(const RenderPipelineDescriptor* descriptor);
explicit AttachmentStateBlueprint(const RenderPipelineDescriptor2* descriptor);
explicit AttachmentStateBlueprint(const RenderPassDescriptor* descriptor);
AttachmentStateBlueprint(const AttachmentStateBlueprint& rhs);

View File

@ -551,6 +551,103 @@ namespace dawn_native {
return std::move(result);
}
ResultOrError<Ref<RenderPipelineBase>> DeviceBase::GetOrCreateRenderPipeline(
const RenderPipelineDescriptor2* descriptor) {
RenderPipelineBase blueprint(this, descriptor);
const size_t blueprintHash = blueprint.ComputeContentHash();
blueprint.SetContentHash(blueprintHash);
Ref<RenderPipelineBase> result;
auto iter = mCaches->renderPipelines.find(&blueprint);
if (iter != mCaches->renderPipelines.end()) {
result = *iter;
} else {
// Convert descriptor to the older format it before proceeding.
// TODO: Convert the rest of the code to operate on the newer format.
RenderPipelineDescriptor normalizedDescriptor;
VertexStateDescriptor vertexState;
normalizedDescriptor.vertexState = &vertexState;
RasterizationStateDescriptor rasterizationState;
normalizedDescriptor.rasterizationState = &rasterizationState;
normalizedDescriptor.label = descriptor->label;
normalizedDescriptor.layout = descriptor->layout;
normalizedDescriptor.vertexStage.module = descriptor->vertex.module;
normalizedDescriptor.vertexStage.entryPoint = descriptor->vertex.entryPoint;
normalizedDescriptor.primitiveTopology = descriptor->primitive.topology;
normalizedDescriptor.sampleCount = descriptor->multisample.count;
normalizedDescriptor.sampleMask = descriptor->multisample.mask;
normalizedDescriptor.alphaToCoverageEnabled =
descriptor->multisample.alphaToCoverageEnabled;
vertexState.vertexBufferCount = descriptor->vertex.bufferCount;
vertexState.vertexBuffers = descriptor->vertex.buffers;
vertexState.indexFormat = descriptor->primitive.stripIndexFormat;
rasterizationState.frontFace = descriptor->primitive.frontFace;
rasterizationState.cullMode = descriptor->primitive.cullMode;
DepthStencilStateDescriptor depthStencilState;
if (descriptor->depthStencil) {
const DepthStencilState* depthStencil = descriptor->depthStencil;
normalizedDescriptor.depthStencilState = &depthStencilState;
depthStencilState.format = depthStencil->format;
depthStencilState.depthWriteEnabled = depthStencil->depthWriteEnabled;
depthStencilState.depthCompare = depthStencil->depthCompare;
depthStencilState.stencilFront = depthStencil->stencilFront;
depthStencilState.stencilBack = depthStencil->stencilBack;
depthStencilState.stencilReadMask = depthStencil->stencilReadMask;
depthStencilState.stencilWriteMask = depthStencil->stencilWriteMask;
rasterizationState.depthBias = depthStencil->depthBias;
rasterizationState.depthBiasSlopeScale = depthStencil->depthBiasSlopeScale;
rasterizationState.depthBiasClamp = depthStencil->depthBiasClamp;
}
ProgrammableStageDescriptor fragmentStage;
std::vector<ColorStateDescriptor> colorStates;
if (descriptor->fragment) {
const FragmentState* fragment = descriptor->fragment;
normalizedDescriptor.fragmentStage = &fragmentStage;
fragmentStage.module = fragment->module;
fragmentStage.entryPoint = fragment->entryPoint;
for (uint32_t i = 0; i < fragment->targetCount; ++i) {
const ColorTargetState& target = fragment->targets[i];
ColorStateDescriptor colorState;
colorState.format = target.format;
colorState.writeMask = target.writeMask;
if (target.blend) {
const BlendState* blend = target.blend;
colorState.colorBlend.srcFactor = blend->color.srcFactor;
colorState.colorBlend.dstFactor = blend->color.dstFactor;
colorState.colorBlend.operation = blend->color.operation;
colorState.alphaBlend.srcFactor = blend->alpha.srcFactor;
colorState.alphaBlend.dstFactor = blend->alpha.dstFactor;
colorState.alphaBlend.operation = blend->alpha.operation;
}
colorStates.push_back(colorState);
}
normalizedDescriptor.colorStateCount = fragment->targetCount;
normalizedDescriptor.colorStates = colorStates.data();
}
DAWN_TRY_ASSIGN(result, CreateRenderPipelineImpl(&normalizedDescriptor));
result->SetIsCachedReference();
result->SetContentHash(blueprintHash);
mCaches->renderPipelines.insert(result.Get());
}
return std::move(result);
}
void DeviceBase::UncacheRenderPipeline(RenderPipelineBase* obj) {
ASSERT(obj->IsCachedReference());
size_t removedCount = mCaches->renderPipelines.erase(obj);
@ -649,6 +746,12 @@ namespace dawn_native {
return GetOrCreateAttachmentState(&blueprint);
}
Ref<AttachmentState> DeviceBase::GetOrCreateAttachmentState(
const RenderPipelineDescriptor2* descriptor) {
AttachmentStateBlueprint blueprint(descriptor);
return GetOrCreateAttachmentState(&blueprint);
}
Ref<AttachmentState> DeviceBase::GetOrCreateAttachmentState(
const RenderPassDescriptor* descriptor) {
AttachmentStateBlueprint blueprint(descriptor);
@ -1038,92 +1141,20 @@ namespace dawn_native {
DAWN_TRY(ValidateRenderPipelineDescriptor(this, descriptor));
}
// Convert descriptor to the older format it before proceeding.
// TODO: Convert the rest of the code to operate on the newer format.
RenderPipelineDescriptor normalizedDescriptor;
VertexStateDescriptor vertexState;
normalizedDescriptor.vertexState = &vertexState;
RasterizationStateDescriptor rasterizationState;
normalizedDescriptor.rasterizationState = &rasterizationState;
normalizedDescriptor.label = descriptor->label;
normalizedDescriptor.layout = descriptor->layout;
normalizedDescriptor.vertexStage.module = descriptor->vertex.module;
normalizedDescriptor.vertexStage.entryPoint = descriptor->vertex.entryPoint;
normalizedDescriptor.primitiveTopology = descriptor->primitive.topology;
normalizedDescriptor.sampleCount = descriptor->multisample.count;
normalizedDescriptor.sampleMask = descriptor->multisample.mask;
normalizedDescriptor.alphaToCoverageEnabled =
descriptor->multisample.alphaToCoverageEnabled;
vertexState.vertexBufferCount = descriptor->vertex.bufferCount;
vertexState.vertexBuffers = descriptor->vertex.buffers;
vertexState.indexFormat = descriptor->primitive.stripIndexFormat;
rasterizationState.frontFace = descriptor->primitive.frontFace;
rasterizationState.cullMode = descriptor->primitive.cullMode;
DepthStencilStateDescriptor depthStencilState;
if (descriptor->depthStencil) {
const DepthStencilState* depthStencil = descriptor->depthStencil;
normalizedDescriptor.depthStencilState = &depthStencilState;
depthStencilState.format = depthStencil->format;
depthStencilState.depthWriteEnabled = depthStencil->depthWriteEnabled;
depthStencilState.depthCompare = depthStencil->depthCompare;
depthStencilState.stencilFront = depthStencil->stencilFront;
depthStencilState.stencilBack = depthStencil->stencilBack;
depthStencilState.stencilReadMask = depthStencil->stencilReadMask;
depthStencilState.stencilWriteMask = depthStencil->stencilWriteMask;
rasterizationState.depthBias = depthStencil->depthBias;
rasterizationState.depthBiasSlopeScale = depthStencil->depthBiasSlopeScale;
rasterizationState.depthBiasClamp = depthStencil->depthBiasClamp;
}
ProgrammableStageDescriptor fragmentStage;
std::vector<ColorStateDescriptor> colorStates;
if (descriptor->fragment) {
const FragmentState* fragment = descriptor->fragment;
normalizedDescriptor.fragmentStage = &fragmentStage;
fragmentStage.module = fragment->module;
fragmentStage.entryPoint = fragment->entryPoint;
for (uint32_t i = 0; i < fragment->targetCount; ++i) {
const ColorTargetState& target = fragment->targets[i];
ColorStateDescriptor colorState;
colorState.format = target.format;
colorState.writeMask = target.writeMask;
if (target.blend) {
const BlendState* blend = target.blend;
colorState.colorBlend.srcFactor = blend->color.srcFactor;
colorState.colorBlend.dstFactor = blend->color.dstFactor;
colorState.colorBlend.operation = blend->color.operation;
colorState.alphaBlend.srcFactor = blend->alpha.srcFactor;
colorState.alphaBlend.dstFactor = blend->alpha.dstFactor;
colorState.alphaBlend.operation = blend->alpha.operation;
}
colorStates.push_back(colorState);
}
normalizedDescriptor.colorStateCount = fragment->targetCount;
normalizedDescriptor.colorStates = colorStates.data();
}
Ref<PipelineLayoutBase> layoutRef;
if (descriptor->layout == nullptr) {
RenderPipelineDescriptor2 descriptorWithDefaultLayout = *descriptor;
// Ref will keep the pipeline layout alive until the end of the function where
// the pipeline will take another reference.
Ref<PipelineLayoutBase> layoutRef;
DAWN_TRY_ASSIGN(layoutRef,
PipelineLayoutBase::CreateDefault(this, GetStages(descriptor)));
normalizedDescriptor.layout = layoutRef.Get();
}
descriptorWithDefaultLayout.layout = layoutRef.Get();
return GetOrCreateRenderPipeline(&normalizedDescriptor);
return GetOrCreateRenderPipeline(&descriptorWithDefaultLayout);
} else {
return GetOrCreateRenderPipeline(descriptor);
}
}
ResultOrError<Ref<RenderPipelineBase>> DeviceBase::CreateRenderPipelineInternal(

View File

@ -120,6 +120,8 @@ namespace dawn_native {
ResultOrError<Ref<RenderPipelineBase>> GetOrCreateRenderPipeline(
const RenderPipelineDescriptor* descriptor);
ResultOrError<Ref<RenderPipelineBase>> GetOrCreateRenderPipeline(
const RenderPipelineDescriptor2* descriptor);
void UncacheRenderPipeline(RenderPipelineBase* obj);
ResultOrError<Ref<SamplerBase>> GetOrCreateSampler(const SamplerDescriptor* descriptor);
@ -134,6 +136,8 @@ namespace dawn_native {
Ref<AttachmentState> GetOrCreateAttachmentState(
const RenderBundleEncoderDescriptor* descriptor);
Ref<AttachmentState> GetOrCreateAttachmentState(const RenderPipelineDescriptor* descriptor);
Ref<AttachmentState> GetOrCreateAttachmentState(
const RenderPipelineDescriptor2* descriptor);
Ref<AttachmentState> GetOrCreateAttachmentState(const RenderPassDescriptor* descriptor);
void UncacheAttachmentState(AttachmentState* obj);

View File

@ -674,6 +674,84 @@ namespace dawn_native {
// attachment are set?
}
RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
const RenderPipelineDescriptor2* descriptor)
: PipelineBase(device,
descriptor->layout,
{{SingleShaderStage::Vertex, descriptor->vertex.module,
descriptor->vertex.entryPoint},
{SingleShaderStage::Fragment, descriptor->fragment->module,
descriptor->fragment->entryPoint}}),
mAttachmentState(device->GetOrCreateAttachmentState(descriptor)) {
mVertexBufferCount = descriptor->vertex.bufferCount;
const VertexBufferLayout* buffers = descriptor->vertex.buffers;
for (uint8_t slot = 0; slot < mVertexBufferCount; ++slot) {
if (buffers[slot].attributeCount == 0) {
continue;
}
VertexBufferSlot typedSlot(slot);
mVertexBufferSlotsUsed.set(typedSlot);
mVertexBufferInfos[typedSlot].arrayStride = buffers[slot].arrayStride;
mVertexBufferInfos[typedSlot].stepMode = buffers[slot].stepMode;
for (uint32_t i = 0; i < buffers[slot].attributeCount; ++i) {
VertexAttributeLocation location = VertexAttributeLocation(
static_cast<uint8_t>(buffers[slot].attributes[i].shaderLocation));
mAttributeLocationsUsed.set(location);
mAttributeInfos[location].shaderLocation = location;
mAttributeInfos[location].vertexBufferSlot = typedSlot;
mAttributeInfos[location].offset = buffers[slot].attributes[i].offset;
mAttributeInfos[location].format =
dawn::NormalizeVertexFormat(buffers[slot].attributes[i].format);
}
}
mPrimitive = descriptor->primitive;
mMultisample = descriptor->multisample;
if (mAttachmentState->HasDepthStencilAttachment()) {
mDepthStencil = *descriptor->depthStencil;
} else {
// These default values below are useful for backends to fill information.
// The values indicate that depth and stencil test are disabled when backends
// set their own depth stencil states/descriptors according to the values in
// mDepthStencil.
mDepthStencil.format = wgpu::TextureFormat::Undefined;
mDepthStencil.depthWriteEnabled = false;
mDepthStencil.depthCompare = wgpu::CompareFunction::Always;
mDepthStencil.stencilBack.compare = wgpu::CompareFunction::Always;
mDepthStencil.stencilBack.failOp = wgpu::StencilOperation::Keep;
mDepthStencil.stencilBack.depthFailOp = wgpu::StencilOperation::Keep;
mDepthStencil.stencilBack.passOp = wgpu::StencilOperation::Keep;
mDepthStencil.stencilFront.compare = wgpu::CompareFunction::Always;
mDepthStencil.stencilFront.failOp = wgpu::StencilOperation::Keep;
mDepthStencil.stencilFront.depthFailOp = wgpu::StencilOperation::Keep;
mDepthStencil.stencilFront.passOp = wgpu::StencilOperation::Keep;
mDepthStencil.stencilReadMask = 0xff;
mDepthStencil.stencilWriteMask = 0xff;
mDepthStencil.depthBias = 0;
mDepthStencil.depthBiasSlopeScale = 0.0f;
mDepthStencil.depthBiasClamp = 0.0f;
}
for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
const ColorTargetState* target =
&descriptor->fragment->targets[static_cast<uint8_t>(i)];
mTargets[i] = *target;
if (target->blend != nullptr) {
mTargetBlend[i] = *target->blend;
mTargets[i].blend = &mTargetBlend[i];
}
}
// TODO(cwallez@chromium.org): Check against the shader module that the correct color
// attachment are set?
}
RenderPipelineBase::RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: PipelineBase(device, tag) {
}

View File

@ -58,6 +58,7 @@ namespace dawn_native {
class RenderPipelineBase : public PipelineBase {
public:
RenderPipelineBase(DeviceBase* device, const RenderPipelineDescriptor* descriptor);
RenderPipelineBase(DeviceBase* device, const RenderPipelineDescriptor2* descriptor);
~RenderPipelineBase() override;
static RenderPipelineBase* MakeError(DeviceBase* device);