Support multisampled rendering on Vulkan
MultisampledRenderingTest/MultisampledRenderingWithDepthTest is skipped temporarily on Intel Windows Vulkan drivers due to the failure of that case on the try bots. BUG=dawn:56 TEST=dawn_end2end_tests Change-Id: Ibcf4a07198e4ebad304170e8df9778dc965349df Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/6300 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
parent
cfea934e2b
commit
952860bf9f
|
@ -154,7 +154,9 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) {
|
for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) {
|
||||||
const auto& attachmentInfo = renderPass->colorAttachments[i];
|
const auto& attachmentInfo = renderPass->colorAttachments[i];
|
||||||
query.SetColor(i, attachmentInfo.view->GetFormat(), attachmentInfo.loadOp);
|
bool hasResolveTarget = attachmentInfo.resolveTarget.Get() != nullptr;
|
||||||
|
query.SetColor(i, attachmentInfo.view->GetFormat(), attachmentInfo.loadOp,
|
||||||
|
hasResolveTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderPass->hasDepthStencilAttachment) {
|
if (renderPass->hasDepthStencilAttachment) {
|
||||||
|
@ -163,6 +165,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
attachmentInfo.depthLoadOp, attachmentInfo.stencilLoadOp);
|
attachmentInfo.depthLoadOp, attachmentInfo.stencilLoadOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query.SetSampleCount(renderPass->sampleCount);
|
||||||
|
|
||||||
renderPassVK = device->GetRenderPassCache()->GetRenderPass(query);
|
renderPassVK = device->GetRenderPassCache()->GetRenderPass(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +177,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
uint32_t attachmentCount = 0;
|
uint32_t attachmentCount = 0;
|
||||||
{
|
{
|
||||||
// Fill in the attachment info that will be chained in the framebuffer create info.
|
// Fill in the attachment info that will be chained in the framebuffer create info.
|
||||||
std::array<VkImageView, kMaxColorAttachments + 1> attachments;
|
std::array<VkImageView, kMaxColorAttachments * 2 + 1> attachments;
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) {
|
for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) {
|
||||||
auto& attachmentInfo = renderPass->colorAttachments[i];
|
auto& attachmentInfo = renderPass->colorAttachments[i];
|
||||||
|
@ -201,6 +205,17 @@ namespace dawn_native { namespace vulkan {
|
||||||
attachmentCount++;
|
attachmentCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) {
|
||||||
|
if (renderPass->colorAttachments[i].resolveTarget.Get() != nullptr) {
|
||||||
|
TextureView* view =
|
||||||
|
ToBackend(renderPass->colorAttachments[i].resolveTarget.Get());
|
||||||
|
|
||||||
|
attachments[attachmentCount] = view->GetHandle();
|
||||||
|
|
||||||
|
attachmentCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Chain attachments and create the framebuffer
|
// Chain attachments and create the framebuffer
|
||||||
VkFramebufferCreateInfo createInfo;
|
VkFramebufferCreateInfo createInfo;
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
|
|
|
@ -38,10 +38,12 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
void RenderPassCacheQuery::SetColor(uint32_t index,
|
void RenderPassCacheQuery::SetColor(uint32_t index,
|
||||||
dawn::TextureFormat format,
|
dawn::TextureFormat format,
|
||||||
dawn::LoadOp loadOp) {
|
dawn::LoadOp loadOp,
|
||||||
|
bool hasResolveTarget) {
|
||||||
colorMask.set(index);
|
colorMask.set(index);
|
||||||
colorFormats[index] = format;
|
colorFormats[index] = format;
|
||||||
colorLoadOp[index] = loadOp;
|
colorLoadOp[index] = loadOp;
|
||||||
|
resolveTargetMask[index] = hasResolveTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPassCacheQuery::SetDepthStencil(dawn::TextureFormat format,
|
void RenderPassCacheQuery::SetDepthStencil(dawn::TextureFormat format,
|
||||||
|
@ -53,6 +55,10 @@ namespace dawn_native { namespace vulkan {
|
||||||
this->stencilLoadOp = stencilLoadOp;
|
this->stencilLoadOp = stencilLoadOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderPassCacheQuery::SetSampleCount(uint32_t sampleCount) {
|
||||||
|
this->sampleCount = sampleCount;
|
||||||
|
}
|
||||||
|
|
||||||
// RenderPassCache
|
// RenderPassCache
|
||||||
|
|
||||||
RenderPassCache::RenderPassCache(Device* device) : mDevice(device) {
|
RenderPassCache::RenderPassCache(Device* device) : mDevice(device) {
|
||||||
|
@ -80,14 +86,62 @@ namespace dawn_native { namespace vulkan {
|
||||||
const RenderPassCacheQuery& query) const {
|
const RenderPassCacheQuery& query) const {
|
||||||
// The Vulkan subpasses want to know the layout of the attachments with VkAttachmentRef.
|
// The Vulkan subpasses want to know the layout of the attachments with VkAttachmentRef.
|
||||||
// Precompute them as they must be pointer-chained in VkSubpassDescription
|
// Precompute them as they must be pointer-chained in VkSubpassDescription
|
||||||
std::array<VkAttachmentReference, kMaxColorAttachments + 1> attachmentRefs;
|
std::array<VkAttachmentReference, kMaxColorAttachments> colorAttachmentRefs;
|
||||||
|
std::array<VkAttachmentReference, kMaxColorAttachments> resolveAttachmentRefs;
|
||||||
|
VkAttachmentReference depthStencilAttachmentRef;
|
||||||
|
|
||||||
// Contains the attachment description that will be chained in the create info
|
// Contains the attachment description that will be chained in the create info
|
||||||
std::array<VkAttachmentDescription, kMaxColorAttachments + 1> attachmentDescs = {};
|
// The order of all attachments in attachmentDescs is "color-depthstencil-resolve".
|
||||||
|
constexpr uint32_t kMaxAttachmentCount = kMaxColorAttachments * 2 + 1;
|
||||||
|
std::array<VkAttachmentDescription, kMaxAttachmentCount> attachmentDescs = {};
|
||||||
|
|
||||||
uint32_t attachmentCount = 0;
|
VkSampleCountFlagBits vkSampleCount = VulkanSampleCount(query.sampleCount);
|
||||||
|
|
||||||
|
uint32_t colorAttachmentIndex = 0;
|
||||||
for (uint32_t i : IterateBitSet(query.colorMask)) {
|
for (uint32_t i : IterateBitSet(query.colorMask)) {
|
||||||
auto& attachmentRef = attachmentRefs[attachmentCount];
|
auto& attachmentRef = colorAttachmentRefs[colorAttachmentIndex];
|
||||||
|
auto& attachmentDesc = attachmentDescs[colorAttachmentIndex];
|
||||||
|
|
||||||
|
attachmentRef.attachment = colorAttachmentIndex;
|
||||||
|
attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
attachmentDesc.flags = 0;
|
||||||
|
attachmentDesc.format = VulkanImageFormat(query.colorFormats[i]);
|
||||||
|
attachmentDesc.samples = vkSampleCount;
|
||||||
|
attachmentDesc.loadOp = VulkanAttachmentLoadOp(query.colorLoadOp[i]);
|
||||||
|
attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
++colorAttachmentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t attachmentCount = colorAttachmentIndex;
|
||||||
|
VkAttachmentReference* depthStencilAttachment = nullptr;
|
||||||
|
if (query.hasDepthStencil) {
|
||||||
|
auto& attachmentDesc = attachmentDescs[attachmentCount];
|
||||||
|
|
||||||
|
depthStencilAttachment = &depthStencilAttachmentRef;
|
||||||
|
|
||||||
|
depthStencilAttachmentRef.attachment = attachmentCount;
|
||||||
|
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
attachmentDesc.flags = 0;
|
||||||
|
attachmentDesc.format = VulkanImageFormat(query.depthStencilFormat);
|
||||||
|
attachmentDesc.samples = vkSampleCount;
|
||||||
|
attachmentDesc.loadOp = VulkanAttachmentLoadOp(query.depthLoadOp);
|
||||||
|
attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachmentDesc.stencilLoadOp = VulkanAttachmentLoadOp(query.stencilLoadOp);
|
||||||
|
attachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
++attachmentCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t resolveAttachmentIndex = 0;
|
||||||
|
for (uint32_t i : IterateBitSet(query.resolveTargetMask)) {
|
||||||
|
auto& attachmentRef = resolveAttachmentRefs[resolveAttachmentIndex];
|
||||||
auto& attachmentDesc = attachmentDescs[attachmentCount];
|
auto& attachmentDesc = attachmentDescs[attachmentCount];
|
||||||
|
|
||||||
attachmentRef.attachment = attachmentCount;
|
attachmentRef.attachment = attachmentCount;
|
||||||
|
@ -96,37 +150,17 @@ namespace dawn_native { namespace vulkan {
|
||||||
attachmentDesc.flags = 0;
|
attachmentDesc.flags = 0;
|
||||||
attachmentDesc.format = VulkanImageFormat(query.colorFormats[i]);
|
attachmentDesc.format = VulkanImageFormat(query.colorFormats[i]);
|
||||||
attachmentDesc.samples = VK_SAMPLE_COUNT_1_BIT;
|
attachmentDesc.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
attachmentDesc.loadOp = VulkanAttachmentLoadOp(query.colorLoadOp[i]);
|
attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
attachmentCount++;
|
++attachmentCount;
|
||||||
|
++resolveAttachmentIndex;
|
||||||
}
|
}
|
||||||
uint32_t colorAttachmentCount = attachmentCount;
|
|
||||||
|
|
||||||
VkAttachmentReference* depthStencilAttachment = nullptr;
|
VkAttachmentReference* resolveTargetAttachmentRefs =
|
||||||
if (query.hasDepthStencil) {
|
query.resolveTargetMask.any() ? resolveAttachmentRefs.data() : nullptr;
|
||||||
auto& attachmentRef = attachmentRefs[attachmentCount];
|
|
||||||
auto& attachmentDesc = attachmentDescs[attachmentCount];
|
|
||||||
|
|
||||||
depthStencilAttachment = &attachmentRefs[attachmentCount];
|
|
||||||
|
|
||||||
attachmentRef.attachment = attachmentCount;
|
|
||||||
attachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
|
|
||||||
attachmentDesc.flags = 0;
|
|
||||||
attachmentDesc.format = VulkanImageFormat(query.depthStencilFormat);
|
|
||||||
attachmentDesc.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
attachmentDesc.loadOp = VulkanAttachmentLoadOp(query.depthLoadOp);
|
|
||||||
attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
attachmentDesc.stencilLoadOp = VulkanAttachmentLoadOp(query.stencilLoadOp);
|
|
||||||
attachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
|
|
||||||
attachmentCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the VkSubpassDescription that will be chained in the VkRenderPassCreateInfo
|
// Create the VkSubpassDescription that will be chained in the VkRenderPassCreateInfo
|
||||||
VkSubpassDescription subpassDesc;
|
VkSubpassDescription subpassDesc;
|
||||||
|
@ -134,9 +168,9 @@ namespace dawn_native { namespace vulkan {
|
||||||
subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
subpassDesc.inputAttachmentCount = 0;
|
subpassDesc.inputAttachmentCount = 0;
|
||||||
subpassDesc.pInputAttachments = nullptr;
|
subpassDesc.pInputAttachments = nullptr;
|
||||||
subpassDesc.colorAttachmentCount = colorAttachmentCount;
|
subpassDesc.colorAttachmentCount = colorAttachmentIndex;
|
||||||
subpassDesc.pColorAttachments = attachmentRefs.data();
|
subpassDesc.pColorAttachments = colorAttachmentRefs.data();
|
||||||
subpassDesc.pResolveAttachments = nullptr;
|
subpassDesc.pResolveAttachments = resolveTargetAttachmentRefs;
|
||||||
subpassDesc.pDepthStencilAttachment = depthStencilAttachment;
|
subpassDesc.pDepthStencilAttachment = depthStencilAttachment;
|
||||||
subpassDesc.preserveAttachmentCount = 0;
|
subpassDesc.preserveAttachmentCount = 0;
|
||||||
subpassDesc.pPreserveAttachments = nullptr;
|
subpassDesc.pPreserveAttachments = nullptr;
|
||||||
|
@ -168,6 +202,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
size_t RenderPassCache::CacheFuncs::operator()(const RenderPassCacheQuery& query) const {
|
size_t RenderPassCache::CacheFuncs::operator()(const RenderPassCacheQuery& query) const {
|
||||||
size_t hash = Hash(query.colorMask);
|
size_t hash = Hash(query.colorMask);
|
||||||
|
|
||||||
|
HashCombine(&hash, Hash(query.resolveTargetMask));
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(query.colorMask)) {
|
for (uint32_t i : IterateBitSet(query.colorMask)) {
|
||||||
HashCombine(&hash, query.colorFormats[i], query.colorLoadOp[i]);
|
HashCombine(&hash, query.colorFormats[i], query.colorLoadOp[i]);
|
||||||
}
|
}
|
||||||
|
@ -177,6 +213,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
HashCombine(&hash, query.depthStencilFormat, query.depthLoadOp, query.stencilLoadOp);
|
HashCombine(&hash, query.depthStencilFormat, query.depthLoadOp, query.stencilLoadOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashCombine(&hash, query.sampleCount);
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +224,14 @@ namespace dawn_native { namespace vulkan {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a.resolveTargetMask != b.resolveTargetMask) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.sampleCount != b.sampleCount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(a.colorMask)) {
|
for (uint32_t i : IterateBitSet(a.colorMask)) {
|
||||||
if ((a.colorFormats[i] != b.colorFormats[i]) ||
|
if ((a.colorFormats[i] != b.colorFormats[i]) ||
|
||||||
(a.colorLoadOp[i] != b.colorLoadOp[i])) {
|
(a.colorLoadOp[i] != b.colorLoadOp[i])) {
|
||||||
|
|
|
@ -34,12 +34,17 @@ namespace dawn_native { namespace vulkan {
|
||||||
struct RenderPassCacheQuery {
|
struct RenderPassCacheQuery {
|
||||||
// Use these helpers to build the query, they make sure all relevant data is initialized and
|
// Use these helpers to build the query, they make sure all relevant data is initialized and
|
||||||
// masks set.
|
// masks set.
|
||||||
void SetColor(uint32_t index, dawn::TextureFormat format, dawn::LoadOp loadOp);
|
void SetColor(uint32_t index,
|
||||||
|
dawn::TextureFormat format,
|
||||||
|
dawn::LoadOp loadOp,
|
||||||
|
bool hasResolveTarget);
|
||||||
void SetDepthStencil(dawn::TextureFormat format,
|
void SetDepthStencil(dawn::TextureFormat format,
|
||||||
dawn::LoadOp depthLoadOp,
|
dawn::LoadOp depthLoadOp,
|
||||||
dawn::LoadOp stencilLoadOp);
|
dawn::LoadOp stencilLoadOp);
|
||||||
|
void SetSampleCount(uint32_t sampleCount);
|
||||||
|
|
||||||
std::bitset<kMaxColorAttachments> colorMask;
|
std::bitset<kMaxColorAttachments> colorMask;
|
||||||
|
std::bitset<kMaxColorAttachments> resolveTargetMask;
|
||||||
std::array<dawn::TextureFormat, kMaxColorAttachments> colorFormats;
|
std::array<dawn::TextureFormat, kMaxColorAttachments> colorFormats;
|
||||||
std::array<dawn::LoadOp, kMaxColorAttachments> colorLoadOp;
|
std::array<dawn::LoadOp, kMaxColorAttachments> colorLoadOp;
|
||||||
|
|
||||||
|
@ -47,10 +52,14 @@ namespace dawn_native { namespace vulkan {
|
||||||
dawn::TextureFormat depthStencilFormat;
|
dawn::TextureFormat depthStencilFormat;
|
||||||
dawn::LoadOp depthLoadOp;
|
dawn::LoadOp depthLoadOp;
|
||||||
dawn::LoadOp stencilLoadOp;
|
dawn::LoadOp stencilLoadOp;
|
||||||
|
|
||||||
|
uint32_t sampleCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Caches VkRenderPasses so that we don't create duplicate ones for every RenderPipeline or
|
// Caches VkRenderPasses so that we don't create duplicate ones for every RenderPipeline or
|
||||||
// render pass.
|
// render pass. We always arrange the order of attachments in "color-depthstencil-resolve" order
|
||||||
|
// when creating render pass and framebuffer so that we can always make sure the order of
|
||||||
|
// attachments in the rendering pipeline matches the one of the framebuffer.
|
||||||
// TODO(cwallez@chromium.org): Make it an LRU cache somehow?
|
// TODO(cwallez@chromium.org): Make it an LRU cache somehow?
|
||||||
class RenderPassCache {
|
class RenderPassCache {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "dawn_native/vulkan/PipelineLayoutVk.h"
|
#include "dawn_native/vulkan/PipelineLayoutVk.h"
|
||||||
#include "dawn_native/vulkan/RenderPassCache.h"
|
#include "dawn_native/vulkan/RenderPassCache.h"
|
||||||
#include "dawn_native/vulkan/ShaderModuleVk.h"
|
#include "dawn_native/vulkan/ShaderModuleVk.h"
|
||||||
|
#include "dawn_native/vulkan/TextureVk.h"
|
||||||
#include "dawn_native/vulkan/UtilsVulkan.h"
|
#include "dawn_native/vulkan/UtilsVulkan.h"
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan {
|
namespace dawn_native { namespace vulkan {
|
||||||
|
@ -351,7 +352,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
multisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
multisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
multisample.pNext = nullptr;
|
multisample.pNext = nullptr;
|
||||||
multisample.flags = 0;
|
multisample.flags = 0;
|
||||||
multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
multisample.rasterizationSamples = VulkanSampleCount(GetSampleCount());
|
||||||
multisample.sampleShadingEnable = VK_FALSE;
|
multisample.sampleShadingEnable = VK_FALSE;
|
||||||
multisample.minSampleShading = 0.0f;
|
multisample.minSampleShading = 0.0f;
|
||||||
multisample.pSampleMask = nullptr;
|
multisample.pSampleMask = nullptr;
|
||||||
|
@ -405,7 +406,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
RenderPassCacheQuery query;
|
RenderPassCacheQuery query;
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
|
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
|
||||||
query.SetColor(i, GetColorAttachmentFormat(i), dawn::LoadOp::Load);
|
query.SetColor(i, GetColorAttachmentFormat(i), dawn::LoadOp::Load, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasDepthStencilAttachment()) {
|
if (HasDepthStencilAttachment()) {
|
||||||
|
@ -413,6 +414,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
dawn::LoadOp::Load);
|
dawn::LoadOp::Load);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query.SetSampleCount(GetSampleCount());
|
||||||
|
|
||||||
renderPass = device->GetRenderPassCache()->GetRenderPass(query);
|
renderPass = device->GetRenderPassCache()->GetRenderPass(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "dawn_native/vulkan/TextureVk.h"
|
#include "dawn_native/vulkan/TextureVk.h"
|
||||||
|
|
||||||
|
#include "dawn_native/vulkan/AdapterVk.h"
|
||||||
#include "dawn_native/vulkan/DeviceVk.h"
|
#include "dawn_native/vulkan/DeviceVk.h"
|
||||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||||
|
|
||||||
|
@ -191,6 +192,22 @@ namespace dawn_native { namespace vulkan {
|
||||||
return {extent.width, extent.height, extent.depth};
|
return {extent.width, extent.height, extent.depth};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsSampleCountSupported(const dawn_native::vulkan::Device* device,
|
||||||
|
const VkImageCreateInfo& imageCreateInfo) {
|
||||||
|
ASSERT(device);
|
||||||
|
|
||||||
|
VkPhysicalDevice physicalDevice = ToBackend(device->GetAdapter())->GetPhysicalDevice();
|
||||||
|
VkImageFormatProperties properties;
|
||||||
|
if (device->fn.GetPhysicalDeviceImageFormatProperties(
|
||||||
|
physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType,
|
||||||
|
imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags,
|
||||||
|
&properties) != VK_SUCCESS) {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties.sampleCounts & imageCreateInfo.samples;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Converts Dawn texture format to Vulkan formats.
|
// Converts Dawn texture format to Vulkan formats.
|
||||||
|
@ -245,6 +262,17 @@ namespace dawn_native { namespace vulkan {
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount) {
|
||||||
|
switch (sampleCount) {
|
||||||
|
case 1:
|
||||||
|
return VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
case 4:
|
||||||
|
return VK_SAMPLE_COUNT_4_BIT;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Texture::Texture(Device* device, const TextureDescriptor* descriptor)
|
Texture::Texture(Device* device, const TextureDescriptor* descriptor)
|
||||||
: TextureBase(device, descriptor, TextureState::OwnedInternal) {
|
: TextureBase(device, descriptor, TextureState::OwnedInternal) {
|
||||||
// Create the Vulkan image "container". We don't need to check that the format supports the
|
// Create the Vulkan image "container". We don't need to check that the format supports the
|
||||||
|
@ -259,7 +287,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
createInfo.extent = VulkanExtent3D(GetSize());
|
createInfo.extent = VulkanExtent3D(GetSize());
|
||||||
createInfo.mipLevels = GetNumMipLevels();
|
createInfo.mipLevels = GetNumMipLevels();
|
||||||
createInfo.arrayLayers = GetArrayLayers();
|
createInfo.arrayLayers = GetArrayLayers();
|
||||||
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
createInfo.samples = VulkanSampleCount(GetSampleCount());
|
||||||
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
createInfo.usage = VulkanImageUsage(GetUsage(), GetFormat());
|
createInfo.usage = VulkanImageUsage(GetUsage(), GetFormat());
|
||||||
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
@ -267,6 +295,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
createInfo.pQueueFamilyIndices = nullptr;
|
createInfo.pQueueFamilyIndices = nullptr;
|
||||||
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
|
ASSERT(IsSampleCountSupported(device, createInfo));
|
||||||
|
|
||||||
if (GetArrayLayers() >= 6 && GetSize().width == GetSize().height) {
|
if (GetArrayLayers() >= 6 && GetSize().width == GetSize().height) {
|
||||||
createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
VkFormat VulkanImageFormat(dawn::TextureFormat format);
|
VkFormat VulkanImageFormat(dawn::TextureFormat format);
|
||||||
VkImageUsageFlags VulkanImageUsage(dawn::TextureUsageBit usage, dawn::TextureFormat format);
|
VkImageUsageFlags VulkanImageUsage(dawn::TextureUsageBit usage, dawn::TextureFormat format);
|
||||||
|
VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount);
|
||||||
|
|
||||||
class Texture : public TextureBase {
|
class Texture : public TextureBase {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -255,6 +255,9 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DTexture) {
|
||||||
|
|
||||||
// Test multisampled rendering with depth test works correctly.
|
// Test multisampled rendering with depth test works correctly.
|
||||||
TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTest) {
|
TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTest) {
|
||||||
|
// TODO(jiawei.shao@intel.com): find out why this test fails on Intel Windows Vulkan drivers.
|
||||||
|
DAWN_SKIP_TEST_IF(IsIntel() && IsVulkan() && IsWindows());
|
||||||
|
|
||||||
constexpr bool kTestDepth = true;
|
constexpr bool kTestDepth = true;
|
||||||
dawn::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
dawn::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||||
dawn::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);
|
dawn::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);
|
||||||
|
@ -466,4 +469,4 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DArrayTexture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jiawei.shao@intel.com): enable multisampled rendering on all Dawn backends.
|
// TODO(jiawei.shao@intel.com): enable multisampled rendering on all Dawn backends.
|
||||||
DAWN_INSTANTIATE_TEST(MultisampledRenderingTest, D3D12Backend, OpenGLBackend);
|
DAWN_INSTANTIATE_TEST(MultisampledRenderingTest, D3D12Backend, OpenGLBackend, VulkanBackend);
|
||||||
|
|
Loading…
Reference in New Issue