Commit 0aa1ffe3 by Luc Ferron Committed by Commit Bot

Vulkan: Autogen mandatory texture caps

* This commit includes a JS file to execute on the spec and generate the JSON output of all the mandatory texture caps. Bug: angleproject:2348 Change-Id: I57e969915bdd0e7104e00a73fd3743ff1ecf0a6d Reviewed-on: https://chromium-review.googlesource.com/911615 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8170eab7
......@@ -136,6 +136,17 @@ generators = {
],
'script': 'src/libANGLE/renderer/vulkan/gen_vk_format_table.py',
},
'Vulkan mandatory format support table': {
'inputs': [
'src/libANGLE/renderer/angle_format.py',
'third_party/vulkan-validation-layers/src/scripts/vk.xml',
'src/libANGLE/renderer/vulkan/vk_mandatory_format_support_data.json',
],
'outputs': [
'src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp',
],
'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py',
},
}
root_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
......
/**
* Copyright 2018 The ANGLE Project Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
* This script is meant to be executed agaisnt the vulkan spec 31.3.3 tables.
* Instructions: Copy all the tables from the HTML source to a plain document
* and add a textarea at the bottom with ID='result'. Execute this JS on load
* of the document and you should have a JSON string in the textarea with the
* mandatory specs included. If the spec changes format / CSS in any way, the
* selectors will need to be modified.
**/
var indexToFeatureMap = [];
var index = 12;
var outputJson = {};
// Map all features to indexes of squares.
$("#features-formats-mandatory-features-subbyte td").each(function() {
$this = $(this);
$this.find("code").each(function() {
if ($(this).text().startsWith("VK_FORMAT_FEATURE")) {
indexToFeatureMap[index--] = $(this).text();
}
});
});
var allTableIds =
["features-formats-mandatory-features-subbyte",
"features-formats-mandatory-features-2byte",
"features-formats-mandatory-features-4byte",
"features-formats-mandatory-features-10bit",
"features-formats-mandatory-features-16bit",
"features-formats-mandatory-features-32bit",
"features-formats-mandatory-features-64bit",
"features-formats-mandatory-features-depth-stencil",
"features-formats-mandatory-features-features-bcn",
"features-formats-mandatory-features-features-etc",
"features-formats-mandatory-features-features-astc"];
for (var i = 0; i < allTableIds.length; i++) {
$("#" + allTableIds[i] + " td").each(function() {
$this = $(this);
$this.find("code").each(function() {
if (!$(this).text().startsWith("VK_FORMAT_FEATURE") &&
$(this).text().startsWith("VK_FORMAT")) {
// Found one vkFormat to features line.
var vkFormat = $(this).text();
var squareIndex = 0;
var features = [];
var skipEntry = false;
$(this).closest("tr").find("td.halign-center").each(function() {
// Find all squares with features.
if ($(this).text() === "✓") {
features.push(indexToFeatureMap[squareIndex]);
}
if ($(this).text() === "†") {
skipEntry = true;
return false; // Break;
}
squareIndex++;
});
if (!skipEntry &&
(features.length > 0)) {
Object.defineProperty(outputJson, vkFormat, {
value: features,
enumerable: true,
readable: true,
writable: false
});
}
}
});
});
}
$("#result").text(JSON.stringify(outputJson));
#!/usr/bin/python
# Copyright 2018 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_vk_mandatory_format_support_table.py:
# Code generation for mandatory formats supported by Vulkan.
from datetime import date
import sys
sys.path.append('..')
import angle_format
import xml.etree.ElementTree as etree
import sys, os
template_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name} and
// the vk.xml file situated at
// /third_party/vulkan-validation-layers/src/scripts/vk.xml
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// {out_file_name}:
// Queries for full Vulkan mandatory format support information based on VK format.
#include "libANGLE/renderer/vulkan/vk_format_utils.h"
using namespace angle;
namespace
{{
constexpr std::array<VkFormatProperties, {num_formats}> kFormatProperties = {{{{
{format_case_data}
}}}};
}} // anonymous namespace
namespace rx
{{
namespace vk
{{
const VkFormatProperties& GetMandatoryFormatSupport(VkFormat vkFormat)
{{
ASSERT(static_cast<uint64_t>(vkFormat) < sizeof(kFormatProperties));
return kFormatProperties[vkFormat];
}}
}} // namespace vk
}} // namespace rx
"""
template_format_property = """
/* {vk_format} */
{{{{}}, {optimal_features}, {buffer_features}}}"""
def script_relative(path):
return os.path.join(os.path.dirname(sys.argv[0]), path)
def gen_format_case(index, vk_to_index_to_format_map, vk_map):
vk_format = vk_to_index_to_format_map[index]
if vk_format in vk_map and len(vk_map[vk_format]) > 0:
# Check which feature is a buffer feature or not.
buffer_features = [x for x in vk_map[vk_format] if x.find("_BUFFER_") != -1]
optimal_features = [x for x in vk_map[vk_format] if x.find("_BUFFER_") == -1]
optimal_features_str = "|".join(optimal_features) if len(optimal_features) else "0"
buffer_features_str = "|".join(buffer_features) if len(buffer_features) else "0"
else:
optimal_features_str = "0"
buffer_features_str = "0"
return template_format_property.format(
vk_format = vk_format,
optimal_features = optimal_features_str,
buffer_features = buffer_features_str)
input_file_name = 'vk_mandatory_format_support_data.json'
out_file_name = 'vk_mandatory_format_support_table'
tree = etree.parse(script_relative('../../../../third_party/vulkan-validation-layers/src/scripts/vk.xml'))
root = tree.getroot()
vk_format_enums = root.findall(".//enums[@name='VkFormat']/enum")
vk_format_name_to_index_map = {}
num_formats = len(vk_format_enums)
for format_enum in vk_format_enums:
index = int(format_enum.attrib['value'])
vk_format = format_enum.attrib['name']
vk_format_name_to_index_map[index] = vk_format
vk_map = angle_format.load_json(input_file_name)
vk_cases = [gen_format_case(index, vk_format_name_to_index_map, vk_map) for index in vk_format_name_to_index_map]
output_cpp = template_table_autogen_cpp.format(
copyright_year = date.today().year,
num_formats = num_formats,
format_case_data = "\n,".join(vk_cases),
script_name = __file__,
out_file_name = out_file_name,
input_file_name = input_file_name)
with open(out_file_name + '_autogen.cpp', 'wt') as out_file:
out_file.write(output_cpp)
out_file.close()
......@@ -128,18 +128,16 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties,
outCaps->maxVaryingVectors = physicalDeviceProperties.limits.maxVertexOutputComponents / 4;
}
gl::TextureCaps GenerateTextureFormatCaps(const VkFormatProperties &formatProperties)
void FillTextureFormatCaps(const VkFormatProperties &formatProperties,
gl::TextureCaps *outTextureCaps)
{
gl::TextureCaps textureCaps;
textureCaps.texturable =
outTextureCaps->texturable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, formatProperties);
textureCaps.filterable =
outTextureCaps->filterable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, formatProperties);
textureCaps.renderable =
outTextureCaps->renderable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, formatProperties) ||
HasFormatFeatureBits(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, formatProperties);
return textureCaps;
}
} // namespace vk
} // namespace rx
......@@ -34,7 +34,9 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties,
gl::Extensions *outExtensions,
gl::Limitations * /* outLimitations */);
gl::TextureCaps GenerateTextureFormatCaps(const VkFormatProperties &formatProperties);
void FillTextureFormatCaps(const VkFormatProperties &formatProperties,
gl::TextureCaps *outTextureCaps);
} // namespace vk
} // namespace rx
......
......@@ -12,6 +12,16 @@
#include "libANGLE/renderer/load_functions_table.h"
#include "vk_caps_utils.h"
namespace
{
constexpr VkFormatFeatureFlags kNecessaryBitsFullSupportDepthStencil =
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
constexpr VkFormatFeatureFlags kNecessaryBitsFullSupportColor =
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
} // anonymous namespace
namespace rx
{
......@@ -53,7 +63,7 @@ void FormatTable::initialize(VkPhysicalDevice physicalDevice,
{
for (size_t formatIndex = 0; formatIndex < angle::kNumANGLEFormats; ++formatIndex)
{
const angle::Format::ID formatID = static_cast<angle::Format::ID>(formatIndex);
const auto formatID = static_cast<angle::Format::ID>(formatIndex);
const angle::Format &angleFormat = angle::Format::Get(formatID);
mFormatData[formatIndex].initialize(physicalDevice, angleFormat);
const GLenum internalFormat = mFormatData[formatIndex].internalFormat;
......@@ -66,11 +76,31 @@ void FormatTable::initialize(VkPhysicalDevice physicalDevice,
// http://anglebug.com/2358
continue;
}
VkFormatProperties formatProperties;
vkGetPhysicalDeviceFormatProperties(
physicalDevice, mFormatData[formatIndex].vkTextureFormat, &formatProperties);
const gl::TextureCaps textureCaps = GenerateTextureFormatCaps(formatProperties);
const VkFormat vkFormat = mFormatData[formatIndex].vkTextureFormat;
// Try filling out the info from our hard coded format data, if we can't find the
// information we need, we'll make the call to Vulkan.
const VkFormatProperties &formatProperties = GetMandatoryFormatSupport(vkFormat);
gl::TextureCaps textureCaps;
// Once we filled what we could with the mandatory texture caps, we verify if
// all the bits we need to satify all our checks are present, and if so we can
// skip the device call.
if (!IsMaskFlagSet(formatProperties.optimalTilingFeatures,
kNecessaryBitsFullSupportColor) &&
!IsMaskFlagSet(formatProperties.optimalTilingFeatures,
kNecessaryBitsFullSupportDepthStencil))
{
VkFormatProperties queriedFormatProperties;
vkGetPhysicalDeviceFormatProperties(physicalDevice, vkFormat, &queriedFormatProperties);
FillTextureFormatCaps(queriedFormatProperties, &textureCaps);
}
else
{
FillTextureFormatCaps(formatProperties, &textureCaps);
}
outTextureCapsMap->set(formatID, textureCaps);
// TODO(lucferron): Optimize this by including compressed bool in the FormatID
......
......@@ -70,6 +70,12 @@ class FormatTable final : angle::NonCopyable
// TODO(jmadill): This is temporary. Figure out how to handle format conversions.
VkFormat GetNativeVertexFormat(gl::VertexFormatType vertexFormat);
// This will return a reference to a VkFormatProperties with the feature flags supported
// if the format is a mandatory format described in section 31.3.3. Required Format Support
// of the Vulkan spec. If the vkFormat isn't mandatory, it will return a VkFormatProperties
// initialized to 0.
const VkFormatProperties &GetMandatoryFormatSupport(VkFormat vkFormat);
} // namespace vk
} // namespace rx
......
......@@ -764,6 +764,7 @@
'libANGLE/renderer/vulkan/vk_format_table_autogen.cpp',
'libANGLE/renderer/vulkan/vk_format_utils.h',
'libANGLE/renderer/vulkan/vk_format_utils.cpp',
'libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp',
'libANGLE/renderer/vulkan/vk_utils.cpp',
'libANGLE/renderer/vulkan/vk_utils.h',
],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment