LiteralToUniformReductionOpportunities { static List<LiteralToUniformReductionOpportunity> findOpportunities( ShaderJob shaderJob, ReducerContext context) { final List<LiteralToUniformReductionOpportunity> opportunities = new ArrayList<>(); for (TranslationUnit tu : shaderJob.getShaders()) { new StandardVisitor() { @Override public void visitArrayIndexExpr(ArrayIndexExpr arrayIndexExpr) { if (arrayIndexExpr.getArray() instanceof VariableIdentifierExpr) { String name = ((VariableIdentifierExpr) arrayIndexExpr.getArray()).getName(); if (name.equals(Constants.FLOAT_LITERAL_UNIFORM_VALUES) || name.equals(Constants.INT_LITERAL_UNIFORM_VALUES) || name.equals(Constants.UINT_LITERAL_UNIFORM_VALUES)) { return; } } super.visitArrayIndexExpr(arrayIndexExpr); } @Override public void visitArrayInfo(ArrayInfo arrayInfo) { } @Override public void visitIntConstantExpr(IntConstantExpr intConstantExpr) { super.visitIntConstantExpr(intConstantExpr); opportunities.add(new LiteralToUniformReductionOpportunity(intConstantExpr, tu, shaderJob, getVistitationDepth())); } @Override public void visitFloatConstantExpr(FloatConstantExpr floatConstantExpr) { super.visitFloatConstantExpr(floatConstantExpr); opportunities.add(new LiteralToUniformReductionOpportunity(floatConstantExpr, tu, shaderJob, getVistitationDepth())); } @Override public void visitUIntConstantExpr(UIntConstantExpr uintConstantExpr) { super.visitUIntConstantExpr(uintConstantExpr); opportunities.add(new LiteralToUniformReductionOpportunity(uintConstantExpr, tu, shaderJob, getVistitationDepth())); } }.visit(tu); } return opportunities; } private  LiteralToUniformReductionOpportunities();   }
@Test public void testReplaceSimpleInt() throws Exception { final String vertexShader = "void main() { " + "int a = 1;}"; final String vertexShaderReplaced = "uniform int _GLF_uniform_int_values[2];" + "void main()" + "{" + " int a = _GLF_uniform_int_values[0];" + "}"; final String fragmentShader = "void main() { " + "int a = 2;}"; final String fragmentShaderReplaced = "uniform int _GLF_uniform_int_values[2];" + "void main()" + "{" + " int a = _GLF_uniform_int_values[1];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(vertexShader, ShaderKind.VERTEX)); shaders.add(ParseHelper.parse(fragmentShader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be two opportunities", 2, ops.size()); assertEquals(0, pipelineInfo.getNumUniforms()); ops.forEach(AbstractReductionOpportunity::applyReduction); CompareAsts.assertEqualAsts(fragmentShaderReplaced, shaderJob.getFragmentShader().get()); CompareAsts.assertEqualAsts(vertexShaderReplaced, shaderJob.getVertexShader().get()); assertTrue(shaderJob.getPipelineInfo().hasUniform(Constants.INT_LITERAL_UNIFORM_VALUES)); assertEquals(1, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }
@Test public void testReplaceIntAndFloat() throws Exception { final String vertexShader = "void main() { " + "int a = 1;}"; final String vertexShaderReplaced = "uniform int _GLF_uniform_int_values[1];" + "void main()" + "{" + " int a = _GLF_uniform_int_values[0];" + "}"; final String fragmentShader = "void main() { " + "float a = 2.0;}"; final String fragmentShaderReplaced = "uniform float _GLF_uniform_float_values[1];" + "void main()" + "{" + " float a = _GLF_uniform_float_values[0];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(vertexShader, ShaderKind.VERTEX)); shaders.add(ParseHelper.parse(fragmentShader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be two opportunities", 2, ops.size()); assertEquals(0, pipelineInfo.getNumUniforms()); ops.forEach(AbstractReductionOpportunity::applyReduction); CompareAsts.assertEqualAsts(fragmentShaderReplaced, shaderJob.getFragmentShader().get()); CompareAsts.assertEqualAsts(vertexShaderReplaced, shaderJob.getVertexShader().get()); assertTrue(shaderJob.getPipelineInfo().hasUniform(Constants.INT_LITERAL_UNIFORM_VALUES)); assertTrue(shaderJob.getPipelineInfo().hasUniform(Constants.FLOAT_LITERAL_UNIFORM_VALUES)); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }
@Test public void testReplaceSameInt() throws Exception { final String vertexShader = "void main() { " + "int a = 1;}"; final String vertexShaderReplaced = "uniform int _GLF_uniform_int_values[1];" + "void main()" + "{" + " int a = _GLF_uniform_int_values[0];" + "}"; final String fragmentShader = "void main() { " + "int b = 1;}"; final String fragmentShaderReplaced = "uniform int _GLF_uniform_int_values[1];" + "void main()" + "{" + " int b = _GLF_uniform_int_values[0];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(vertexShader, ShaderKind.VERTEX)); shaders.add(ParseHelper.parse(fragmentShader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be two opportunities", 2, ops.size()); assertEquals(0, pipelineInfo.getNumUniforms()); ops.forEach(AbstractReductionOpportunity::applyReduction); CompareAsts.assertEqualAsts(fragmentShaderReplaced, shaderJob.getFragmentShader().get()); CompareAsts.assertEqualAsts(vertexShaderReplaced, shaderJob.getVertexShader().get()); assertTrue(shaderJob.getPipelineInfo().hasUniform(Constants.INT_LITERAL_UNIFORM_VALUES)); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }
@Test public void testReplaceSameFloat() throws Exception { final String vertexShader = "void main() { " + "float a = 1.0;}"; final String vertexShaderReplaced = "uniform float _GLF_uniform_float_values[1];" + "void main()" + "{" + " float a = _GLF_uniform_float_values[0];" + "}"; final String fragmentShader = "void main() { " + "float a = 1.0;}"; final String fragmentShaderReplaced = "uniform float _GLF_uniform_float_values[1];" + "void main()" + "{" + " float a = _GLF_uniform_float_values[0];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(vertexShader, ShaderKind.VERTEX)); shaders.add(ParseHelper.parse(fragmentShader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be two opportunities", 2, ops.size()); assertEquals(0, pipelineInfo.getNumUniforms()); ops.forEach(AbstractReductionOpportunity::applyReduction); CompareAsts.assertEqualAsts(fragmentShaderReplaced, shaderJob.getFragmentShader().get()); CompareAsts.assertEqualAsts(vertexShaderReplaced, shaderJob.getVertexShader().get()); assertTrue(shaderJob.getPipelineInfo().hasUniform(Constants.FLOAT_LITERAL_UNIFORM_VALUES)); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }
@Test public void testReplaceUInts() throws Exception { final String vertexShader = "void main() { " + "uint a = 44u;}"; final String vertexShaderReplaced = "uniform uint _GLF_uniform_uint_values[2];" + "void main()" + "{" + " uint a = _GLF_uniform_uint_values[0];" + "}"; final String fragmentShader = "void main() { " + "uint a = 33u;}"; final String fragmentShaderReplaced = "uniform uint _GLF_uniform_uint_values[2];" + "void main()" + "{" + " uint a = _GLF_uniform_uint_values[1];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(vertexShader, ShaderKind.VERTEX)); shaders.add(ParseHelper.parse(fragmentShader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be two opportunities", 2, ops.size()); assertEquals(0, pipelineInfo.getNumUniforms()); ops.forEach(AbstractReductionOpportunity::applyReduction); CompareAsts.assertEqualAsts(fragmentShaderReplaced, shaderJob.getFragmentShader().get()); CompareAsts.assertEqualAsts(vertexShaderReplaced, shaderJob.getVertexShader().get()); assertTrue(shaderJob.getPipelineInfo().hasUniform(Constants.UINT_LITERAL_UNIFORM_VALUES)); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }
@Test public void testManuallyAddedUniform() throws Exception { final String vertexShader = "void main()" + "{ " + " int a = 1;" + " int b = 1;" + "}"; final String vertexShaderReplaced = "uniform int _GLF_uniform_int_values[1];" + "void main()" + "{" + " int a = _GLF_uniform_int_values[0];" + " int b = 1;" + "}"; final String vertexShaderReplaced2 = "uniform int _GLF_uniform_int_values[2];" + "void main()" + "{" + " int a = _GLF_uniform_int_values[0];" + " int b = _GLF_uniform_int_values[0];" + "}"; final String fragmentShader = "void main() " + "{ " + " int b = 2;" + "}"; final String fragmentShaderNotReplaced = "void main()" + "{" + " int b = 2;" + "}"; final String fragmentShaderReplaced = "uniform int _GLF_uniform_int_values[2];" + "void main()" + "{" + " int b = _GLF_uniform_int_values[1];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(vertexShader, ShaderKind.VERTEX)); shaders.add(ParseHelper.parse(fragmentShader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be three opportunities", 3, ops.size()); assertEquals(0, pipelineInfo.getNumUniforms()); ops.get(0).applyReduction(); CompareAsts.assertEqualAsts(vertexShaderReplaced, shaderJob.getVertexShader().get()); CompareAsts.assertEqualAsts(fragmentShaderNotReplaced, shaderJob.getFragmentShader().get()); assertEquals(1, pipelineInfo.getNumUniforms()); shaderJob.getPipelineInfo().addUniform("TEST", BasicType.INT, Optional.of(0), new ArrayList<>()); ops.forEach(AbstractReductionOpportunity::applyReduction); assertEquals("There should be three opportunities", 3, ops.size()); assertEquals(2, pipelineInfo.getNumUniforms()); CompareAsts.assertEqualAsts(vertexShaderReplaced2, shaderJob.getVertexShader().get()); CompareAsts.assertEqualAsts(fragmentShaderReplaced, shaderJob.getFragmentShader().get()); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }
@Test public void testReplaceMultipleLiterals() throws Exception { final String vertexShader = "void main() { " + "float a = 1.0;" + "float b = 2.0;" + "int c = 1;" + "int d = 2;" + "int e = 3;" + "}"; final String vertexShaderReplaced = "uniform int _GLF_uniform_int_values[3];" + "uniform float _GLF_uniform_float_values[3];" + "void main()" + "{" + " float a = _GLF_uniform_float_values[0];" + " float b = _GLF_uniform_float_values[1];" + " int c = _GLF_uniform_int_values[0];" + " int d = _GLF_uniform_int_values[1];" + " int e = _GLF_uniform_int_values[2];" + "}"; final String fragmentShader = "void main() { " + "float a = 3.0;" + "float b = 2.0;" + "float c = 1.0;" + "int d = 1;" + "int e = 2;" + "}"; final String fragmentShaderReplaced = "uniform int _GLF_uniform_int_values[3];" + "uniform float _GLF_uniform_float_values[3];" + "void main()" + "{" + " float a = _GLF_uniform_float_values[2];" + " float b = _GLF_uniform_float_values[1];" + " float c = _GLF_uniform_float_values[0];" + " int d = _GLF_uniform_int_values[0];" + " int e = _GLF_uniform_int_values[1];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(vertexShader, ShaderKind.VERTEX)); shaders.add(ParseHelper.parse(fragmentShader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be 10 opportunities", 10, ops.size()); assertEquals(0, pipelineInfo.getNumUniforms()); ops.forEach(AbstractReductionOpportunity::applyReduction); CompareAsts.assertEqualAsts(fragmentShaderReplaced, shaderJob.getFragmentShader().get()); CompareAsts.assertEqualAsts(vertexShaderReplaced, shaderJob.getVertexShader().get()); assertEquals(2, pipelineInfo.getNumUniforms()); assertTrue(shaderJob.getPipelineInfo().hasUniform(Constants.FLOAT_LITERAL_UNIFORM_VALUES)); assertTrue(shaderJob.getPipelineInfo().hasUniform(Constants.INT_LITERAL_UNIFORM_VALUES)); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }
@Test public void testArrayDeclaration() throws Exception { final String shader = "void main()" + "{" + "float a[2*4];" + "float b = 1;" + "a[0] = 2;" + "}"; final String shaderReplaced = "uniform int _GLF_uniform_int_values[3];" + "void main()" + "{" + "float a[2*4];" + "float b = _GLF_uniform_int_values[0];" + "a[_GLF_uniform_int_values[1]] = _GLF_uniform_int_values[2];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(shader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be three opportunities", 3, ops.size()); ops.forEach(AbstractReductionOpportunity::applyReduction); assertEquals(1, pipelineInfo.getNumUniforms()); CompareAsts.assertEqualAsts(shaderReplaced, shaderJob.getFragmentShader().get()); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }
@Test public void testArrayConstructor() throws Exception { final String shader = "void main() {" + "int A[3] = int[3](1, 2, 3);" + "int B[3] = int[3](4, 5, 6);" + "int x = (true ? A : B)[2];" + "}"; final String shaderReplaced = "uniform int _GLF_uniform_int_values[6];" + "\n" + "void main()" + "{" + "int A[3] = int[3](_GLF_uniform_int_values[0], _GLF_uniform_int_values[1], " + "_GLF_uniform_int_values[2]);" + "int B[3] = int[3](_GLF_uniform_int_values[3], _GLF_uniform_int_values[4], " + "_GLF_uniform_int_values[5]);" + "int x = (true ? A : B)[_GLF_uniform_int_values[1]];" + "}"; final List<TranslationUnit> shaders = new ArrayList<>(); shaders.add(ParseHelper.parse(shader, ShaderKind.FRAGMENT)); final PipelineInfo pipelineInfo = new PipelineInfo(); final ShaderJob shaderJob = new GlslShaderJob(Optional.empty(), pipelineInfo, shaders); assertEquals(0, pipelineInfo.getNumUniforms()); final List<LiteralToUniformReductionOpportunity> ops = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be seven opportunities", 7, ops.size()); ops.forEach(AbstractReductionOpportunity::applyReduction); assertEquals(1, pipelineInfo.getNumUniforms()); CompareAsts.assertEqualAsts(shaderReplaced, shaderJob.getFragmentShader().get()); final List<LiteralToUniformReductionOpportunity> ops2 = LiteralToUniformReductionOpportunities .findOpportunities(shaderJob, new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals("There should be no opportunities", 0, ops2.size()); }