Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions include/amber/amber_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ struct VulkanEngineConfig : public EngineConfig {
/// the extension is not enabled, |available_features| will be used.
VkPhysicalDeviceFeatures2KHR available_features2;

/// Physical device properties available for |physical_device|. The
/// |available_properties| will be ignored if
/// VK_KHR_get_physical_device_properties2 is enabled, |available_properties2|
/// will be used in that case.
VkPhysicalDeviceProperties available_properties;

/// Physical device properties for |physical_device|.The
/// |available_properties2| will only be used if
/// VK_KHR_get_physical_device_properties2 is enabled. If the extension is not
/// enabled, |available_properties| will be used.
VkPhysicalDeviceProperties2KHR available_properties2;

/// Instance extensions available.
std::vector<std::string> available_instance_extensions;

Expand Down
6 changes: 6 additions & 0 deletions include/amber/recipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class RecipeImpl {
/// Returns required features in the given recipe.
virtual std::vector<std::string> GetRequiredFeatures() const = 0;

/// Returns required features in the given recipe.
virtual std::vector<std::string> GetRequiredProperties() const = 0;

/// Returns required device extensions in the given recipe.
virtual std::vector<std::string> GetRequiredDeviceExtensions() const = 0;

Expand Down Expand Up @@ -67,6 +70,9 @@ class Recipe {
/// Returns required features in the given recipe.
std::vector<std::string> GetRequiredFeatures() const;

/// Returns required properties in the given recipe.
std::vector<std::string> GetRequiredProperties() const;

/// Returns required device extensions in the given recipe.
std::vector<std::string> GetRequiredDeviceExtensions() const;

Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ if (${AMBER_ENABLE_TESTS})
amberscript/parser_copy_test.cc
amberscript/parser_depth_test.cc
amberscript/parser_device_feature_test.cc
amberscript/parser_device_property_test.cc
amberscript/parser_expect_test.cc
amberscript/parser_extension_test.cc
amberscript/parser_framebuffer_test.cc
Expand Down
1 change: 1 addition & 0 deletions src/amber.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Result CreateEngineAndCheckRequirements(const Recipe* recipe,
// much else. Refactor this if they end up doing to much here.
Result r =
engine->Initialize(opts->config, delegate, script->GetRequiredFeatures(),
script->GetRequiredProperties(),
script->GetRequiredInstanceExtensions(),
script->GetRequiredDeviceExtensions());
if (!r.IsSuccess())
Expand Down
16 changes: 16 additions & 0 deletions src/amberscript/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ Result Parser::Parse(const std::string& data) {
r = ParseDeviceFeature();
} else if (tok == "DEVICE_EXTENSION") {
r = ParseDeviceExtension();
} else if (tok == "DEVICE_PROPERTY") {
r = ParseDeviceProperty();
} else if (tok == "IMAGE") {
r = ParseImage();
} else if (tok == "INSTANCE_EXTENSION") {
Expand Down Expand Up @@ -3421,6 +3423,20 @@ Result Parser::ParseDeviceFeature() {
return ValidateEndOfStatement("DEVICE_FEATURE command");
}

Result Parser::ParseDeviceProperty() {
auto token = tokenizer_->NextToken();
if (token->IsEOS() || token->IsEOL())
return Result("missing property name for DEVICE_PROPERTY command");
if (!token->IsIdentifier())
return Result("invalid property name for DEVICE_PROPERTY command");
if (!script_->IsKnownProperty(token->AsString()))
return Result("unknown property name for DEVICE_PROPERTY command");

script_->AddRequiredProperty(token->AsString());

return ValidateEndOfStatement("DEVICE_PROPERTY command");
}

Result Parser::ParseRepeat() {
auto token = tokenizer_->NextToken();
if (token->IsEOL() || token->IsEOL())
Expand Down
1 change: 1 addition & 0 deletions src/amberscript/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class Parser : public amber::Parser {
Result ParseCopy();
Result ParseDeviceFeature();
Result ParseDeviceExtension();
Result ParseDeviceProperty();
Result ParseInstanceExtension();
Result ParseRepeat();
Result ParseSet();
Expand Down
120 changes: 120 additions & 0 deletions src/amberscript/parser_device_property_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright 2024 The Amber Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or parseried.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "gtest/gtest.h"
#include "src/amberscript/parser.h"

namespace amber {
namespace amberscript {

using AmberScriptParserTest = testing::Test;

TEST_F(AmberScriptParserTest, DeviceProperty) {
std::string in = R"(
DEVICE_PROPERTY FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat16
DEVICE_PROPERTY FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat32
DEVICE_PROPERTY FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat64
DEVICE_PROPERTY FloatControlsProperties.shaderDenormPreserveFloat16
DEVICE_PROPERTY FloatControlsProperties.shaderDenormPreserveFloat32
DEVICE_PROPERTY FloatControlsProperties.shaderDenormPreserveFloat64
DEVICE_PROPERTY FloatControlsProperties.shaderDenormFlushToZeroFloat16
DEVICE_PROPERTY FloatControlsProperties.shaderDenormFlushToZeroFloat32
DEVICE_PROPERTY FloatControlsProperties.shaderDenormFlushToZeroFloat64
DEVICE_PROPERTY FloatControlsProperties.shaderRoundingModeRTEFloat16
DEVICE_PROPERTY FloatControlsProperties.shaderRoundingModeRTEFloat32
DEVICE_PROPERTY FloatControlsProperties.shaderRoundingModeRTEFloat64
DEVICE_PROPERTY FloatControlsProperties.shaderRoundingModeRTZFloat16
DEVICE_PROPERTY FloatControlsProperties.shaderRoundingModeRTZFloat32
DEVICE_PROPERTY FloatControlsProperties.shaderRoundingModeRTZFloat64)";

Parser parser;
Result r = parser.Parse(in);
ASSERT_TRUE(r.IsSuccess()) << r.Error();

auto script = parser.GetScript();
const auto& properties = script->GetRequiredProperties();
ASSERT_EQ(15U, properties.size());
EXPECT_EQ("FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat16",
properties[0]);
EXPECT_EQ("FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat32",
properties[1]);
EXPECT_EQ("FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat64",
properties[2]);
EXPECT_EQ("FloatControlsProperties.shaderDenormPreserveFloat16",
properties[3]);
EXPECT_EQ("FloatControlsProperties.shaderDenormPreserveFloat32",
properties[4]);
EXPECT_EQ("FloatControlsProperties.shaderDenormPreserveFloat64",
properties[5]);
EXPECT_EQ("FloatControlsProperties.shaderDenormFlushToZeroFloat16",
properties[6]);
EXPECT_EQ("FloatControlsProperties.shaderDenormFlushToZeroFloat32",
properties[7]);
EXPECT_EQ("FloatControlsProperties.shaderDenormFlushToZeroFloat64",
properties[8]);
EXPECT_EQ("FloatControlsProperties.shaderRoundingModeRTEFloat16",
properties[9]);
EXPECT_EQ("FloatControlsProperties.shaderRoundingModeRTEFloat32",
properties[10]);
EXPECT_EQ("FloatControlsProperties.shaderRoundingModeRTEFloat64",
properties[11]);
EXPECT_EQ("FloatControlsProperties.shaderRoundingModeRTZFloat16",
properties[12]);
EXPECT_EQ("FloatControlsProperties.shaderRoundingModeRTZFloat32",
properties[13]);
EXPECT_EQ("FloatControlsProperties.shaderRoundingModeRTZFloat64",
properties[14]);
}

TEST_F(AmberScriptParserTest, DevicePropertyMissingProperty) {
std::string in = "DEVICE_PROPERTY";

Parser parser;
Result r = parser.Parse(in);
ASSERT_FALSE(r.IsSuccess());
EXPECT_EQ("1: missing property name for DEVICE_PROPERTY command", r.Error());
}

TEST_F(AmberScriptParserTest, DevicePropertyUnknown) {
std::string in = "DEVICE_PROPERTY unknown";

Parser parser;
Result r = parser.Parse(in);
ASSERT_FALSE(r.IsSuccess());
EXPECT_EQ("1: unknown property name for DEVICE_PROPERTY command", r.Error());
}

TEST_F(AmberScriptParserTest, DevicePropertyInvalid) {
std::string in = "DEVICE_PROPERTY 12345";

Parser parser;
Result r = parser.Parse(in);
ASSERT_FALSE(r.IsSuccess());
EXPECT_EQ("1: invalid property name for DEVICE_PROPERTY command", r.Error());
}

TEST_F(AmberScriptParserTest, DevicePropertyExtraParams) {
std::string in =
"DEVICE_PROPERTY FloatControlsProperties.shaderDenormPreserveFloat16 "
"EXTRA";

Parser parser;
Result r = parser.Parse(in);
ASSERT_FALSE(r.IsSuccess());
EXPECT_EQ("1: extra parameters after DEVICE_PROPERTY command: EXTRA",
r.Error());
}

} // namespace amberscript
} // namespace amber
1 change: 1 addition & 0 deletions src/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class Engine {
EngineConfig* config,
Delegate* delegate,
const std::vector<std::string>& features,
const std::vector<std::string>& properties,
const std::vector<std::string>& instance_extensions,
const std::vector<std::string>& device_extensions) = 0;

Expand Down
13 changes: 11 additions & 2 deletions src/executor_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ class EngineStub : public Engine {
Result Initialize(EngineConfig*,
Delegate*,
const std::vector<std::string>& features,
const std::vector<std::string>& properties,
const std::vector<std::string>& instance_exts,
const std::vector<std::string>& device_exts) override {
features_ = features;
properties_ = properties;
instance_extensions_ = instance_exts;
device_extensions_ = device_exts;
return {};
Expand Down Expand Up @@ -193,6 +195,7 @@ class EngineStub : public Engine {
bool did_buffer_command_ = false;

std::vector<std::string> features_;
std::vector<std::string> properties_;
std::vector<std::string> instance_extensions_;
std::vector<std::string> device_extensions_;

Expand All @@ -207,11 +210,12 @@ class VkScriptExecutorTest : public testing::Test {
std::unique_ptr<Engine> MakeEngine() { return MakeUnique<EngineStub>(); }
std::unique_ptr<Engine> MakeAndInitializeEngine(
const std::vector<std::string>& features,
const std::vector<std::string>& properties,
const std::vector<std::string>& instance_extensions,
const std::vector<std::string>& device_extensions) {
std::unique_ptr<Engine> engine = MakeUnique<EngineStub>();
engine->Initialize(nullptr, nullptr, features, instance_extensions,
device_extensions);
engine->Initialize(nullptr, nullptr, features, properties,
instance_extensions, device_extensions);
return engine;
}
EngineStub* ToStub(Engine* engine) {
Expand All @@ -233,6 +237,7 @@ logicOp)";

auto script = parser.GetScript();
auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
script->GetRequiredProperties(),
script->GetRequiredInstanceExtensions(),
script->GetRequiredDeviceExtensions());

Expand Down Expand Up @@ -263,6 +268,7 @@ VK_KHR_variable_pointers)";

auto script = parser.GetScript();
auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
script->GetRequiredProperties(),
script->GetRequiredInstanceExtensions(),
script->GetRequiredDeviceExtensions());

Expand Down Expand Up @@ -293,6 +299,7 @@ depthstencil D24_UNORM_S8_UINT)";

auto script = parser.GetScript();
auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
script->GetRequiredProperties(),
script->GetRequiredInstanceExtensions(),
script->GetRequiredDeviceExtensions());

Expand Down Expand Up @@ -320,6 +327,7 @@ fence_timeout 12345)";

auto script = parser.GetScript();
auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
script->GetRequiredProperties(),
script->GetRequiredInstanceExtensions(),
script->GetRequiredDeviceExtensions());

Expand Down Expand Up @@ -355,6 +363,7 @@ fence_timeout 12345)";

auto script = parser.GetScript();
auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
script->GetRequiredProperties(),
script->GetRequiredInstanceExtensions(),
script->GetRequiredDeviceExtensions());

Expand Down
4 changes: 4 additions & 0 deletions src/recipe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ std::vector<std::string> Recipe::GetRequiredFeatures() const {
return impl_ ? impl_->GetRequiredFeatures() : std::vector<std::string>();
}

std::vector<std::string> Recipe::GetRequiredProperties() const {
return impl_ ? impl_->GetRequiredProperties() : std::vector<std::string>();
}

std::vector<std::string> Recipe::GetRequiredDeviceExtensions() const {
return impl_ ? impl_->GetRequiredDeviceExtensions()
: std::vector<std::string>();
Expand Down
21 changes: 21 additions & 0 deletions src/script.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,27 @@ bool Script::IsKnownFeature(const std::string& name) const {
"ShaderSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes";
}

bool Script::IsKnownProperty(const std::string& name) const {
return name ==
"FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat16" ||
name ==
"FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat32" ||
name ==
"FloatControlsProperties.shaderSignedZeroInfNanPreserveFloat64" ||
name == "FloatControlsProperties.shaderDenormPreserveFloat16" ||
name == "FloatControlsProperties.shaderDenormPreserveFloat32" ||
name == "FloatControlsProperties.shaderDenormPreserveFloat64" ||
name == "FloatControlsProperties.shaderDenormFlushToZeroFloat16" ||
name == "FloatControlsProperties.shaderDenormFlushToZeroFloat32" ||
name == "FloatControlsProperties.shaderDenormFlushToZeroFloat64" ||
name == "FloatControlsProperties.shaderRoundingModeRTEFloat16" ||
name == "FloatControlsProperties.shaderRoundingModeRTEFloat32" ||
name == "FloatControlsProperties.shaderRoundingModeRTEFloat64" ||
name == "FloatControlsProperties.shaderRoundingModeRTZFloat16" ||
name == "FloatControlsProperties.shaderRoundingModeRTZFloat32" ||
name == "FloatControlsProperties.shaderRoundingModeRTZFloat64";
}

type::Type* Script::ParseType(const std::string& str) {
auto type = GetType(str);
if (type)
Expand Down
19 changes: 19 additions & 0 deletions src/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Script : public RecipeImpl {
~Script() override;

bool IsKnownFeature(const std::string& name) const;
bool IsKnownProperty(const std::string& name) const;

/// Retrieves information on the shaders in the given script.
std::vector<ShaderInfo> GetShaderInfo() const override;
Expand All @@ -52,6 +53,10 @@ class Script : public RecipeImpl {
return engine_info_.required_features;
}

std::vector<std::string> GetRequiredProperties() const override {
return engine_info_.required_properties;
}

/// Returns required device extensions in the given recipe.
std::vector<std::string> GetRequiredDeviceExtensions() const override {
return engine_info_.required_device_extensions;
Expand Down Expand Up @@ -166,13 +171,26 @@ class Script : public RecipeImpl {
engine_info_.required_features.push_back(feature);
}

/// Adds |prop| to the list of properties that must be supported by the
/// engine.
void AddRequiredProperty(const std::string& prop) {
engine_info_.required_properties.push_back(prop);
}

/// Checks if |feature| is in required features
bool IsRequiredFeature(const std::string& feature) const {
return std::find(engine_info_.required_features.begin(),
engine_info_.required_features.end(),
feature) != engine_info_.required_features.end();
}

/// Checks if |prop| is in required features
bool IsRequiredProperty(const std::string& prop) const {
return std::find(engine_info_.required_properties.begin(),
engine_info_.required_properties.end(),
prop) != engine_info_.required_properties.end();
}

/// Adds |ext| to the list of device extensions that must be supported.
void AddRequiredDeviceExtension(const std::string& ext) {
engine_info_.required_device_extensions.push_back(ext);
Expand Down Expand Up @@ -257,6 +275,7 @@ class Script : public RecipeImpl {
private:
struct {
std::vector<std::string> required_features;
std::vector<std::string> required_properties;
std::vector<std::string> required_device_extensions;
std::vector<std::string> required_instance_extensions;
} engine_info_;
Expand Down
Loading