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:
parent
984e72dbf9
commit
3ceb65443c
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue