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