[graphite] Enable MSAA.
Bug: skia:13212 Change-Id: I8fc8bcd01181fcfb9955119984afa4bfbb1f73e5 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/529756 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
09c279fe84
commit
bd73e796d7
@ -64,6 +64,7 @@ public:
|
||||
private:
|
||||
#ifdef SK_METAL
|
||||
friend class MtlCaps;
|
||||
friend class MtlGraphicsPipeline;
|
||||
friend class MtlTexture;
|
||||
const MtlTextureSpec& mtlTextureSpec() const {
|
||||
SkASSERT(fValid && fBackend == BackendApi::kMetal);
|
||||
|
@ -36,9 +36,7 @@ public:
|
||||
Protected,
|
||||
Renderable) const = 0;
|
||||
|
||||
virtual TextureInfo getDefaultMSAATextureInfo(SkColorType,
|
||||
uint32_t sampleCount,
|
||||
Protected) const = 0;
|
||||
virtual TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo) const = 0;
|
||||
|
||||
virtual TextureInfo getDefaultDepthStencilTextureInfo(Mask<DepthStencilFlags>,
|
||||
uint32_t sampleCount,
|
||||
@ -81,6 +79,9 @@ public:
|
||||
protected:
|
||||
Caps();
|
||||
|
||||
// TODO: This value should be set by some context option. For now just making it 4.
|
||||
uint32_t defaultMSAASamples() const { return 4; }
|
||||
|
||||
// ColorTypeInfo for a specific format.
|
||||
// Used in format tables.
|
||||
struct ColorTypeInfo {
|
||||
|
@ -118,21 +118,46 @@ sk_sp<Task> DrawContext::snapRenderPassTask(Recorder* recorder,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Caps* caps = recorder->priv().caps();
|
||||
|
||||
// TODO: At this point we would determine all the targets used by the drawPasses,
|
||||
// build up the union of them and store them in the RenderPassDesc. However, for
|
||||
// the moment we should have only one drawPass.
|
||||
SkASSERT(fDrawPasses.size() == 1);
|
||||
RenderPassDesc desc;
|
||||
auto& drawPass = fDrawPasses[0];
|
||||
desc.fColorAttachment.fTextureInfo = drawPass->target()->textureInfo();
|
||||
std::tie(desc.fColorAttachment.fLoadOp, desc.fColorAttachment.fStoreOp) = drawPass->ops();
|
||||
const TextureInfo& targetInfo = drawPass->target()->textureInfo();
|
||||
auto [loadOp, storeOp] = drawPass->ops();
|
||||
// It doesn't make sense to have a storeOp for our main target not be store. Why are we doing
|
||||
// this DrawPass then
|
||||
SkASSERT(storeOp == StoreOp::kStore);
|
||||
if (drawPass->requiresMSAA()) {
|
||||
desc.fColorAttachment.fTextureInfo = caps->getDefaultMSAATextureInfo(targetInfo);
|
||||
if (loadOp != LoadOp::kClear) {
|
||||
desc.fColorAttachment.fLoadOp = LoadOp::kDiscard;
|
||||
} else {
|
||||
desc.fColorAttachment.fLoadOp = LoadOp::kClear;
|
||||
}
|
||||
desc.fColorAttachment.fStoreOp = StoreOp::kDiscard;
|
||||
|
||||
desc.fColorResolveAttachment.fTextureInfo = targetInfo;
|
||||
if (loadOp != LoadOp::kLoad) {
|
||||
desc.fColorResolveAttachment.fLoadOp = LoadOp::kDiscard;
|
||||
} else {
|
||||
desc.fColorResolveAttachment.fLoadOp = LoadOp::kLoad;
|
||||
}
|
||||
desc.fColorResolveAttachment.fStoreOp = storeOp;
|
||||
} else {
|
||||
desc.fColorAttachment.fTextureInfo = targetInfo;
|
||||
desc.fColorAttachment.fLoadOp = loadOp;
|
||||
desc.fColorAttachment.fStoreOp = storeOp;
|
||||
}
|
||||
desc.fClearColor = drawPass->clearColor();
|
||||
|
||||
if (drawPass->depthStencilFlags() != DepthStencilFlags::kNone) {
|
||||
const Caps* caps = recorder->priv().caps();
|
||||
desc.fDepthStencilAttachment.fTextureInfo =
|
||||
caps->getDefaultDepthStencilTextureInfo(drawPass->depthStencilFlags(),
|
||||
1 /*sampleCount*/, // TODO: MSAA
|
||||
desc.fDepthStencilAttachment.fTextureInfo = caps->getDefaultDepthStencilTextureInfo(
|
||||
drawPass->depthStencilFlags(),
|
||||
desc.fColorAttachment.fTextureInfo.numSamples(),
|
||||
Protected::kNo);
|
||||
// Always clear the depth and stencil to 0 at the start of a DrawPass, but discard at the
|
||||
// end since their contents do not affect the next frame.
|
||||
|
@ -52,19 +52,44 @@ bool RenderPassTask::addCommands(ResourceProvider* resourceProvider, CommandBuff
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<Texture> depthStencilTexture;
|
||||
sk_sp<Texture> colorAttachment;
|
||||
sk_sp<Texture> resolveAttachment;
|
||||
if (fRenderPassDesc.fColorResolveAttachment.fTextureInfo.isValid()) {
|
||||
SkASSERT(fTarget->numSamples() == 1 &&
|
||||
fRenderPassDesc.fColorAttachment.fTextureInfo.numSamples() > 1);
|
||||
colorAttachment = resourceProvider->findOrCreateDiscardableMSAAAttachment(
|
||||
fTarget->dimensions(), fRenderPassDesc.fColorAttachment.fTextureInfo);
|
||||
if (!colorAttachment) {
|
||||
SKGPU_LOG_W("Could not get Color attachment for RenderPassTask");
|
||||
return false;
|
||||
}
|
||||
resolveAttachment = fTarget->refTexture();
|
||||
} else {
|
||||
colorAttachment = fTarget->refTexture();
|
||||
}
|
||||
|
||||
sk_sp<Texture> depthStencilAttachment;
|
||||
if (fRenderPassDesc.fDepthStencilAttachment.fTextureInfo.isValid()) {
|
||||
// TODO: ensure this is a scratch/recycled texture
|
||||
depthStencilTexture = resourceProvider->findOrCreateDepthStencilAttachment(
|
||||
depthStencilAttachment = resourceProvider->findOrCreateDepthStencilAttachment(
|
||||
fTarget->dimensions(), fRenderPassDesc.fDepthStencilAttachment.fTextureInfo);
|
||||
if (!depthStencilTexture) {
|
||||
if (!depthStencilAttachment) {
|
||||
SKGPU_LOG_W("Could not get DepthStencil attachment for RenderPassTask");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (commandBuffer->beginRenderPass(fRenderPassDesc, fTarget->refTexture(), nullptr,
|
||||
std::move(depthStencilTexture))) {
|
||||
// TODO: We need to handle the case where we need to load the single sampled target's data into
|
||||
// the discardable MSAA Surface. On different backends this will be done in various ways. On
|
||||
// Metal we can simply insert a draw at the start of the render pass sampling the single target
|
||||
// texture as normal. In Vulkan, we need to create a whole new subpass at the start, use the
|
||||
// single sample resolve as an input attachment in that subpass, and then do a draw. The big
|
||||
// thing with Vulkan is that this input attachment and subpass means we also need to update
|
||||
// the fRenderPassDesc here.
|
||||
if (commandBuffer->beginRenderPass(fRenderPassDesc,
|
||||
std::move(colorAttachment),
|
||||
std::move(resolveAttachment),
|
||||
std::move(depthStencilAttachment))) {
|
||||
// Assuming one draw pass per renderpasstask for now
|
||||
SkASSERT(fDrawPasses.size() == 1);
|
||||
for (const auto& drawPass: fDrawPasses) {
|
||||
|
@ -243,6 +243,7 @@ private:
|
||||
SkDEBUGCODE(bool performsShading = false;)
|
||||
for (int i = 0 ; i < fStepCount; ++i) {
|
||||
fSteps[i] = steps[i];
|
||||
fRequiresMSAA |= fSteps[i]->requiresMSAA();
|
||||
fDepthStencilFlags |= fSteps[i]->depthStencilFlags();
|
||||
SkDEBUGCODE(performsShading |= fSteps[i]->performsShading());
|
||||
}
|
||||
|
@ -26,9 +26,7 @@ public:
|
||||
Protected,
|
||||
Renderable) const override;
|
||||
|
||||
TextureInfo getDefaultMSAATextureInfo(SkColorType,
|
||||
uint32_t sampleCount,
|
||||
Protected) const override;
|
||||
TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo) const override;
|
||||
|
||||
TextureInfo getDefaultDepthStencilTextureInfo(Mask<DepthStencilFlags>,
|
||||
uint32_t sampleCount,
|
||||
|
@ -484,15 +484,15 @@ TextureInfo MtlCaps::getDefaultSampledTextureInfo(SkColorType colorType,
|
||||
return info;
|
||||
}
|
||||
|
||||
TextureInfo MtlCaps::getDefaultMSAATextureInfo(SkColorType colorType,
|
||||
uint32_t sampleCount,
|
||||
Protected) const {
|
||||
TextureInfo MtlCaps::getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo) const {
|
||||
const MtlTextureSpec& singleSpec = singleSampledInfo.mtlTextureSpec();
|
||||
|
||||
MTLTextureUsage usage = MTLTextureUsageRenderTarget;
|
||||
|
||||
MtlTextureInfo info;
|
||||
info.fSampleCount = sampleCount;
|
||||
info.fSampleCount = this->defaultMSAASamples();
|
||||
info.fLevelCount = 1;
|
||||
info.fFormat = this->getFormatFromColorType(colorType);
|
||||
info.fFormat = singleSpec.fFormat;
|
||||
info.fUsage = usage;
|
||||
info.fStorageMode = MTLStorageModePrivate;
|
||||
info.fFramebufferOnly = false;
|
||||
|
@ -123,12 +123,8 @@ bool MtlCommandBuffer::onBeginRenderPass(const RenderPassDesc& renderPassDesc,
|
||||
// Inclusion of a resolve texture implies the client wants to finish the
|
||||
// renderpass with a resolve.
|
||||
if (@available(macOS 10.12, iOS 10.0, *)) {
|
||||
if (colorAttachment.storeAction == MTLStoreActionStore) {
|
||||
colorAttachment.storeAction = MTLStoreActionStoreAndMultisampleResolve;
|
||||
} else {
|
||||
SkASSERT(colorAttachment.storeAction == MTLStoreActionDontCare);
|
||||
colorAttachment.storeAction = MTLStoreActionMultisampleResolve;
|
||||
}
|
||||
} else {
|
||||
// We expect at least Metal 2
|
||||
// TODO: Add error output
|
||||
|
@ -549,16 +549,17 @@ sk_sp<MtlGraphicsPipeline> MtlGraphicsPipeline::Make(
|
||||
// TODO: I *think* this gets cleaned up by the pipelineDescriptor?
|
||||
(*psoDescriptor).vertexDescriptor = create_vertex_descriptor(pipelineDesc.renderStep());
|
||||
|
||||
MtlTextureInfo mtlTexInfo;
|
||||
renderPassDesc.fColorAttachment.fTextureInfo.getMtlTextureInfo(&mtlTexInfo);
|
||||
|
||||
auto mtlColorAttachment = create_color_attachment((MTLPixelFormat)mtlTexInfo.fFormat,
|
||||
const MtlTextureSpec& mtlColorSpec =
|
||||
renderPassDesc.fColorAttachment.fTextureInfo.mtlTextureSpec();
|
||||
auto mtlColorAttachment = create_color_attachment((MTLPixelFormat)mtlColorSpec.fFormat,
|
||||
blendInfo);
|
||||
|
||||
(*psoDescriptor).colorAttachments[0] = mtlColorAttachment;
|
||||
|
||||
renderPassDesc.fDepthStencilAttachment.fTextureInfo.getMtlTextureInfo(&mtlTexInfo);
|
||||
MTLPixelFormat depthStencilFormat = (MTLPixelFormat)mtlTexInfo.fFormat;
|
||||
(*psoDescriptor).sampleCount = renderPassDesc.fColorAttachment.fTextureInfo.numSamples();
|
||||
|
||||
const MtlTextureSpec& mtlDSSpec =
|
||||
renderPassDesc.fDepthStencilAttachment.fTextureInfo.mtlTextureSpec();
|
||||
MTLPixelFormat depthStencilFormat = (MTLPixelFormat)mtlDSSpec.fFormat;
|
||||
if (MtlFormatIsStencil(depthStencilFormat)) {
|
||||
(*psoDescriptor).stencilAttachmentPixelFormat = depthStencilFormat;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user