Implement multisample "disable" in Vulkan
Emulates multisample disable by colocating all samples at pixel center. Multisample disable will be required in order for us to integrate mixed samples. Change-Id: I52b67e22c979584b5d001e737a08eef07bd7ffe2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/253282 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
52591f6880
commit
b204e4c3d3
@ -99,7 +99,15 @@ GrPipeline::GrPipeline(GrScissorTest scissorTest, sk_sp<const GrXferProcessor> x
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GrPipeline::getBlendInfoKey() const {
|
||||
void GrPipeline::genKey(GrProcessorKeyBuilder* b, const GrCaps& caps) const {
|
||||
// kSnapVerticesToPixelCenters is implemented in a shader.
|
||||
InputFlags ignoredFlags = InputFlags::kSnapVerticesToPixelCenters;
|
||||
if (!caps.multisampleDisableSupport()) {
|
||||
// Ganesh will omit kHWAntialias regardless multisampleDisableSupport.
|
||||
ignoredFlags |= InputFlags::kHWAntialias;
|
||||
}
|
||||
b->add32((uint32_t)fFlags & ~(uint32_t)ignoredFlags);
|
||||
|
||||
const GrXferProcessor::BlendInfo& blendInfo = this->getXferProcessor().getBlendInfo();
|
||||
|
||||
static const uint32_t kBlendWriteShift = 1;
|
||||
@ -107,10 +115,10 @@ uint32_t GrPipeline::getBlendInfoKey() const {
|
||||
GR_STATIC_ASSERT(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
|
||||
GR_STATIC_ASSERT(kFirstAdvancedGrBlendEquation - 1 < 4);
|
||||
|
||||
uint32_t key = blendInfo.fWriteColor;
|
||||
key |= (blendInfo.fSrcBlend << kBlendWriteShift);
|
||||
key |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
|
||||
key |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
|
||||
uint32_t blendKey = blendInfo.fWriteColor;
|
||||
blendKey |= (blendInfo.fSrcBlend << kBlendWriteShift);
|
||||
blendKey |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
|
||||
blendKey |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
|
||||
|
||||
return key;
|
||||
b->add32(blendKey);
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ public:
|
||||
GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const;
|
||||
|
||||
// Used by Vulkan and Metal to cache their respective pipeline objects
|
||||
uint32_t getBlendInfoKey() const;
|
||||
void genKey(GrProcessorKeyBuilder*, const GrCaps&) const;
|
||||
|
||||
const GrSwizzle& outputSwizzle() const { return fOutputSwizzle; }
|
||||
|
||||
|
@ -468,7 +468,7 @@ bool GrMtlPipelineStateBuilder::Desc::Build(Desc* desc,
|
||||
b.add32((uint32_t)programInfo.pipeline().isStencilEnabled());
|
||||
// Stencil samples don't seem to be tracked in the MTLRenderPipeline
|
||||
|
||||
b.add32(programInfo.pipeline().getBlendInfoKey());
|
||||
programInfo.pipeline().genKey(&b, *gpu->caps());
|
||||
|
||||
b.add32((uint32_t)programInfo.primitiveType());
|
||||
|
||||
|
@ -461,29 +461,6 @@ void GrVkCaps::applyDriverCorrectnessWorkarounds(const VkPhysicalDevicePropertie
|
||||
}
|
||||
}
|
||||
|
||||
int get_max_sample_count(VkSampleCountFlags flags) {
|
||||
SkASSERT(flags & VK_SAMPLE_COUNT_1_BIT);
|
||||
if (!(flags & VK_SAMPLE_COUNT_2_BIT)) {
|
||||
return 0;
|
||||
}
|
||||
if (!(flags & VK_SAMPLE_COUNT_4_BIT)) {
|
||||
return 2;
|
||||
}
|
||||
if (!(flags & VK_SAMPLE_COUNT_8_BIT)) {
|
||||
return 4;
|
||||
}
|
||||
if (!(flags & VK_SAMPLE_COUNT_16_BIT)) {
|
||||
return 8;
|
||||
}
|
||||
if (!(flags & VK_SAMPLE_COUNT_32_BIT)) {
|
||||
return 16;
|
||||
}
|
||||
if (!(flags & VK_SAMPLE_COUNT_64_BIT)) {
|
||||
return 32;
|
||||
}
|
||||
return 64;
|
||||
}
|
||||
|
||||
void GrVkCaps::initGrCaps(const GrVkInterface* vkInterface,
|
||||
VkPhysicalDevice physDev,
|
||||
const VkPhysicalDeviceProperties& properties,
|
||||
@ -497,6 +474,11 @@ void GrVkCaps::initGrCaps(const GrVkInterface* vkInterface,
|
||||
static const uint32_t kMaxVertexAttributes = 64;
|
||||
fMaxVertexAttributes = SkTMin(properties.limits.maxVertexInputAttributes, kMaxVertexAttributes);
|
||||
|
||||
if (extensions.hasExtension(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, 1)) {
|
||||
// We "disable" multisample by colocating all samples at pixel center.
|
||||
fMultisampleDisableSupport = true;
|
||||
}
|
||||
|
||||
// We could actually query and get a max size for each config, however maxImageDimension2D will
|
||||
// give the minimum max size across all configs. So for simplicity we will use that for now.
|
||||
fMaxRenderTargetSize = SkTMin(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);
|
||||
@ -1187,12 +1169,8 @@ void GrVkCaps::FormatInfo::initSampleCounts(const GrVkInterface* interface,
|
||||
if (flags & VK_SAMPLE_COUNT_16_BIT) {
|
||||
fColorSampleCounts.push_back(16);
|
||||
}
|
||||
if (flags & VK_SAMPLE_COUNT_32_BIT) {
|
||||
fColorSampleCounts.push_back(32);
|
||||
}
|
||||
if (flags & VK_SAMPLE_COUNT_64_BIT) {
|
||||
fColorSampleCounts.push_back(64);
|
||||
}
|
||||
// Standard sample locations are not defined for more than 16 samples, and we don't need more
|
||||
// than 16. Omit 32 and 64.
|
||||
}
|
||||
|
||||
void GrVkCaps::FormatInfo::init(const GrVkInterface* interface,
|
||||
|
@ -294,6 +294,29 @@ static void setup_multisample_state(const GrProgramInfo& programInfo,
|
||||
multisampleInfo->alphaToOneEnable = VK_FALSE;
|
||||
}
|
||||
|
||||
static void setup_all_sample_locations_at_pixel_center(
|
||||
const GrProgramInfo& programInfo,
|
||||
VkPipelineSampleLocationsStateCreateInfoEXT* sampleLocations) {
|
||||
constexpr static VkSampleLocationEXT kCenteredSampleLocations[16] = {
|
||||
{.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f},
|
||||
{.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}};
|
||||
memset(sampleLocations, 0, sizeof(VkPipelineSampleLocationsStateCreateInfoEXT));
|
||||
sampleLocations->sType = VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT;
|
||||
sampleLocations->pNext = nullptr;
|
||||
sampleLocations->sampleLocationsEnable = VK_TRUE;
|
||||
sampleLocations->sampleLocationsInfo.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT;
|
||||
sampleLocations->sampleLocationsInfo.pNext = nullptr;
|
||||
SkAssertResult(GrSampleCountToVkSampleCount(
|
||||
programInfo.numSamples(),
|
||||
&sampleLocations->sampleLocationsInfo.sampleLocationsPerPixel));
|
||||
sampleLocations->sampleLocationsInfo.sampleLocationGridSize.width = 1;
|
||||
sampleLocations->sampleLocationsInfo.sampleLocationGridSize.height = 1;
|
||||
SkASSERT(programInfo.numSamples() < (int)SK_ARRAY_COUNT(kCenteredSampleLocations));
|
||||
sampleLocations->sampleLocationsInfo.sampleLocationsCount = std::min(
|
||||
programInfo.numSamples(), (int)SK_ARRAY_COUNT(kCenteredSampleLocations));
|
||||
sampleLocations->sampleLocationsInfo.pSampleLocations = kCenteredSampleLocations;
|
||||
}
|
||||
|
||||
static VkBlendFactor blend_coeff_to_vk_blend(GrBlendCoeff coeff) {
|
||||
static const VkBlendFactor gTable[] = {
|
||||
VK_BLEND_FACTOR_ZERO, // kZero_GrBlendCoeff
|
||||
@ -523,6 +546,15 @@ GrVkPipeline* GrVkPipeline::Create(
|
||||
VkPipelineMultisampleStateCreateInfo multisampleInfo;
|
||||
setup_multisample_state(programInfo, gpu->caps(), &multisampleInfo);
|
||||
|
||||
VkPipelineSampleLocationsStateCreateInfoEXT sampleLocations;
|
||||
if (gpu->caps()->multisampleDisableSupport()) {
|
||||
if (programInfo.numSamples() > 1 && !programInfo.pipeline().isHWAntialiasState()) {
|
||||
setup_all_sample_locations_at_pixel_center(programInfo, &sampleLocations);
|
||||
sampleLocations.pNext = multisampleInfo.pNext;
|
||||
multisampleInfo.pNext = &sampleLocations;
|
||||
}
|
||||
}
|
||||
|
||||
// We will only have one color attachment per pipeline.
|
||||
VkPipelineColorBlendAttachmentState attachmentStates[1];
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendInfo;
|
||||
|
@ -346,7 +346,7 @@ bool GrVkPipelineStateBuilder::Desc::Build(Desc* desc,
|
||||
|
||||
stencil.genKey(&b);
|
||||
|
||||
b.add32(programInfo.pipeline().getBlendInfoKey());
|
||||
programInfo.pipeline().genKey(&b, *gpu->caps());
|
||||
|
||||
// Vulkan requires the full primitive type as part of its key
|
||||
b.add32((uint32_t)programInfo.primitiveType());
|
||||
|
@ -96,12 +96,6 @@ bool GrSampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits* vkSam
|
||||
case 16:
|
||||
*vkSamples = VK_SAMPLE_COUNT_16_BIT;
|
||||
return true;
|
||||
case 32:
|
||||
*vkSamples = VK_SAMPLE_COUNT_32_BIT;
|
||||
return true;
|
||||
case 64:
|
||||
*vkSamples = VK_SAMPLE_COUNT_64_BIT;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user