HLSL: add subpass input types and methods

Add support for Subpass Input proposal of issue #1069.

Subpass input types are given as:

    layout(input_attachment_index = 1) SubpassInput<float4> subpass_f;
    layout(input_attachment_index = 2) SubpassInput<int4>   subpass_i;
    layout(input_attachment_index = 3) SubpassInput<uint4>  subpass_u;

    layout(input_attachment_index = 1) SubpassInputMS<float4> subpass_ms_f;
    layout(input_attachment_index = 2) SubpassInputMS<int4>   subpass_ms_i;
    layout(input_attachment_index = 3) SubpassInputMS<uint4>  subpass_ms_u;

The input attachment may also be specified using attribute syntax:

    [[vk::input_attachment_index(7)]] SubpassInput subpass_2;

The template type may be a shorter-than-vec4 vector, but currently user
structs are not supported.  (An unimplemented error will be issued).

The load operations are methods on objects of the above type:

    float4 result = subpass_f.SubpassLoad();
    int4   result = subpass_i.SubpassLoad();
    uint4  result = subpass_u.SubpassLoad();

    float4 result = subpass_ms_f.SubpassLoad(samp);
    int4   result = subpass_ms_i.SubpassLoad(samp);
    uint4  result = subpass_ms_u.SubpassLoad(samp);

Additionally, the AST printer could not print EOpSubpass* nodes.  Now it can.

Fixes #1069
This commit is contained in:
LoopDawg
2017-09-27 09:04:43 -06:00
parent 092b7d2e20
commit 7f93d56ef2
14 changed files with 1136 additions and 16 deletions

View File

@@ -1088,6 +1088,69 @@ bool HlslGrammar::acceptAnnotations(TQualifier&)
return true;
}
// subpass input type
// : SUBPASSINPUT
// | SUBPASSINPUT VECTOR LEFT_ANGLE template_type RIGHT_ANGLE
// | SUBPASSINPUTMS
// | SUBPASSINPUTMS VECTOR LEFT_ANGLE template_type RIGHT_ANGLE
bool HlslGrammar::acceptSubpassInputType(TType& type)
{
// read subpass type
const EHlslTokenClass subpassInputType = peek();
bool multisample;
switch (subpassInputType) {
case EHTokSubpassInput: multisample = false; break;
case EHTokSubpassInputMS: multisample = true; break;
default:
return false; // not a subpass input declaration
}
advanceToken(); // consume the sampler type keyword
TType subpassType(EbtFloat, EvqUniform, 4); // default type is float4
if (acceptTokenClass(EHTokLeftAngle)) {
if (! acceptType(subpassType)) {
expected("scalar or vector type");
return false;
}
const TBasicType basicRetType = subpassType.getBasicType() ;
switch (basicRetType) {
case EbtFloat:
case EbtUint:
case EbtInt:
case EbtStruct:
break;
default:
unimplemented("basic type in subpass input");
return false;
}
if (! acceptTokenClass(EHTokRightAngle)) {
expected("right angle bracket");
return false;
}
}
const TBasicType subpassBasicType = subpassType.isStruct() ? (*subpassType.getStruct())[0].type->getBasicType()
: subpassType.getBasicType();
TSampler sampler;
sampler.setSubpass(subpassBasicType, multisample);
// Remember the declared return type. Function returns false on error.
if (!parseContext.setTextureReturnType(sampler, subpassType, token.loc))
return false;
type.shallowCopy(TType(sampler, EvqUniform));
return true;
}
// sampler_type
// : SAMPLER
// | SAMPLER1D
@@ -1357,6 +1420,11 @@ bool HlslGrammar::acceptType(TType& type, TIntermNode*& nodeList)
return acceptSamplerType(type);
break;
case EHTokSubpassInput: // fall through
case EHTokSubpassInputMS: // ...
return acceptSubpassInputType(type);
break;
case EHTokBuffer: // fall through
case EHTokTexture1d: // ...
case EHTokTexture1darray: // ...