Merge pull request #2048 from CookiePLMonster/vertex-stream-cache-optimization
Optimize vertex stream cache for partial buffer access
This commit is contained in:
commit
362c93801f
|
@ -6864,7 +6864,7 @@ void CxbxDrawIndexed(CxbxDrawContext &DrawContext)
|
|||
// for an explanation on the function of the BaseVertexIndex, MinVertexIndex, NumVertices and StartIndex arguments.
|
||||
HRESULT hRet = g_pD3DDevice->DrawIndexedPrimitive(
|
||||
/* PrimitiveType = */EmuXB2PC_D3DPrimitiveType(DrawContext.XboxPrimitiveType),
|
||||
BaseVertexIndex,
|
||||
/* BaseVertexIndex, = */-CacheEntry.LowIndex, // Base vertex index has been accounted for in the stream conversion, now we need to "un-offset" the index buffer
|
||||
/* MinVertexIndex = */CacheEntry.LowIndex,
|
||||
/* NumVertices = */(CacheEntry.HighIndex - CacheEntry.LowIndex) + 1,
|
||||
/* startIndex = DrawContext.dwStartVertex = */0,
|
||||
|
@ -7516,9 +7516,6 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_DrawVertices)
|
|||
// Draw quadlists using a single 'quad-to-triangle mapping' index buffer :
|
||||
// Assure & activate that special index buffer :
|
||||
CxbxAssureQuadListD3DIndexBuffer(/*NrOfQuadIndices=*/DrawContext.dwVertexCount);
|
||||
// This API's StartVertex argument is multiplied by vertex stride and added to the start of the vertex buffer;
|
||||
// BaseVertexIndex offers the same functionality on host :
|
||||
UINT BaseVertexIndex = DrawContext.dwStartVertex;
|
||||
// Convert quad vertex count to triangle vertex count :
|
||||
UINT NumVertices = QuadToTriangleVertexCount(DrawContext.dwVertexCount);
|
||||
// Convert quad primitive count to triangle primitive count :
|
||||
|
@ -7528,7 +7525,7 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_DrawVertices)
|
|||
// Emulate drawing quads by drawing each quad with two indexed triangles :
|
||||
HRESULT hRet = g_pD3DDevice->DrawIndexedPrimitive(
|
||||
/*PrimitiveType=*/D3DPT_TRIANGLELIST,
|
||||
BaseVertexIndex,
|
||||
/*BaseVertexIndex=*/0, // Base vertex index has been accounted for in the stream conversion
|
||||
/*MinVertexIndex=*/0,
|
||||
NumVertices,
|
||||
/*startIndex=*/0,
|
||||
|
@ -7542,7 +7539,7 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_DrawVertices)
|
|||
// if (StartVertex > 0) LOG_TEST_CASE("StartVertex > 0 (non-quad)"); // Verified test case : XDK Sample (PlayField)
|
||||
HRESULT hRet = g_pD3DDevice->DrawPrimitive(
|
||||
EmuXB2PC_D3DPrimitiveType(DrawContext.XboxPrimitiveType),
|
||||
DrawContext.dwStartVertex,
|
||||
/*StartVertex=*/0, // Start vertex has been accounted for in the stream conversion
|
||||
DrawContext.dwHostPrimitiveCount
|
||||
);
|
||||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->DrawPrimitive");
|
||||
|
@ -7553,8 +7550,8 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_DrawVertices)
|
|||
LOG_TEST_CASE("X_D3DPT_LINELOOP"); // TODO : Text-cases needed
|
||||
|
||||
assert(DrawContext.dwBaseVertexIndex == 0); // if this fails, it needs to be added to LowIndex and HighIndex :
|
||||
INDEX16 LowIndex = (INDEX16)DrawContext.dwStartVertex;
|
||||
INDEX16 HighIndex = (INDEX16)(DrawContext.dwStartVertex + DrawContext.dwHostPrimitiveCount);
|
||||
INDEX16 LowIndex = 0;
|
||||
INDEX16 HighIndex = (INDEX16)(DrawContext.dwHostPrimitiveCount);
|
||||
// Draw the closing line using a helper function (which will SetIndices)
|
||||
CxbxDrawIndexedClosingLine(LowIndex, HighIndex);
|
||||
// NOTE : We don't restore the previously active index buffer
|
||||
|
|
|
@ -261,9 +261,7 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
UINT HostStreamNumber = XboxStreamNumber; // Use Xbox stream index on host
|
||||
uint8_t *pXboxVertexData = xbox::zeroptr;
|
||||
UINT uiXboxVertexStride = 0;
|
||||
UINT uiVertexCount = 0;
|
||||
UINT uiHostVertexStride = 0;
|
||||
DWORD dwHostVertexDataSize = 0;
|
||||
uint8_t *pHostVertexData = nullptr;
|
||||
IDirect3DVertexBuffer *pNewHostVertexBuffer = nullptr;
|
||||
|
||||
|
@ -275,9 +273,7 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
|
||||
pXboxVertexData = (uint8_t *)pDrawContext->pXboxVertexStreamZeroData;
|
||||
uiXboxVertexStride = pDrawContext->uiXboxVertexStreamZeroStride;
|
||||
uiVertexCount = pDrawContext->VerticesInBuffer;
|
||||
uiHostVertexStride = (bNeedVertexPatching) ? pVertexShaderStreamInfo->HostVertexStride : uiXboxVertexStride;
|
||||
dwHostVertexDataSize = uiVertexCount * uiHostVertexStride;
|
||||
} else {
|
||||
xbox::X_STREAMINPUT& XboxStreamInput = GetXboxVertexStreamInput(XboxStreamNumber);
|
||||
xbox::X_D3DVertexBuffer *pXboxVertexBuffer = XboxStreamInput.VertexBuffer;
|
||||
|
@ -298,14 +294,11 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
|
||||
pXboxVertexData += XboxStreamInput.Offset;
|
||||
uiXboxVertexStride = XboxStreamInput.Stride;
|
||||
// Set a new (exact) vertex count
|
||||
uiVertexCount = pDrawContext->VerticesInBuffer;
|
||||
// Dxbx note : Don't overwrite pDrawContext.dwVertexCount with uiVertexCount, because an indexed draw
|
||||
// can (and will) use less vertices than the supplied nr of indexes. Thix fixes
|
||||
// the missing parts in the CompressedVertices sample (in Vertex shader mode).
|
||||
|
||||
uiHostVertexStride = (bNeedVertexPatching) ? pVertexShaderStreamInfo->HostVertexStride : uiXboxVertexStride;
|
||||
dwHostVertexDataSize = uiVertexCount * uiHostVertexStride;
|
||||
|
||||
// Copy stream for patching and caching.
|
||||
bNeedStreamCopy = true;
|
||||
|
@ -327,7 +320,17 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
}
|
||||
|
||||
// Now we have enough information to hash the existing resource and find it in our cache!
|
||||
DWORD xboxVertexDataSize = uiVertexCount * uiXboxVertexStride;
|
||||
// To avoid hashing and converting unused vertices, identify the "interesting" region
|
||||
// basing on the index/starting vertex data
|
||||
if (pDrawContext->pXboxIndexData != nullptr) {
|
||||
pXboxVertexData += (pDrawContext->dwBaseVertexIndex + pDrawContext->LowIndex) * uiXboxVertexStride;
|
||||
} else {
|
||||
pXboxVertexData += pDrawContext->dwStartVertex * uiXboxVertexStride;
|
||||
}
|
||||
|
||||
const UINT uiVertexCount = pDrawContext->NumVerticesToUse;
|
||||
const DWORD dwHostVertexDataSize = uiVertexCount * uiHostVertexStride;
|
||||
const DWORD xboxVertexDataSize = uiVertexCount * uiXboxVertexStride;
|
||||
uint64_t vertexDataHash = ComputeHash(pXboxVertexData, xboxVertexDataSize);
|
||||
uint64_t pVertexShaderSteamInfoHash = 0;
|
||||
|
||||
|
@ -634,9 +637,6 @@ void CxbxVertexBufferConverter::Apply(CxbxDrawContext *pDrawContext)
|
|||
|
||||
m_pCxbxVertexDeclaration = CxbxGetVertexDeclaration();
|
||||
|
||||
// If we are drawing from an offset, we know that the vertex count must have
|
||||
// 'offset' vertices before the first drawn vertices
|
||||
pDrawContext->VerticesInBuffer = pDrawContext->dwStartVertex + pDrawContext->dwVertexCount;
|
||||
// When this is an indexed draw, take the index buffer into account
|
||||
if (pDrawContext->pXboxIndexData) {
|
||||
// Is the highest index in this buffer not set yet?
|
||||
|
@ -646,11 +646,13 @@ void CxbxVertexBufferConverter::Apply(CxbxDrawContext *pDrawContext)
|
|||
LOG_TEST_CASE("HighIndex == 0"); // TODO : If this is never hit, replace entire block by assert(pDrawContext->HighIndex > 0);
|
||||
WalkIndexBuffer(pDrawContext->LowIndex, pDrawContext->HighIndex, pDrawContext->pXboxIndexData, pDrawContext->dwVertexCount);
|
||||
}
|
||||
// Convert highest index (including the base offset) into a count
|
||||
DWORD dwHighestVertexCount = pDrawContext->dwBaseVertexIndex + pDrawContext->HighIndex + 1;
|
||||
// Use the biggest vertex count that can be reached
|
||||
if (pDrawContext->VerticesInBuffer < dwHighestVertexCount)
|
||||
pDrawContext->VerticesInBuffer = dwHighestVertexCount;
|
||||
// Convert the range of indices into a count
|
||||
pDrawContext->NumVerticesToUse = pDrawContext->HighIndex - pDrawContext->LowIndex + 1;
|
||||
}
|
||||
else {
|
||||
// If we are drawing from an offset, we know that the vertex count must have
|
||||
// 'offset' vertices before the first drawn vertices
|
||||
pDrawContext->NumVerticesToUse = pDrawContext->dwVertexCount;
|
||||
}
|
||||
|
||||
// Get the number of streams
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct _CxbxDrawContext
|
|||
IN PWORD pXboxIndexData; // Set by D3DDevice_DrawIndexedVertices, D3DDevice_DrawIndexedVerticesUP and HLE_draw_inline_elements
|
||||
IN DWORD dwBaseVertexIndex; // Set to g_Xbox_BaseVertexIndex in D3DDevice_DrawIndexedVertices
|
||||
IN INDEX16 LowIndex, HighIndex; // Set when pXboxIndexData is set
|
||||
IN size_t VerticesInBuffer; // Set by CxbxVertexBufferConverter::Apply
|
||||
IN UINT NumVerticesToUse; // Set by CxbxVertexBufferConverter::Apply
|
||||
// Data if Draw...UP call
|
||||
IN PVOID pXboxVertexStreamZeroData;
|
||||
IN UINT uiXboxVertexStreamZeroStride;
|
||||
|
|
Loading…
Reference in New Issue