Addressed code review remarks, by adding explanations in comments and renaming a few arguments
This commit is contained in:
parent
eb9f610780
commit
ec25283551
|
@ -161,10 +161,10 @@ static CxbxVertexBufferConverter VertexBufferConverter = {};
|
||||||
static IDirect3DIndexBuffer *g_pClosingLineLoopHostIndexBuffer = nullptr;
|
static IDirect3DIndexBuffer *g_pClosingLineLoopHostIndexBuffer = nullptr;
|
||||||
|
|
||||||
static IDirect3DIndexBuffer *g_pQuadToTriangleHostIndexBuffer = nullptr;
|
static IDirect3DIndexBuffer *g_pQuadToTriangleHostIndexBuffer = nullptr;
|
||||||
static UINT g_QuadToTriangleHostIndexBuffer_Size = 0; // = NrOfQuadVertices
|
static UINT g_QuadToTriangleHostIndexBuffer_Size = 0; // = NrOfQuadIndices
|
||||||
|
|
||||||
static INDEX16 *g_pQuadToTriangleIndexData = nullptr;
|
static INDEX16 *g_pQuadToTriangleIndexData = nullptr;
|
||||||
static UINT g_QuadToTriangleIndexData_Size = 0; // = NrOfQuadVertices
|
static UINT g_QuadToTriangleIndexData_Size = 0; // = NrOfQuadIndices
|
||||||
|
|
||||||
static IDirect3DSurface *g_DefaultHostDepthBufferSuface = NULL;
|
static IDirect3DSurface *g_DefaultHostDepthBufferSuface = NULL;
|
||||||
XTL::X_D3DSurface *g_XboxBackBufferSurface = NULL;
|
XTL::X_D3DSurface *g_XboxBackBufferSurface = NULL;
|
||||||
|
@ -2469,8 +2469,18 @@ constexpr UINT QuadToTriangleVertexCount(UINT NrOfQuadVertices)
|
||||||
bool bUseClockWiseWindingOrder = true; // TODO : Should this be fetched from X_D3DRS_FRONTFACE (or X_D3DRS_CULLMODE)?
|
bool bUseClockWiseWindingOrder = true; // TODO : Should this be fetched from X_D3DRS_FRONTFACE (or X_D3DRS_CULLMODE)?
|
||||||
|
|
||||||
// TODO : Move to own file
|
// TODO : Move to own file
|
||||||
|
// This function convertes quad to triangle indices.
|
||||||
|
// When pXboxQuadIndexData is set, original quad indices are read from this buffer
|
||||||
|
// (this use-case is for when an indexed quad draw is to be emulated).
|
||||||
|
// When pXboxQuadIndexData is null, quad-emulating indices are generated
|
||||||
|
// (this use-case is for when a non-indexed quad draw is to be emulated).
|
||||||
|
// The number of indices to generate is specified through uNrOfTriangleIndices.
|
||||||
|
// Resulting triangle indices are written to pTriangleIndexData, which must
|
||||||
|
// be pre-allocated to fit the output data.
|
||||||
|
// (Note, this function is marked 'constexpr' to allow the compiler to optimize
|
||||||
|
// the case when pXboxQuadIndexData is null)
|
||||||
constexpr void CxbxConvertQuadListToTriangleListIndices(
|
constexpr void CxbxConvertQuadListToTriangleListIndices(
|
||||||
INDEX16* pQuadIndexData,
|
INDEX16* pXboxQuadIndexData,
|
||||||
unsigned uNrOfTriangleIndices,
|
unsigned uNrOfTriangleIndices,
|
||||||
INDEX16* pTriangleIndexData)
|
INDEX16* pTriangleIndexData)
|
||||||
{
|
{
|
||||||
|
@ -2482,25 +2492,25 @@ constexpr void CxbxConvertQuadListToTriangleListIndices(
|
||||||
while (i + (VERTICES_PER_TRIANGLE * TRIANGLES_PER_QUAD) <= uNrOfTriangleIndices) {
|
while (i + (VERTICES_PER_TRIANGLE * TRIANGLES_PER_QUAD) <= uNrOfTriangleIndices) {
|
||||||
if (bUseClockWiseWindingOrder) {
|
if (bUseClockWiseWindingOrder) {
|
||||||
// ABCD becomes ABC+CDA, so this is triangle 1 :
|
// ABCD becomes ABC+CDA, so this is triangle 1 :
|
||||||
pTriangleIndexData[i + 0] = pQuadIndexData ? pQuadIndexData[j + 0] : j + 0; // A
|
pTriangleIndexData[i + 0] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 0] : j + 0; // A
|
||||||
pTriangleIndexData[i + 1] = pQuadIndexData ? pQuadIndexData[j + 1] : j + 1; // B
|
pTriangleIndexData[i + 1] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 1] : j + 1; // B
|
||||||
pTriangleIndexData[i + 2] = pQuadIndexData ? pQuadIndexData[j + 2] : j + 2; // C
|
pTriangleIndexData[i + 2] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 2] : j + 2; // C
|
||||||
i += VERTICES_PER_TRIANGLE;
|
i += VERTICES_PER_TRIANGLE;
|
||||||
// And this is triangle 2 :
|
// And this is triangle 2 :
|
||||||
pTriangleIndexData[i + 0] = pQuadIndexData ? pQuadIndexData[j + 2] : j + 2; // C
|
pTriangleIndexData[i + 0] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 2] : j + 2; // C
|
||||||
pTriangleIndexData[i + 1] = pQuadIndexData ? pQuadIndexData[j + 3] : j + 3; // D
|
pTriangleIndexData[i + 1] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 3] : j + 3; // D
|
||||||
pTriangleIndexData[i + 2] = pQuadIndexData ? pQuadIndexData[j + 0] : j + 0; // A
|
pTriangleIndexData[i + 2] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 0] : j + 0; // A
|
||||||
i += VERTICES_PER_TRIANGLE;
|
i += VERTICES_PER_TRIANGLE;
|
||||||
} else {
|
} else {
|
||||||
// ABCD becomes ADC+CBA, so this is triangle 1 :
|
// ABCD becomes ADC+CBA, so this is triangle 1 :
|
||||||
pTriangleIndexData[i + 0] = pQuadIndexData ? pQuadIndexData[j + 0] : j + 0; // A
|
pTriangleIndexData[i + 0] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 0] : j + 0; // A
|
||||||
pTriangleIndexData[i + 1] = pQuadIndexData ? pQuadIndexData[j + 3] : j + 3; // D
|
pTriangleIndexData[i + 1] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 3] : j + 3; // D
|
||||||
pTriangleIndexData[i + 2] = pQuadIndexData ? pQuadIndexData[j + 2] : j + 2; // C
|
pTriangleIndexData[i + 2] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 2] : j + 2; // C
|
||||||
i += VERTICES_PER_TRIANGLE;
|
i += VERTICES_PER_TRIANGLE;
|
||||||
// And this is triangle 2 :
|
// And this is triangle 2 :
|
||||||
pTriangleIndexData[i + 0] = pQuadIndexData ? pQuadIndexData[j + 2] : j + 2; // C
|
pTriangleIndexData[i + 0] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 2] : j + 2; // C
|
||||||
pTriangleIndexData[i + 1] = pQuadIndexData ? pQuadIndexData[j + 1] : j + 1; // B
|
pTriangleIndexData[i + 1] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 1] : j + 1; // B
|
||||||
pTriangleIndexData[i + 2] = pQuadIndexData ? pQuadIndexData[j + 0] : j + 0; // A
|
pTriangleIndexData[i + 2] = pXboxQuadIndexData ? pXboxQuadIndexData[j + 0] : j + 0; // A
|
||||||
i += VERTICES_PER_TRIANGLE;
|
i += VERTICES_PER_TRIANGLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2510,11 +2520,20 @@ constexpr void CxbxConvertQuadListToTriangleListIndices(
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : Move to own file
|
// TODO : Move to own file
|
||||||
INDEX16* CxbxCreateQuadListToTriangleListIndexData(INDEX16* pQuadIndexData, unsigned QuadVertexCount)
|
// Called from EMUPATCH(D3DDevice_DrawIndexedVerticesUP) when PrimitiveType == X_D3DPT_QUADLIST.
|
||||||
|
// This API receives the number of vertices to draw (VertexCount), the index data that references
|
||||||
|
// vertices and a single stream of vertex data. The number of vertices to draw indicates the number
|
||||||
|
// of indices that are going to be fetched. The vertex data is referenced up to the highest index
|
||||||
|
// number present in the index data.
|
||||||
|
// To emulate drawing indexed quads, g_pD3DDevice->DrawIndexedPrimitiveUP is called on host,
|
||||||
|
// whereby the quad indices are converted to triangle indices. This implies for every four
|
||||||
|
// quad indices, we have to generate (two times three is) six triangle indices. (Note, that
|
||||||
|
// vertex data undergoes it's own Xbox-to-host conversion, independent from these indices.)
|
||||||
|
INDEX16* CxbxCreateQuadListToTriangleListIndexData(INDEX16* pXboxQuadIndexData, unsigned QuadVertexCount)
|
||||||
{
|
{
|
||||||
UINT NrOfTriangleVertices = QuadToTriangleVertexCount(QuadVertexCount);
|
UINT NrOfTriangleIndices = QuadToTriangleVertexCount(QuadVertexCount);
|
||||||
INDEX16* pQuadToTriangleIndexBuffer = (INDEX16*)malloc(NrOfTriangleVertices * sizeof(INDEX16));
|
INDEX16* pQuadToTriangleIndexBuffer = (INDEX16*)malloc(NrOfTriangleIndices * sizeof(INDEX16));
|
||||||
CxbxConvertQuadListToTriangleListIndices(pQuadIndexData, NrOfTriangleVertices, pQuadToTriangleIndexBuffer);
|
CxbxConvertQuadListToTriangleListIndices(pXboxQuadIndexData, NrOfTriangleIndices, pQuadToTriangleIndexBuffer);
|
||||||
return pQuadToTriangleIndexBuffer;
|
return pQuadToTriangleIndexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6518,35 +6537,46 @@ constexpr unsigned int IndicesPerPage = PAGE_SIZE / sizeof(INDEX16);
|
||||||
constexpr unsigned int InputQuadsPerPage = ((IndicesPerPage * VERTICES_PER_QUAD) / VERTICES_PER_TRIANGLE) / TRIANGLES_PER_QUAD;
|
constexpr unsigned int InputQuadsPerPage = ((IndicesPerPage * VERTICES_PER_QUAD) / VERTICES_PER_TRIANGLE) / TRIANGLES_PER_QUAD;
|
||||||
|
|
||||||
// TODO : Move to own file
|
// TODO : Move to own file
|
||||||
INDEX16 *CxbxAssureQuadListIndexData(UINT NrOfQuadVertices)
|
// Called by CxbxDrawPrimitiveUP (indirectly by D3DDevice_DrawVerticesUP,
|
||||||
|
// EmuExecutePushBufferRaw and EmuFlushIVB) when PrimitiveType == X_D3DPT_QUADLIST.
|
||||||
|
// Emulated by calling g_pD3DDevice->DrawIndexedPrimitiveUP with index data that maps
|
||||||
|
// quads to triangles. This function creates the index buffer that is needed for this;
|
||||||
|
// For every quad that must be drawn, we generate indices for two triangles.
|
||||||
|
// Note, that the resulting index data can be re-used for later comparable draw calls
|
||||||
|
// and only needs to grow when current length doesn't suffices for a larger draw.
|
||||||
|
INDEX16 *CxbxAssureQuadListIndexData(UINT NrOfQuadIndices)
|
||||||
{
|
{
|
||||||
if (g_QuadToTriangleIndexData_Size < NrOfQuadVertices)
|
if (g_QuadToTriangleIndexData_Size < NrOfQuadIndices)
|
||||||
{
|
{
|
||||||
g_QuadToTriangleIndexData_Size = RoundUp(NrOfQuadVertices, InputQuadsPerPage);
|
g_QuadToTriangleIndexData_Size = RoundUp(NrOfQuadIndices, InputQuadsPerPage);
|
||||||
UINT NrOfTriangleVertices = QuadToTriangleVertexCount(g_QuadToTriangleIndexData_Size);
|
UINT NrOfTriangleIndices = QuadToTriangleVertexCount(g_QuadToTriangleIndexData_Size);
|
||||||
if (g_pQuadToTriangleIndexData != nullptr) {
|
if (g_pQuadToTriangleIndexData != nullptr) {
|
||||||
free(g_pQuadToTriangleIndexData);
|
free(g_pQuadToTriangleIndexData);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pQuadToTriangleIndexData = (INDEX16 *)malloc(NrOfTriangleVertices * sizeof(INDEX16));
|
g_pQuadToTriangleIndexData = (INDEX16 *)malloc(NrOfTriangleIndices * sizeof(INDEX16));
|
||||||
CxbxConvertQuadListToTriangleListIndices(nullptr, NrOfTriangleVertices, g_pQuadToTriangleIndexData);
|
CxbxConvertQuadListToTriangleListIndices(nullptr, NrOfTriangleIndices, g_pQuadToTriangleIndexData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_pQuadToTriangleIndexData;
|
return g_pQuadToTriangleIndexData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : Move to own file
|
// TODO : Move to own file
|
||||||
void CxbxAssureQuadListD3DIndexBuffer(UINT NrOfQuadVertices)
|
// Makes a D3D IndexBuffer active that contains quadlist-to-trianglelist indices.
|
||||||
|
// Uses CxbxAssureQuadListIndexData to populate the index buffer with.
|
||||||
|
// Note, that the resulting index buffer can be re-used for later comparable draw calls
|
||||||
|
// and only needs to grow when current length doesn't sufficesw for a larger draw.
|
||||||
|
void CxbxAssureQuadListD3DIndexBuffer(UINT NrOfQuadIndices)
|
||||||
{
|
{
|
||||||
LOG_INIT // Allows use of DEBUG_D3DRESULT
|
LOG_INIT // Allows use of DEBUG_D3DRESULT
|
||||||
|
|
||||||
HRESULT hRet;
|
HRESULT hRet;
|
||||||
|
|
||||||
if (g_QuadToTriangleHostIndexBuffer_Size < NrOfQuadVertices)
|
if (g_QuadToTriangleHostIndexBuffer_Size < NrOfQuadIndices)
|
||||||
{
|
{
|
||||||
// Round the number of indices up so we'll allocate whole pages
|
// Round the number of indices up so we'll allocate whole pages
|
||||||
g_QuadToTriangleHostIndexBuffer_Size = RoundUp(NrOfQuadVertices, InputQuadsPerPage);
|
g_QuadToTriangleHostIndexBuffer_Size = RoundUp(NrOfQuadIndices, InputQuadsPerPage);
|
||||||
UINT NrOfTriangleVertices = QuadToTriangleVertexCount(g_QuadToTriangleHostIndexBuffer_Size); // 4 > 6
|
UINT NrOfTriangleIndices = QuadToTriangleVertexCount(g_QuadToTriangleHostIndexBuffer_Size); // 4 > 6
|
||||||
|
|
||||||
// Create a new native index buffer of the above determined size :
|
// Create a new native index buffer of the above determined size :
|
||||||
if (g_pQuadToTriangleHostIndexBuffer != nullptr) {
|
if (g_pQuadToTriangleHostIndexBuffer != nullptr) {
|
||||||
|
@ -6555,7 +6585,7 @@ void CxbxAssureQuadListD3DIndexBuffer(UINT NrOfQuadVertices)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new native index buffer of the above determined size :
|
// Create a new native index buffer of the above determined size :
|
||||||
g_pQuadToTriangleHostIndexBuffer = CxbxCreateIndexBuffer(NrOfTriangleVertices);
|
g_pQuadToTriangleHostIndexBuffer = CxbxCreateIndexBuffer(NrOfTriangleIndices);
|
||||||
if (g_pQuadToTriangleHostIndexBuffer == nullptr)
|
if (g_pQuadToTriangleHostIndexBuffer == nullptr)
|
||||||
CxbxKrnlCleanup("CxbxAssureQuadListD3DIndexBuffer : IndexBuffer Create Failed!");
|
CxbxKrnlCleanup("CxbxAssureQuadListD3DIndexBuffer : IndexBuffer Create Failed!");
|
||||||
|
|
||||||
|
@ -6566,7 +6596,7 @@ void CxbxAssureQuadListD3DIndexBuffer(UINT NrOfQuadVertices)
|
||||||
if (pHostIndexBufferData == nullptr)
|
if (pHostIndexBufferData == nullptr)
|
||||||
CxbxKrnlCleanup("CxbxAssureQuadListD3DIndexBuffer : Could not lock index buffer!");
|
CxbxKrnlCleanup("CxbxAssureQuadListD3DIndexBuffer : Could not lock index buffer!");
|
||||||
|
|
||||||
CxbxConvertQuadListToTriangleListIndices(nullptr, NrOfTriangleVertices, pHostIndexBufferData);
|
memcpy(pHostIndexBufferData, CxbxAssureQuadListIndexData(NrOfTriangleIndices), NrOfTriangleIndices * sizeof(INDEX16));
|
||||||
|
|
||||||
g_pQuadToTriangleHostIndexBuffer->Unlock();
|
g_pQuadToTriangleHostIndexBuffer->Unlock();
|
||||||
}
|
}
|
||||||
|
@ -6610,7 +6640,7 @@ void CxbxDrawIndexedClosingLine(INDEX16 LowIndex, INDEX16 HighIndex)
|
||||||
hRet = g_pD3DDevice->DrawIndexedPrimitive(
|
hRet = g_pD3DDevice->DrawIndexedPrimitive(
|
||||||
/*PrimitiveType=*/D3DPT_LINELIST,
|
/*PrimitiveType=*/D3DPT_LINELIST,
|
||||||
/*BaseVertexIndex=*/0, // Note : Callers must apply BaseVertexIndex to the LowIndex and HighIndex argument values
|
/*BaseVertexIndex=*/0, // Note : Callers must apply BaseVertexIndex to the LowIndex and HighIndex argument values
|
||||||
/*MinVertrexIndex=*/LowIndex,
|
/*MinVertexIndex=*/LowIndex,
|
||||||
/*NumVertices=*/VERTICES_PER_LINE,
|
/*NumVertices=*/VERTICES_PER_LINE,
|
||||||
/*startIndex=*/0,
|
/*startIndex=*/0,
|
||||||
/*primCount=*/1
|
/*primCount=*/1
|
||||||
|
@ -6990,7 +7020,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DrawVertices)
|
||||||
|
|
||||||
// Draw quadlists using a single 'quad-to-triangle mapping' index buffer :
|
// Draw quadlists using a single 'quad-to-triangle mapping' index buffer :
|
||||||
// Assure & activate that special index buffer :
|
// Assure & activate that special index buffer :
|
||||||
CxbxAssureQuadListD3DIndexBuffer(/*NrOfQuadVertices=*/DrawContext.dwVertexCount);
|
CxbxAssureQuadListD3DIndexBuffer(/*NrOfQuadIndices=*/DrawContext.dwVertexCount);
|
||||||
// Convert quad vertex-count & start to triangle vertex count & start :
|
// Convert quad vertex-count & start to triangle vertex count & start :
|
||||||
UINT startIndex = QuadToTriangleVertexCount(DrawContext.dwStartVertex);
|
UINT startIndex = QuadToTriangleVertexCount(DrawContext.dwStartVertex);
|
||||||
UINT primCount = DrawContext.dwHostPrimitiveCount * TRIANGLES_PER_QUAD;
|
UINT primCount = DrawContext.dwHostPrimitiveCount * TRIANGLES_PER_QUAD;
|
||||||
|
|
|
@ -767,8 +767,9 @@ void CxbxVertexBufferConverter::Apply(CxbxDrawContext *pDrawContext)
|
||||||
// If we are drawing from an offset, we know that the vertex count must have
|
// If we are drawing from an offset, we know that the vertex count must have
|
||||||
// 'offset' vertices before the first drawn vertices
|
// 'offset' vertices before the first drawn vertices
|
||||||
pDrawContext->VerticesInBuffer = pDrawContext->dwStartVertex + pDrawContext->dwVertexCount;
|
pDrawContext->VerticesInBuffer = pDrawContext->dwStartVertex + pDrawContext->dwVertexCount;
|
||||||
// Whhen this is an indexed draw, take the index buffer into account
|
// When this is an indexed draw, take the index buffer into account
|
||||||
if (pDrawContext->pXboxIndexData) {
|
if (pDrawContext->pXboxIndexData) {
|
||||||
|
// Is the highest index in this buffer not set yet?
|
||||||
if (pDrawContext->HighIndex == 0) {
|
if (pDrawContext->HighIndex == 0) {
|
||||||
// TODO : Instead of calling WalkIndexBuffer here, set LowIndex and HighIndex
|
// TODO : Instead of calling WalkIndexBuffer here, set LowIndex and HighIndex
|
||||||
// in all callers that end up here (since they might be able to avoid the call)
|
// in all callers that end up here (since they might be able to avoid the call)
|
||||||
|
|
Loading…
Reference in New Issue