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
5 changes: 5 additions & 0 deletions docs/amber_script.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ 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`.
# 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}
```

#### Images
Expand Down
3 changes: 3 additions & 0 deletions include/amber/amber.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,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.
Expand Down
22 changes: 22 additions & 0 deletions samples/amber.cc
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,29 @@ 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(path_ + 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;
bool log_execute_calls_ = false;
std::string path_ = "";
};

std::string disassemble(const std::string& env,
Expand Down Expand Up @@ -531,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()) {
Expand Down
19 changes: 19 additions & 0 deletions samples/png.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,23 @@ amber::Result ConvertToPNG(uint32_t width,
return {};
}

amber::Result LoadPNG(const std::string file_name,
uint32_t* width,
uint32_t* height,
std::vector<amber::Value>* values) {
std::vector<uint8_t> 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
8 changes: 8 additions & 0 deletions samples/png.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ amber::Result ConvertToPNG(uint32_t width,
const std::vector<amber::Value>& values,
std::vector<uint8_t>* 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<amber::Value>* values);

} // namespace png

#endif // SAMPLES_PNG_H_
25 changes: 19 additions & 6 deletions src/amberscript/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
25 changes: 25 additions & 0 deletions src/amberscript/parser_buffer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions src/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ 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; }

/// 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.
std::vector<uint8_t>* ValuePtr() { return &bytes_; }
/// Returns a pointer to the internal storage of the buffer.
Expand Down Expand Up @@ -252,6 +258,7 @@ class Buffer {
Format* format_ = nullptr;
Sampler* sampler_ = nullptr;
ImageDimension image_dim_ = ImageDimension::kUnknown;
std::string data_file_;
};

} // namespace amber
Expand Down
15 changes: 15 additions & 0 deletions src/executor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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().empty())
continue;

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);
}

// Process Commands
for (const auto& cmd : script->GetCommands()) {
if (options->delegate && options->delegate->LogExecuteCalls()) {
Expand Down
66 changes: 66 additions & 0 deletions tests/cases/draw_png_texture.amber
Original file line number Diff line number Diff line change
@@ -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<float> DATA
-0.75 -0.75
0.75 -0.75
0.75 0.75
-0.75 0.75
END
BUFFER texcoords DATA_TYPE vec2<float> 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
Binary file added tests/cases/texture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,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:
Expand Down