VulkanContext: Detect the appropriate depth buffer format to use, expose it.

This should help AMD compatibility.
This commit is contained in:
Henrik Rydgard 2016-03-21 20:11:28 +01:00
parent 20f227cc4d
commit dff585e440
3 changed files with 42 additions and 18 deletions

View file

@ -626,6 +626,22 @@ VkResult VulkanContext::CreateDevice(int physical_device) {
assert(found);
assert(queue_count >= 1);
// Detect preferred formats, in this order.
static const VkFormat depthStencilFormats[] = {
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D16_UNORM_S8_UINT,
};
deviceInfo_.preferredDepthStencilFormat = VK_FORMAT_UNDEFINED;
for (int i = 0; i < ARRAY_SIZE(depthStencilFormats); i++) {
VkFormatProperties props;
vkGetPhysicalDeviceFormatProperties(physical_devices_[0], VK_FORMAT_D24_UNORM_S8_UINT, &props);
if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
deviceInfo_.preferredDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
break;
}
}
// This is as good a place as any to do this
vkGetPhysicalDeviceMemoryProperties(physical_devices_[0], &memory_properties);
vkGetPhysicalDeviceProperties(physical_devices_[0], &gpu_props);
@ -730,24 +746,9 @@ void VulkanContext::InitDepthStencilBuffer(VkCommandBuffer cmd) {
VkResult U_ASSERT_ONLY res;
bool U_ASSERT_ONLY pass;
VkImageCreateInfo image_info = {};
// const VkFormat depth_format = VK_FORMAT_D16_UNORM;
// int aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
const VkFormat depth_format = VK_FORMAT_D24_UNORM_S8_UINT;
const VkFormat depth_format = deviceInfo_.preferredDepthStencilFormat;
int aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
VkFormatProperties props;
vkGetPhysicalDeviceFormatProperties(physical_devices_[0], depth_format, &props);
if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
} else if (props.linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
image_info.tiling = VK_IMAGE_TILING_LINEAR;
} else {
/* Try other depth formats? */
std::cout << "VK_FORMAT_D16_UNORM Unsupported.\n";
exit(-1);
}
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_info.pNext = NULL;
image_info.imageType = VK_IMAGE_TYPE_2D;
@ -774,7 +775,6 @@ void VulkanContext::InitDepthStencilBuffer(VkCommandBuffer cmd) {
depth.format = depth_format;
/* Create image */
res = vkCreateImage(device_, &image_info, NULL, &depth.image);
assert(res == VK_SUCCESS);

View file

@ -49,6 +49,11 @@ struct layer_properties {
std::vector<VkExtensionProperties> extensions;
};
struct VulkanPhysicalDeviceInfo {
VkFormat preferredDepthStencilFormat;
};
// This is a bit repetitive...
class VulkanDeleteList {
public:
@ -61,6 +66,8 @@ public:
void QueueDeleteDeviceMemory(VkDeviceMemory deviceMemory) { deviceMemory_.push_back(deviceMemory); }
void QueueDeleteSampler(VkSampler sampler) { samplers_.push_back(sampler); }
void QueueDeletePipelineCache(VkPipelineCache pipelineCache) { pipelineCaches_.push_back(pipelineCache); }
void QueueDeleteRenderPass(VkRenderPass renderPass) { renderPasses_.push_back(renderPass); }
void QueueDeleteFramebuffer(VkFramebuffer framebuffer) { framebuffers_.push_back(framebuffer); }
void Take(VulkanDeleteList &del) {
assert(descPools_.size() == 0);
@ -72,6 +79,7 @@ public:
assert(deviceMemory_.size() == 0);
assert(samplers_.size() == 0);
assert(pipelineCaches_.size() == 0);
assert(renderPasses_.size() == 0);
descPools_ = std::move(del.descPools_);
modules_ = std::move(del.modules_);
buffers_ = std::move(del.buffers_);
@ -81,6 +89,8 @@ public:
deviceMemory_ = std::move(del.deviceMemory_);
samplers_ = std::move(del.samplers_);
pipelineCaches_ = std::move(del.pipelineCaches_);
renderPasses_ = std::move(del.renderPasses_);
framebuffers_ = std::move(del.framebuffers_);
}
void PerformDeletes(VkDevice device) {
@ -120,6 +130,14 @@ public:
vkDestroyPipelineCache(device, pcache, nullptr);
}
pipelineCaches_.clear();
for (auto &renderPass : renderPasses_) {
vkDestroyRenderPass(device, renderPass, nullptr);
}
renderPasses_.clear();
for (auto &framebuffer : framebuffers_) {
vkDestroyFramebuffer(device, framebuffer, nullptr);
}
renderPasses_.clear();
}
private:
@ -132,6 +150,8 @@ private:
std::vector<VkDeviceMemory> deviceMemory_;
std::vector<VkSampler> samplers_;
std::vector<VkPipelineCache> pipelineCaches_;
std::vector<VkRenderPass> renderPasses_;
std::vector<VkFramebuffer> framebuffers_;
};
// VulkanContext sets up the basics necessary for rendering to a window, including framebuffers etc.
@ -236,6 +256,8 @@ public:
const VkPhysicalDeviceFeatures &GetFeaturesAvailable() const { return featuresAvailable_; }
const VkPhysicalDeviceFeatures &GetFeaturesEnabled() const { return featuresEnabled_; }
const VulkanPhysicalDeviceInfo &GetDeviceInfo() const { return deviceInfo_; }
private:
VkSemaphore acquireSemaphore;
@ -273,6 +295,9 @@ private:
std::vector<VkQueueFamilyProperties> queue_props;
VkPhysicalDeviceMemoryProperties memory_properties;
// Custom collection of things that are good to know
VulkanPhysicalDeviceInfo deviceInfo_;
struct swap_chain_buffer {
VkImage image;
VkImageView view;

View file

@ -93,7 +93,6 @@ public:
void Execute_Spline(u32 op, u32 diff);
void Execute_BoundingBox(u32 op, u32 diff);
void Execute_VertexType(u32 op, u32 diff);
void Execute_VertexTypeSkinning(u32 op, u32 diff);
void Execute_Region(u32 op, u32 diff);
void Execute_Scissor(u32 op, u32 diff);
void Execute_FramebufType(u32 op, u32 diff);