Improve DXIL BufferStore/TextureStore out of bounds handling

For texture data the maximum number of components to store comes from the format
For non-texture data the maximum number of components is four which is then clamped to stop buffer overrun (by data size or offset)
This commit is contained in:
Jake Turner
2025-01-02 13:09:24 +00:00
parent 75aeb4820a
commit 8ba666f0a9
+7 -5
View File
@@ -2160,14 +2160,15 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
{
data += dataOffset;
int numComps = fmt.numComps;
int maxNumComps = fmt.numComps;
// Clamp the number of components to read based on the amount of data in the buffer
if(!texData)
{
RDCASSERTNOTEQUAL(numElems, 0);
int maxNumComps = (int)((dataSize - dataOffset) / fmt.byteWidth);
fmt.numComps = RDCMIN(fmt.numComps, maxNumComps);
const int maxNumCompsData = (int)((dataSize - dataOffset) / fmt.byteWidth);
size_t maxOffset = (firstElem + numElems) * stride + structOffset;
maxNumComps = (int)((maxOffset - dataOffset) / fmt.byteWidth);
const int maxNumCompsOffset = (int)((maxOffset - dataOffset) / fmt.byteWidth);
maxNumComps = RDCMIN(maxNumCompsData, maxNumCompsOffset);
fmt.numComps = RDCMIN(fmt.numComps, maxNumComps);
}
@@ -2186,7 +2187,8 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
numComps = 0;
// Modify the correct components
const uint32_t valueStart = (dxOpCode == DXOp::TextureStore) ? 5 : 4;
for(uint32_t c = 0; c < (uint32_t)fmt.numComps; ++c)
const uint32_t numArgs = RDCMIN(4, maxNumComps);
for(uint32_t c = 0; c < numArgs; ++c)
{
if(GetShaderVariable(inst.args[c + valueStart], opCode, dxOpCode, arg))
{
@@ -2196,7 +2198,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
++numComps;
}
}
fmt.numComps = numComps;
fmt.numComps = RDCMIN(numComps, maxNumComps);
TypedUAVStore(fmt, (byte *)data, result.value);
}
}