From 1401744b3d8650f8beb6707d42d1e0656067af8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Mon, 23 Mar 2020 10:56:18 +0200 Subject: [PATCH 1/6] Add buffer data loading from a png file --- docs/amber_script.md | 4 ++ include/amber/amber.h | 4 ++ samples/amber.cc | 17 +++++++ samples/png.cc | 18 +++++++ samples/png.h | 8 ++++ src/amberscript/parser.cc | 25 +++++++--- src/amberscript/parser_buffer_test.cc | 25 ++++++++++ src/buffer.h | 6 +++ src/executor.cc | 15 ++++++ tests/cases/draw_png_texture.amber | 66 ++++++++++++++++++++++++++ tests/cases/texture.png | Bin 0 -> 32776 bytes 11 files changed, 182 insertions(+), 6 deletions(-) create mode 100644 tests/cases/draw_png_texture.amber create mode 100644 tests/cases/texture.png diff --git a/docs/amber_script.md b/docs/amber_script.md index 1191d60f8..93c5caea2 100644 --- a/docs/amber_script.md +++ b/docs/amber_script.md @@ -156,6 +156,10 @@ BUFFER {name} DATA_TYPE {type} {STD140 | STD430} WIDTH {w} HEIGHT {h} \ # The buffer will be sized based on the `RENDER_SIZE` of the `PIPELINE`. BUFFER {name} FORMAT {format_string} \ [ MIP_LEVELS _mip_levels_ (default 1) ] + +# Load buffer data from a PNG image with file name specified by `FILE`. +# Format specified by `FORMAT` must match the image format. +BUFFER {name} FORMAT {format_string} FILE {file_name.png} ``` #### Images diff --git a/include/amber/amber.h b/include/amber/amber.h index 1fffd384d..99142536e 100644 --- a/include/amber/amber.h +++ b/include/amber/amber.h @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -116,6 +117,9 @@ struct Options { bool disable_spirv_validation; /// Delegate implementation Delegate* delegate; + + std::function + loadBufferDataFunc; }; /// Main interface to the Amber environment. diff --git a/samples/amber.cc b/samples/amber.cc index 221da5060..5f15a205f 100644 --- a/samples/amber.cc +++ b/samples/amber.cc @@ -28,6 +28,7 @@ #include "samples/config_helper.h" #include "samples/ppm.h" #include "samples/timestamp.h" +#include "src/buffer.h" #include "src/build-versions.h" #include "src/make_unique.h" @@ -69,6 +70,21 @@ struct Options { std::string spv_env; }; +amber::Result loadBufferData(std::string file_name, amber::BufferInfo& buffer) { +#if AMBER_ENABLE_LODEPNG + // Try to load as png first. + amber::Result r = + png::LoadPNG(file_name, buffer.width, buffer.height, buffer.values); + + if (r.IsSuccess()) + return r; +#endif // AMBER_ENABLE_LODEPNG + + // TODO(asuonpaa): Try to load a binary format. + + return amber::Result("Failed to load buffer data " + file_name); +} + const char kUsage[] = R"(Usage: amber [options] SCRIPT [SCRIPTS...] options: @@ -450,6 +466,7 @@ int main(int argc, const char** argv) { delegate.SetLogExecuteCalls(true); amber::Options amber_options; + amber_options.loadBufferDataFunc = loadBufferData; amber_options.engine = options.engine; amber_options.spv_env = options.spv_env; amber_options.execution_type = options.pipeline_create_only diff --git a/samples/png.cc b/samples/png.cc index 93e227996..76209c59f 100644 --- a/samples/png.cc +++ b/samples/png.cc @@ -81,4 +81,22 @@ amber::Result ConvertToPNG(uint32_t width, return {}; } +amber::Result LoadPNG(const std::string file_name, + uint32_t& width, + uint32_t& height, + std::vector& values) { + std::vector decoded_buffer; + if (lodepng::decode(decoded_buffer, width, height, file_name, + LodePNGColorType::LCT_RGBA, 8) != 0) + return amber::Result("lodepng::decode() returned non-zero"); + + for (auto d : decoded_buffer) { + amber::Value v; + v.SetIntValue(d); + values.push_back(v); + } + + return {}; +} + } // namespace png diff --git a/samples/png.h b/samples/png.h index 74802e728..52f882bac 100644 --- a/samples/png.h +++ b/samples/png.h @@ -31,6 +31,14 @@ amber::Result ConvertToPNG(uint32_t width, const std::vector& values, std::vector* buffer); +/// Loads a PNG image from |file_name|. Image dimensions of the loaded file are +/// stored into |width| and |height|, and the image data is stored in a one +/// byte per data element format into |values|. +amber::Result LoadPNG(const std::string file_name, + uint32_t& width, + uint32_t& height, + std::vector& values); + } // namespace png #endif // SAMPLES_PNG_H_ diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index 815747614..60292b08c 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -1224,14 +1224,27 @@ Result Parser::ParseBuffer() { script_->RegisterFormat(std::move(fmt)); token = tokenizer_->PeekNextToken(); - if (token->IsIdentifier() && token->AsString() == "MIP_LEVELS") { - tokenizer_->NextToken(); - token = tokenizer_->NextToken(); + while (token->IsIdentifier()) { + if (token->AsString() == "MIP_LEVELS") { + tokenizer_->NextToken(); + token = tokenizer_->NextToken(); - if (!token->IsInteger()) - return Result("invalid value for MIP_LEVELS"); + if (!token->IsInteger()) + return Result("invalid value for MIP_LEVELS"); - buffer->SetMipLevels(token->AsUint32()); + buffer->SetMipLevels(token->AsUint32()); + } else if (token->AsString() == "FILE") { + tokenizer_->NextToken(); + token = tokenizer_->NextToken(); + + if (!token->IsIdentifier()) + return Result("invalid value for FILE"); + + buffer->SetDataFile(token->AsString()); + } else { + break; + } + token = tokenizer_->PeekNextToken(); } } else { return Result("unknown BUFFER command provided: " + cmd); diff --git a/src/amberscript/parser_buffer_test.cc b/src/amberscript/parser_buffer_test.cc index dcbd98256..d2f1eb11f 100644 --- a/src/amberscript/parser_buffer_test.cc +++ b/src/amberscript/parser_buffer_test.cc @@ -1067,5 +1067,30 @@ TEST_F(AmberScriptParserTest, BufferMissingMipLevels) { EXPECT_EQ("1: invalid value for MIP_LEVELS", r.Error()); } +TEST_F(AmberScriptParserTest, BufferMissingDataFile) { + std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM FILE"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + + EXPECT_EQ("1: invalid value for FILE", r.Error()); +} + +TEST_F(AmberScriptParserTest, BufferDataFile) { + std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM FILE foo.png"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& buffers = script->GetBuffers(); + ASSERT_EQ(1U, buffers.size()); + + ASSERT_TRUE(buffers[0] != nullptr); + EXPECT_EQ("foo.png", buffers[0]->GetDataFile()); +} + } // namespace amberscript } // namespace amber diff --git a/src/buffer.h b/src/buffer.h index d867a5a52..1d482c4d8 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -196,6 +196,11 @@ class Buffer { /// Returns the number of mip levels. uint32_t GetMipLevels() { return mip_levels_; } + /// Sets the file name for loading data into the buffer. + void SetDataFile(std::string data_file) { data_file_ = data_file; } + + std::string GetDataFile() { return data_file_; } + /// Returns a pointer to the internal storage of the buffer. std::vector* ValuePtr() { return &bytes_; } /// Returns a pointer to the internal storage of the buffer. @@ -252,6 +257,7 @@ class Buffer { Format* format_ = nullptr; Sampler* sampler_ = nullptr; ImageDimension image_dim_ = ImageDimension::kUnknown; + std::string data_file_; }; } // namespace amber diff --git a/src/executor.cc b/src/executor.cc index 0d428e949..197ecbd64 100644 --- a/src/executor.cc +++ b/src/executor.cc @@ -88,6 +88,21 @@ Result Executor::Execute(Engine* engine, Engine::Debugger* debugger = nullptr; + // Load data to buffers + for (const auto& buf : script->GetBuffers()) { + if (buf->GetDataFile() != "") { + BufferInfo info; + Result r = options->loadBufferDataFunc(buf->GetDataFile(), info); + + if (!r.IsSuccess()) + return r; + + buf->SetData(info.values); + buf->SetWidth(info.width); + buf->SetHeight(info.height); + } + } + // Process Commands for (const auto& cmd : script->GetCommands()) { if (options->delegate && options->delegate->LogExecuteCalls()) { diff --git a/tests/cases/draw_png_texture.amber b/tests/cases/draw_png_texture.amber new file mode 100644 index 000000000..c7b9885f5 --- /dev/null +++ b/tests/cases/draw_png_texture.amber @@ -0,0 +1,66 @@ +#!amber +# Copyright 2020 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 +# +# https://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 implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +SHADER vertex vert_shader_tex GLSL +#version 430 +layout(location = 0) in vec4 position; +layout(location = 1) in vec2 texcoords_in; +layout(location = 0) out vec2 texcoords_out; +void main() { + gl_Position = position; + texcoords_out = texcoords_in; +} +END + +SHADER fragment frag_shader_tex GLSL +#version 430 +layout(location = 0) in vec2 texcoords_in; +layout(location = 0) out vec4 color_out; +uniform layout(set=0, binding=0) sampler2D tex_sampler; +void main() { + color_out = texture(tex_sampler, texcoords_in); +} +END + +BUFFER texture FORMAT R8G8B8A8_UNORM FILE texture.png +BUFFER framebuffer FORMAT B8G8R8A8_UNORM +SAMPLER sampler +BUFFER position DATA_TYPE vec2 DATA +-0.75 -0.75 + 0.75 -0.75 + 0.75 0.75 +-0.75 0.75 +END +BUFFER texcoords DATA_TYPE vec2 DATA +0.0 0.0 +1.0 0.0 +1.0 1.0 +0.0 1.0 +END + +PIPELINE graphics pipeline + ATTACH vert_shader_tex + ATTACH frag_shader_tex + BIND BUFFER texture AS combined_image_sampler SAMPLER sampler DESCRIPTOR_SET 0 BINDING 0 + VERTEX_DATA position LOCATION 0 + VERTEX_DATA texcoords LOCATION 1 + FRAMEBUFFER_SIZE 256 256 + BIND BUFFER framebuffer AS color LOCATION 0 +END + +# Draw the texture using a default sampler. +CLEAR_COLOR pipeline 0 255 0 255 +CLEAR pipeline +RUN pipeline DRAW_ARRAY AS TRIANGLE_FAN START_IDX 0 COUNT 4 diff --git a/tests/cases/texture.png b/tests/cases/texture.png new file mode 100644 index 0000000000000000000000000000000000000000..465bf9a101862eb2c22cd54ecae25629abd01c51 GIT binary patch literal 32776 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�Gj2eA9L6B?Z~ifzGWGY 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 Date: Mon, 23 Mar 2020 11:13:33 +0200 Subject: [PATCH 2/6] Added a comment. --- src/buffer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/buffer.h b/src/buffer.h index 1d482c4d8..9d6f3d6e0 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -199,6 +199,7 @@ class Buffer { /// Sets the file name for loading data into the buffer. void SetDataFile(std::string data_file) { data_file_ = data_file; } + /// Returns the file name used to load buffer data from. std::string GetDataFile() { return data_file_; } /// Returns a pointer to the internal storage of the buffer. From 217f8370e46faf2c9db1cc39818b3374b62b6e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Mon, 23 Mar 2020 12:12:38 +0200 Subject: [PATCH 3/6] Fixed lint errors. --- include/amber/amber.h | 2 +- samples/amber.cc | 4 ++-- samples/png.cc | 10 +++++----- samples/png.h | 6 +++--- src/executor.cc | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/amber/amber.h b/include/amber/amber.h index 99142536e..c7de73081 100644 --- a/include/amber/amber.h +++ b/include/amber/amber.h @@ -118,7 +118,7 @@ struct Options { /// Delegate implementation Delegate* delegate; - std::function + std::function loadBufferDataFunc; }; diff --git a/samples/amber.cc b/samples/amber.cc index 5f15a205f..89028d052 100644 --- a/samples/amber.cc +++ b/samples/amber.cc @@ -70,11 +70,11 @@ struct Options { std::string spv_env; }; -amber::Result loadBufferData(std::string file_name, amber::BufferInfo& buffer) { +amber::Result loadBufferData(std::string file_name, amber::BufferInfo* buffer) { #if AMBER_ENABLE_LODEPNG // Try to load as png first. amber::Result r = - png::LoadPNG(file_name, buffer.width, buffer.height, buffer.values); + png::LoadPNG(file_name, &buffer->width, &buffer->height, &buffer->values); if (r.IsSuccess()) return r; diff --git a/samples/png.cc b/samples/png.cc index 76209c59f..32be4eafa 100644 --- a/samples/png.cc +++ b/samples/png.cc @@ -82,18 +82,18 @@ amber::Result ConvertToPNG(uint32_t width, } amber::Result LoadPNG(const std::string file_name, - uint32_t& width, - uint32_t& height, - std::vector& values) { + uint32_t* width, + uint32_t* height, + std::vector* values) { std::vector decoded_buffer; - if (lodepng::decode(decoded_buffer, width, height, file_name, + if (lodepng::decode(decoded_buffer, *width, *height, file_name, LodePNGColorType::LCT_RGBA, 8) != 0) return amber::Result("lodepng::decode() returned non-zero"); for (auto d : decoded_buffer) { amber::Value v; v.SetIntValue(d); - values.push_back(v); + values->push_back(v); } return {}; diff --git a/samples/png.h b/samples/png.h index 52f882bac..b08d74de5 100644 --- a/samples/png.h +++ b/samples/png.h @@ -35,9 +35,9 @@ amber::Result ConvertToPNG(uint32_t width, /// stored into |width| and |height|, and the image data is stored in a one /// byte per data element format into |values|. amber::Result LoadPNG(const std::string file_name, - uint32_t& width, - uint32_t& height, - std::vector& values); + uint32_t* width, + uint32_t* height, + std::vector* values); } // namespace png diff --git a/src/executor.cc b/src/executor.cc index 197ecbd64..66483fcd5 100644 --- a/src/executor.cc +++ b/src/executor.cc @@ -92,7 +92,7 @@ Result Executor::Execute(Engine* engine, for (const auto& buf : script->GetBuffers()) { if (buf->GetDataFile() != "") { BufferInfo info; - Result r = options->loadBufferDataFunc(buf->GetDataFile(), info); + Result r = options->loadBufferDataFunc(buf->GetDataFile(), &info); if (!r.IsSuccess()) return r; From b67ee110f8d7666e01b8bcf0130f59111305b242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Mon, 23 Mar 2020 12:54:50 +0200 Subject: [PATCH 4/6] Fixed regular expression (tried to run .png). Exclude png test since the test script is not running in the same directory as the image file. --- tests/run_tests.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/run_tests.py b/tests/run_tests.py index b3903cdd8..bd2ee871c 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -43,14 +43,20 @@ "multiple_ubo_update_with_graphics_pipeline.vkscript", # DXC not currently building on bot "draw_triangle_list_hlsl.amber", + # Texture file not found from this path + "draw_png_texture.amber", ], "Linux": [ # DXC not currently building on bot "draw_triangle_list_hlsl.amber", + # Texture file not found from this path + "draw_png_texture.amber", ], "Win": [ # DXC not currently building on bot "draw_triangle_list_hlsl.amber", + # Texture file not found from this path + "draw_png_texture.amber", ] } @@ -323,7 +329,7 @@ def Run(self): print("--test-prog-path must point to an executable") return 1 - input_file_re = re.compile('^.+[.][amber|vkscript]') + input_file_re = re.compile('^.+[\.]amber|vkscript') self.test_cases = [] if self.args: From 18cbcb865e5528b1732a5020895fc9b37c70d415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Mon, 23 Mar 2020 15:17:37 +0200 Subject: [PATCH 5/6] Changes requested in a review. --- docs/amber_script.md | 4 +++- include/amber/amber.h | 7 +++---- samples/amber.cc | 32 ++++++++++++++++---------------- samples/png.cc | 3 ++- src/executor.cc | 18 +++++++++--------- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/docs/amber_script.md b/docs/amber_script.md index 93c5caea2..9dcc330a3 100644 --- a/docs/amber_script.md +++ b/docs/amber_script.md @@ -158,7 +158,9 @@ BUFFER {name} FORMAT {format_string} \ [ MIP_LEVELS _mip_levels_ (default 1) ] # Load buffer data from a PNG image with file name specified by `FILE`. -# Format specified by `FORMAT` must match the image format. +# The file path is relative to the current working directory where the +# amber is executed from. Format specified by `FORMAT` must match the +# image format. BUFFER {name} FORMAT {format_string} FILE {file_name.png} ``` diff --git a/include/amber/amber.h b/include/amber/amber.h index c7de73081..b665de2ec 100644 --- a/include/amber/amber.h +++ b/include/amber/amber.h @@ -17,7 +17,6 @@ #include -#include #include #include #include @@ -86,6 +85,9 @@ class Delegate { virtual uint64_t GetTimestampNs() const = 0; /// Tells whether to log each test as it's executed virtual bool LogExecuteCalls() const = 0; + /// Loads buffer data from a file + virtual amber::Result LoadBufferData(const std::string file_name, + amber::BufferInfo* buffer) const = 0; }; /// Stores configuration options for Amber. @@ -117,9 +119,6 @@ struct Options { bool disable_spirv_validation; /// Delegate implementation Delegate* delegate; - - std::function - loadBufferDataFunc; }; /// Main interface to the Amber environment. diff --git a/samples/amber.cc b/samples/amber.cc index 89028d052..60a73556d 100644 --- a/samples/amber.cc +++ b/samples/amber.cc @@ -70,21 +70,6 @@ struct Options { std::string spv_env; }; -amber::Result loadBufferData(std::string file_name, amber::BufferInfo* buffer) { -#if AMBER_ENABLE_LODEPNG - // Try to load as png first. - amber::Result r = - png::LoadPNG(file_name, &buffer->width, &buffer->height, &buffer->values); - - if (r.IsSuccess()) - return r; -#endif // AMBER_ENABLE_LODEPNG - - // TODO(asuonpaa): Try to load a binary format. - - return amber::Result("Failed to load buffer data " + file_name); -} - const char kUsage[] = R"(Usage: amber [options] SCRIPT [SCRIPTS...] options: @@ -340,6 +325,22 @@ class SampleDelegate : public amber::Delegate { return timestamp::SampleGetTimestampNs(); } + amber::Result LoadBufferData(const std::string file_name, + amber::BufferInfo* buffer) const override { +#if AMBER_ENABLE_LODEPNG + // Try to load as png first. + amber::Result r = png::LoadPNG(file_name, &buffer->width, &buffer->height, + &buffer->values); + + if (r.IsSuccess()) + return r; +#endif // AMBER_ENABLE_LODEPNG + + // TODO(asuonpaa): Try to load a binary format. + + return amber::Result("Failed to load buffer data " + file_name); + } + private: bool log_graphics_calls_ = false; bool log_graphics_calls_time_ = false; @@ -466,7 +467,6 @@ int main(int argc, const char** argv) { delegate.SetLogExecuteCalls(true); amber::Options amber_options; - amber_options.loadBufferDataFunc = loadBufferData; amber_options.engine = options.engine; amber_options.spv_env = options.spv_env; amber_options.execution_type = options.pipeline_create_only diff --git a/samples/png.cc b/samples/png.cc index 32be4eafa..3dbf4fd63 100644 --- a/samples/png.cc +++ b/samples/png.cc @@ -87,8 +87,9 @@ amber::Result LoadPNG(const std::string file_name, std::vector* values) { std::vector decoded_buffer; if (lodepng::decode(decoded_buffer, *width, *height, file_name, - LodePNGColorType::LCT_RGBA, 8) != 0) + LodePNGColorType::LCT_RGBA, 8) != 0) { return amber::Result("lodepng::decode() returned non-zero"); + } for (auto d : decoded_buffer) { amber::Value v; diff --git a/src/executor.cc b/src/executor.cc index 66483fcd5..5ff76d249 100644 --- a/src/executor.cc +++ b/src/executor.cc @@ -90,17 +90,17 @@ Result Executor::Execute(Engine* engine, // Load data to buffers for (const auto& buf : script->GetBuffers()) { - if (buf->GetDataFile() != "") { - BufferInfo info; - Result r = options->loadBufferDataFunc(buf->GetDataFile(), &info); + if (buf->GetDataFile().empty()) + continue; - if (!r.IsSuccess()) - return r; + BufferInfo info; + Result r = options->delegate->LoadBufferData(buf->GetDataFile(), &info); + if (!r.IsSuccess()) + return r; - buf->SetData(info.values); - buf->SetWidth(info.width); - buf->SetHeight(info.height); - } + buf->SetData(info.values); + buf->SetWidth(info.width); + buf->SetHeight(info.height); } // Process Commands From bf26ffef69df57893d2930eaf11b1cfa14c8e448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Tue, 24 Mar 2020 11:46:58 +0200 Subject: [PATCH 6/6] Load image data from a path relative to the script. --- docs/amber_script.md | 5 ++--- samples/amber.cc | 11 ++++++++--- tests/run_tests.py | 6 ------ 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/docs/amber_script.md b/docs/amber_script.md index 9dcc330a3..56430f716 100644 --- a/docs/amber_script.md +++ b/docs/amber_script.md @@ -158,9 +158,8 @@ BUFFER {name} FORMAT {format_string} \ [ MIP_LEVELS _mip_levels_ (default 1) ] # Load buffer data from a PNG image with file name specified by `FILE`. -# The file path is relative to the current working directory where the -# amber is executed from. Format specified by `FORMAT` must match the -# image format. +# The file path is relative to the script file being run. Format specified +# by `FORMAT` must match the image format. BUFFER {name} FORMAT {format_string} FILE {file_name.png} ``` diff --git a/samples/amber.cc b/samples/amber.cc index 60a73556d..31e66f92e 100644 --- a/samples/amber.cc +++ b/samples/amber.cc @@ -28,7 +28,6 @@ #include "samples/config_helper.h" #include "samples/ppm.h" #include "samples/timestamp.h" -#include "src/buffer.h" #include "src/build-versions.h" #include "src/make_unique.h" @@ -325,12 +324,14 @@ class SampleDelegate : public amber::Delegate { return timestamp::SampleGetTimestampNs(); } + void SetScriptPath(std::string path) { path_ = path; } + amber::Result LoadBufferData(const std::string file_name, amber::BufferInfo* buffer) const override { #if AMBER_ENABLE_LODEPNG // Try to load as png first. - amber::Result r = png::LoadPNG(file_name, &buffer->width, &buffer->height, - &buffer->values); + amber::Result r = png::LoadPNG(path_ + file_name, &buffer->width, + &buffer->height, &buffer->values); if (r.IsSuccess()) return r; @@ -345,6 +346,7 @@ class SampleDelegate : public amber::Delegate { bool log_graphics_calls_ = false; bool log_graphics_calls_time_ = false; bool log_execute_calls_ = false; + std::string path_ = ""; }; std::string disassemble(const std::string& env, @@ -548,6 +550,9 @@ int main(int argc, const char** argv) { const auto* recipe = recipe_data_elem.recipe.get(); const auto& file = recipe_data_elem.file; + // Parse file path and set it for delegate to use when loading buffer data. + delegate.SetScriptPath(file.substr(0, file.find_last_of("/\\") + 1)); + amber::Amber am; result = am.Execute(recipe, &amber_options); if (!result.IsSuccess()) { diff --git a/tests/run_tests.py b/tests/run_tests.py index bd2ee871c..6b17f5652 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -43,20 +43,14 @@ "multiple_ubo_update_with_graphics_pipeline.vkscript", # DXC not currently building on bot "draw_triangle_list_hlsl.amber", - # Texture file not found from this path - "draw_png_texture.amber", ], "Linux": [ # DXC not currently building on bot "draw_triangle_list_hlsl.amber", - # Texture file not found from this path - "draw_png_texture.amber", ], "Win": [ # DXC not currently building on bot "draw_triangle_list_hlsl.amber", - # Texture file not found from this path - "draw_png_texture.amber", ] }