Commit 5c3eed54 by John Kessenich

SPV: Create more access chains addressing a few swizzling issues.

- Fixes #1233 - Treats local bools like anything else - more consistently deals with a dynamic component selection
parent 2651ccae
......@@ -1388,16 +1388,13 @@ Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const std::vect
return createCompositeInsert(source, target, typeId, channels.front());
Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);
assert(isVector(target));
swizzle->addIdOperand(target);
if (accessChain.component != NoResult)
// For dynamic component selection, source does not involve in l-value swizzle
swizzle->addIdOperand(target);
else {
assert(getNumComponents(source) == (int)channels.size());
assert(isVector(source));
swizzle->addIdOperand(source);
}
assert(getNumComponents(source) == (int)channels.size());
assert(isVector(source));
swizzle->addIdOperand(source);
// Set up an identity shuffle from the base value to the result value
unsigned int components[4];
......@@ -1406,12 +1403,8 @@ Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const std::vect
components[i] = i;
// Punch in the l-value swizzle
for (int i = 0; i < (int)channels.size(); ++i) {
if (accessChain.component != NoResult)
components[i] = channels[i]; // Only shuffle the base value
else
components[channels[i]] = numTargetComponents + i;
}
for (int i = 0; i < (int)channels.size(); ++i)
components[channels[i]] = numTargetComponents + i;
// finish the instruction with these components selectors
for (int i = 0; i < numTargetComponents; ++i)
......@@ -2203,7 +2196,7 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
accessChain.preSwizzleBaseType = preSwizzleBaseType;
// if needed, propagate the swizzle for the current access chain
if (accessChain.swizzle.size()) {
if (accessChain.swizzle.size() > 0) {
std::vector<unsigned> oldSwizzle = accessChain.swizzle;
accessChain.swizzle.resize(0);
for (unsigned int i = 0; i < swizzle.size(); ++i) {
......@@ -2224,24 +2217,18 @@ void Builder::accessChainStore(Id rvalue)
transferAccessChainSwizzle(true);
Id base = collapseAccessChain();
Id source = rvalue;
// dynamic component should be gone
assert(accessChain.component == NoResult);
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
// extract and insert elements to perform writeMask and/or swizzle.
Id source = NoResult;
if (accessChain.swizzle.size()) {
if (accessChain.swizzle.size() > 0) {
Id tempBaseId = createLoad(base);
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, rvalue, accessChain.swizzle);
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
}
// dynamic component selection
if (accessChain.component != NoResult) {
Id tempBaseId = (source == NoResult) ? createLoad(base) : source;
source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue, accessChain.component);
}
if (source == NoResult)
source = rvalue;
createStore(source, base);
}
......@@ -2251,7 +2238,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
Id id;
if (accessChain.isRValue) {
// transfer access chain, but keep it static, so we can stay in registers
// transfer access chain, but try to stay in registers
transferAccessChainSwizzle(false);
if (accessChain.indexChain.size() > 0) {
Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType;
......@@ -2299,16 +2286,16 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
return id;
// Do remaining swizzling
// First, static swizzling
if (accessChain.swizzle.size()) {
// static swizzle
// Do the basic swizzle
if (accessChain.swizzle.size() > 0) {
Id swizzledType = getScalarTypeId(getTypeId(id));
if (accessChain.swizzle.size() > 1)
swizzledType = makeVectorType(swizzledType, (int)accessChain.swizzle.size());
id = createRvalueSwizzle(precision, swizzledType, id, accessChain.swizzle);
}
// dynamic single-component selection
// Do the dynamic component
if (accessChain.component != NoResult)
id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
......@@ -2458,26 +2445,66 @@ void Builder::dump(std::vector<unsigned int>& out) const
// Protected methods.
//
// Turn the described access chain in 'accessChain' into an instruction
// Turn the described access chain in 'accessChain' into an instruction(s)
// computing its address. This *cannot* include complex swizzles, which must
// be handled after this is called, but it does include swizzles that select
// an individual element, as a single address of a scalar type can be
// computed by an OpAccessChain instruction.
// be handled after this is called.
//
// Can generate code.
Id Builder::collapseAccessChain()
{
assert(accessChain.isRValue == false);
if (accessChain.indexChain.size() > 0) {
if (accessChain.instr == 0) {
StorageClass storageClass = (StorageClass)module.getStorageClass(getTypeId(accessChain.base));
accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
}
// did we already emit an access chain for this?
if (accessChain.instr != NoResult)
return accessChain.instr;
} else
// If we have a dynamic component, we can still transfer
// that into a final operand to the access chain. We need to remap the
// dynamic component through the swizzle to get a new dynamic component to
// update.
//
// This was not done in transferAccessChainSwizzle() because it might
// generate code.
remapDynamicSwizzle();
if (accessChain.component != NoResult) {
// transfer the dynamic component to the access chain
accessChain.indexChain.push_back(accessChain.component);
accessChain.component = NoResult;
}
// note that non-trivial swizzling is left pending
// do we have an access chain?
if (accessChain.indexChain.size() == 0)
return accessChain.base;
// note that non-trivial swizzling is left pending...
// emit the access chain
StorageClass storageClass = (StorageClass)module.getStorageClass(getTypeId(accessChain.base));
accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
return accessChain.instr;
}
// For a dynamic component selection of a swizzle.
//
// Turn the swizzle and dynamic component into just a dynamic component.
//
// Generates code.
void Builder::remapDynamicSwizzle()
{
// do we have a swizzle to remap a dynamic component through?
if (accessChain.component != NoResult && accessChain.swizzle.size() > 1) {
// build a vector of the swizzle for the component to map into
std::vector<Id> components;
for (int c = 0; c < accessChain.swizzle.size(); ++c)
components.push_back(makeUintConstant(accessChain.swizzle[c]));
Id mapType = makeVectorType(makeUintType(32), (int)accessChain.swizzle.size());
Id map = makeCompositeConstant(mapType, components);
// use it
accessChain.component = createVectorExtractDynamic(map, makeUintType(32), accessChain.component);
accessChain.swizzle.clear();
}
}
// clear out swizzle if it is redundant, that is reselecting the same components
......@@ -2503,38 +2530,30 @@ void Builder::simplifyAccessChainSwizzle()
// To the extent any swizzling can become part of the chain
// of accesses instead of a post operation, make it so.
// If 'dynamic' is true, include transferring a non-static component index,
// otherwise, only transfer static indexes.
// If 'dynamic' is true, include transferring the dynamic component,
// otherwise, leave it pending.
//
// Also, Boolean vectors are likely to be special. While
// for external storage, they should only be integer types,
// function-local bool vectors could use sub-word indexing,
// so keep that as a separate Insert/Extract on a loaded vector.
// Does not generate code. just updates the access chain.
void Builder::transferAccessChainSwizzle(bool dynamic)
{
// too complex?
if (accessChain.swizzle.size() > 1)
return;
// non existent?
if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)
return;
// single component...
// skip doing it for Boolean vectors
if (isBoolType(getContainedTypeId(accessChain.preSwizzleBaseType)))
// too complex?
// (this requires either a swizzle, or generating code for a dynamic component)
if (accessChain.swizzle.size() > 1)
return;
// single component, either in the swizzle and/or dynamic component
if (accessChain.swizzle.size() == 1) {
// handle static component
assert(accessChain.component == NoResult);
// handle static component selection
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
accessChain.swizzle.clear();
// note, the only valid remaining dynamic access would be to this one
// component, so don't bother even looking at accessChain.component
accessChain.preSwizzleBaseType = NoType;
accessChain.component = NoResult;
} else if (dynamic && accessChain.component != NoResult) {
assert(accessChain.swizzle.size() == 0);
// handle dynamic component
accessChain.indexChain.push_back(accessChain.component);
accessChain.preSwizzleBaseType = NoType;
......
......@@ -533,12 +533,15 @@ public:
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
// push a variable component selection onto the access chain; supporting only one, so unsided
// push a dynamic component selection onto the access chain, only applicable with a
// non-trivial swizzle or no swizzle
void accessChainPushComponent(Id component, Id preSwizzleBaseType)
{
accessChain.component = component;
if (accessChain.preSwizzleBaseType == NoType)
accessChain.preSwizzleBaseType = preSwizzleBaseType;
if (accessChain.swizzle.size() != 1) {
accessChain.component = component;
if (accessChain.preSwizzleBaseType == NoType)
accessChain.preSwizzleBaseType = preSwizzleBaseType;
}
}
// use accessChain and swizzle to store value
......@@ -577,6 +580,7 @@ public:
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
Id findCompositeConstant(Op typeClass, const std::vector<Id>& comps) const;
Id collapseAccessChain();
void remapDynamicSwizzle();
void transferAccessChainSwizzle(bool dynamic);
void simplifyAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*);
......
......@@ -1368,18 +1368,18 @@ spv.400.frag
997: 10(float) Select 995 996 21
998: 39(float) FConvert 997
999: 39(float) FAdd 994 998
1000: 437(bvec2) Load 439(bvec2v)
1001: 428(bool) CompositeExtract 1000 0
1000: 429(ptr) AccessChain 439(bvec2v) 33
1001: 428(bool) Load 1000
1002: 10(float) Select 1001 996 21
1003: 39(float) FConvert 1002
1004: 39(float) FAdd 999 1003
1005: 446(bvec3) Load 448(bvec3v)
1006: 428(bool) CompositeExtract 1005 0
1005: 429(ptr) AccessChain 448(bvec3v) 33
1006: 428(bool) Load 1005
1007: 10(float) Select 1006 996 21
1008: 39(float) FConvert 1007
1009: 39(float) FAdd 1004 1008
1010: 455(bvec4) Load 457(bvec4v)
1011: 428(bool) CompositeExtract 1010 0
1010: 429(ptr) AccessChain 457(bvec4v) 33
1011: 428(bool) Load 1010
1012: 10(float) Select 1011 996 21
1013: 39(float) FConvert 1012
1014: 39(float) FAdd 1009 1013
......
......@@ -119,8 +119,8 @@ spv.conversion.frag
315: 13(int) Constant 1
321: TypePointer Output 95(fvec4)
322(gl_FragColor): 321(ptr) Variable Output
367: 13(int) Constant 2
380: 13(int) Constant 3
337: 13(int) Constant 2
350: 13(int) Constant 3
427: TypePointer Private 6(bool)
428(u_b): 427(ptr) Variable Private
429: TypePointer Private 23(bvec2)
......@@ -440,8 +440,8 @@ spv.conversion.frag
Branch 300
300: Label
306: 16(float) Load 297
308: 23(bvec2) Load 25(b2)
309: 6(bool) CompositeExtract 308 0
308: 7(ptr) AccessChain 25(b2) 14
309: 6(bool) Load 308
SelectionMerge 311 None
BranchConditional 309 310 314
310: Label
......@@ -462,64 +462,64 @@ spv.conversion.frag
Branch 296
296: Label
324: 6(bool) Load 8(b)
325: 23(bvec2) Load 25(b2)
326: 6(bool) CompositeExtract 325 0
325: 7(ptr) AccessChain 25(b2) 14
326: 6(bool) Load 325
327: 6(bool) LogicalOr 324 326
328: 23(bvec2) Load 25(b2)
329: 6(bool) CompositeExtract 328 1
328: 7(ptr) AccessChain 25(b2) 315
329: 6(bool) Load 328
330: 6(bool) LogicalOr 327 329
331: 31(bvec3) Load 33(b3)
332: 6(bool) CompositeExtract 331 0
331: 7(ptr) AccessChain 33(b3) 14
332: 6(bool) Load 331
333: 6(bool) LogicalOr 330 332
334: 31(bvec3) Load 33(b3)
335: 6(bool) CompositeExtract 334 1
334: 7(ptr) AccessChain 33(b3) 315
335: 6(bool) Load 334
336: 6(bool) LogicalOr 333 335
337: 31(bvec3) Load 33(b3)
338: 6(bool) CompositeExtract 337 2
339: 6(bool) LogicalOr 336 338
340: 43(bvec4) Load 45(b4)
341: 6(bool) CompositeExtract 340 0
342: 6(bool) LogicalOr 339 341
343: 43(bvec4) Load 45(b4)
344: 6(bool) CompositeExtract 343 1
345: 6(bool) LogicalOr 342 344
346: 43(bvec4) Load 45(b4)
347: 6(bool) CompositeExtract 346 2
348: 6(bool) LogicalOr 345 347
349: 43(bvec4) Load 45(b4)
350: 6(bool) CompositeExtract 349 3
351: 6(bool) LogicalOr 348 350
SelectionMerge 353 None
BranchConditional 351 352 415
352: Label
354: 9(int) Load 58(i)
355: 57(ptr) AccessChain 68(i2) 14
356: 9(int) Load 355
357: 9(int) IAdd 354 356
358: 57(ptr) AccessChain 68(i2) 315
359: 9(int) Load 358
360: 9(int) IAdd 357 359
361: 57(ptr) AccessChain 81(i3) 14
362: 9(int) Load 361
363: 9(int) IAdd 360 362
364: 57(ptr) AccessChain 81(i3) 315
365: 9(int) Load 364
366: 9(int) IAdd 363 365
368: 57(ptr) AccessChain 81(i3) 367
369: 9(int) Load 368
370: 9(int) IAdd 366 369
371: 57(ptr) AccessChain 94(i4) 14
372: 9(int) Load 371
373: 9(int) IAdd 370 372
374: 57(ptr) AccessChain 94(i4) 315
375: 9(int) Load 374
376: 9(int) IAdd 373 375
377: 57(ptr) AccessChain 94(i4) 367
378: 9(int) Load 377
379: 9(int) IAdd 376 378
381: 57(ptr) AccessChain 94(i4) 380
338: 7(ptr) AccessChain 33(b3) 337
339: 6(bool) Load 338
340: 6(bool) LogicalOr 336 339
341: 7(ptr) AccessChain 45(b4) 14
342: 6(bool) Load 341
343: 6(bool) LogicalOr 340 342
344: 7(ptr) AccessChain 45(b4) 315
345: 6(bool) Load 344
346: 6(bool) LogicalOr 343 345
347: 7(ptr) AccessChain 45(b4) 337
348: 6(bool) Load 347
349: 6(bool) LogicalOr 346 348
351: 7(ptr) AccessChain 45(b4) 350
352: 6(bool) Load 351
353: 6(bool) LogicalOr 349 352
SelectionMerge 355 None
BranchConditional 353 354 415
354: Label
356: 9(int) Load 58(i)
357: 57(ptr) AccessChain 68(i2) 14
358: 9(int) Load 357
359: 9(int) IAdd 356 358
360: 57(ptr) AccessChain 68(i2) 315
361: 9(int) Load 360
362: 9(int) IAdd 359 361
363: 57(ptr) AccessChain 81(i3) 14
364: 9(int) Load 363
365: 9(int) IAdd 362 364
366: 57(ptr) AccessChain 81(i3) 315
367: 9(int) Load 366
368: 9(int) IAdd 365 367
369: 57(ptr) AccessChain 81(i3) 337
370: 9(int) Load 369
371: 9(int) IAdd 368 370
372: 57(ptr) AccessChain 94(i4) 14
373: 9(int) Load 372
374: 9(int) IAdd 371 373
375: 57(ptr) AccessChain 94(i4) 315
376: 9(int) Load 375
377: 9(int) IAdd 374 376
378: 57(ptr) AccessChain 94(i4) 337
379: 9(int) Load 378
380: 9(int) IAdd 377 379
381: 57(ptr) AccessChain 94(i4) 350
382: 9(int) Load 381
383: 9(int) IAdd 379 382
383: 9(int) IAdd 380 382
384: 16(float) ConvertSToF 383
385: 16(float) Load 106(f)
386: 16(float) FAdd 384 385
......@@ -535,7 +535,7 @@ spv.conversion.frag
396: 105(ptr) AccessChain 114(f3) 315
397: 16(float) Load 396
398: 16(float) FAdd 395 397
399: 105(ptr) AccessChain 114(f3) 367
399: 105(ptr) AccessChain 114(f3) 337
400: 16(float) Load 399
401: 16(float) FAdd 398 400
402: 105(ptr) AccessChain 118(f4) 14
......@@ -544,19 +544,19 @@ spv.conversion.frag
405: 105(ptr) AccessChain 118(f4) 315
406: 16(float) Load 405
407: 16(float) FAdd 404 406
408: 105(ptr) AccessChain 118(f4) 367
408: 105(ptr) AccessChain 118(f4) 337
409: 16(float) Load 408
410: 16(float) FAdd 407 409
411: 105(ptr) AccessChain 118(f4) 380
411: 105(ptr) AccessChain 118(f4) 350
412: 16(float) Load 411
413: 16(float) FAdd 410 412
414: 95(fvec4) CompositeConstruct 413 413 413 413
Store 323 414
Branch 353
Branch 355
415: Label
Store 323 151
Branch 353
353: Label
Branch 355
355: Label
416: 95(fvec4) Load 323
Store 322(gl_FragColor) 416
Store 417(cv2) 102
......
......@@ -74,6 +74,11 @@ void GetColor13(const S i, int comp)
OutColor.zy[comp] += i.color.x;
}
void GetColor14(const S i, int comp)
{
OutColor.zyx[comp] = i.color.x;
}
void main()
{
S s;
......@@ -91,4 +96,5 @@ void main()
GetColor11(s, u);
GetColor12(s, u);
GetColor13(s, u);
GetColor14(s, u);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment