Add tests for buffer block flattening

This commit is contained in:
Arseny Kapoulkine 2017-01-16 14:19:49 -08:00
parent 0185f0a6b8
commit 24c66250c7
17 changed files with 329 additions and 18 deletions

View File

@ -672,7 +672,7 @@ int main(int argc, char *argv[])
if (args.flatten_ubo)
for (auto &ubo : res.uniform_buffers)
compiler->flatten_interface_block(ubo.id);
compiler->flatten_buffer_block(ubo.id);
auto pls_inputs = remap_pls(args.pls_in, res.stage_inputs, &res.subpass_inputs);
auto pls_outputs = remap_pls(args.pls_out, res.stage_outputs, nullptr);

View File

@ -0,0 +1,10 @@
#version 310 es
uniform vec4 UBO[14];
in vec4 aVertex;
void main()
{
gl_Position = (mat4(UBO[0],UBO[1],UBO[2],UBO[3]) * aVertex) + UBO[13];
}

View File

@ -0,0 +1,13 @@
#version 310 es
uniform vec4 UBO[4];
in vec4 aVertex;
out vec3 vNormal;
in vec3 aNormal;
void main()
{
gl_Position = mat4(UBO[0],UBO[1],UBO[2],UBO[3]) * aVertex;
vNormal = aNormal;
}

View File

@ -0,0 +1,29 @@
#version 310 es
struct Light
{
vec3 Position;
float Radius;
vec4 Color;
};
uniform vec4 UBO[12];
in vec4 aVertex;
out vec4 vColor;
in vec3 aNormal;
void main()
{
gl_Position = mat4(UBO[0],UBO[1],UBO[2],UBO[3]) * aVertex;
vColor = vec4(0.0);
for (int i = 0; i < 4; i++)
{
Light light;
light.Position = Light(UBO[i*2+4].xyz,UBO[i*2+4].w,UBO[i*2+5]).Position;
light.Radius = Light(UBO[i*2+4].xyz,UBO[i*2+4].w,UBO[i*2+5]).Radius;
light.Color = Light(UBO[i*2+4].xyz,UBO[i*2+4].w,UBO[i*2+5]).Color;
vec3 L = aVertex.xyz - light.Position;
vColor += ((UBO[i*2+5] * clamp(1.0 - (length(L) / light.Radius), 0.0, 1.0)) * dot(aNormal, normalize(L)));
}
}

View File

@ -0,0 +1,25 @@
#version 310 es
struct Light
{
vec3 Position;
float Radius;
vec4 Color;
};
uniform vec4 UBO[12];
in vec4 aVertex;
out vec4 vColor;
in vec3 aNormal;
void main()
{
gl_Position = mat4(UBO[0],UBO[1],UBO[2],UBO[3]) * aVertex;
vColor = vec4(0.0);
for (int i = 0; i < 4; i++)
{
vec3 L = aVertex.xyz - UBO[i*2+4].xyz;
vColor += ((UBO[i*2+5] * clamp(1.0 - (length(L) / UBO[i*2+4].w), 0.0, 1.0)) * dot(aNormal, normalize(L)));
}
}

View File

@ -0,0 +1,10 @@
#version 310 es
uniform vec4 UBO[15];
in ivec2 aIndex;
void main()
{
gl_Position = UBO[aIndex.x*5+aIndex.y*1+0];
}

View File

@ -0,0 +1,22 @@
#version 310 es
struct Light
{
vec3 Position;
float Radius;
vec4 Color;
};
uniform vec4 UBO[6];
in vec4 aVertex;
out vec4 vColor;
in vec3 aNormal;
void main()
{
gl_Position = mat4(UBO[0],UBO[1],UBO[2],UBO[3]) * aVertex;
vColor = vec4(0.0);
vec3 L = aVertex.xyz - UBO[4].xyz;
vColor += ((UBO[5] * clamp(1.0 - (length(L) / UBO[4].w), 0.0, 1.0)) * dot(aNormal, normalize(L)));
}

View File

@ -0,0 +1,21 @@
#version 310 es
uniform vec4 UBO[8];
out vec4 oA;
out vec4 oB;
out vec4 oC;
out vec4 oD;
out vec4 oE;
out vec4 oF;
void main()
{
gl_Position = vec4(0.0);
oA = UBO[0];
oB = vec4(UBO[1].xy, UBO[1].zw);
oC = vec4(UBO[2].x, UBO[3].xyz);
oD = vec4(UBO[4].xyz, UBO[4].w);
oE = vec4(UBO[5].x, UBO[5].y, UBO[5].z, UBO[5].w);
oF = vec4(UBO[6].x, UBO[6].zw, UBO[7].x);
}

View File

@ -0,0 +1,16 @@
#version 310 es
layout(std140) uniform UBO
{
uniform mat4 uMVP;
vec4 A1[2];
vec4 A2[2][2];
float A3[3];
vec4 Offset;
};
in vec4 aVertex;
void main()
{
gl_Position = uMVP * aVertex + Offset;
}

View File

@ -0,0 +1,15 @@
#version 310 es
layout(std140) uniform UBO
{
uniform mat4 uMVP;
};
in vec4 aVertex;
in vec3 aNormal;
out vec3 vNormal;
void main()
{
gl_Position = uMVP * aVertex;
vNormal = aNormal;
}

View File

@ -0,0 +1,34 @@
#version 310 es
struct Light
{
vec3 Position;
float Radius;
vec4 Color;
};
layout(std140) uniform UBO
{
mat4 uMVP;
Light lights[4];
};
in vec4 aVertex;
in vec3 aNormal;
out vec4 vColor;
void main()
{
gl_Position = uMVP * aVertex;
vColor = vec4(0.0);
for (int i = 0; i < 4; ++i)
{
Light light = lights[i];
vec3 L = aVertex.xyz - light.Position;
vColor += dot(aNormal, normalize(L)) * (clamp(1.0 - length(L) / light.Radius, 0.0, 1.0) * lights[i].Color);
}
}

View File

@ -0,0 +1,33 @@
#version 310 es
struct Light
{
vec3 Position;
float Radius;
vec4 Color;
};
layout(std140) uniform UBO
{
mat4 uMVP;
Light lights[4];
};
in vec4 aVertex;
in vec3 aNormal;
out vec4 vColor;
void main()
{
gl_Position = uMVP * aVertex;
vColor = vec4(0.0);
for (int i = 0; i < 4; ++i)
{
vec3 L = aVertex.xyz - lights[i].Position;
vColor += dot(aNormal, normalize(L)) * (clamp(1.0 - length(L) / lights[i].Radius, 0.0, 1.0) * lights[i].Color);
}
}

View File

@ -0,0 +1,13 @@
#version 310 es
layout(std140) uniform UBO
{
vec4 Data[3][5];
};
in ivec2 aIndex;
void main()
{
gl_Position = Data[aIndex.x][aIndex.y];
}

View File

@ -0,0 +1,30 @@
#version 310 es
struct Light
{
vec3 Position;
float Radius;
vec4 Color;
};
layout(std140) uniform UBO
{
mat4 uMVP;
Light light;
};
in vec4 aVertex;
in vec3 aNormal;
out vec4 vColor;
void main()
{
gl_Position = uMVP * aVertex;
vColor = vec4(0.0);
vec3 L = aVertex.xyz - light.Position;
vColor += dot(aNormal, normalize(L)) * (clamp(1.0 - length(L) / light.Radius, 0.0, 1.0) * light.Color);
}

View File

@ -0,0 +1,42 @@
#version 310 es
// comments note the 16b alignment boundaries (see GL spec 7.6.2.2 Standard Uniform Block Layout)
layout(std140) uniform UBO
{
// 16b boundary
uniform vec4 A;
// 16b boundary
uniform vec2 B0;
uniform vec2 B1;
// 16b boundary
uniform float C0;
// 16b boundary (vec3 is aligned to 16b)
uniform vec3 C1;
// 16b boundary
uniform vec3 D0;
uniform float D1;
// 16b boundary
uniform float E0;
uniform float E1;
uniform float E2;
uniform float E3;
// 16b boundary
uniform float F0;
uniform vec2 F1;
// 16b boundary (vec2 before us is aligned to 8b)
uniform float F2;
};
out vec4 oA, oB, oC, oD, oE, oF;
void main()
{
gl_Position = vec4(0.0);
oA = A;
oB = vec4(B0, B1);
oC = vec4(C0, C1);
oD = vec4(D0, D1);
oE = vec4(E0, E1, E2, E3);
oF = vec4(F0, F1, F2);
}

View File

@ -3272,7 +3272,7 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, bool* need_transpose)
{
if (flattened_buffer_blocks.find(base) != flattened_buffer_blocks.end())
if (flattened_buffer_blocks.count(base))
{
std::string expr;
flattened_access_chain(expr, base, indices, count, target_type, 0);
@ -3280,10 +3280,6 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
if (need_transpose)
*need_transpose = false;
expr += "/*";
expr += access_chain(base, indices, count, false);
expr += "*/";
return expr;
}
else

View File

@ -66,7 +66,7 @@ def validate_shader(shader, vulkan):
else:
subprocess.check_call(['glslangValidator', shader])
def cross_compile(shader, vulkan, spirv, eliminate, invalid_spirv, is_legacy):
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo):
spirv_f, spirv_path = tempfile.mkstemp()
glsl_f, glsl_path = tempfile.mkstemp(suffix = os.path.basename(shader))
os.close(spirv_f)
@ -84,25 +84,23 @@ def cross_compile(shader, vulkan, spirv, eliminate, invalid_spirv, is_legacy):
if not invalid_spirv:
subprocess.check_call(['spirv-val', spirv_path])
legacy_cmd = []
extra_args = []
if eliminate:
extra_args += ['--remove-unused-variables']
if is_legacy:
legacy_cmd = ['--version', '100', '--es']
extra_args += ['--version', '100', '--es']
if flatten_ubo:
extra_args += ['--flatten-ubo']
spirv_cross_path = './spirv-cross'
if eliminate:
subprocess.check_call([spirv_cross_path, '--remove-unused-variables', '--entry', 'main', '--output', glsl_path, spirv_path] + legacy_cmd)
else:
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', glsl_path, spirv_path] + legacy_cmd)
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', glsl_path, spirv_path] + extra_args)
# A shader might not be possible to make valid GLSL from, skip validation for this case.
if (not ('nocompat' in glsl_path)) and (not spirv):
validate_shader(glsl_path, False)
if vulkan or spirv:
if eliminate:
subprocess.check_call([spirv_cross_path, '--remove-unused-variables', '--entry', 'main', '--vulkan-semantics', '--output', vulkan_glsl_path, spirv_path])
else:
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--vulkan-semantics', '--output', vulkan_glsl_path, spirv_path])
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--vulkan-semantics', '--output', vulkan_glsl_path, spirv_path] + extra_args)
validate_shader(vulkan_glsl_path, vulkan)
return (spirv_path, glsl_path, vulkan_glsl_path if vulkan else None)
@ -178,6 +176,9 @@ def shader_is_invalid_spirv(shader):
def shader_is_legacy(shader):
return '.legacy.' in shader
def shader_is_flatten_ubo(shader):
return '.flatten.' in shader
def test_shader(stats, shader, update, keep):
joined_path = os.path.join(shader[0], shader[1])
vulkan = shader_is_vulkan(shader[1])
@ -186,9 +187,10 @@ def test_shader(stats, shader, update, keep):
is_spirv = shader_is_spirv(shader[1])
invalid_spirv = shader_is_invalid_spirv(shader[1])
is_legacy = shader_is_legacy(shader[1])
flatten_ubo = shader_is_flatten_ubo(shader[1])
print('Testing shader:', joined_path)
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, eliminate, invalid_spirv, is_legacy)
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo)
# Only test GLSL stats if we have a shader following GL semantics.
if stats and (not vulkan) and (not is_spirv) and (not desktop):