GLSL: Implement 1D texture emulation for ES.
ES does not support 1D images at all. Fake it by promoting 1D images to 2D.
This commit is contained in:
parent
3f855646f0
commit
1c88730e12
30
reference/shaders-no-opt/frag/texture1d-emulation.es.frag
Normal file
30
reference/shaders-no-opt/frag/texture1d-emulation.es.frag
Normal file
@ -0,0 +1,30 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
layout(binding = 0) uniform highp sampler2D uSamp;
|
||||
layout(binding = 1) uniform highp sampler2DShadow uSampShadow;
|
||||
layout(binding = 2) uniform highp sampler2DArray uSampArray;
|
||||
layout(binding = 3) uniform highp sampler2DArrayShadow uSampArrayShadow;
|
||||
layout(binding = 4, r32f) uniform highp image2D uImage;
|
||||
|
||||
layout(location = 0) out highp vec4 FragColor;
|
||||
layout(location = 0) in highp vec4 vUV;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(uSamp, vec2(vUV.x, 0.0));
|
||||
FragColor += textureProj(uSamp, vec3(vUV.xy.x, 0.0, vUV.xy.y));
|
||||
FragColor += texelFetch(uSamp, ivec2(int(vUV.x), 0), 0);
|
||||
FragColor += vec4(texture(uSampShadow, vec3(vUV.xyz.x, 0.0, vUV.xyz.z)));
|
||||
highp vec4 _54 = vUV;
|
||||
highp vec4 _57 = _54;
|
||||
_57.y = _54.w;
|
||||
FragColor += vec4(textureProj(uSampShadow, vec4(_57.x, 0.0, _54.z, _57.y)));
|
||||
FragColor = texture(uSampArray, vec3(vUV.xy.x, 0.0, vUV.xy.y));
|
||||
FragColor += texelFetch(uSampArray, ivec3(ivec2(vUV.xy).x, 0, ivec2(vUV.xy).y), 0);
|
||||
FragColor += vec4(texture(uSampArrayShadow, vec4(vUV.xyz.xy.x, 0.0, vUV.xyz.xy.y, vUV.xyz.z)));
|
||||
FragColor += imageLoad(uImage, ivec2(int(vUV.x), 0));
|
||||
imageStore(uImage, ivec2(int(vUV.x), 0), FragColor);
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
#version 100
|
||||
#extension GL_EXT_shadow_samplers : require
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
uniform highp sampler2D uSamp;
|
||||
uniform highp sampler2DShadow uSampShadow;
|
||||
|
||||
varying highp vec4 vUV;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragData[0] = texture2D(uSamp, vec2(vUV.x, 0.0));
|
||||
gl_FragData[0] += texture2DProj(uSamp, vec3(vUV.xy.x, 0.0, vUV.xy.y));
|
||||
gl_FragData[0] += vec4(shadow2DEXT(uSampShadow, vec3(vUV.xyz.x, 0.0, vUV.xyz.z)));
|
||||
highp vec4 _44 = vUV;
|
||||
highp vec4 _47 = _44;
|
||||
_47.y = _44.w;
|
||||
gl_FragData[0] += vec4(shadow2DProjEXT(uSampShadow, vec4(_47.x, 0.0, _44.z, _47.y)));
|
||||
}
|
||||
|
32
shaders-no-opt/frag/texture1d-emulation.es.frag
Normal file
32
shaders-no-opt/frag/texture1d-emulation.es.frag
Normal file
@ -0,0 +1,32 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler1D uSamp;
|
||||
layout(set = 0, binding = 1) uniform sampler1DShadow uSampShadow;
|
||||
layout(set = 0, binding = 2) uniform sampler1DArray uSampArray;
|
||||
layout(set = 0, binding = 3) uniform sampler1DArrayShadow uSampArrayShadow;
|
||||
layout(set = 0, binding = 4, r32f) uniform image1D uImage;
|
||||
layout(location = 0) in vec4 vUV;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// 1D
|
||||
FragColor = texture(uSamp, vUV.x);
|
||||
FragColor += textureProj(uSamp, vUV.xy);
|
||||
FragColor += texelFetch(uSamp, int(vUV.x), 0);
|
||||
|
||||
// 1D Shadow
|
||||
FragColor += texture(uSampShadow, vUV.xyz);
|
||||
FragColor += textureProj(uSampShadow, vUV);
|
||||
|
||||
// 1D Array
|
||||
FragColor = texture(uSampArray, vUV.xy);
|
||||
FragColor += texelFetch(uSampArray, ivec2(vUV.xy), 0);
|
||||
|
||||
// 1D Array Shadow
|
||||
FragColor += texture(uSampArrayShadow, vUV.xyz);
|
||||
|
||||
// 1D images
|
||||
FragColor += imageLoad(uImage, int(vUV.x));
|
||||
imageStore(uImage, int(vUV.x), FragColor);
|
||||
}
|
17
shaders-no-opt/frag/texture1d-emulation.legacy.frag
Normal file
17
shaders-no-opt/frag/texture1d-emulation.legacy.frag
Normal file
@ -0,0 +1,17 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler1D uSamp;
|
||||
layout(set = 0, binding = 1) uniform sampler1DShadow uSampShadow;
|
||||
layout(location = 0) in vec4 vUV;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// 1D
|
||||
FragColor = texture(uSamp, vUV.x);
|
||||
FragColor += textureProj(uSamp, vUV.xy);
|
||||
|
||||
// 1D Shadow
|
||||
FragColor += texture(uSampShadow, vUV.xyz);
|
||||
FragColor += textureProj(uSampShadow, vUV);
|
||||
}
|
@ -6340,7 +6340,11 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp
|
||||
switch (imgtype.image.dim)
|
||||
{
|
||||
case spv::Dim1D:
|
||||
type = (imgtype.image.arrayed && !options.es) ? "1DArray" : "1D";
|
||||
// Force 2D path for ES.
|
||||
if (options.es)
|
||||
type = (imgtype.image.arrayed && !options.es) ? "2DArray" : "2D";
|
||||
else
|
||||
type = (imgtype.image.arrayed && !options.es) ? "1DArray" : "1D";
|
||||
break;
|
||||
case spv::Dim2D:
|
||||
type = (imgtype.image.arrayed && !options.es) ? "2DArray" : "2D";
|
||||
@ -7018,8 +7022,8 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool
|
||||
expr += to_function_args(args, forward);
|
||||
expr += ")";
|
||||
|
||||
// texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here.
|
||||
if (is_legacy() && is_depth_image(imgtype, img))
|
||||
// texture(samplerXShadow) returns float. shadowX() returns vec4, but only in desktop GLSL. Swizzle here.
|
||||
if (is_legacy() && !options.es && is_depth_image(imgtype, img))
|
||||
expr += ".r";
|
||||
|
||||
// Sampling from a texture which was deduced to be a depth image, might actually return 1 component here.
|
||||
@ -7300,10 +7304,29 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
// Create a composite which merges coord/dref into a single vector.
|
||||
auto type = expression_type(args.coord);
|
||||
type.vecsize = args.coord_components + 1;
|
||||
if (imgtype.image.dim == Dim1D && options.es)
|
||||
type.vecsize++;
|
||||
farg_str += ", ";
|
||||
farg_str += type_to_glsl_constructor(type);
|
||||
farg_str += "(";
|
||||
farg_str += coord_expr;
|
||||
|
||||
if (imgtype.image.dim == Dim1D && options.es)
|
||||
{
|
||||
if (imgtype.image.arrayed)
|
||||
{
|
||||
farg_str += enclose_expression(coord_expr) + ".x";
|
||||
farg_str += ", 0.0, ";
|
||||
farg_str += enclose_expression(coord_expr) + ".y";
|
||||
}
|
||||
else
|
||||
{
|
||||
farg_str += coord_expr;
|
||||
farg_str += ", 0.0";
|
||||
}
|
||||
}
|
||||
else
|
||||
farg_str += coord_expr;
|
||||
|
||||
farg_str += ", ";
|
||||
farg_str += to_expression(args.dref);
|
||||
farg_str += ")";
|
||||
@ -7311,6 +7334,33 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
}
|
||||
else
|
||||
{
|
||||
if (imgtype.image.dim == Dim1D && options.es)
|
||||
{
|
||||
// Have to fake a second coordinate.
|
||||
if (type_is_floating_point(coord_type))
|
||||
{
|
||||
// Cannot mix proj and array.
|
||||
if (imgtype.image.arrayed || args.base.is_proj)
|
||||
{
|
||||
coord_expr = join("vec3(", enclose_expression(coord_expr), ".x, 0.0, ",
|
||||
enclose_expression(coord_expr), ".y)");
|
||||
}
|
||||
else
|
||||
coord_expr = join("vec2(", coord_expr, ", 0.0)");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (imgtype.image.arrayed)
|
||||
{
|
||||
coord_expr = join("ivec3(", enclose_expression(coord_expr),
|
||||
".x, 0, ",
|
||||
enclose_expression(coord_expr), ".y)");
|
||||
}
|
||||
else
|
||||
coord_expr = join("ivec2(", coord_expr, ", 0)");
|
||||
}
|
||||
}
|
||||
|
||||
farg_str += ", ";
|
||||
farg_str += coord_expr;
|
||||
}
|
||||
@ -12484,6 +12534,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
target_coord_type.basetype = SPIRType::Int;
|
||||
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[3]).basetype, coord_expr);
|
||||
|
||||
// ES needs to emulate 1D images as 2D.
|
||||
if (type.image.dim == Dim1D && options.es)
|
||||
coord_expr = join("ivec2(", coord_expr, ", 0)");
|
||||
|
||||
// Plain image load/store.
|
||||
if (sparse)
|
||||
{
|
||||
@ -12596,6 +12650,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
target_coord_type.basetype = SPIRType::Int;
|
||||
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[1]).basetype, coord_expr);
|
||||
|
||||
// ES needs to emulate 1D images as 2D.
|
||||
if (type.image.dim == Dim1D && options.es)
|
||||
coord_expr = join("ivec2(", coord_expr, ", 0)");
|
||||
|
||||
if (type.image.ms)
|
||||
{
|
||||
uint32_t operands = ops[3];
|
||||
@ -13956,7 +14014,8 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
switch (type.image.dim)
|
||||
{
|
||||
case Dim1D:
|
||||
res += "1D";
|
||||
// ES doesn't support 1D. Fake it with 2D.
|
||||
res += options.es ? "2D" : "1D";
|
||||
break;
|
||||
case Dim2D:
|
||||
res += "2D";
|
||||
|
@ -537,7 +537,7 @@ def validate_shader(shader, vulkan, paths):
|
||||
else:
|
||||
subprocess.check_call([paths.glslang, shader])
|
||||
|
||||
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt, push_ubo, iterations, paths):
|
||||
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, force_es, flatten_ubo, sso, flatten_dim, opt, push_ubo, iterations, paths):
|
||||
spirv_path = create_temporary()
|
||||
glsl_path = create_temporary(os.path.basename(shader))
|
||||
|
||||
@ -576,6 +576,8 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl
|
||||
extra_args += ['--remove-unused-variables']
|
||||
if is_legacy:
|
||||
extra_args += ['--version', '100', '--es']
|
||||
if force_es:
|
||||
extra_args += ['--version', '310', '--es']
|
||||
if flatten_ubo:
|
||||
extra_args += ['--flatten-ubo']
|
||||
if sso:
|
||||
@ -768,6 +770,9 @@ def shader_is_invalid_spirv(shader):
|
||||
def shader_is_legacy(shader):
|
||||
return '.legacy.' in shader
|
||||
|
||||
def shader_is_force_es(shader):
|
||||
return '.es.' in shader
|
||||
|
||||
def shader_is_flatten_ubo(shader):
|
||||
return '.flatten.' in shader
|
||||
|
||||
@ -791,6 +796,7 @@ def test_shader(stats, shader, args, paths):
|
||||
is_spirv = shader_is_spirv(shader[1])
|
||||
invalid_spirv = shader_is_invalid_spirv(shader[1])
|
||||
is_legacy = shader_is_legacy(shader[1])
|
||||
force_es = shader_is_force_es(shader[1])
|
||||
flatten_ubo = shader_is_flatten_ubo(shader[1])
|
||||
sso = shader_is_sso(shader[1])
|
||||
flatten_dim = shader_is_flatten_dimensions(shader[1])
|
||||
@ -798,7 +804,7 @@ def test_shader(stats, shader, args, paths):
|
||||
push_ubo = shader_is_push_ubo(shader[1])
|
||||
|
||||
print('Testing shader:', joined_path)
|
||||
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, args.opt and (not noopt), push_ubo, args.iterations, paths)
|
||||
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, force_es, flatten_ubo, sso, flatten_dim, args.opt and (not noopt), push_ubo, args.iterations, paths)
|
||||
|
||||
# Only test GLSL stats if we have a shader following GL semantics.
|
||||
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
||||
|
Loading…
Reference in New Issue
Block a user