Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for drawing to multiple render targets #6657

Merged
merged 16 commits into from
Jul 6, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,11 @@ public void testGlslDirectives() throws Exception {
"#extension GL_OES_standard_derivatives : enable\n" +
"precision mediump float;\n" +
"\n" +
"out vec4 _DMENGINE_GENERATED_gl_FragColor;\n" +
"out vec4 _DMENGINE_GENERATED_gl_FragColor_0;\n" +
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GLSL transformation now supports multiple outputs, so the default will always be postfixed with _0.

"\n" +
"#line 1\n" +
"void main() {\n" +
" _DMENGINE_GENERATED_gl_FragColor = vec4(1.0);\n" +
" _DMENGINE_GENERATED_gl_FragColor_0 = vec4(1.0);\n" +
"}\n";
testOutput(expected, source);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ public static enum ShaderType {
private static final Pattern regexVersionStringPattern = Pattern.compile("^\\h*#\\h*version\\h+(?<version>\\d+)(\\h+(?<profile>\\S+))?\\h*\\n");
private static final Pattern regexPrecisionKeywordPattern = Pattern.compile("(?<keyword>precision)\\s+(?<precision>lowp|mediump|highp)\\s+(?<type>float|int)\\s*;");
private static final Pattern regexUniformKeywordPattern = Pattern.compile("((?<keyword>uniform)\\s+|(?<layout>layout\\s*\\(.*\\n*.*\\)\\s*)\\s+|(?<precision>lowp|mediump|highp)\\s+)*(?<type>\\S+)\\s+(?<identifier>\\S+)\\s*(?<any>.*)\\s*;");
private static final Pattern regexFragDataArrayPattern = Pattern.compile("gl_FragData\\[(?<index>\\d+)\\]");

private static final String[][] vsKeywordReps = {{"varying", "out"}, {"attribute", "in"}, {"texture2D", "texture"}, {"textureCube", "texture"}};
private static final String[][] fsKeywordReps = {{"varying", "in"}, {"texture2D", "texture"}, {"textureCube", "texture"}};
Expand All @@ -203,7 +204,7 @@ public static enum ShaderType {
private static final String glFragColorKeyword = "gl_FragColor";
private static final String glFragDataKeyword = "gl_FragData";
private static final String glFragColorRep = dmEngineGeneratedRep + glFragColorKeyword;
private static final String glFragColorAttrRep = "\nout vec4 " + glFragColorRep + ";\n";
private static final String glFragColorAttrRep = "\nout vec4 " + glFragColorRep + "%s;\n";
private static final String floatPrecisionAttrRep = "precision mediump float;\n";

public static Result transform(String input, ShaderType shaderType, String targetProfile, int targetVersion, boolean useLatestFeatures) throws CompileExceptionError {
Expand Down Expand Up @@ -246,12 +247,27 @@ public static Result transform(String input, ShaderType shaderType, String targe
input = input.replaceAll("\\b" + keywordRep[0] + "\\b", keywordRep[1]);
}

// Get data output array size
Matcher fragDataArrayMatcher = regexFragDataArrayPattern.matcher(input);
int maxColorOutputs = 1;
while (fragDataArrayMatcher.find()) {
String fragDataArrayIndex = fragDataArrayMatcher.group("index");
maxColorOutputs = Math.max(maxColorOutputs, Integer.parseInt(fragDataArrayIndex) + 1);
}

// Replace fragment output variables
boolean output_glFragColor = input.contains(glFragColorKeyword);
boolean output_glFragData = input.contains(glFragDataKeyword);

if (output_glFragColor)
input = input.replaceAll("\\b" + glFragColorKeyword + "\\b", glFragColorRep);
{
input = input.replaceAll("\\b" + glFragColorKeyword + "\\b", glFragColorRep + "_0");
}

if (output_glFragData)
input = input.replaceAll("\\b" + glFragDataKeyword + "\\b", glFragColorRep);
{
input = input.replaceAll("\\b" + glFragDataKeyword + "\\[(\\d+)\\]", glFragColorRep + "_$1");
}

Comment on lines +268 to 271
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously the gl_FragData keyword would be replaced with the same color output as gl_FragColor, but that doesn't work for multiple outputs. Instead we generate specific outputs for each assignment of gl_FragData[x] into gl_FragData_x variables.

// Split into slices separated by semicolon, curly bracket scopes and preprocessor definition lines: ";", "{", "}" and "#..<\n>"
// This to reduce parsing complexity
Expand Down Expand Up @@ -333,8 +349,10 @@ else if (line.contains("precision")) {
if(floatPrecisionIndex < 0 && targetProfile.equals("es")) {
output.add(patchLineIndex++, floatPrecisionAttrRep);
}
// insert fragcolor out attr
output.add(patchLineIndex++, glFragColorAttrRep);
for (int i = 0; i < maxColorOutputs; i++) {
// insert fragcolor out attr
output.add(patchLineIndex++, String.format(glFragColorAttrRep, "_" + i));
}
Comment on lines +352 to +355
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will always be at least one output

}
}

Expand Down
4 changes: 2 additions & 2 deletions engine/engine/src/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,7 @@ namespace dmEngine
for (int i = 0; i < 3; ++i) {
dmGraphics::BeginFrame(engine->m_GraphicsContext);
dmGraphics::SetViewport(engine->m_GraphicsContext, 0, 0, dmGraphics::GetWindowWidth(engine->m_GraphicsContext), dmGraphics::GetWindowHeight(engine->m_GraphicsContext));
dmGraphics::Clear(engine->m_GraphicsContext, dmGraphics::BUFFER_TYPE_COLOR_BIT,
dmGraphics::Clear(engine->m_GraphicsContext, dmGraphics::BUFFER_TYPE_COLOR0_BIT,
(float)((engine->m_ClearColor>> 0)&0xFF),
(float)((engine->m_ClearColor>> 8)&0xFF),
(float)((engine->m_ClearColor>>16)&0xFF),
Expand Down Expand Up @@ -1599,7 +1599,7 @@ namespace dmEngine
else
{
dmGraphics::SetViewport(engine->m_GraphicsContext, 0, 0, dmGraphics::GetWindowWidth(engine->m_GraphicsContext), dmGraphics::GetWindowHeight(engine->m_GraphicsContext));
dmGraphics::Clear(engine->m_GraphicsContext, dmGraphics::BUFFER_TYPE_COLOR_BIT | dmGraphics::BUFFER_TYPE_DEPTH_BIT | dmGraphics::BUFFER_TYPE_STENCIL_BIT,
dmGraphics::Clear(engine->m_GraphicsContext, dmGraphics::BUFFER_TYPE_COLOR0_BIT | dmGraphics::BUFFER_TYPE_DEPTH_BIT | dmGraphics::BUFFER_TYPE_STENCIL_BIT,
(float)((engine->m_ClearColor>> 0)&0xFF),
(float)((engine->m_ClearColor>> 8)&0xFF),
(float)((engine->m_ClearColor>>16)&0xFF),
Expand Down
2 changes: 1 addition & 1 deletion engine/gamesys/src/gamesys/test/fontview/fontview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ namespace dmFontView
if (dmHID::GetKey(&keybdata, dmHID::KEY_ESC))
break;

dmGraphics::Clear(context->m_GraphicsContext, dmGraphics::BUFFER_TYPE_COLOR_BIT | dmGraphics::BUFFER_TYPE_DEPTH_BIT, 0, 0, 0, 0, 1.0, 0);
dmGraphics::Clear(context->m_GraphicsContext, dmGraphics::BUFFER_TYPE_COLOR0_BIT | dmGraphics::BUFFER_TYPE_DEPTH_BIT, 0, 0, 0, 0, 1.0, 0);
dmGraphics::SetViewport(context->m_GraphicsContext, 0, 0, context->m_ScreenWidth, context->m_ScreenHeight);

uint16_t x = 10;
Expand Down
2 changes: 1 addition & 1 deletion engine/graphics/src/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ namespace dmGraphics
AttachmentToBufferType::AttachmentToBufferType()
{
memset(m_AttachmentToBufferType, 0x0, sizeof(m_AttachmentToBufferType));
m_AttachmentToBufferType[ATTACHMENT_COLOR] = BUFFER_TYPE_COLOR_BIT;
m_AttachmentToBufferType[ATTACHMENT_COLOR] = BUFFER_TYPE_COLOR0_BIT;
m_AttachmentToBufferType[ATTACHMENT_DEPTH] = BUFFER_TYPE_DEPTH_BIT;
m_AttachmentToBufferType[ATTACHMENT_STENCIL] = BUFFER_TYPE_STENCIL_BIT;
}
Expand Down
28 changes: 20 additions & 8 deletions engine/graphics/src/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,16 @@ namespace dmGraphics
// buffer clear types, each value is guaranteed to be separate bits
enum BufferType
{
BUFFER_TYPE_COLOR_BIT = 0x1,
BUFFER_TYPE_DEPTH_BIT = 0x2,
BUFFER_TYPE_STENCIL_BIT = 0x4,
BUFFER_TYPE_COLOR0_BIT = 0x01,
BUFFER_TYPE_COLOR1_BIT = 0x02,
BUFFER_TYPE_COLOR2_BIT = 0x04,
BUFFER_TYPE_COLOR3_BIT = 0x08,
BUFFER_TYPE_DEPTH_BIT = 0x10,
BUFFER_TYPE_STENCIL_BIT = 0x20,
};
static const uint8_t MAX_BUFFER_TYPE_COUNT = 3;

static const uint8_t MAX_BUFFER_COLOR_ATTACHMENTS = 4;
static const uint8_t MAX_BUFFER_TYPE_COUNT = 2 + MAX_BUFFER_COLOR_ATTACHMENTS;

// render states
enum State
Expand Down Expand Up @@ -633,7 +638,10 @@ namespace dmGraphics
{
switch(buffer_type)
{
case BUFFER_TYPE_COLOR_BIT: return "BUFFER_TYPE_COLOR_BIT";
case BUFFER_TYPE_COLOR0_BIT: return "BUFFER_TYPE_COLOR_BIT";
case BUFFER_TYPE_COLOR1_BIT: return "BUFFER_TYPE_COLOR1_BIT";
case BUFFER_TYPE_COLOR2_BIT: return "BUFFER_TYPE_COLOR2_BIT";
case BUFFER_TYPE_COLOR3_BIT: return "BUFFER_TYPE_COLOR3_BIT";
case BUFFER_TYPE_DEPTH_BIT: return "BUFFER_TYPE_DEPTH_BIT";
case BUFFER_TYPE_STENCIL_BIT: return "BUFFER_TYPE_STENCIL_BIT";
default:break;
Expand All @@ -645,9 +653,13 @@ namespace dmGraphics
{
switch(buffer_type)
{
case BUFFER_TYPE_COLOR_BIT: return 0;
case BUFFER_TYPE_DEPTH_BIT: return 1;
case BUFFER_TYPE_STENCIL_BIT: return 2;
case BUFFER_TYPE_COLOR0_BIT: return 0;
case BUFFER_TYPE_COLOR1_BIT: return 1;
case BUFFER_TYPE_COLOR2_BIT: return 2;
case BUFFER_TYPE_COLOR3_BIT: return 3;
case BUFFER_TYPE_DEPTH_BIT: return 4;
case BUFFER_TYPE_STENCIL_BIT: return 5;
default: break;
}
return ~0u;
}
Expand Down
Loading