aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorasuonpaa <34128694+asuonpaa@users.noreply.github.com>2021-09-25 15:02:21 +0300
committerGitHub <noreply@github.com>2021-09-25 13:02:21 +0100
commit6b3fcb0353533d1236035c4aa3b587be5d8b37cd (patch)
tree2d8161e7c49e1e5874d01d0bcd52db37b6ef5770 /src
parent51ef48a2d7c239af32c16d3d72ec5f00a6618d81 (diff)
downloadamber-6b3fcb0353533d1236035c4aa3b587be5d8b37cd.tar.gz
Add PATCH_CONTROL_POINTS to AmberScript (#963)
Previously only VkScript had the access to set the number of patch control points. Now this can also be set in AmberScript pipeline settings.
Diffstat (limited to 'src')
-rw-r--r--src/amberscript/parser.cc16
-rw-r--r--src/amberscript/parser.h1
-rw-r--r--src/amberscript/parser_pipeline_test.cc82
-rw-r--r--src/pipeline_data.h7
-rw-r--r--src/vulkan/engine_vulkan.cc3
5 files changed, 109 insertions, 0 deletions
diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc
index 809baa1..dfc2cfb 100644
--- a/src/amberscript/parser.cc
+++ b/src/amberscript/parser.cc
@@ -622,6 +622,8 @@ Result Parser::ParsePipelineBody(const std::string& cmd_name,
r = ParsePipelineStencil(pipeline.get());
} else if (tok == "SUBGROUP") {
r = ParsePipelineSubgroup(pipeline.get());
+ } else if (tok == "PATCH_CONTROL_POINTS") {
+ r = ParsePipelinePatchControlPoints(pipeline.get());
} else {
r = Result("unknown token in pipeline block: " + tok);
}
@@ -931,6 +933,20 @@ Result Parser::ParsePipelineSubgroup(Pipeline* pipeline) {
return ValidateEndOfStatement("SUBGROUP command");
}
+Result Parser::ParsePipelinePatchControlPoints(Pipeline* pipeline) {
+ auto token = tokenizer_->NextToken();
+ if (token->IsEOL() || token->IsEOS())
+ return Result(
+ "missing number of control points in PATCH_CONTROL_POINTS command");
+
+ if (!token->IsInteger())
+ return Result("expecting integer for the number of control points");
+
+ pipeline->GetPipelineData()->SetPatchControlPoints(token->AsUint32());
+
+ return ValidateEndOfStatement("PATCH_CONTROL_POINTS command");
+}
+
Result Parser::ParsePipelineFramebufferSize(Pipeline* pipeline) {
auto token = tokenizer_->NextToken();
if (token->IsEOL() || token->IsEOS())
diff --git a/src/amberscript/parser.h b/src/amberscript/parser.h
index 6fb25ce..8f59351 100644
--- a/src/amberscript/parser.h
+++ b/src/amberscript/parser.h
@@ -64,6 +64,7 @@ class Parser : public amber::Parser {
Result ParsePipelineShaderOptimizations(Pipeline*);
Result ParsePipelineShaderCompileOptions(Pipeline*);
Result ParsePipelineSubgroup(Pipeline* pipeline);
+ Result ParsePipelinePatchControlPoints(Pipeline* pipeline);
Result ParsePipelineFramebufferSize(Pipeline*);
Result ParsePipelineViewport(Pipeline*);
Result ParsePipelineBind(Pipeline*);
diff --git a/src/amberscript/parser_pipeline_test.cc b/src/amberscript/parser_pipeline_test.cc
index 2b56e2e..4707dd9 100644
--- a/src/amberscript/parser_pipeline_test.cc
+++ b/src/amberscript/parser_pipeline_test.cc
@@ -61,6 +61,8 @@ END
EXPECT_EQ(kShaderTypeFragment, shaders[1].GetShader()->GetType());
EXPECT_EQ(static_cast<uint32_t>(0),
shaders[1].GetShaderOptimizations().size());
+
+ EXPECT_EQ(pipelines[0]->GetPipelineData()->GetPatchControlPoints(), 3u);
}
TEST_F(AmberScriptParserTest, PipelineMissingEnd) {
@@ -541,5 +543,85 @@ END
EXPECT_EQ(4u, s2[0].GetSpecialization().at(3));
}
+TEST_F(AmberScriptParserTest, PipelinePatchControlPoints) {
+ std::string in = R"(
+DEVICE_FEATURE tessellationShader
+
+SHADER vertex my_shader PASSTHROUGH
+SHADER fragment my_fragment GLSL
+# GLSL Shader
+END
+
+SHADER tessellation_control my_tesc GLSL
+# GLSL Shader
+END
+
+SHADER tessellation_evaluation my_tese GLSL
+# GLSL Shader
+END
+
+PIPELINE graphics my_pipeline
+ ATTACH my_shader
+ ATTACH my_tesc
+ ATTACH my_tese
+ ATTACH my_fragment
+
+ PATCH_CONTROL_POINTS 4
+END
+)";
+
+ Parser parser;
+ Result r = parser.Parse(in);
+ ASSERT_TRUE(r.IsSuccess()) << r.Error();
+
+ auto script = parser.GetScript();
+ const auto& pipelines = script->GetPipelines();
+ ASSERT_EQ(1U, pipelines.size());
+
+ EXPECT_EQ(pipelines[0]->GetPipelineData()->GetPatchControlPoints(), 4u);
+}
+
+TEST_F(AmberScriptParserTest, PipelineDerivePatchControlPoints) {
+ std::string in = R"(
+DEVICE_FEATURE tessellationShader
+
+SHADER vertex my_shader PASSTHROUGH
+SHADER fragment my_fragment GLSL
+# GLSL Shader
+END
+
+SHADER tessellation_control my_tesc GLSL
+# GLSL Shader
+END
+
+SHADER tessellation_evaluation my_tese GLSL
+# GLSL Shader
+END
+
+PIPELINE graphics my_pipeline
+ ATTACH my_shader
+ ATTACH my_tesc
+ ATTACH my_tese
+ ATTACH my_fragment
+
+ PATCH_CONTROL_POINTS 4
+END
+
+DERIVE_PIPELINE child_pipeline FROM my_pipeline
+END
+)";
+
+ Parser parser;
+ Result r = parser.Parse(in);
+ ASSERT_TRUE(r.IsSuccess()) << r.Error();
+
+ auto script = parser.GetScript();
+ const auto& pipelines = script->GetPipelines();
+ ASSERT_EQ(2U, pipelines.size());
+
+ EXPECT_EQ(pipelines[0]->GetPipelineData()->GetPatchControlPoints(), 4u);
+ EXPECT_EQ(pipelines[1]->GetPipelineData()->GetPatchControlPoints(), 4u);
+}
+
} // namespace amberscript
} // namespace amber
diff --git a/src/pipeline_data.h b/src/pipeline_data.h
index 9a3b4d1..c763f37 100644
--- a/src/pipeline_data.h
+++ b/src/pipeline_data.h
@@ -178,6 +178,11 @@ class PipelineData {
bool HasViewportData() const { return has_viewport_data; }
const Viewport& GetViewport() const { return vp; }
+ void SetPatchControlPoints(uint32_t control_points) {
+ patch_control_points_ = control_points;
+ }
+ uint32_t GetPatchControlPoints() const { return patch_control_points_; }
+
private:
StencilOp front_fail_op_ = StencilOp::kKeep;
StencilOp front_pass_op_ = StencilOp::kKeep;
@@ -233,6 +238,8 @@ class PipelineData {
bool has_viewport_data = false;
Viewport vp;
+
+ uint32_t patch_control_points_ = 3u;
};
} // namespace amber
diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc
index 6bed716..8d16545 100644
--- a/src/vulkan/engine_vulkan.cc
+++ b/src/vulkan/engine_vulkan.cc
@@ -180,6 +180,9 @@ Result EngineVulkan::CreatePipeline(amber::Pipeline* pipeline) {
pipeline->GetDepthStencilBuffer(), engine_data.fence_timeout_ms,
stage_create_info);
+ vk_pipeline->AsGraphics()->SetPatchControlPoints(
+ pipeline->GetPipelineData()->GetPatchControlPoints());
+
r = vk_pipeline->AsGraphics()->Initialize(pipeline->GetFramebufferWidth(),
pipeline->GetFramebufferHeight(),
pool_.get());