Skip to content

Commit

Permalink
Replace inOutLocMap with inputLocMap/outputLocMap
Browse files Browse the repository at this point in the history
`InOutLocMap` is introduced to a <unsigned, unsigned> map for input/output
packing by decoding the unsigned as `InOutLocationInfo`. However, it is
a bit reduncant. Original `inputLocMap`/`outputLocMap` also do a
<unsigned, unsigned> mapping from user specified locations to
concecutive locations. We could reuse it for both packing and
non-packing code paths. This change will include:
-Refactor `InOutLocationInfo` by adding set/get functions and
`operator<`.
-Change the type of the key and valu of `inputLocMap`/`outputLocMap` to
`InOutLocInfo` and rename `inputLocMap`/`outputLocMap` to
`inputLocInfoMap`/`outputLocInfoMap` to distinguish with pure location
maps.
-In packing code path, replace `inOutLocMap` with
`inputLocInfoMap`/`outputLocInfoMap`.
-In non-packing code path, construct a `InOutLocationInfo` for map
lookup and extract requried bit field from mapped `InOutLocationInfo`.
  • Loading branch information
xuechen417 authored and JaxLinAMD committed Dec 2, 2020
1 parent f454d20 commit 796032b
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 270 deletions.
48 changes: 30 additions & 18 deletions lgc/builder/InOutBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,22 +288,23 @@ void InOutBuilder::markGenericInputOutputUsage(bool isOutput, unsigned location,
auto resUsage = getPipelineState()->getShaderResourceUsage(m_shaderStage);

// Mark the input or output locations as in use.
std::map<unsigned, unsigned> *inOutLocMap = nullptr;
std::map<InOutLocationInfo, InOutLocationInfo> *inOutLocInfoMap = nullptr;
std::map<unsigned, unsigned> *perPatchInOutLocMap = nullptr;
if (!isOutput) {
if (m_shaderStage != ShaderStageTessEval || vertexIndex) {
// Normal input
inOutLocMap = &resUsage->inOutUsage.inputLocMap;
inOutLocInfoMap = &resUsage->inOutUsage.inputLocInfoMap;
} else {
// TES per-patch input
inOutLocMap = &resUsage->inOutUsage.perPatchInputLocMap;
perPatchInOutLocMap = &resUsage->inOutUsage.perPatchInputLocMap;
}
} else {
if (m_shaderStage != ShaderStageTessControl || vertexIndex) {
// Normal output
inOutLocMap = &resUsage->inOutUsage.outputLocMap;
inOutLocInfoMap = &resUsage->inOutUsage.outputLocInfoMap;
} else {
// TCS per-patch output
inOutLocMap = &resUsage->inOutUsage.perPatchOutputLocMap;
perPatchInOutLocMap = &resUsage->inOutUsage.perPatchOutputLocMap;
}
}

Expand All @@ -317,15 +318,26 @@ void InOutBuilder::markGenericInputOutputUsage(bool isOutput, unsigned location,
}
unsigned startLocation = (keepAllLocations ? 0 : location);
// Non-GS-output case.
for (unsigned i = startLocation; i < location + locationCount; ++i)
(*inOutLocMap)[i] = InvalidValue;
if (inOutLocInfoMap) {
for (unsigned i = startLocation; i < location + locationCount; ++i) {
InOutLocationInfo origLocationInfo(0);
origLocationInfo.setLocation(i);
auto &newLocationInfo = (*inOutLocInfoMap)[origLocationInfo];
newLocationInfo.setData(InvalidValue);
}
}
if (perPatchInOutLocMap) {
for (unsigned i = startLocation; i < location + locationCount; ++i)
(*perPatchInOutLocMap)[i] = InvalidValue;
}
} else {
// GS output. We include the stream ID with the location in the map key.
for (unsigned i = 0; i < locationCount; ++i) {
InOutLocationInfo outLocInfo = {};
outLocInfo.location = location + i;
outLocInfo.streamId = inOutInfo.getStreamId();
(*inOutLocMap)[outLocInfo.u16All] = InvalidValue;
InOutLocationInfo outLocationInfo(0);
outLocationInfo.setLocation(location + i);
outLocationInfo.setStreamId(inOutInfo.getStreamId());
auto &newLocationInfo = (*inOutLocInfoMap)[outLocationInfo];
newLocationInfo.setData(InvalidValue);
}
}

Expand Down Expand Up @@ -556,10 +568,10 @@ Instruction *InOutBuilder::CreateWriteXfbOutput(Value *valueToWrite, bool isBuil

if (m_shaderStage == ShaderStageGeometry) {
// Mark the XFB output for copy shader generation.
InOutLocationInfo outLocInfo = {};
outLocInfo.location = location;
outLocInfo.isBuiltIn = isBuiltIn;
outLocInfo.streamId = streamId;
InOutLocationInfo outLocationInfo(0);
outLocationInfo.setLocation(location);
outLocationInfo.setBuiltIn(isBuiltIn);
outLocationInfo.setStreamId(streamId);

XfbOutInfo xfbOutInfo = {};
xfbOutInfo.xfbBuffer = xfbBuffer;
Expand All @@ -568,11 +580,11 @@ Instruction *InOutBuilder::CreateWriteXfbOutput(Value *valueToWrite, bool isBuil
xfbOutInfo.xfbExtraOffset = 0;

auto resUsage = getPipelineState()->getShaderResourceUsage(ShaderStageGeometry);
resUsage->inOutUsage.gs.xfbOutsInfo[outLocInfo.u16All] = xfbOutInfo.u32All;
resUsage->inOutUsage.gs.xfbOutsInfo[outLocationInfo] = xfbOutInfo.u32All;
if (valueToWrite->getType()->getPrimitiveSizeInBits() > 128) {
++outLocInfo.location;
outLocationInfo.setLocation(location + 1);
xfbOutInfo.xfbOffset += 32;
resUsage->inOutUsage.gs.xfbOutsInfo[outLocInfo.u16All] = xfbOutInfo.u32All;
resUsage->inOutUsage.gs.xfbOutsInfo[outLocationInfo] = xfbOutInfo.u32All;
}
}

Expand Down
60 changes: 43 additions & 17 deletions lgc/include/lgc/state/ResourceUsage.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,45 @@ struct FsInterpInfo {
// Invalid interpolation info
static const FsInterpInfo InvalidFsInterpInfo = {InvalidValue, false, false, false, false, false};

// Represents the location info of input/output
union InOutLocationInfo {
struct {
uint16_t half : 1; // High half in case of 16-bit attriburtes
uint16_t component : 2; // The component index
uint16_t location : 10; // The location
uint16_t isBuiltIn : 1; // Whether location is actually built-in ID
uint16_t streamId : 2; // Output vertex stream ID
};
uint16_t u16All;
// Represents the location information on an input or output
class InOutLocationInfo {
public:
InOutLocationInfo() { m_data.u16All = 0; }
InOutLocationInfo(unsigned data) { this->m_data.u16All = static_cast<uint16_t>(data); }
InOutLocationInfo(const InOutLocationInfo &inOutLocInfo) { m_data.u16All = inOutLocInfo.getData(); }

unsigned getData() const { return static_cast<uint16_t>(m_data.u16All); }
void setData(unsigned data) { m_data.u16All = static_cast<uint16_t>(data); }
bool isInvalid() const { return m_data.u16All == 0xFFFF; }

bool isHighHalf() const { return m_data.bits.isHighHalf; }
void setHighHalf(bool isHighHalf) { m_data.bits.isHighHalf = isHighHalf; }

unsigned getComponent() const { return m_data.bits.component; }
void setComponent(unsigned compIdx) { m_data.bits.component = static_cast<uint16_t>(compIdx); }

unsigned getLocation() const { return m_data.bits.location; }
void setLocation(unsigned loc) { m_data.bits.location = static_cast<uint16_t>(loc); }

bool isBuiltIn() const { return m_data.bits.isBuiltIn; }
void setBuiltIn(bool isBuiltIn) { m_data.bits.isBuiltIn = isBuiltIn; }

unsigned getStreamId() const { return m_data.bits.streamId; }
void setStreamId(unsigned streamId) { m_data.bits.streamId = static_cast<uint16_t>(streamId); }

bool operator<(const InOutLocationInfo &rhs) const { return this->getData() < rhs.getData(); }

private:
union {
struct {
uint16_t isHighHalf : 1; // High half in case of 16-bit attriburtes
uint16_t component : 2; // The component index
uint16_t location : 10; // The location
uint16_t isBuiltIn : 1; // Whether location is actually built-in ID
uint16_t streamId : 2; // Output vertex stream ID
} bits;
uint16_t u16All;
} m_data;
};

// Enumerate the workgroup layout options.
Expand Down Expand Up @@ -262,12 +291,9 @@ struct ResourceUsage {

// Usage of generic input/output
struct {
// Map from shader specified locations to tightly packed locations
std::map<unsigned, unsigned> inputLocMap;
std::map<unsigned, unsigned> outputLocMap;

// The original and new InOutLocations for shader cache
std::map<unsigned, unsigned> inOutLocMap;
// Map from shader specified InOutLocations to tightly packed InOutLocations
std::map<InOutLocationInfo, InOutLocationInfo> inputLocInfoMap;
std::map<InOutLocationInfo, InOutLocationInfo> outputLocInfoMap;

std::map<unsigned, unsigned> perPatchInputLocMap;
std::map<unsigned, unsigned> perPatchOutputLocMap;
Expand Down Expand Up @@ -343,7 +369,7 @@ struct ResourceUsage {
std::unordered_map<unsigned, std::vector<unsigned>> genericOutByteSizes[MaxGsStreams];

// Map from output location to the transform feedback info
std::map<unsigned, unsigned> xfbOutsInfo;
std::map<InOutLocationInfo, unsigned> xfbOutsInfo;

// ID of the vertex stream sent to rasterizor
unsigned rasterStream = 0;
Expand Down
8 changes: 5 additions & 3 deletions lgc/patch/FragColorExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,12 @@ void LowerFragColorExport::updateFragColors(CallInst *callInst, ColorExportValue
const unsigned compIdx = cast<ConstantInt>(callInst->getOperand(1))->getZExtValue();
Value *output = callInst->getOperand(2);

auto it = m_resUsage->inOutUsage.outputLocMap.find(location);
if (it == m_resUsage->inOutUsage.outputLocMap.end())
InOutLocationInfo origLocInfo(0);
origLocInfo.setLocation(location);
auto locInfoMapIt = m_resUsage->inOutUsage.outputLocInfoMap.find(origLocInfo);
if (locInfoMapIt == m_resUsage->inOutUsage.outputLocInfoMap.end())
return;
unsigned hwColorTarget = it->second;
unsigned hwColorTarget = locInfoMapIt->second.getLocation();

Type *outputTy = output->getType();

Expand Down
5 changes: 2 additions & 3 deletions lgc/patch/PatchCheckShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,8 @@ bool PatchCheckShaderCache::runOnModule(Module &module) {
raw_string_ostream stream(inOutUsageStreams[stage]);

// Update input/output usage
streamMapEntries(resUsage->inOutUsage.inputLocMap, stream);
streamMapEntries(resUsage->inOutUsage.outputLocMap, stream);
streamMapEntries(resUsage->inOutUsage.inOutLocMap, stream);
streamMapEntries(resUsage->inOutUsage.inputLocInfoMap, stream);
streamMapEntries(resUsage->inOutUsage.outputLocInfoMap, stream);
streamMapEntries(resUsage->inOutUsage.perPatchInputLocMap, stream);
streamMapEntries(resUsage->inOutUsage.perPatchOutputLocMap, stream);
streamMapEntries(resUsage->inOutUsage.builtInInputLocMap, stream);
Expand Down
45 changes: 22 additions & 23 deletions lgc/patch/PatchCopyShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,15 @@ void PatchCopyShader::collectGsGenericOutputInfo(Function *gsEntryPoint) {
unsigned value = cast<ConstantInt>(callInst->getOperand(0))->getZExtValue();
const unsigned streamId = cast<ConstantInt>(callInst->getOperand(2))->getZExtValue();

InOutLocationInfo outLocInfo = {};
outLocInfo.location = value;
outLocInfo.isBuiltIn = false;
outLocInfo.streamId = streamId;
InOutLocationInfo outLocInfo(0);
outLocInfo.setLocation(value);
outLocInfo.setStreamId(streamId);

auto locMapIt = resUsage->inOutUsage.outputLocMap.find(outLocInfo.u16All);
if (locMapIt == resUsage->inOutUsage.outputLocMap.end())
auto locInfoMapIt = resUsage->inOutUsage.outputLocInfoMap.find(outLocInfo);
if (locInfoMapIt == resUsage->inOutUsage.outputLocInfoMap.end())
continue;

unsigned location = locMapIt->second;
unsigned location = locInfoMapIt->second.getLocation();
const unsigned compIdx = cast<ConstantInt>(callInst->getOperand(1))->getZExtValue();

unsigned compCount = 1;
Expand Down Expand Up @@ -563,20 +562,20 @@ void PatchCopyShader::exportGenericOutput(Value *outputValue, unsigned location,
BuilderBase &builder) {
auto resUsage = m_pipelineState->getShaderResourceUsage(ShaderStageCopyShader);
if (resUsage->inOutUsage.enableXfb) {
auto &outLocMap = resUsage->inOutUsage.outputLocMap;
auto &outLocInfoMap = resUsage->inOutUsage.outputLocInfoMap;
auto &xfbOutsInfo = resUsage->inOutUsage.gs.xfbOutsInfo;

// Find original location in outLocMap which equals used location in copy shader
auto locIter =
find_if(outLocMap.begin(), outLocMap.end(), [location, streamId](const std::pair<unsigned, unsigned> &outLoc) {
unsigned outLocInfo = outLoc.first;
bool isStreamId = (reinterpret_cast<InOutLocationInfo *>(&outLocInfo))->streamId == streamId;
return outLoc.second == location && isStreamId;
});
// Find original location in outLocInfoMap which equals used location in copy shader
auto locInfoIter =
find_if(outLocInfoMap.begin(), outLocInfoMap.end(),
[location, streamId](const std::pair<InOutLocationInfo, InOutLocationInfo> &outLocInfo) {
const auto &newLocationInfo = outLocInfo.second;
return newLocationInfo.getLocation() == location && newLocationInfo.getStreamId() == streamId;
});

assert(locIter != outLocMap.end());
if (xfbOutsInfo.find(locIter->first) != xfbOutsInfo.end()) {
XfbOutInfo *xfbOutInfo = reinterpret_cast<XfbOutInfo *>(&xfbOutsInfo[locIter->first]);
assert(locInfoIter != outLocInfoMap.end());
if (xfbOutsInfo.find(locInfoIter->first) != xfbOutsInfo.end()) {
XfbOutInfo *xfbOutInfo = reinterpret_cast<XfbOutInfo *>(&xfbOutsInfo[locInfoIter->first]);

if (xfbOutInfo->is16bit) {
// NOTE: For 16-bit transform feedback output, the value is 32-bit dword loaded from GS-VS ring
Expand Down Expand Up @@ -629,13 +628,13 @@ void PatchCopyShader::exportBuiltInOutput(Value *outputValue, BuiltInKind builtI
auto resUsage = m_pipelineState->getShaderResourceUsage(ShaderStageCopyShader);

if (resUsage->inOutUsage.enableXfb) {
InOutLocationInfo outLocInfo = {};
outLocInfo.location = builtInId;
outLocInfo.isBuiltIn = true;
outLocInfo.streamId = streamId;
InOutLocationInfo outLocInfo(0);
outLocInfo.setLocation(builtInId);
outLocInfo.setBuiltIn(true);
outLocInfo.setStreamId(streamId);

auto &xfbOutsInfo = resUsage->inOutUsage.gs.xfbOutsInfo;
auto locIter = xfbOutsInfo.find(outLocInfo.u16All);
auto locIter = xfbOutsInfo.find(outLocInfo);
if (locIter != xfbOutsInfo.end()) {
XfbOutInfo *xfbOutInfo = reinterpret_cast<XfbOutInfo *>(&xfbOutsInfo[locIter->first]);

Expand Down
Loading

0 comments on commit 796032b

Please sign in to comment.