GLSL: Implement sparse feedback.
This commit is contained in:
parent
d385bf096f
commit
275974e062
@ -0,0 +1,105 @@
|
||||
#version 450
|
||||
#extension GL_ARB_sparse_texture2 : require
|
||||
#extension GL_ARB_sparse_texture_clamp : require
|
||||
|
||||
struct ResType
|
||||
{
|
||||
int _m0;
|
||||
vec4 _m1;
|
||||
};
|
||||
|
||||
layout(binding = 0) uniform sampler2D uSamp;
|
||||
layout(binding = 1) uniform sampler2DMS uSampMS;
|
||||
layout(binding = 2, rgba8) uniform readonly image2D uImage;
|
||||
layout(binding = 3, rgba8) uniform readonly image2DMS uImageMS;
|
||||
|
||||
layout(location = 0) in vec2 vUV;
|
||||
|
||||
void main()
|
||||
{
|
||||
int _144;
|
||||
vec4 _145;
|
||||
_144 = sparseTextureARB(uSamp, vUV, _145);
|
||||
ResType _24 = ResType(_144, _145);
|
||||
vec4 texel = _24._m1;
|
||||
bool ret = sparseTexelsResidentARB(_24._m0);
|
||||
int _146;
|
||||
vec4 _147;
|
||||
_146 = sparseTextureARB(uSamp, vUV, _147, 1.10000002384185791015625);
|
||||
ResType _31 = ResType(_146, _147);
|
||||
texel = _31._m1;
|
||||
ret = sparseTexelsResidentARB(_31._m0);
|
||||
int _148;
|
||||
vec4 _149;
|
||||
_148 = sparseTextureLodARB(uSamp, vUV, 1.0, _149);
|
||||
ResType _38 = ResType(_148, _149);
|
||||
texel = _38._m1;
|
||||
ret = sparseTexelsResidentARB(_38._m0);
|
||||
int _150;
|
||||
vec4 _151;
|
||||
_150 = sparseTextureOffsetARB(uSamp, vUV, ivec2(1), _151);
|
||||
ResType _47 = ResType(_150, _151);
|
||||
texel = _47._m1;
|
||||
ret = sparseTexelsResidentARB(_47._m0);
|
||||
int _152;
|
||||
vec4 _153;
|
||||
_152 = sparseTextureOffsetARB(uSamp, vUV, ivec2(2), _153, 0.5);
|
||||
ResType _56 = ResType(_152, _153);
|
||||
texel = _56._m1;
|
||||
ret = sparseTexelsResidentARB(_56._m0);
|
||||
int _154;
|
||||
vec4 _155;
|
||||
_154 = sparseTexelFetchARB(uSamp, ivec2(vUV), 1, _155);
|
||||
ResType _64 = ResType(_154, _155);
|
||||
texel = _64._m1;
|
||||
ret = sparseTexelsResidentARB(_64._m0);
|
||||
int _156;
|
||||
vec4 _157;
|
||||
_156 = sparseTexelFetchARB(uSampMS, ivec2(vUV), 2, _157);
|
||||
ResType _76 = ResType(_156, _157);
|
||||
texel = _76._m1;
|
||||
ret = sparseTexelsResidentARB(_76._m0);
|
||||
int _158;
|
||||
vec4 _159;
|
||||
_158 = sparseTexelFetchOffsetARB(uSamp, ivec2(vUV), 1, ivec2(2, 3), _159);
|
||||
ResType _86 = ResType(_158, _159);
|
||||
texel = _86._m1;
|
||||
ret = sparseTexelsResidentARB(_86._m0);
|
||||
int _160;
|
||||
vec4 _161;
|
||||
_160 = sparseTextureLodOffsetARB(uSamp, vUV, 1.5, ivec2(2, 3), _161);
|
||||
ResType _93 = ResType(_160, _161);
|
||||
texel = _93._m1;
|
||||
ret = sparseTexelsResidentARB(_93._m0);
|
||||
int _162;
|
||||
vec4 _163;
|
||||
_162 = sparseTextureGradARB(uSamp, vUV, vec2(1.0), vec2(3.0), _163);
|
||||
ResType _102 = ResType(_162, _163);
|
||||
texel = _102._m1;
|
||||
ret = sparseTexelsResidentARB(_102._m0);
|
||||
int _164;
|
||||
vec4 _165;
|
||||
_164 = sparseTextureGradOffsetARB(uSamp, vUV, vec2(1.0), vec2(3.0), ivec2(-2, -3), _165);
|
||||
ResType _111 = ResType(_164, _165);
|
||||
texel = _111._m1;
|
||||
ret = sparseTexelsResidentARB(_111._m0);
|
||||
int _166;
|
||||
vec4 _167;
|
||||
_166 = sparseTextureClampARB(uSamp, vUV, 4.0, _167);
|
||||
ResType _118 = ResType(_166, _167);
|
||||
texel = _118._m1;
|
||||
ret = sparseTexelsResidentARB(_118._m0);
|
||||
int _168;
|
||||
vec4 _169;
|
||||
_168 = sparseImageLoadARB(uImage, ivec2(vUV), _169);
|
||||
ResType _128 = ResType(_168, _169);
|
||||
texel = _128._m1;
|
||||
ret = sparseTexelsResidentARB(_128._m0);
|
||||
int _170;
|
||||
vec4 _171;
|
||||
_170 = sparseImageLoadARB(uImageMS, ivec2(vUV), 1, _171);
|
||||
ResType _138 = ResType(_170, _171);
|
||||
texel = _138._m1;
|
||||
ret = sparseTexelsResidentARB(_138._m0);
|
||||
}
|
||||
|
31
shaders-no-opt/frag/sparse-texture-feedback.desktop.frag
Normal file
31
shaders-no-opt/frag/sparse-texture-feedback.desktop.frag
Normal file
@ -0,0 +1,31 @@
|
||||
#version 450
|
||||
#extension GL_ARB_sparse_texture2 : require
|
||||
#extension GL_ARB_sparse_texture_clamp : require
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D uSamp;
|
||||
layout(set = 0, binding = 1) uniform sampler2DMS uSampMS;
|
||||
layout(set = 0, binding = 2, rgba8) uniform image2D uImage;
|
||||
layout(set = 0, binding = 3, rgba8) uniform image2DMS uImageMS;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) in vec2 vUV;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texel;
|
||||
bool ret;
|
||||
|
||||
ret = sparseTexelsResidentARB(sparseTextureARB(uSamp, vUV, texel));
|
||||
ret = sparseTexelsResidentARB(sparseTextureARB(uSamp, vUV, texel, 1.1));
|
||||
ret = sparseTexelsResidentARB(sparseTextureLodARB(uSamp, vUV, 1.0, texel));
|
||||
ret = sparseTexelsResidentARB(sparseTextureOffsetARB(uSamp, vUV, ivec2(1, 1), texel));
|
||||
ret = sparseTexelsResidentARB(sparseTextureOffsetARB(uSamp, vUV, ivec2(2, 2), texel, 0.5));
|
||||
ret = sparseTexelsResidentARB(sparseTexelFetchARB(uSamp, ivec2(vUV), 1, texel));
|
||||
ret = sparseTexelsResidentARB(sparseTexelFetchARB(uSampMS, ivec2(vUV), 2, texel));
|
||||
ret = sparseTexelsResidentARB(sparseTexelFetchOffsetARB(uSamp, ivec2(vUV), 1, ivec2(2, 3), texel));
|
||||
ret = sparseTexelsResidentARB(sparseTextureLodOffsetARB(uSamp, vUV, 1.5, ivec2(2, 3), texel));
|
||||
ret = sparseTexelsResidentARB(sparseTextureGradARB(uSamp, vUV, vec2(1.0), vec2(3.0), texel));
|
||||
ret = sparseTexelsResidentARB(sparseTextureGradOffsetARB(uSamp, vUV, vec2(1.0), vec2(3.0), ivec2(-2, -3), texel));
|
||||
ret = sparseTexelsResidentARB(sparseTextureClampARB(uSamp, vUV, 4.0, texel));
|
||||
ret = sparseTexelsResidentARB(sparseImageLoadARB(uImage, ivec2(vUV), texel));
|
||||
ret = sparseTexelsResidentARB(sparseImageLoadARB(uImageMS, ivec2(vUV), 1, texel));
|
||||
}
|
184
spirv_glsl.cpp
184
spirv_glsl.cpp
@ -5363,7 +5363,29 @@ static inline bool image_opcode_is_sample_no_dref(Op op)
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
void CompilerGLSL::emit_sparse_feedback_temporaries(uint32_t result_type_id, uint32_t id,
|
||||
uint32_t &feedback_id, uint32_t &texel_id)
|
||||
{
|
||||
// Need to allocate two temporaries.
|
||||
if (options.es)
|
||||
SPIRV_CROSS_THROW("Sparse texture feedback is not supported on ESSL.");
|
||||
require_extension_internal("GL_ARB_sparse_texture2");
|
||||
|
||||
auto &temps = extra_sub_expressions[id];
|
||||
if (temps == 0)
|
||||
temps = ir.increase_bound_by(2);
|
||||
|
||||
feedback_id = temps + 0;
|
||||
texel_id = temps + 1;
|
||||
|
||||
auto &return_type = get<SPIRType>(result_type_id);
|
||||
if (return_type.basetype != SPIRType::Struct || return_type.member_types.size() != 2)
|
||||
SPIRV_CROSS_THROW("Invalid return type for sparse feedback.");
|
||||
emit_uninitialized_temporary(return_type.member_types[0], feedback_id);
|
||||
emit_uninitialized_temporary(return_type.member_types[1], texel_id);
|
||||
}
|
||||
|
||||
void CompilerGLSL::emit_texture_op(const Instruction &i, bool sparse)
|
||||
{
|
||||
auto *ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
@ -5372,13 +5394,29 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
|
||||
uint32_t result_type_id = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
auto &return_type = get<SPIRType>(result_type_id);
|
||||
|
||||
uint32_t sparse_code_id = 0;
|
||||
uint32_t sparse_texel_id = 0;
|
||||
if (sparse)
|
||||
emit_sparse_feedback_temporaries(result_type_id, id, sparse_code_id, sparse_texel_id);
|
||||
|
||||
bool forward = false;
|
||||
string expr = to_texture_op(i, &forward, inherited_expressions);
|
||||
string expr = to_texture_op(i, sparse, &forward, inherited_expressions);
|
||||
|
||||
if (sparse)
|
||||
{
|
||||
statement(to_expression(sparse_code_id), " = ", expr, ";");
|
||||
expr = join(type_to_glsl(return_type), "(", to_expression(sparse_code_id), ", ", to_expression(sparse_texel_id), ")");
|
||||
forward = true;
|
||||
inherited_expressions.clear();
|
||||
}
|
||||
|
||||
emit_op(result_type_id, id, expr, forward);
|
||||
for (auto &inherit : inherited_expressions)
|
||||
inherit_expression_dependencies(id, inherit);
|
||||
|
||||
// Do not register sparse ops as control dependent as they are always lowered to a temporary.
|
||||
switch (op)
|
||||
{
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
@ -5393,7 +5431,7 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
}
|
||||
}
|
||||
|
||||
std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool *forward,
|
||||
SmallVector<uint32_t> &inherited_expressions)
|
||||
{
|
||||
auto *ops = stream(i);
|
||||
@ -5422,6 +5460,8 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
{
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
case OpImageSampleDrefExplicitLod:
|
||||
case OpImageSparseSampleDrefImplicitLod:
|
||||
case OpImageSparseSampleDrefExplicitLod:
|
||||
dref = ops[4];
|
||||
opt = &ops[5];
|
||||
length -= 5;
|
||||
@ -5429,6 +5469,8 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
|
||||
case OpImageSampleProjDrefImplicitLod:
|
||||
case OpImageSampleProjDrefExplicitLod:
|
||||
case OpImageSparseSampleProjDrefImplicitLod:
|
||||
case OpImageSparseSampleProjDrefExplicitLod:
|
||||
dref = ops[4];
|
||||
opt = &ops[5];
|
||||
length -= 5;
|
||||
@ -5436,6 +5478,7 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
break;
|
||||
|
||||
case OpImageDrefGather:
|
||||
case OpImageSparseDrefGather:
|
||||
dref = ops[4];
|
||||
opt = &ops[5];
|
||||
length -= 5;
|
||||
@ -5443,6 +5486,7 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
break;
|
||||
|
||||
case OpImageGather:
|
||||
case OpImageSparseGather:
|
||||
comp = ops[4];
|
||||
opt = &ops[5];
|
||||
length -= 5;
|
||||
@ -5450,6 +5494,7 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
break;
|
||||
|
||||
case OpImageFetch:
|
||||
case OpImageSparseFetch:
|
||||
case OpImageRead: // Reads == fetches in Metal (other langs will not get here)
|
||||
opt = &ops[4];
|
||||
length -= 4;
|
||||
@ -5458,6 +5503,8 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
|
||||
case OpImageSampleProjImplicitLod:
|
||||
case OpImageSampleProjExplicitLod:
|
||||
case OpImageSparseSampleProjImplicitLod:
|
||||
case OpImageSparseSampleProjExplicitLod:
|
||||
opt = &ops[4];
|
||||
length -= 4;
|
||||
proj = true;
|
||||
@ -5542,10 +5589,14 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
|
||||
string expr;
|
||||
expr += to_function_name(img, imgtype, !!fetch, !!gather, !!proj, !!coffsets, (!!coffset || !!offset),
|
||||
(!!grad_x || !!grad_y), !!dref, lod, minlod);
|
||||
(!!grad_x || !!grad_y), !!dref, sparse, lod, minlod);
|
||||
expr += "(";
|
||||
|
||||
uint32_t sparse_texel_id = 0;
|
||||
if (sparse)
|
||||
sparse_texel_id = extra_sub_expressions[ops[1]] + 1;
|
||||
expr += to_function_args(img, imgtype, fetch, gather, proj, coord, coord_components, dref, grad_x, grad_y, lod,
|
||||
coffset, offset, bias, comp, sample, minlod, forward);
|
||||
coffset, offset, bias, comp, sample, sparse_texel_id, minlod, forward);
|
||||
expr += ")";
|
||||
|
||||
// texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here.
|
||||
@ -5576,7 +5627,7 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
expr = remap_swizzle(result_type, 1, expr);
|
||||
}
|
||||
|
||||
if (!backend.support_small_type_sampling_result && result_type.width < 32)
|
||||
if (!sparse && !backend.support_small_type_sampling_result && result_type.width < 32)
|
||||
{
|
||||
// Just value cast (narrowing) to expected type since we cannot rely on narrowing to work automatically.
|
||||
// Hopefully compiler picks this up and converts the texturing instruction to the appropriate precision.
|
||||
@ -5602,10 +5653,15 @@ bool CompilerGLSL::expression_is_constant_null(uint32_t id) const
|
||||
// For some subclasses, the function is a method on the specified image.
|
||||
string CompilerGLSL::to_function_name(VariableID tex, const SPIRType &imgtype, bool is_fetch, bool is_gather,
|
||||
bool is_proj, bool has_array_offsets, bool has_offset, bool has_grad, bool,
|
||||
uint32_t lod, uint32_t minlod)
|
||||
bool is_sparse_feedback, uint32_t lod, uint32_t minlod)
|
||||
{
|
||||
if (minlod != 0)
|
||||
SPIRV_CROSS_THROW("Sparse texturing not yet supported.");
|
||||
{
|
||||
if (options.es)
|
||||
SPIRV_CROSS_THROW("Sparse residency is not supported in ESSL.");
|
||||
require_extension_internal("GL_ARB_sparse_texture_clamp");
|
||||
return "sparseTextureClampARB";
|
||||
}
|
||||
|
||||
string fname;
|
||||
|
||||
@ -5625,11 +5681,14 @@ string CompilerGLSL::to_function_name(VariableID tex, const SPIRType &imgtype, b
|
||||
workaround_lod_array_shadow_as_grad = true;
|
||||
}
|
||||
|
||||
if (is_sparse_feedback)
|
||||
fname += "sparse";
|
||||
|
||||
if (is_fetch)
|
||||
fname += "texelFetch";
|
||||
fname += is_sparse_feedback ? "TexelFetch" : "texelFetch";
|
||||
else
|
||||
{
|
||||
fname += "texture";
|
||||
fname += is_sparse_feedback ? "Texture" : "texture";
|
||||
|
||||
if (is_gather)
|
||||
fname += "Gather";
|
||||
@ -5646,6 +5705,9 @@ string CompilerGLSL::to_function_name(VariableID tex, const SPIRType &imgtype, b
|
||||
if (has_offset)
|
||||
fname += "Offset";
|
||||
|
||||
if (is_sparse_feedback)
|
||||
fname += "ARB";
|
||||
|
||||
return is_legacy() ? legacy_tex_op(fname, imgtype, lod, tex) : fname;
|
||||
}
|
||||
|
||||
@ -5694,7 +5756,7 @@ std::string CompilerGLSL::convert_separate_image_to_expression(uint32_t id)
|
||||
string CompilerGLSL::to_function_args(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
|
||||
bool is_proj, uint32_t coord, uint32_t coord_components, uint32_t dref,
|
||||
uint32_t grad_x, uint32_t grad_y, uint32_t lod, uint32_t coffset, uint32_t offset,
|
||||
uint32_t bias, uint32_t comp, uint32_t sample, uint32_t /*minlod*/,
|
||||
uint32_t bias, uint32_t comp, uint32_t sample, uint32_t sparse_texel_id, uint32_t minlod,
|
||||
bool *p_forward)
|
||||
{
|
||||
string farg_str;
|
||||
@ -5869,6 +5931,25 @@ string CompilerGLSL::to_function_args(VariableID img, const SPIRType &imgtype, b
|
||||
farg_str += to_expression(offset);
|
||||
}
|
||||
|
||||
if (sample)
|
||||
{
|
||||
farg_str += ", ";
|
||||
farg_str += to_expression(sample);
|
||||
}
|
||||
|
||||
if (minlod)
|
||||
{
|
||||
farg_str += ", ";
|
||||
farg_str += to_expression(minlod);
|
||||
}
|
||||
|
||||
if (sparse_texel_id)
|
||||
{
|
||||
// Sparse texel output parameter comes after everything else, except it's before the optional, component/bias arguments.
|
||||
farg_str += ", ";
|
||||
farg_str += to_expression(sparse_texel_id);
|
||||
}
|
||||
|
||||
if (bias)
|
||||
{
|
||||
forward = forward && should_forward(bias);
|
||||
@ -5883,12 +5964,6 @@ string CompilerGLSL::to_function_args(VariableID img, const SPIRType &imgtype, b
|
||||
farg_str += to_expression(comp);
|
||||
}
|
||||
|
||||
if (sample)
|
||||
{
|
||||
farg_str += ", ";
|
||||
farg_str += to_expression(sample);
|
||||
}
|
||||
|
||||
*p_forward = forward;
|
||||
|
||||
return farg_str;
|
||||
@ -10081,7 +10156,29 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
case OpImageGather:
|
||||
case OpImageDrefGather:
|
||||
// Gets a bit hairy, so move this to a separate instruction.
|
||||
emit_texture_op(instruction);
|
||||
emit_texture_op(instruction, false);
|
||||
break;
|
||||
|
||||
case OpImageSparseSampleExplicitLod:
|
||||
case OpImageSparseSampleProjExplicitLod:
|
||||
case OpImageSparseSampleDrefExplicitLod:
|
||||
case OpImageSparseSampleProjDrefExplicitLod:
|
||||
case OpImageSparseSampleImplicitLod:
|
||||
case OpImageSparseSampleProjImplicitLod:
|
||||
case OpImageSparseSampleDrefImplicitLod:
|
||||
case OpImageSparseSampleProjDrefImplicitLod:
|
||||
case OpImageSparseFetch:
|
||||
case OpImageSparseGather:
|
||||
case OpImageSparseDrefGather:
|
||||
// Gets a bit hairy, so move this to a separate instruction.
|
||||
emit_texture_op(instruction, true);
|
||||
break;
|
||||
|
||||
case OpImageSparseTexelsResident:
|
||||
if (options.es)
|
||||
SPIRV_CROSS_THROW("Sparse feedback is not supported in GLSL.");
|
||||
require_extension_internal("GL_ARB_sparse_texture2");
|
||||
GLSL_UFOP(sparseTexelsResidentARB);
|
||||
break;
|
||||
|
||||
case OpImage:
|
||||
@ -10174,6 +10271,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
|
||||
// Image load/store
|
||||
case OpImageRead:
|
||||
case OpImageSparseRead:
|
||||
{
|
||||
// We added Nonreadable speculatively to the OpImage variable due to glslangValidator
|
||||
// not adding the proper qualifiers.
|
||||
@ -10267,6 +10365,12 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
}
|
||||
else
|
||||
{
|
||||
bool sparse = opcode == OpImageSparseRead;
|
||||
uint32_t sparse_code_id = 0;
|
||||
uint32_t sparse_texel_id = 0;
|
||||
if (sparse)
|
||||
emit_sparse_feedback_temporaries(ops[0], ops[1], sparse_code_id, sparse_texel_id);
|
||||
|
||||
// imageLoad only accepts int coords, not uint.
|
||||
auto coord_expr = to_expression(ops[3]);
|
||||
auto target_coord_type = expression_type(ops[3]);
|
||||
@ -10274,20 +10378,46 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[3]).basetype, coord_expr);
|
||||
|
||||
// Plain image load/store.
|
||||
if (type.image.ms)
|
||||
if (sparse)
|
||||
{
|
||||
uint32_t operands = ops[4];
|
||||
if (operands != ImageOperandsSampleMask || length != 6)
|
||||
SPIRV_CROSS_THROW("Multisampled image used in OpImageRead, but unexpected operand mask was used.");
|
||||
if (type.image.ms)
|
||||
{
|
||||
uint32_t operands = ops[4];
|
||||
if (operands != ImageOperandsSampleMask || length != 6)
|
||||
SPIRV_CROSS_THROW(
|
||||
"Multisampled image used in OpImageRead, but unexpected operand mask was used.");
|
||||
|
||||
uint32_t samples = ops[5];
|
||||
imgexpr =
|
||||
join("imageLoad(", to_expression(ops[2]), ", ", coord_expr, ", ", to_expression(samples), ")");
|
||||
uint32_t samples = ops[5];
|
||||
statement(to_expression(sparse_code_id), " = sparseImageLoadARB(", to_expression(ops[2]), ", ",
|
||||
coord_expr, ", ", to_expression(samples), ", ", to_expression(sparse_texel_id), ");");
|
||||
}
|
||||
else
|
||||
{
|
||||
statement(to_expression(sparse_code_id), " = sparseImageLoadARB(", to_expression(ops[2]), ", ",
|
||||
coord_expr, ", ", to_expression(sparse_texel_id), ");");
|
||||
}
|
||||
imgexpr = join(type_to_glsl(get<SPIRType>(result_type)), "(",
|
||||
to_expression(sparse_code_id), ", ", to_expression(sparse_texel_id), ")");
|
||||
}
|
||||
else
|
||||
imgexpr = join("imageLoad(", to_expression(ops[2]), ", ", coord_expr, ")");
|
||||
{
|
||||
if (type.image.ms)
|
||||
{
|
||||
uint32_t operands = ops[4];
|
||||
if (operands != ImageOperandsSampleMask || length != 6)
|
||||
SPIRV_CROSS_THROW(
|
||||
"Multisampled image used in OpImageRead, but unexpected operand mask was used.");
|
||||
|
||||
imgexpr = remap_swizzle(get<SPIRType>(result_type), 4, imgexpr);
|
||||
uint32_t samples = ops[5];
|
||||
imgexpr =
|
||||
join("imageLoad(", to_expression(ops[2]), ", ", coord_expr, ", ", to_expression(samples), ")");
|
||||
}
|
||||
else
|
||||
imgexpr = join("imageLoad(", to_expression(ops[2]), ", ", coord_expr, ")");
|
||||
}
|
||||
|
||||
if (!sparse)
|
||||
imgexpr = remap_swizzle(get<SPIRType>(result_type), 4, imgexpr);
|
||||
pure = false;
|
||||
}
|
||||
|
||||
|
@ -268,8 +268,8 @@ protected:
|
||||
const SpecializationConstant &y, const SpecializationConstant &z);
|
||||
|
||||
virtual void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id);
|
||||
virtual void emit_texture_op(const Instruction &i);
|
||||
virtual std::string to_texture_op(const Instruction &i, bool *forward,
|
||||
virtual void emit_texture_op(const Instruction &i, bool sparse);
|
||||
virtual std::string to_texture_op(const Instruction &i, bool sparse, bool *forward,
|
||||
SmallVector<uint32_t> &inherited_expressions);
|
||||
virtual void emit_subgroup_op(const Instruction &i);
|
||||
virtual std::string type_to_glsl(const SPIRType &type, uint32_t id = 0);
|
||||
@ -286,12 +286,13 @@ protected:
|
||||
virtual std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id);
|
||||
virtual std::string to_function_name(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
|
||||
bool is_proj, bool has_array_offsets, bool has_offset, bool has_grad,
|
||||
bool has_dref, uint32_t lod, uint32_t minlod);
|
||||
bool has_dref, bool is_sparse_feedback, uint32_t lod, uint32_t minlod);
|
||||
virtual std::string to_function_args(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
|
||||
bool is_proj, uint32_t coord, uint32_t coord_components, uint32_t dref,
|
||||
uint32_t grad_x, uint32_t grad_y, uint32_t lod, uint32_t coffset,
|
||||
uint32_t offset, uint32_t bias, uint32_t comp, uint32_t sample,
|
||||
uint32_t minlod, bool *p_forward);
|
||||
uint32_t sparse_texel, uint32_t minlod, bool *p_forward);
|
||||
void emit_sparse_feedback_temporaries(uint32_t result_type_id, uint32_t id, uint32_t &feedback_id, uint32_t &texel_id);
|
||||
virtual void emit_buffer_block(const SPIRVariable &type);
|
||||
virtual void emit_push_constant_block(const SPIRVariable &var);
|
||||
virtual void emit_uniform(const SPIRVariable &var);
|
||||
|
@ -2607,8 +2607,11 @@ void CompilerHLSL::emit_fixup()
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_texture_op(const Instruction &i)
|
||||
void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)
|
||||
{
|
||||
if (sparse)
|
||||
SPIRV_CROSS_THROW("Sparse feedback not yet supported in HLSL.");
|
||||
|
||||
auto *ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
@ -4886,7 +4889,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
}
|
||||
|
||||
case OpImageQueryLod:
|
||||
emit_texture_op(instruction);
|
||||
emit_texture_op(instruction, false);
|
||||
break;
|
||||
|
||||
case OpImageQuerySizeLod:
|
||||
|
@ -204,7 +204,7 @@ private:
|
||||
void emit_interface_block_in_struct(const SPIRVariable &type, std::unordered_set<uint32_t> &active_locations);
|
||||
void emit_builtin_inputs_in_struct();
|
||||
void emit_builtin_outputs_in_struct();
|
||||
void emit_texture_op(const Instruction &i) override;
|
||||
void emit_texture_op(const Instruction &i, bool sparse) override;
|
||||
void emit_instruction(const Instruction &instruction) override;
|
||||
void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
uint32_t count) override;
|
||||
|
@ -6215,7 +6215,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
}
|
||||
}
|
||||
|
||||
emit_texture_op(instruction);
|
||||
emit_texture_op(instruction, false);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -6303,7 +6303,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
|
||||
statement(join(to_expression(img_id), ".write(",
|
||||
remap_swizzle(store_type, texel_type.vecsize, to_expression(texel_id)), ", ",
|
||||
to_function_args(img_id, img_type, true, false, false, coord_id, 0, 0, 0, 0, lod, 0, 0, 0, 0, 0,
|
||||
to_function_args(img_id, img_type, true, false, false, coord_id, 0, 0, 0, 0, lod, 0, 0, 0, 0, 0, 0,
|
||||
0, &forward),
|
||||
");"));
|
||||
|
||||
@ -6746,8 +6746,11 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
previous_instruction_opcode = opcode;
|
||||
}
|
||||
|
||||
void CompilerMSL::emit_texture_op(const Instruction &i)
|
||||
void CompilerMSL::emit_texture_op(const Instruction &i, bool sparse)
|
||||
{
|
||||
if (sparse)
|
||||
SPIRV_CROSS_THROW("Sparse feedback not yet supported in MSL.");
|
||||
|
||||
if (msl_options.is_ios() && msl_options.ios_use_framebuffer_fetch_subpasses)
|
||||
{
|
||||
auto *ops = stream(i);
|
||||
@ -6771,7 +6774,7 @@ void CompilerMSL::emit_texture_op(const Instruction &i)
|
||||
}
|
||||
|
||||
// Fallback to default implementation
|
||||
CompilerGLSL::emit_texture_op(i);
|
||||
CompilerGLSL::emit_texture_op(i, sparse);
|
||||
}
|
||||
|
||||
void CompilerMSL::emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uint32_t id_mem_sem)
|
||||
@ -7486,7 +7489,7 @@ static bool needs_chroma_reconstruction(const MSLConstexprSampler *constexpr_sam
|
||||
|
||||
// Returns the texture sampling function string for the specified image and sampling characteristics.
|
||||
string CompilerMSL::to_function_name(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool, bool,
|
||||
bool, bool, bool has_dref, uint32_t, uint32_t)
|
||||
bool, bool, bool has_dref, bool, uint32_t, uint32_t)
|
||||
{
|
||||
const MSLConstexprSampler *constexpr_sampler = nullptr;
|
||||
bool is_dynamic_img_sampler = false;
|
||||
@ -7651,7 +7654,7 @@ static inline bool sampling_type_needs_f32_conversion(const SPIRType &type)
|
||||
string CompilerMSL::to_function_args(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
|
||||
bool is_proj, uint32_t coord, uint32_t, uint32_t dref, uint32_t grad_x,
|
||||
uint32_t grad_y, uint32_t lod, uint32_t coffset, uint32_t offset, uint32_t bias,
|
||||
uint32_t comp, uint32_t sample, uint32_t minlod, bool *p_forward)
|
||||
uint32_t comp, uint32_t sample, uint32_t /*sparse_texel_id*/, uint32_t minlod, bool *p_forward)
|
||||
{
|
||||
const MSLConstexprSampler *constexpr_sampler = nullptr;
|
||||
bool is_dynamic_img_sampler = false;
|
||||
@ -8128,7 +8131,7 @@ void CompilerMSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_id
|
||||
set<SPIRCombinedImageSampler>(result_id, result_type, image_id, samp_id);
|
||||
}
|
||||
|
||||
string CompilerMSL::to_texture_op(const Instruction &i, bool *forward, SmallVector<uint32_t> &inherited_expressions)
|
||||
string CompilerMSL::to_texture_op(const Instruction &i, bool sparse, bool *forward, SmallVector<uint32_t> &inherited_expressions)
|
||||
{
|
||||
auto *ops = stream(i);
|
||||
uint32_t result_type_id = ops[0];
|
||||
@ -8196,7 +8199,7 @@ string CompilerMSL::to_texture_op(const Instruction &i, bool *forward, SmallVect
|
||||
expr += "spvTextureSwizzle(";
|
||||
}
|
||||
|
||||
string inner_expr = CompilerGLSL::to_texture_op(i, forward, inherited_expressions);
|
||||
string inner_expr = CompilerGLSL::to_texture_op(i, sparse, forward, inherited_expressions);
|
||||
|
||||
if (constexpr_sampler && constexpr_sampler->ycbcr_conversion_enable && !is_dynamic_img_sampler)
|
||||
{
|
||||
|
@ -583,7 +583,7 @@ protected:
|
||||
|
||||
// If the underlying resource has been used for comparison then duplicate loads of that resource must be too
|
||||
// Use Metal's native frame-buffer fetch API for subpass inputs.
|
||||
void emit_texture_op(const Instruction &i) override;
|
||||
void emit_texture_op(const Instruction &i, bool sparse) override;
|
||||
void emit_binary_unord_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op);
|
||||
void emit_instruction(const Instruction &instr) override;
|
||||
void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
@ -594,7 +594,7 @@ protected:
|
||||
void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override;
|
||||
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
||||
void emit_subgroup_op(const Instruction &i) override;
|
||||
std::string to_texture_op(const Instruction &i, bool *forward,
|
||||
std::string to_texture_op(const Instruction &i, bool sparse, bool *forward,
|
||||
SmallVector<uint32_t> &inherited_expressions) override;
|
||||
void emit_fixup() override;
|
||||
std::string to_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||
@ -619,12 +619,12 @@ protected:
|
||||
std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override;
|
||||
std::string to_name(uint32_t id, bool allow_alias = true) const override;
|
||||
std::string to_function_name(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
|
||||
bool has_array_offsets, bool has_offset, bool has_grad, bool has_dref, uint32_t lod,
|
||||
uint32_t minlod) override;
|
||||
bool has_array_offsets, bool has_offset, bool has_grad, bool has_dref, bool is_sparse_feedback,
|
||||
uint32_t lod, uint32_t minlod) override;
|
||||
std::string to_function_args(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
|
||||
uint32_t coord, uint32_t coord_components, uint32_t dref, uint32_t grad_x,
|
||||
uint32_t grad_y, uint32_t lod, uint32_t coffset, uint32_t offset, uint32_t bias,
|
||||
uint32_t comp, uint32_t sample, uint32_t minlod, bool *p_forward) override;
|
||||
uint32_t comp, uint32_t sample, uint32_t sparse_texel_id, uint32_t minlod, bool *p_forward) override;
|
||||
std::string to_initializer_expression(const SPIRVariable &var) override;
|
||||
std::string to_zero_initialized_expression(uint32_t type_id) override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user