[SPIR-V] Version, float controls
This commit is contained in:
parent
cacf702948
commit
52a8ed8e6d
|
@ -108,9 +108,10 @@ int shader_compiler_main(const std::vector<std::string>& args) {
|
||||||
shader_type, ucode_data_hash, ucode_dwords.data(), ucode_dwords.size());
|
shader_type, ucode_data_hash, ucode_dwords.data(), ucode_dwords.size());
|
||||||
|
|
||||||
std::unique_ptr<ShaderTranslator> translator;
|
std::unique_ptr<ShaderTranslator> translator;
|
||||||
|
SpirvShaderTranslator::Features spirv_features(true);
|
||||||
if (cvars::shader_output_type == "spirv" ||
|
if (cvars::shader_output_type == "spirv" ||
|
||||||
cvars::shader_output_type == "spirvtext") {
|
cvars::shader_output_type == "spirvtext") {
|
||||||
translator = std::make_unique<SpirvShaderTranslator>();
|
translator = std::make_unique<SpirvShaderTranslator>(spirv_features);
|
||||||
} else if (cvars::shader_output_type == "dxbc" ||
|
} else if (cvars::shader_output_type == "dxbc" ||
|
||||||
cvars::shader_output_type == "dxbctext") {
|
cvars::shader_output_type == "dxbctext") {
|
||||||
translator = std::make_unique<DxbcShaderTranslator>(
|
translator = std::make_unique<DxbcShaderTranslator>(
|
||||||
|
@ -161,7 +162,7 @@ int shader_compiler_main(const std::vector<std::string>& args) {
|
||||||
spv::Disassemble(spirv_disasm_stream, spirv_source);
|
spv::Disassemble(spirv_disasm_stream, spirv_source);
|
||||||
spirv_disasm = std::move(spirv_disasm_stream.str());
|
spirv_disasm = std::move(spirv_disasm_stream.str());
|
||||||
ui::vulkan::SpirvToolsContext spirv_tools_context;
|
ui::vulkan::SpirvToolsContext spirv_tools_context;
|
||||||
if (spirv_tools_context.Initialize()) {
|
if (spirv_tools_context.Initialize(spirv_features.spirv_version)) {
|
||||||
std::string spirv_validation_error;
|
std::string spirv_validation_error;
|
||||||
spirv_tools_context.Validate(
|
spirv_tools_context.Validate(
|
||||||
reinterpret_cast<const uint32_t*>(spirv_source.data()),
|
reinterpret_cast<const uint32_t*>(spirv_source.data()),
|
||||||
|
|
|
@ -20,10 +20,34 @@
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
SpirvShaderTranslator::SpirvShaderTranslator(bool supports_clip_distance,
|
SpirvShaderTranslator::Features::Features(bool all)
|
||||||
bool supports_cull_distance)
|
: spirv_version(all ? spv::Spv_1_5 : spv::Spv_1_0),
|
||||||
: supports_clip_distance_(supports_clip_distance),
|
clip_distance(all),
|
||||||
supports_cull_distance_(supports_cull_distance) {}
|
cull_distance(all),
|
||||||
|
float_controls(all) {}
|
||||||
|
|
||||||
|
SpirvShaderTranslator::Features::Features(
|
||||||
|
const ui::vulkan::VulkanProvider& provider)
|
||||||
|
: clip_distance(provider.device_features().shaderClipDistance),
|
||||||
|
cull_distance(provider.device_features().shaderCullDistance) {
|
||||||
|
uint32_t device_version = provider.device_properties().apiVersion;
|
||||||
|
const ui::vulkan::VulkanProvider::DeviceExtensions& device_extensions =
|
||||||
|
provider.device_extensions();
|
||||||
|
if (device_version >= VK_MAKE_VERSION(1, 2, 0)) {
|
||||||
|
spirv_version = spv::Spv_1_5;
|
||||||
|
} else if (device_extensions.khr_spirv_1_4) {
|
||||||
|
spirv_version = spv::Spv_1_4;
|
||||||
|
} else if (device_version >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||||
|
spirv_version = spv::Spv_1_3;
|
||||||
|
} else {
|
||||||
|
spirv_version = spv::Spv_1_0;
|
||||||
|
}
|
||||||
|
float_controls = spirv_version >= spv::Spv_1_4 ||
|
||||||
|
device_extensions.khr_shader_float_controls;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpirvShaderTranslator::SpirvShaderTranslator(const Features& features)
|
||||||
|
: features_(features) {}
|
||||||
|
|
||||||
void SpirvShaderTranslator::Reset() {
|
void SpirvShaderTranslator::Reset() {
|
||||||
ShaderTranslator::Reset();
|
ShaderTranslator::Reset();
|
||||||
|
@ -32,6 +56,7 @@ void SpirvShaderTranslator::Reset() {
|
||||||
|
|
||||||
uniform_float_constants_ = spv::NoResult;
|
uniform_float_constants_ = spv::NoResult;
|
||||||
|
|
||||||
|
main_interface_.clear();
|
||||||
var_main_registers_ = spv::NoResult;
|
var_main_registers_ = spv::NoResult;
|
||||||
|
|
||||||
main_switch_op_.reset();
|
main_switch_op_.reset();
|
||||||
|
@ -45,10 +70,16 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
// Tool ID 26 "Xenia Emulator Microcode Translator".
|
// Tool ID 26 "Xenia Emulator Microcode Translator".
|
||||||
// https://github.com/KhronosGroup/SPIRV-Headers/blob/c43a43c7cc3af55910b9bec2a71e3e8a622443cf/include/spirv/spir-v.xml#L79
|
// https://github.com/KhronosGroup/SPIRV-Headers/blob/c43a43c7cc3af55910b9bec2a71e3e8a622443cf/include/spirv/spir-v.xml#L79
|
||||||
// TODO(Triang3l): Logger.
|
// TODO(Triang3l): Logger.
|
||||||
builder_ = std::make_unique<spv::Builder>(1 << 16, (26 << 16) | 1, nullptr);
|
builder_ = std::make_unique<spv::Builder>(features_.spirv_version,
|
||||||
|
(26 << 16) | 1, nullptr);
|
||||||
|
|
||||||
builder_->addCapability(IsSpirvTessEvalShader() ? spv::CapabilityTessellation
|
builder_->addCapability(IsSpirvTessEvalShader() ? spv::CapabilityTessellation
|
||||||
: spv::CapabilityShader);
|
: spv::CapabilityShader);
|
||||||
|
if (features_.spirv_version < spv::Spv_1_4) {
|
||||||
|
if (features_.float_controls) {
|
||||||
|
builder_->addExtension("SPV_KHR_float_controls");
|
||||||
|
}
|
||||||
|
}
|
||||||
ext_inst_glsl_std_450_ = builder_->import("GLSL.std.450");
|
ext_inst_glsl_std_450_ = builder_->import("GLSL.std.450");
|
||||||
builder_->setMemoryModel(spv::AddressingModelLogical,
|
builder_->setMemoryModel(spv::AddressingModelLogical,
|
||||||
spv::MemoryModelGLSL450);
|
spv::MemoryModelGLSL450);
|
||||||
|
@ -133,6 +164,9 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
: kDescriptorSetFloatConstantsVertex));
|
: kDescriptorSetFloatConstantsVertex));
|
||||||
builder_->addDecoration(uniform_float_constants_, spv::DecorationBinding,
|
builder_->addDecoration(uniform_float_constants_, spv::DecorationBinding,
|
||||||
0);
|
0);
|
||||||
|
if (features_.spirv_version >= spv::Spv_1_4) {
|
||||||
|
main_interface_.push_back(uniform_float_constants_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common uniform buffer - bool and loop constants.
|
// Common uniform buffer - bool and loop constants.
|
||||||
|
@ -168,6 +202,9 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
int(kDescriptorSetBoolLoopConstants));
|
int(kDescriptorSetBoolLoopConstants));
|
||||||
builder_->addDecoration(uniform_bool_loop_constants_, spv::DecorationBinding,
|
builder_->addDecoration(uniform_bool_loop_constants_, spv::DecorationBinding,
|
||||||
0);
|
0);
|
||||||
|
if (features_.spirv_version >= spv::Spv_1_4) {
|
||||||
|
main_interface_.push_back(uniform_bool_loop_constants_);
|
||||||
|
}
|
||||||
|
|
||||||
if (IsSpirvVertexOrTessEvalShader()) {
|
if (IsSpirvVertexOrTessEvalShader()) {
|
||||||
StartVertexOrTessEvalShaderBeforeMain();
|
StartVertexOrTessEvalShaderBeforeMain();
|
||||||
|
@ -364,11 +401,23 @@ std::vector<uint8_t> SpirvShaderTranslator::CompleteTranslation() {
|
||||||
? spv::ExecutionModelTessellationEvaluation
|
? spv::ExecutionModelTessellationEvaluation
|
||||||
: spv::ExecutionModelVertex;
|
: spv::ExecutionModelVertex;
|
||||||
}
|
}
|
||||||
|
if (features_.float_controls) {
|
||||||
|
// Flush to zero, similar to the real hardware, also for things like Shader
|
||||||
|
// Model 3 multiplication emulation.
|
||||||
|
builder_->addCapability(spv::CapabilityDenormFlushToZero);
|
||||||
|
builder_->addExecutionMode(function_main_,
|
||||||
|
spv::ExecutionModeDenormFlushToZero, 32);
|
||||||
|
// Signed zero used to get VFACE from ps_param_gen, also special behavior
|
||||||
|
// for infinity in certain instructions (such as logarithm, reciprocal,
|
||||||
|
// muls_prev2).
|
||||||
|
builder_->addCapability(spv::CapabilitySignedZeroInfNanPreserve);
|
||||||
|
builder_->addExecutionMode(function_main_,
|
||||||
|
spv::ExecutionModeSignedZeroInfNanPreserve, 32);
|
||||||
|
}
|
||||||
spv::Instruction* entry_point =
|
spv::Instruction* entry_point =
|
||||||
builder_->addEntryPoint(execution_model, function_main_, "main");
|
builder_->addEntryPoint(execution_model, function_main_, "main");
|
||||||
|
for (spv::Id interface_id : main_interface_) {
|
||||||
if (IsSpirvVertexOrTessEvalShader()) {
|
entry_point->addIdOperand(interface_id);
|
||||||
CompleteVertexOrTessEvalShaderAfterMain(entry_point);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Triang3l): Avoid copy?
|
// TODO(Triang3l): Avoid copy?
|
||||||
|
@ -721,11 +770,13 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderBeforeMain() {
|
||||||
spv::NoPrecision, spv::StorageClassInput, type_int_, "gl_PrimitiveID");
|
spv::NoPrecision, spv::StorageClassInput, type_int_, "gl_PrimitiveID");
|
||||||
builder_->addDecoration(input_primitive_id_, spv::DecorationBuiltIn,
|
builder_->addDecoration(input_primitive_id_, spv::DecorationBuiltIn,
|
||||||
spv::BuiltInPrimitiveId);
|
spv::BuiltInPrimitiveId);
|
||||||
|
main_interface_.push_back(input_primitive_id_);
|
||||||
} else {
|
} else {
|
||||||
input_vertex_index_ = builder_->createVariable(
|
input_vertex_index_ = builder_->createVariable(
|
||||||
spv::NoPrecision, spv::StorageClassInput, type_int_, "gl_VertexIndex");
|
spv::NoPrecision, spv::StorageClassInput, type_int_, "gl_VertexIndex");
|
||||||
builder_->addDecoration(input_vertex_index_, spv::DecorationBuiltIn,
|
builder_->addDecoration(input_vertex_index_, spv::DecorationBuiltIn,
|
||||||
spv::BuiltInVertexIndex);
|
spv::BuiltInVertexIndex);
|
||||||
|
main_interface_.push_back(input_vertex_index_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the entire GLSL 4.50 gl_PerVertex output similar to what glslang
|
// Create the entire GLSL 4.50 gl_PerVertex output similar to what glslang
|
||||||
|
@ -733,10 +784,10 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderBeforeMain() {
|
||||||
// ClipDistance and CullDistance may exist even if the device doesn't support
|
// ClipDistance and CullDistance may exist even if the device doesn't support
|
||||||
// them, as long as the capabilities aren't enabled, and nothing is stored to
|
// them, as long as the capabilities aren't enabled, and nothing is stored to
|
||||||
// them.
|
// them.
|
||||||
if (supports_clip_distance_) {
|
if (features_.clip_distance) {
|
||||||
builder_->addCapability(spv::CapabilityClipDistance);
|
builder_->addCapability(spv::CapabilityClipDistance);
|
||||||
}
|
}
|
||||||
if (supports_cull_distance_) {
|
if (features_.cull_distance) {
|
||||||
builder_->addCapability(spv::CapabilityCullDistance);
|
builder_->addCapability(spv::CapabilityCullDistance);
|
||||||
}
|
}
|
||||||
std::vector<spv::Id> struct_per_vertex_members;
|
std::vector<spv::Id> struct_per_vertex_members;
|
||||||
|
@ -746,7 +797,7 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderBeforeMain() {
|
||||||
// TODO(Triang3l): Specialization constant for ucp_cull_only_ena, for 6 + 1
|
// TODO(Triang3l): Specialization constant for ucp_cull_only_ena, for 6 + 1
|
||||||
// or 1 + 7 array sizes.
|
// or 1 + 7 array sizes.
|
||||||
struct_per_vertex_members.push_back(builder_->makeArrayType(
|
struct_per_vertex_members.push_back(builder_->makeArrayType(
|
||||||
type_float_, builder_->makeUintConstant(supports_clip_distance_ ? 6 : 1),
|
type_float_, builder_->makeUintConstant(features_.clip_distance ? 6 : 1),
|
||||||
0));
|
0));
|
||||||
struct_per_vertex_members.push_back(
|
struct_per_vertex_members.push_back(
|
||||||
builder_->makeArrayType(type_float_, builder_->makeUintConstant(1), 0));
|
builder_->makeArrayType(type_float_, builder_->makeUintConstant(1), 0));
|
||||||
|
@ -777,6 +828,7 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderBeforeMain() {
|
||||||
output_per_vertex_ =
|
output_per_vertex_ =
|
||||||
builder_->createVariable(spv::NoPrecision, spv::StorageClassOutput,
|
builder_->createVariable(spv::NoPrecision, spv::StorageClassOutput,
|
||||||
type_struct_per_vertex, "xe_out_gl_PerVertex");
|
type_struct_per_vertex, "xe_out_gl_PerVertex");
|
||||||
|
main_interface_.push_back(output_per_vertex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpirvShaderTranslator::StartVertexOrTessEvalShaderInMain() {
|
void SpirvShaderTranslator::StartVertexOrTessEvalShaderInMain() {
|
||||||
|
@ -787,16 +839,6 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderInMain() {
|
||||||
|
|
||||||
void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {}
|
void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {}
|
||||||
|
|
||||||
void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderAfterMain(
|
|
||||||
spv::Instruction* entry_point) {
|
|
||||||
if (IsSpirvTessEvalShader()) {
|
|
||||||
entry_point->addIdOperand(input_primitive_id_);
|
|
||||||
} else {
|
|
||||||
entry_point->addIdOperand(input_vertex_index_);
|
|
||||||
}
|
|
||||||
entry_point->addIdOperand(output_per_vertex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpirvShaderTranslator::UpdateExecConditionals(
|
void SpirvShaderTranslator::UpdateExecConditionals(
|
||||||
ParsedExecInstruction::Type type, uint32_t bool_constant_index,
|
ParsedExecInstruction::Type type, uint32_t bool_constant_index,
|
||||||
bool condition) {
|
bool condition) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "third_party/glslang/SPIRV/SpvBuilder.h"
|
#include "third_party/glslang/SPIRV/SpvBuilder.h"
|
||||||
#include "xenia/gpu/shader_translator.h"
|
#include "xenia/gpu/shader_translator.h"
|
||||||
|
#include "xenia/ui/vulkan/vulkan_provider.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
@ -46,8 +47,16 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||||
kDescriptorSetSharedMemoryAndEdram,
|
kDescriptorSetSharedMemoryAndEdram,
|
||||||
kDescriptorSetCount,
|
kDescriptorSetCount,
|
||||||
};
|
};
|
||||||
SpirvShaderTranslator(bool supports_clip_distance = true,
|
|
||||||
bool supports_cull_distance = true);
|
struct Features {
|
||||||
|
explicit Features(const ui::vulkan::VulkanProvider& provider);
|
||||||
|
explicit Features(bool all = false);
|
||||||
|
unsigned int spirv_version;
|
||||||
|
bool clip_distance;
|
||||||
|
bool cull_distance;
|
||||||
|
bool float_controls;
|
||||||
|
};
|
||||||
|
SpirvShaderTranslator(const Features& features);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
|
@ -90,7 +99,6 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||||
void StartVertexOrTessEvalShaderBeforeMain();
|
void StartVertexOrTessEvalShaderBeforeMain();
|
||||||
void StartVertexOrTessEvalShaderInMain();
|
void StartVertexOrTessEvalShaderInMain();
|
||||||
void CompleteVertexOrTessEvalShaderInMain();
|
void CompleteVertexOrTessEvalShaderInMain();
|
||||||
void CompleteVertexOrTessEvalShaderAfterMain(spv::Instruction* entry_point);
|
|
||||||
|
|
||||||
// Updates the current flow control condition (to be called in the beginning
|
// Updates the current flow control condition (to be called in the beginning
|
||||||
// of exec and in jumps), closing the previous conditionals if needed.
|
// of exec and in jumps), closing the previous conditionals if needed.
|
||||||
|
@ -148,8 +156,7 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||||
spv::Id ProcessVectorAluOperation(const ParsedAluInstruction& instr,
|
spv::Id ProcessVectorAluOperation(const ParsedAluInstruction& instr,
|
||||||
bool& predicate_written);
|
bool& predicate_written);
|
||||||
|
|
||||||
bool supports_clip_distance_;
|
Features features_;
|
||||||
bool supports_cull_distance_;
|
|
||||||
|
|
||||||
std::unique_ptr<spv::Builder> builder_;
|
std::unique_ptr<spv::Builder> builder_;
|
||||||
|
|
||||||
|
@ -223,6 +230,7 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||||
};
|
};
|
||||||
spv::Id output_per_vertex_;
|
spv::Id output_per_vertex_;
|
||||||
|
|
||||||
|
std::vector<spv::Id> main_interface_;
|
||||||
spv::Function* function_main_;
|
spv::Function* function_main_;
|
||||||
// bool.
|
// bool.
|
||||||
spv::Id var_main_predicate_;
|
spv::Id var_main_predicate_;
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace xe {
|
||||||
namespace ui {
|
namespace ui {
|
||||||
namespace vulkan {
|
namespace vulkan {
|
||||||
|
|
||||||
bool SpirvToolsContext::Initialize() {
|
bool SpirvToolsContext::Initialize(unsigned int spirv_version) {
|
||||||
const char* vulkan_sdk_env = std::getenv("VULKAN_SDK");
|
const char* vulkan_sdk_env = std::getenv("VULKAN_SDK");
|
||||||
if (!vulkan_sdk_env) {
|
if (!vulkan_sdk_env) {
|
||||||
XELOGE("SPIRV-Tools: Failed to get the VULKAN_SDK environment variable");
|
XELOGE("SPIRV-Tools: Failed to get the VULKAN_SDK environment variable");
|
||||||
|
@ -63,7 +63,17 @@ bool SpirvToolsContext::Initialize() {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
context_ = fn_spvContextCreate_(SPV_ENV_VULKAN_1_0);
|
spv_target_env target_env;
|
||||||
|
if (spirv_version >= 0x10500) {
|
||||||
|
target_env = SPV_ENV_VULKAN_1_2;
|
||||||
|
} else if (spirv_version >= 0x10400) {
|
||||||
|
target_env = SPV_ENV_VULKAN_1_1_SPIRV_1_4;
|
||||||
|
} else if (spirv_version >= 0x10300) {
|
||||||
|
target_env = SPV_ENV_VULKAN_1_1;
|
||||||
|
} else {
|
||||||
|
target_env = SPV_ENV_VULKAN_1_0;
|
||||||
|
}
|
||||||
|
context_ = fn_spvContextCreate_(target_env);
|
||||||
if (!context_) {
|
if (!context_) {
|
||||||
XELOGE("SPIRV-Tools: Failed to create a Vulkan 1.0 context");
|
XELOGE("SPIRV-Tools: Failed to create a Vulkan 1.0 context");
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
|
|
@ -32,7 +32,7 @@ class SpirvToolsContext {
|
||||||
SpirvToolsContext(const SpirvToolsContext& context) = delete;
|
SpirvToolsContext(const SpirvToolsContext& context) = delete;
|
||||||
SpirvToolsContext& operator=(const SpirvToolsContext& context) = delete;
|
SpirvToolsContext& operator=(const SpirvToolsContext& context) = delete;
|
||||||
~SpirvToolsContext() { Shutdown(); }
|
~SpirvToolsContext() { Shutdown(); }
|
||||||
bool Initialize();
|
bool Initialize(unsigned int spirv_version);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
spv_result_t Validate(const uint32_t* words, size_t num_words,
|
spv_result_t Validate(const uint32_t* words, size_t num_words,
|
||||||
|
|
|
@ -392,6 +392,10 @@ bool VulkanProvider::Initialize() {
|
||||||
std::memset(&device_extensions_, 0, sizeof(device_extensions_));
|
std::memset(&device_extensions_, 0, sizeof(device_extensions_));
|
||||||
if (device_properties_.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
if (device_properties_.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||||
device_extensions_.khr_dedicated_allocation = true;
|
device_extensions_.khr_dedicated_allocation = true;
|
||||||
|
if (device_properties_.apiVersion >= VK_MAKE_VERSION(1, 2, 0)) {
|
||||||
|
device_extensions_.khr_shader_float_controls = true;
|
||||||
|
device_extensions_.khr_spirv_1_4 = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool device_supports_swapchain = false;
|
bool device_supports_swapchain = false;
|
||||||
for (const VkExtensionProperties& device_extension :
|
for (const VkExtensionProperties& device_extension :
|
||||||
|
@ -405,6 +409,13 @@ bool VulkanProvider::Initialize() {
|
||||||
!std::strcmp(device_extension_name,
|
!std::strcmp(device_extension_name,
|
||||||
"VK_KHR_dedicated_allocation")) {
|
"VK_KHR_dedicated_allocation")) {
|
||||||
device_extensions_.khr_dedicated_allocation = true;
|
device_extensions_.khr_dedicated_allocation = true;
|
||||||
|
} else if (!device_extensions_.khr_shader_float_controls &&
|
||||||
|
!std::strcmp(device_extension_name,
|
||||||
|
"VK_KHR_shader_float_controls")) {
|
||||||
|
device_extensions_.khr_shader_float_controls = true;
|
||||||
|
} else if (!device_extensions_.khr_spirv_1_4 &&
|
||||||
|
!std::strcmp(device_extension_name, "VK_KHR_spirv_1_4")) {
|
||||||
|
device_extensions_.khr_spirv_1_4 = true;
|
||||||
} else if (!device_supports_swapchain &&
|
} else if (!device_supports_swapchain &&
|
||||||
!std::strcmp(device_extension_name, "VK_KHR_swapchain")) {
|
!std::strcmp(device_extension_name, "VK_KHR_swapchain")) {
|
||||||
device_supports_swapchain = true;
|
device_supports_swapchain = true;
|
||||||
|
@ -466,6 +477,10 @@ bool VulkanProvider::Initialize() {
|
||||||
device_extensions_.ext_fragment_shader_interlock ? "yes" : "no");
|
device_extensions_.ext_fragment_shader_interlock ? "yes" : "no");
|
||||||
XELOGVK("* VK_KHR_dedicated_allocation: {}",
|
XELOGVK("* VK_KHR_dedicated_allocation: {}",
|
||||||
device_extensions_.khr_dedicated_allocation ? "yes" : "no");
|
device_extensions_.khr_dedicated_allocation ? "yes" : "no");
|
||||||
|
XELOGVK("* VK_KHR_shader_float_controls: {}",
|
||||||
|
device_extensions_.khr_shader_float_controls ? "yes" : "no");
|
||||||
|
XELOGVK("* VK_KHR_spirv_1_4: {}",
|
||||||
|
device_extensions_.khr_spirv_1_4 ? "yes" : "no");
|
||||||
// TODO(Triang3l): Report properties, features.
|
// TODO(Triang3l): Report properties, features.
|
||||||
|
|
||||||
// Create the device.
|
// Create the device.
|
||||||
|
@ -493,9 +508,17 @@ bool VulkanProvider::Initialize() {
|
||||||
if (device_extensions_.ext_fragment_shader_interlock) {
|
if (device_extensions_.ext_fragment_shader_interlock) {
|
||||||
device_extensions_enabled.push_back("VK_EXT_fragment_shader_interlock");
|
device_extensions_enabled.push_back("VK_EXT_fragment_shader_interlock");
|
||||||
}
|
}
|
||||||
if (device_properties_.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
|
if (device_properties_.apiVersion < VK_MAKE_VERSION(1, 2, 0)) {
|
||||||
if (device_extensions_.khr_dedicated_allocation) {
|
if (device_properties_.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
|
||||||
device_extensions_enabled.push_back("VK_KHR_dedicated_allocation");
|
if (device_extensions_.khr_dedicated_allocation) {
|
||||||
|
device_extensions_enabled.push_back("VK_KHR_dedicated_allocation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (device_extensions_.khr_shader_float_controls) {
|
||||||
|
device_extensions_enabled.push_back("VK_KHR_shader_float_controls");
|
||||||
|
}
|
||||||
|
if (device_extensions_.khr_spirv_1_4) {
|
||||||
|
device_extensions_enabled.push_back("VK_KHR_spirv_1_4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VkDeviceCreateInfo device_create_info;
|
VkDeviceCreateInfo device_create_info;
|
||||||
|
|
|
@ -104,6 +104,10 @@ class VulkanProvider : public GraphicsProvider {
|
||||||
bool ext_fragment_shader_interlock;
|
bool ext_fragment_shader_interlock;
|
||||||
// Core since 1.1.0.
|
// Core since 1.1.0.
|
||||||
bool khr_dedicated_allocation;
|
bool khr_dedicated_allocation;
|
||||||
|
// Core since 1.2.0.
|
||||||
|
bool khr_shader_float_controls;
|
||||||
|
// Core since 1.2.0.
|
||||||
|
bool khr_spirv_1_4;
|
||||||
};
|
};
|
||||||
const DeviceExtensions& device_extensions() const {
|
const DeviceExtensions& device_extensions() const {
|
||||||
return device_extensions_;
|
return device_extensions_;
|
||||||
|
|
Loading…
Reference in New Issue