diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h index 872bf6c4e..ec1a7ddd2 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h @@ -798,39 +798,94 @@ struct Operand // .xyzw = { 0, 1, 2, 3 } // .wzyx = { 3, 2, 1, 0 } - Operand swizzle(uint8_t c) + Operand &swizzle(uint8_t c) { - Operand ret = *this; - ret.numComponents = NUMCOMPS_1; - ret.comps[0] = comps[c]; - ret.comps[1] = 0xff; - ret.comps[2] = 0xff; - ret.comps[3] = 0xff; - ret.values[0] = values[c]; - ret.values[1] = 0; - ret.values[2] = 0; - ret.values[3] = 0; - return ret; + // you'd think this would use NUMCOMPS_1 but fxc doesn't like that. Those only + // seem to be used for declarations or other special situations, so we keep to NUMCOMPS_4 + flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED)); + flags = Flags(flags | FLAG_SELECTED); + numComponents = NUMCOMPS_4; + + comps[0] = c; + comps[1] = 0xff; + comps[2] = 0xff; + comps[3] = 0xff; + + return *this; } - Operand swizzle(uint8_t x, uint8_t y, uint8_t z, uint8_t w) + Operand &swizzle(uint8_t x, uint8_t y, uint8_t z, uint8_t w) { - Operand ret = *this; - ret.comps[0] = comps[x]; - ret.comps[1] = comps[y]; - ret.comps[2] = z < 4 ? comps[z] : 0xff; - ret.comps[3] = w < 4 ? comps[w] : 0xff; - ret.values[0] = values[x]; - ret.values[1] = values[y]; - ret.values[2] = z < 4 ? values[z] : 0; - ret.values[3] = w < 4 ? values[w] : 0; - return ret; + numComponents = NUMCOMPS_4; + flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED)); + + if(x == 0xff || y == 0xff || z == 0xff || w == 0xff) + flags = Flags(flags | FLAG_MASKED); + else + flags = Flags(flags | FLAG_SWIZZLED); + + comps[0] = x; + comps[1] = y; + comps[2] = z; + comps[3] = w; + + return *this; + } + + Operand &reswizzle(uint8_t c) + { + // you'd think this would use NUMCOMPS_1 but fxc doesn't like that. Those only + // seem to be used for declarations or other special situations, so we keep to NUMCOMPS_4 + flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED)); + flags = Flags(flags | FLAG_SELECTED); + numComponents = NUMCOMPS_4; + + comps[0] = comps[c]; + comps[1] = 0xff; + comps[2] = 0xff; + comps[3] = 0xff; + + values[0] = values[c]; + values[1] = 0; + values[2] = 0; + values[3] = 0; + + return *this; + } + + Operand &reswizzle(uint8_t x, uint8_t y, uint8_t z, uint8_t w) + { + rdcfixedarray oldVals = values; + rdcfixedarray oldComps = comps; + + numComponents = NUMCOMPS_4; + flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED)); + + if(x == 0xff || y == 0xff || z == 0xff || w == 0xff) + flags = Flags(flags | FLAG_MASKED); + else + flags = Flags(flags | FLAG_SWIZZLED); + + comps[0] = oldComps[x]; + comps[1] = y < 4 ? oldComps[y] : 0xff; + comps[2] = z < 4 ? oldComps[z] : 0xff; + comps[3] = w < 4 ? oldComps[w] : 0xff; + + values[0] = oldVals[x]; + values[1] = z < 4 ? oldVals[y] : 0; + values[2] = z < 4 ? oldVals[z] : 0; + values[3] = w < 4 ? oldVals[w] : 0; + + return *this; } void setComps(uint8_t x, uint8_t y, uint8_t z, uint8_t w) { flags = Flags(flags & ~(FLAG_SWIZZLED | FLAG_MASKED | FLAG_SELECTED)); + // you'd think this would use NUMCOMPS_1 but fxc doesn't like that. Those only + // seem to be used for declarations or other special situations, so we keep to NUMCOMPS_4 + numComponents = NUMCOMPS_4; if(y == 0xff && z == 0xff && w == 0xff) flags = Flags(flags | FLAG_SELECTED); else if(x == 0xff || y == 0xff || z == 0xff || w == 0xff) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_vendorext.cpp b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_vendorext.cpp index 4bcc042c6..ef6994494 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_vendorext.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_vendorext.cpp @@ -717,10 +717,10 @@ void Program::PostprocessVendorExtensions() } else { - op.operands.push_back(srcParam[5].swizzle(0)); + op.operands.push_back(srcParam[5].reswizzle(0)); op.operands.back().name = "compare_value.x"_lit; op.operands.back().setComps(srcParam[5].comps[0], 0xff, 0xff, 0xff); - op.operands.push_back(srcParam[6].swizzle(0)); + op.operands.push_back(srcParam[6].reswizzle(0)); op.operands.back().name = "compare_value.y"_lit; op.operands.back().setComps(srcParam[6].comps[0], 0xff, 0xff, 0xff); @@ -742,10 +742,10 @@ void Program::PostprocessVendorExtensions() } else { - op.operands.push_back(srcParam[3].swizzle(0)); + op.operands.push_back(srcParam[3].reswizzle(0)); op.operands.back().name = "value.x"_lit; op.operands.back().setComps(srcParam[3].comps[0], 0xff, 0xff, 0xff); - op.operands.push_back(srcParam[4].swizzle(0)); + op.operands.push_back(srcParam[4].reswizzle(0)); op.operands.back().name = "value.y"_lit; op.operands.back().setComps(srcParam[4].comps[0], 0xff, 0xff, 0xff); @@ -919,16 +919,16 @@ void Program::PostprocessVendorExtensions() op.operands[0] = curOp.operands[0]; op.operands[1].name = "value"_lit; - op.operands[1] = srcParam[0].swizzle(0); + op.operands[1] = srcParam[0].reswizzle(0); if(nvopcode == NvShaderOpcode::Shuffle) op.operands[2].name = "srcLane"_lit; else if(nvopcode == NvShaderOpcode::ShuffleXor) op.operands[2].name = "laneMask"_lit; else op.operands[2].name = "delta"_lit; - op.operands[2] = srcParam[0].swizzle(1); + op.operands[2] = srcParam[0].reswizzle(1); op.operands[3].name = "width"_lit; - op.operands[3] = srcParam[0].swizzle(3); + op.operands[3] = srcParam[0].reswizzle(3); break; } case NvShaderOpcode::VoteAll: @@ -1077,33 +1077,33 @@ void Program::PostprocessVendorExtensions() } // peel out the source parameters - op.operands.push_back(srcParam[3].swizzle(0)); + op.operands.push_back(srcParam[3].reswizzle(0)); op.operands.back().name = "texSpace"_lit; - op.operands.push_back(srcParam[0].swizzle(0)); + op.operands.push_back(srcParam[0].reswizzle(0)); op.operands.back().name = "texIndex"_lit; - op.operands.push_back(srcParam[3].swizzle(1)); + op.operands.push_back(srcParam[3].reswizzle(1)); op.operands.back().name = "smpSpace"_lit; - op.operands.push_back(srcParam[0].swizzle(1)); + op.operands.push_back(srcParam[0].reswizzle(1)); op.operands.back().name = "smpIndex"_lit; - op.operands.push_back(srcParam[3].swizzle(2)); + op.operands.push_back(srcParam[3].reswizzle(2)); op.operands.back().name = "texType"_lit; op.operands.push_back(srcParam[1]); op.operands.back().comps[3] = 0xff; // location is a float3 op.operands.back().values[3] = 0; op.operands.back().name = "location"_lit; - op.operands.push_back(srcParam[3].swizzle(3)); + op.operands.push_back(srcParam[3].reswizzle(3)); op.operands.back().name = "coarse"_lit; - op.operands.push_back(srcParam[1].swizzle(3)); + op.operands.push_back(srcParam[1].reswizzle(3)); op.operands.back().name = "gran"_lit; if(nvopcode == NvShaderOpcode::FootprintBias) { - op.operands.push_back(srcParam[2].swizzle(0)); + op.operands.push_back(srcParam[2].reswizzle(0)); op.operands.back().name = "bias"_lit; } else if(nvopcode == NvShaderOpcode::FootprintLevel) { - op.operands.push_back(srcParam[2].swizzle(0)); + op.operands.push_back(srcParam[2].reswizzle(0)); op.operands.back().name = "lodLevel"_lit; } else if(nvopcode == NvShaderOpcode::FootprintGrad) @@ -1131,11 +1131,11 @@ void Program::PostprocessVendorExtensions() // we expect the params are packed into srcParam[0] - op.operands[2] = srcParam[0].swizzle(0); + op.operands[2] = srcParam[0].reswizzle(0); op.operands[2].name = "value"_lit; - op.operands[3] = srcParam[0].swizzle(1); + op.operands[3] = srcParam[0].reswizzle(1); op.operands[3].name = "srcLane"_lit; - op.operands[4] = srcParam[0].swizzle(2); + op.operands[4] = srcParam[0].reswizzle(2); op.operands[4].name = "width"_lit; break; } @@ -1367,9 +1367,9 @@ void Program::PostprocessVendorExtensions() atomicop = (NvShaderAtomic)srcParam[2].values[0]; - op.operands.push_back(srcParam[0].swizzle(0)); + op.operands.push_back(srcParam[0].reswizzle(0)); op.operands.back().name = "byteAddress"_lit; - op.operands.push_back(srcParam[1].swizzle(0)); + op.operands.push_back(srcParam[1].reswizzle(0)); op.operands.back().name = "value"_lit; break;