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
6 changes: 6 additions & 0 deletions docs/amber_script.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ The following commands are all specified within the `PIPELINE` command.
END
```

```groovy
# Set the polygon mode used for all drawing with the pipeline.
# |mode| is fill, line, or point and it defaults to fill.
POLYGON_MODE {mode}
```

```groovy
# Set the size of the render buffers. |width| and |height| are integers and
# default to 250x250.
Expand Down
25 changes: 25 additions & 0 deletions src/amberscript/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ Result Parser::ParsePipelineBody(const std::string& cmd_name,
r = ParsePipelineSet(pipeline.get());
} else if (tok == "COMPILE_OPTIONS") {
r = ParsePipelineShaderCompileOptions(pipeline.get());
} else if (tok == "POLYGON_MODE") {
r = ParsePipelinePolygonMode(pipeline.get());
} else {
r = Result("unknown token in pipeline block: " + tok);
}
Expand Down Expand Up @@ -1045,6 +1047,25 @@ Result Parser::ParsePipelineSet(Pipeline* pipeline) {
return ValidateEndOfStatement("SET command");
}

Result Parser::ParsePipelinePolygonMode(Pipeline* pipeline) {
auto token = tokenizer_->NextToken();
if (!token->IsIdentifier())
return Result("missing mode in POLYGON_MODE command");

auto mode = token->AsString();

if (mode == "fill")
pipeline->SetPolygonMode(PolygonMode::kFill);
else if (mode == "line")
pipeline->SetPolygonMode(PolygonMode::kLine);
else if (mode == "point")
pipeline->SetPolygonMode(PolygonMode::kPoint);
else
return Result("invalid polygon mode: " + mode);

return ValidateEndOfStatement("POLYGON_MODE command");
}

Result Parser::ParseStruct() {
auto token = tokenizer_->NextToken();
if (!token->IsIdentifier())
Expand Down Expand Up @@ -1646,6 +1667,7 @@ Result Parser::ParseRun() {
command_list_.push_back(std::move(cmd));
return ValidateEndOfStatement("RUN command");
}

if (!token->IsIdentifier())
return Result("invalid token in RUN command: " + token->ToOriginalString());

Expand Down Expand Up @@ -1675,6 +1697,7 @@ Result Parser::ParseRun() {
auto cmd = MakeUnique<DrawRectCommand>(pipeline, PipelineData{});
cmd->SetLine(line);
cmd->EnableOrtho();
cmd->SetPolygonMode(pipeline->GetPolygonMode());

Result r = token->ConvertToDouble();
if (!r.IsSuccess())
Expand Down Expand Up @@ -1743,6 +1766,7 @@ Result Parser::ParseRun() {

auto cmd = MakeUnique<DrawGridCommand>(pipeline);
cmd->SetLine(line);
cmd->SetPolygonMode(pipeline->GetPolygonMode());

Result r = token->ConvertToDouble();
if (!r.IsSuccess())
Expand Down Expand Up @@ -1884,6 +1908,7 @@ Result Parser::ParseRun() {
cmd->SetTopology(topo);
cmd->SetFirstVertexIndex(start_idx);
cmd->SetVertexCount(count);
cmd->SetPolygonMode(pipeline->GetPolygonMode());

if (indexed)
cmd->EnableIndexed();
Expand Down
1 change: 1 addition & 0 deletions src/amberscript/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Parser : public amber::Parser {
Result ParsePipelineVertexData(Pipeline*);
Result ParsePipelineIndexData(Pipeline*);
Result ParsePipelineSet(Pipeline*);
Result ParsePipelinePolygonMode(Pipeline*);
Result ParseRun();
Result ParseDebug();
Result ParseDebugThread(debug::Events*);
Expand Down
91 changes: 91 additions & 0 deletions src/amberscript/parser_pipeline_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,97 @@ END)";
r.Error());
}

TEST_F(AmberScriptParserTest, PipelinePolygonMode) {
std::string in = R"(
SHADER vertex my_shader PASSTHROUGH
SHADER fragment my_fragment GLSL
# GLSL Shader
END

PIPELINE graphics my_pipeline_default
ATTACH my_shader
ATTACH my_fragment
FRAMEBUFFER_SIZE 256 256
END
PIPELINE graphics my_pipeline_fill
ATTACH my_shader
ATTACH my_fragment
POLYGON_MODE fill
FRAMEBUFFER_SIZE 256 256
END
PIPELINE graphics my_pipeline_line
ATTACH my_shader
ATTACH my_fragment
POLYGON_MODE line
FRAMEBUFFER_SIZE 256 256
END
PIPELINE graphics my_pipeline_point
ATTACH my_shader
ATTACH my_fragment
POLYGON_MODE point
FRAMEBUFFER_SIZE 256 256
END)";

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

auto script = parser.GetScript();
const auto& pipelines = script->GetPipelines();
ASSERT_EQ(4U, pipelines.size());

auto mode0 = pipelines[0]->GetPolygonMode();
ASSERT_EQ(mode0, PolygonMode::kFill);
auto mode1 = pipelines[1]->GetPolygonMode();
ASSERT_EQ(mode1, PolygonMode::kFill);
auto mode2 = pipelines[2]->GetPolygonMode();
ASSERT_EQ(mode2, PolygonMode::kLine);
auto mode3 = pipelines[3]->GetPolygonMode();
ASSERT_EQ(mode3, PolygonMode::kPoint);
}

TEST_F(AmberScriptParserTest, PipelineMissingPolygonMode) {
std::string in = R"(
SHADER vertex my_shader PASSTHROUGH
SHADER fragment my_fragment GLSL
# GLSL Shader
END

PIPELINE graphics my_pipeline
ATTACH my_shader
ATTACH my_fragment
POLYGON_MODE
FRAMEBUFFER_SIZE 256 256
END)";

Parser parser;
Result r = parser.Parse(in);
ASSERT_FALSE(r.IsSuccess());

EXPECT_EQ("11: missing mode in POLYGON_MODE command", r.Error());
}

TEST_F(AmberScriptParserTest, PipelineInvalidPolygonMode) {
std::string in = R"(
SHADER vertex my_shader PASSTHROUGH
SHADER fragment my_fragment GLSL
# GLSL Shader
END

PIPELINE graphics my_pipeline
ATTACH my_shader
ATTACH my_fragment
POLYGON_MODE foo
FRAMEBUFFER_SIZE 256 256
END)";

Parser parser;
Result r = parser.Parse(in);
ASSERT_FALSE(r.IsSuccess());

EXPECT_EQ("10: invalid polygon mode: foo", r.Error());
}

TEST_F(AmberScriptParserTest, DerivePipeline) {
std::string in = R"(
SHADER vertex my_shader PASSTHROUGH
Expand Down
8 changes: 8 additions & 0 deletions src/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ class DrawRectCommand : public PipelineCommand {
void SetHeight(float h) { height_ = h; }
float GetHeight() const { return height_; }

void SetPolygonMode(PolygonMode mode) { data_.SetPolygonMode(mode); }

std::string ToString() const override { return "DrawRectCommand"; }

private:
Expand Down Expand Up @@ -211,6 +213,9 @@ class DrawGridCommand : public PipelineCommand {
void SetRows(uint32_t r) { rows_ = r; }
uint32_t GetRows() const { return rows_; }

void SetPolygonMode(PolygonMode mode) { polygon_mode_ = mode; }
PolygonMode GetPolygonMode() const { return polygon_mode_; }

std::string ToString() const override { return "DrawGridCommand"; }

private:
Expand All @@ -220,6 +225,7 @@ class DrawGridCommand : public PipelineCommand {
float height_ = 0.0;
uint32_t columns_ = 0;
uint32_t rows_ = 0;
PolygonMode polygon_mode_ = PolygonMode::kFill;
};

/// Command to draw from a vertex and index buffer.
Expand All @@ -239,6 +245,8 @@ class DrawArraysCommand : public PipelineCommand {
void SetTopology(Topology topo) { topology_ = topo; }
Topology GetTopology() const { return topology_; }

void SetPolygonMode(PolygonMode mode) { data_.SetPolygonMode(mode); }

void SetFirstVertexIndex(uint32_t idx) { first_vertex_index_ = idx; }
uint32_t GetFirstVertexIndex() const { return first_vertex_index_; }

Expand Down
10 changes: 10 additions & 0 deletions src/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ Result Pipeline::SetShaderType(const Shader* shader, ShaderType type) {
shader->GetName());
}

Result Pipeline::SetPolygonMode(PolygonMode mode) {
if (mode != PolygonMode::kFill && mode != PolygonMode::kLine &&
mode != PolygonMode::kPoint)
return Result("invalid polygon mode specified for pipeline");

polygon_mode_ = mode;

return {};
}

Result Pipeline::Validate() const {
for (const auto& attachment : color_attachments_) {
if (attachment.buffer->ElementCount() !=
Expand Down
5 changes: 5 additions & 0 deletions src/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "amber/result.h"
#include "src/buffer.h"
#include "src/command_data.h"
#include "src/sampler.h"
#include "src/shader.h"

Expand Down Expand Up @@ -284,6 +285,9 @@ class Pipeline {
return push_constant_buffer_;
}

Result SetPolygonMode(PolygonMode mode);
PolygonMode GetPolygonMode() const { return polygon_mode_; }

/// Validates that the pipeline has been created correctly.
Result Validate() const;

Expand Down Expand Up @@ -332,6 +336,7 @@ class Pipeline {
BufferInfo depth_buffer_;
BufferInfo push_constant_buffer_;
Buffer* index_buffer_ = nullptr;
PolygonMode polygon_mode_ = PolygonMode::kFill;

uint32_t fb_width_ = 250;
uint32_t fb_height_ = 250;
Expand Down
1 change: 1 addition & 0 deletions src/vulkan/engine_vulkan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ Result EngineVulkan::DoDrawGrid(const DrawGridCommand* command) {
draw.SetFirstVertexIndex(0);
draw.SetVertexCount(vertices);
draw.SetInstanceCount(1);
draw.SetPolygonMode(command->GetPolygonMode());

Result r = graphics->Draw(&draw, vertex_buffer.get());
if (!r.IsSuccess())
Expand Down
90 changes: 90 additions & 0 deletions tests/cases/draw_polygon_mode.amber
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!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.

DEVICE_FEATURE fillModeNonSolid

SHADER vertex vert_shader PASSTHROUGH

SHADER fragment frag_shader GLSL
#version 430

layout(location = 0) out vec4 color;

void main()
{
color = vec4(1);
}
END

BUFFER position_large DATA_TYPE R8G8_SNORM DATA
-120 -120
0 120
120 -120
END

BUFFER position_small DATA_TYPE R8G8_SNORM DATA
-60 -60
0 60
60 -60
END

BUFFER framebuffer FORMAT B8G8R8A8_UNORM

PIPELINE graphics pipeline_line
ATTACH vert_shader
ATTACH frag_shader

VERTEX_DATA position_large LOCATION 0
POLYGON_MODE line

BIND BUFFER framebuffer AS color LOCATION 0
FRAMEBUFFER_SIZE 256 256
END

PIPELINE graphics pipeline_point
ATTACH vert_shader
ATTACH frag_shader

VERTEX_DATA position_small LOCATION 0
POLYGON_MODE point

BIND BUFFER framebuffer AS color LOCATION 0
FRAMEBUFFER_SIZE 256 256
END

PIPELINE graphics pipeline_line_grid
ATTACH vert_shader
ATTACH frag_shader
POLYGON_MODE line

BIND BUFFER framebuffer AS color LOCATION 0
FRAMEBUFFER_SIZE 256 256
END

CLEAR_COLOR pipeline_line 0 0 0 255
CLEAR pipeline_line
# Draw a large triangle with lines
RUN pipeline_line DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 3
# Draw a rect with points
RUN pipeline_point DRAW_RECT POS 20 20 SIZE 216 216
# Draw a small triangle with points
RUN pipeline_point DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 3
# Draw a line grid overlapping the small triangle
RUN pipeline_line_grid DRAW_GRID POS 80 40 SIZE 96 96 CELLS 3 3

# Make sure no solid triangle was drawn by checking the center
# of the middle grid triangle. That location is covered by all
# drawn primitives.
EXPECT framebuffer IDX 134 82 SIZE 5 5 EQ_RGBA 0 0 0 255