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 @@ -802,6 +802,11 @@ when using a Vulkan backend.
END
```

```groovy
# Enable or disable alpha-to-coverage for the pipeline. Defaults to off.
ALPHA_TO_COVERAGE {on | off}
```

```groovy
# Set the size of the render buffers. |width| and |height| are integers and
# default to 250x250.
Expand Down
20 changes: 20 additions & 0 deletions src/amberscript/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,8 @@ Result Parser::ParsePipelineBody(const std::string& cmd_name,
r = ParsePipelinePatchControlPoints(pipeline.get());
} else if (tok == "BLEND") {
r = ParsePipelineBlend(pipeline.get());
} else if (tok == "ALPHA_TO_COVERAGE") {
r = ParsePipelineAlphaToCoverage(pipeline.get());
} else if (tok == "SHADER_GROUP") {
r = ParsePipelineShaderGroup(pipeline.get());
} else if (tok == "SHADER_BINDING_TABLE") {
Expand Down Expand Up @@ -2328,6 +2330,24 @@ Result Parser::ParsePipelineBlend(Pipeline* pipeline) {
return ValidateEndOfStatement("BLEND command");
}

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

auto mode = token->AsString();
if (mode == "on") {
pipeline->GetPipelineData()->SetEnableAlphaToCoverage(true);
} else if (mode == "off") {
pipeline->GetPipelineData()->SetEnableAlphaToCoverage(false);
} else {
return Result("invalid value for ALPHA_TO_COVERAGE: " + mode);
}

return ValidateEndOfStatement("ALPHA_TO_COVERAGE command");
}

Result Parser::ParsePipelineShaderGroup(Pipeline* pipeline) {
std::unique_ptr<Token> token = tokenizer_->NextToken();
if (!token->IsIdentifier()) {
Expand Down
1 change: 1 addition & 0 deletions src/amberscript/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class Parser : public amber::Parser {
Result ParsePipelineDepth(Pipeline* pipeline);
Result ParsePipelineStencil(Pipeline* pipeline);
Result ParsePipelineBlend(Pipeline* pipeline);
Result ParsePipelineAlphaToCoverage(Pipeline* pipeline);
Result ParsePipelineShaderGroup(Pipeline* pipeline);
Result ParseRun();
Result ParseClear();
Expand Down
171 changes: 171 additions & 0 deletions src/amberscript/parser_pipeline_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -623,5 +623,176 @@ END
EXPECT_EQ(pipelines[1]->GetPipelineData()->GetPatchControlPoints(), 4u);
}

TEST_F(AmberScriptParserTest, PipelineAlphaToCoverageDefault) {
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
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_FALSE(pipelines[0]->GetPipelineData()->GetEnableAlphaToCoverage());
}

TEST_F(AmberScriptParserTest, PipelineAlphaToCoverageOn) {
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

ALPHA_TO_COVERAGE on
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_TRUE(pipelines[0]->GetPipelineData()->GetEnableAlphaToCoverage());
}

TEST_F(AmberScriptParserTest, PipelineAlphaToCoverageOff) {
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

ALPHA_TO_COVERAGE on
ALPHA_TO_COVERAGE off
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_FALSE(pipelines[0]->GetPipelineData()->GetEnableAlphaToCoverage());
}

TEST_F(AmberScriptParserTest, PipelineDeriveAlphaToCoverage) {
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

ALPHA_TO_COVERAGE on
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_TRUE(pipelines[0]->GetPipelineData()->GetEnableAlphaToCoverage());
EXPECT_TRUE(pipelines[1]->GetPipelineData()->GetEnableAlphaToCoverage());
}

TEST_F(AmberScriptParserTest, PipelineAlphaToCoverageMissingMode) {
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

ALPHA_TO_COVERAGE
END
)";

Parser parser;
Result r = parser.Parse(in);
ASSERT_FALSE(r.IsSuccess());
EXPECT_EQ("12: missing mode in ALPHA_TO_COVERAGE command", r.Error());
}

TEST_F(AmberScriptParserTest, PipelineAlphaToCoverageInvalidMode) {
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

ALPHA_TO_COVERAGE invalid
END
)";

Parser parser;
Result r = parser.Parse(in);
ASSERT_FALSE(r.IsSuccess());
EXPECT_EQ("11: invalid value for ALPHA_TO_COVERAGE: invalid", r.Error());
}

TEST_F(AmberScriptParserTest, PipelineAlphaToCoverageExtraParams) {
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

ALPHA_TO_COVERAGE on EXTRA
END
)";

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

} // namespace amberscript
} // namespace amber
4 changes: 4 additions & 0 deletions src/dawn/engine_dawn.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,10 @@ Result DawnPipelineHelper::CreateRenderPipelineDescriptor(
primitiveState.frontFace = GetDawnFrontFace(pipeline_data->GetFrontFace());
primitiveState.cullMode = GetDawnCullMode(pipeline_data->GetCullMode());
renderPipelineDescriptor.primitive = primitiveState;

multisampleState.alphaToCoverageEnabled =
pipeline_data->GetEnableAlphaToCoverage();
renderPipelineDescriptor.multisample = multisampleState;
}

// Set defaults for the color state descriptors.
Expand Down
1 change: 1 addition & 0 deletions src/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ std::unique_ptr<Pipeline> Pipeline::Clone() const {
auto clone = std::make_unique<Pipeline>(pipeline_type_);
clone->shaders_ = shaders_;
clone->color_attachments_ = color_attachments_;
clone->resolve_targets_ = resolve_targets_;
clone->vertex_buffers_ = vertex_buffers_;
clone->buffers_ = buffers_;
clone->depth_stencil_buffer_ = depth_stencil_buffer_;
Expand Down
4 changes: 4 additions & 0 deletions src/pipeline_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ class PipelineData {
void SetEnableDepthBoundsTest(bool v) { enable_depth_bounds_test_ = v; }
bool GetEnableDepthBoundsTest() const { return enable_depth_bounds_test_; }

void SetEnableAlphaToCoverage(bool v) { enable_alpha_to_coverage_ = v; }
bool GetEnableAlphaToCoverage() const { return enable_alpha_to_coverage_; }

void SetDepthBiasConstantFactor(float f) { depth_bias_constant_factor_ = f; }
float GetDepthBiasConstantFactor() const {
return depth_bias_constant_factor_;
Expand Down Expand Up @@ -228,6 +231,7 @@ class PipelineData {
bool enable_primitive_restart_ = false;
bool enable_rasterizer_discard_ = false;
bool enable_logic_op_ = false;
bool enable_alpha_to_coverage_ = false;

float line_width_ = 1.0f;
float depth_bias_constant_factor_ = 0.0f;
Expand Down
3 changes: 2 additions & 1 deletion src/vulkan/frame_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ Result FrameBuffer::Initialize(VkRenderPass render_pass) {

depth_stencil_image_ = std::make_unique<TransferImage>(
device_, *depth_stencil_attachment_.buffer->GetFormat(), aspect,
VK_IMAGE_TYPE_2D, usage_flags, width_, height_, depth_, 1u, 0u, 1u, 1u);
VK_IMAGE_TYPE_2D, usage_flags, width_, height_, depth_, 1u, 0u, 1u,
depth_stencil_attachment_.buffer->GetSamples());
Comment thread
dj2 marked this conversation as resolved.

Result r = depth_stencil_image_->Initialize();
if (!r.IsSuccess()) {
Expand Down
16 changes: 14 additions & 2 deletions src/vulkan/graphics_pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ Result GraphicsPipeline::CreateRenderPass() {
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachment_desc.back().finalLayout =
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachment_desc.back().samples = static_cast<VkSampleCountFlagBits>(
depth_stencil_buffer_.buffer->GetSamples());

depth_refer.attachment = static_cast<uint32_t>(attachment_desc.size() - 1);
depth_refer.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
Expand Down Expand Up @@ -653,8 +655,10 @@ Result GraphicsPipeline::CreateVkGraphicsPipeline(
VK_FALSE, /* sampleShadingEnable */
0, /* minSampleShading */
&kSampleMask, /* pSampleMask */
VK_FALSE, /* alphaToCoverageEnable */
VK_FALSE, /* alphaToOneEnable */
pipeline_data->GetEnableAlphaToCoverage()
? VK_TRUE
: VK_FALSE, /* alphaToCoverageEnable */
VK_FALSE, /* alphaToOneEnable */
};

// Search for multisampled color buffers and adjust the rasterization samples
Expand All @@ -666,6 +670,14 @@ Result GraphicsPipeline::CreateVkGraphicsPipeline(
multisampleInfo.rasterizationSamples =
static_cast<VkSampleCountFlagBits>(samples);
}
if (depth_stencil_buffer_.buffer &&
depth_stencil_buffer_.buffer->GetFormat()->IsFormatKnown()) {
uint32_t samples = depth_stencil_buffer_.buffer->GetSamples();
assert(static_cast<VkSampleCountFlagBits>(samples) >=
multisampleInfo.rasterizationSamples);
multisampleInfo.rasterizationSamples =
static_cast<VkSampleCountFlagBits>(samples);
}

VkGraphicsPipelineCreateInfo pipeline_info = VkGraphicsPipelineCreateInfo();
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
Expand Down
Loading
Loading