Skip to content

Commit

Permalink
Support packing input and output on tessellation
Browse files Browse the repository at this point in the history
In the current framework of packing input and output on VS-FS, we add the support to pack input and ouput on pipeline VS-TCS-TES-(FS). Pack VS-TCS and TES-FS.
- The packing for VS-TCS is to reduce lds fragmentations by mapping all scalarized input calls to lds locations as continuious as possible. We execute addSpan and then fillInOutLocMap for TCS inputs as same as FS inputs. In PatchInOutImportExport, we use packed InOutLocationInfo to do patchVsGenericOutputExport and patchTcsGenericInputImport for VS-TCS.
- The packing for TES-FS is similar to VS-FS by re-assembling scalarized output calls in order to reduce the count of time-consuming exp instcutions.

Fixes: #523
  • Loading branch information
xuechen417 authored and JaxLinAMD committed Sep 9, 2020
1 parent 66597ae commit 8cd0205
Show file tree
Hide file tree
Showing 6 changed files with 548 additions and 122 deletions.
43 changes: 33 additions & 10 deletions lgc/patch/PatchInOutImportExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,12 @@ void PatchInOutImportExport::visitCallInst(CallInst &callInst) {
loc = resUsage->inOutUsage.perPatchInputLocMap[value];
}
} else {
if ((m_shaderStage == ShaderStageFragment) && m_pipelineState->isPackInOut()) {
if (m_pipelineState->isPackInOut() &&
(m_shaderStage == ShaderStageFragment || m_shaderStage == ShaderStageTessControl)) {
// The new InOutLocationInfo is used to map scalarized FS and TCS input import as compact as possible
InOutLocationInfo origLocInfo = {};
origLocInfo.location = cast<ConstantInt>(callInst.getOperand(0))->getZExtValue();
const uint32_t elemIdxArgIdx = isInterpolantInputImport ? 2 : 1;
origLocInfo.location = value;
const uint32_t elemIdxArgIdx = isInterpolantInputImport || m_shaderStage != ShaderStageFragment ? 2 : 1;
origLocInfo.component = cast<ConstantInt>(callInst.getOperand(elemIdxArgIdx))->getZExtValue();
origLocInfo.half = false;
assert(resUsage->inOutUsage.inOutLocMap.find(origLocInfo.u16All) != resUsage->inOutUsage.inOutLocMap.end());
Expand All @@ -471,8 +473,10 @@ void PatchInOutImportExport::visitCallInst(CallInst &callInst) {
case ShaderStageTessControl: {
assert(callInst.getNumArgOperands() == 4);

auto elemIdx = callInst.getOperand(2);
assert(isDontCareValue(elemIdx) == false);
if (!elemIdx) {
elemIdx = callInst.getOperand(2);
assert(isDontCareValue(elemIdx) == false);
}

auto vertexIdx = callInst.getOperand(3);
assert(isDontCareValue(vertexIdx) == false);
Expand Down Expand Up @@ -694,6 +698,7 @@ void PatchInOutImportExport::visitCallInst(CallInst &callInst) {
bool exist = false;
unsigned loc = InvalidValue;
Value *locOffset = nullptr;
unsigned elemIdx = InvalidValue;

if (m_shaderStage == ShaderStageTessControl) {
// NOTE: If location offset is a constant, we have to add it to the unmapped location before querying
Expand Down Expand Up @@ -729,7 +734,23 @@ void PatchInOutImportExport::visitCallInst(CallInst &callInst) {
loc = resUsage->inOutUsage.outputLocMap[outLocInfo.u32All];
}
} else {
if (resUsage->inOutUsage.outputLocMap.find(value) != resUsage->inOutUsage.outputLocMap.end()) {
if (m_pipelineState->isPackInOut() && m_shaderStage == ShaderStageVertex &&
m_pipelineState->hasShaderStage(ShaderStageTessControl)) {
// The new InOutLocationInfo is used to map scalarized VS output export in a VS-TCS-TES-FS to lds as compact
// as possible
InOutLocationInfo origLocInfo = {};
origLocInfo.location = value;
origLocInfo.component = cast<ConstantInt>(callInst.getOperand(1))->getZExtValue();
origLocInfo.half = false;
if (resUsage->inOutUsage.inOutLocMap.find(origLocInfo.u16All) != resUsage->inOutUsage.inOutLocMap.end()) {
InOutLocationInfo newLocInfo = {};
newLocInfo.u16All = resUsage->inOutUsage.inOutLocMap[origLocInfo.u16All];
loc = newLocInfo.location;
elemIdx = newLocInfo.component;
exist = true;
} else
exist = false;
} else if (resUsage->inOutUsage.outputLocMap.find(value) != resUsage->inOutUsage.outputLocMap.end()) {
exist = true;
loc = resUsage->inOutUsage.outputLocMap[value];
}
Expand All @@ -742,8 +763,9 @@ void PatchInOutImportExport::visitCallInst(CallInst &callInst) {
switch (m_shaderStage) {
case ShaderStageVertex: {
assert(callInst.getNumArgOperands() == 3);
const unsigned compIdx = cast<ConstantInt>(callInst.getOperand(1))->getZExtValue();
patchVsGenericOutputExport(output, loc, compIdx, &callInst);
if (elemIdx == InvalidValue)
elemIdx = cast<ConstantInt>(callInst.getOperand(1))->getZExtValue();
patchVsGenericOutputExport(output, loc, elemIdx, &callInst);
break;
}
case ShaderStageTessControl: {
Expand All @@ -759,8 +781,9 @@ void PatchInOutImportExport::visitCallInst(CallInst &callInst) {
}
case ShaderStageTessEval: {
assert(callInst.getNumArgOperands() == 3);
const unsigned compIdx = cast<ConstantInt>(callInst.getOperand(1))->getZExtValue();
patchTesGenericOutputExport(output, loc, compIdx, &callInst);
if (elemIdx == InvalidValue)
elemIdx = cast<ConstantInt>(callInst.getOperand(1))->getZExtValue();
patchTesGenericOutputExport(output, loc, elemIdx, &callInst);
break;
}
case ShaderStageGeometry: {
Expand Down
Loading

0 comments on commit 8cd0205

Please sign in to comment.