diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 3c402a2025..5ca54d603e 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -84,8 +84,8 @@ static const D3D11CommandTableEntry commandTable[] = { { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_D3D11::Execute_VertexType }, { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Prim }, - { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Bezier }, - { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Spline }, + { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, + { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_LoadClut }, @@ -547,142 +547,6 @@ void GPU_D3D11::Execute_Prim(u32 op, u32 diff) { AdvanceVerts(vertexType, count, bytesRead); } -void GPU_D3D11::Execute_Bezier(u32 op, u32 diff) { - Flush(); - - // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - - // This also make skipping drawing very effective. - framebufferManagerD3D11_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - // TODO: Should this eat some cycles? Probably yes. Not sure if important. - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - - if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { - DEBUG_LOG_REPORT(G3D, "Bezier + morph: %i", (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT); - } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Bezier + skinning: %i", vertTypeGetNumBoneWeights(gstate.vertType)); - } - - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); - - int bz_ucount = op & 0xFF; - int bz_vcount = (op >> 8) & 0xFF; - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - - if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) { - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.bezier = true; - if (gstate_c.spline_count_u != bz_ucount) { - gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_count_u = bz_ucount; - } - } - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead); - - if (gstate_c.bezier) - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.bezier = false; - - // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = bz_ucount * bz_vcount; - AdvanceVerts(gstate.vertType, count, bytesRead); -} - -void GPU_D3D11::Execute_Spline(u32 op, u32 diff) { - Flush(); - - // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - - // This also make skipping drawing very effective. - framebufferManagerD3D11_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - // TODO: Should this eat some cycles? Probably yes. Not sure if important. - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - - if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { - DEBUG_LOG_REPORT(G3D, "Spline + morph: %i", (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT); - } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Spline + skinning: %i", vertTypeGetNumBoneWeights(gstate.vertType)); - } - - int sp_ucount = op & 0xFF; - int sp_vcount = (op >> 8) & 0xFF; - int sp_utype = (op >> 16) & 0x3; - int sp_vtype = (op >> 18) & 0x3; - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_SPLINE, PatchPrimToPrim(patchPrim)); - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - u32 vertType = gstate.vertType; - - if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) { - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.spline = true; - bool countsChanged = gstate_c.spline_count_u != sp_ucount || gstate_c.spline_count_v != sp_vcount; - bool typesChanged = gstate_c.spline_type_u != sp_utype || gstate_c.spline_type_v != sp_vtype; - if (countsChanged || typesChanged) { - gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_count_u = sp_ucount; - gstate_c.spline_count_v = sp_vcount; - gstate_c.spline_type_u = sp_utype; - gstate_c.spline_type_v = sp_vtype; - } - } - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType, &bytesRead); - - if (gstate_c.spline) - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.spline = false; - - // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = sp_ucount * sp_vcount; - AdvanceVerts(gstate.vertType, count, bytesRead); -} - void GPU_D3D11::Execute_TexSize0(u32 op, u32 diff) { // Render to texture may have overridden the width/height. // Don't reset it unless the size is different / the texture has changed. diff --git a/GPU/D3D11/GPU_D3D11.h b/GPU/D3D11/GPU_D3D11.h index a528d41169..ecf36491ac 100644 --- a/GPU/D3D11/GPU_D3D11.h +++ b/GPU/D3D11/GPU_D3D11.h @@ -68,8 +68,6 @@ public: }; void Execute_Prim(u32 op, u32 diff); - void Execute_Bezier(u32 op, u32 diff); - void Execute_Spline(u32 op, u32 diff); void Execute_VertexType(u32 op, u32 diff); void Execute_VertexTypeSkinning(u32 op, u32 diff); void Execute_TexSize0(u32 op, u32 diff); diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index bc85e33e0f..9d47ba66cc 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -68,8 +68,8 @@ static const D3D9CommandTableEntry commandTable[] = { { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_DX9::Execute_VertexType }, { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_DX9::Execute_Prim }, - { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_Bezier }, - { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_Spline }, + { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, + { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_LoadClut }, @@ -511,109 +511,6 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) { AdvanceVerts(vertexType, count, bytesRead); } -void GPU_DX9::Execute_Bezier(u32 op, u32 diff) { - Flush(); - - // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - - // This also make skipping drawing very effective. - framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - // TODO: Should this eat some cycles? Probably yes. Not sure if important. - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - - if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { - DEBUG_LOG_REPORT(G3D, "Bezier + morph: %i", (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT); - } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Bezier + skinning: %i", vertTypeGetNumBoneWeights(gstate.vertType)); - } - - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); - int bz_ucount = op & 0xFF; - int bz_vcount = (op >> 8) & 0xFF; - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead); - - // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = bz_ucount * bz_vcount; - AdvanceVerts(gstate.vertType, count, bytesRead); -} - -void GPU_DX9::Execute_Spline(u32 op, u32 diff) { - Flush(); - - // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - - // This also make skipping drawing very effective. - framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - // TODO: Should this eat some cycles? Probably yes. Not sure if important. - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - - if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { - DEBUG_LOG_REPORT(G3D, "Spline + morph: %i", (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT); - } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Spline + skinning: %i", vertTypeGetNumBoneWeights(gstate.vertType)); - } - - int sp_ucount = op & 0xFF; - int sp_vcount = (op >> 8) & 0xFF; - int sp_utype = (op >> 16) & 0x3; - int sp_vtype = (op >> 18) & 0x3; - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_SPLINE, PatchPrimToPrim(patchPrim)); - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - u32 vertType = gstate.vertType; - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType, &bytesRead); - - // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = sp_ucount * sp_vcount; - AdvanceVerts(gstate.vertType, count, bytesRead); -} - void GPU_DX9::Execute_TexSize0(u32 op, u32 diff) { // Render to texture may have overridden the width/height. // Don't reset it unless the size is different / the texture has changed. diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h index 2f15d48197..33753a59b6 100644 --- a/GPU/Directx9/GPU_DX9.h +++ b/GPU/Directx9/GPU_DX9.h @@ -69,8 +69,6 @@ public: }; void Execute_Prim(u32 op, u32 diff); - void Execute_Bezier(u32 op, u32 diff); - void Execute_Spline(u32 op, u32 diff); void Execute_VertexType(u32 op, u32 diff); void Execute_VertexTypeSkinning(u32 op, u32 diff); void Execute_TexSize0(u32 op, u32 diff); diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 781f4c5cd7..64ae717b63 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -71,8 +71,8 @@ static const GLESCommandTableEntry commandTable[] = { { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_GLES::Execute_VertexType }, { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_GLES::Execute_Prim }, - { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_Bezier }, - { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_Spline }, + { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, + { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_LoadClut }, @@ -719,143 +719,6 @@ void GPU_GLES::Execute_VertexTypeSkinning(u32 op, u32 diff) { gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE); } -void GPU_GLES::Execute_Bezier(u32 op, u32 diff) { - Flush(); - - // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - - // This also make skipping drawing very effective. - framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - // TODO: Should this eat some cycles? Probably yes. Not sure if important. - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - - if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { - DEBUG_LOG_REPORT(G3D, "Bezier + morph: %i", (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT); - } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Bezier + skinning: %i", vertTypeGetNumBoneWeights(gstate.vertType)); - } - - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); - - int bz_ucount = op & 0xFF; - int bz_vcount = (op >> 8) & 0xFF; - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - - if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) { - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.bezier = true; - if (gstate_c.spline_count_u != bz_ucount) { - gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_count_u = bz_ucount; - } - } - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead); - - if (gstate_c.bezier) - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.bezier = false; - - // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = bz_ucount * bz_vcount; - AdvanceVerts(gstate.vertType, count, bytesRead); -} - -void GPU_GLES::Execute_Spline(u32 op, u32 diff) { - Flush(); - - // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - - // This also make skipping drawing very effective. - framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - // TODO: Should this eat some cycles? Probably yes. Not sure if important. - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - - if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { - DEBUG_LOG_REPORT(G3D, "Spline + morph: %i", (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT); - } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Spline + skinning: %i", vertTypeGetNumBoneWeights(gstate.vertType)); - } - - int sp_ucount = op & 0xFF; - int sp_vcount = (op >> 8) & 0xFF; - int sp_utype = (op >> 16) & 0x3; - int sp_vtype = (op >> 18) & 0x3; - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_SPLINE, PatchPrimToPrim(patchPrim)); - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - u32 vertType = gstate.vertType; - - if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) { - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.spline = true; - bool countsChanged = gstate_c.spline_count_u != sp_ucount || gstate_c.spline_count_v != sp_vcount; - bool typesChanged = gstate_c.spline_type_u != sp_utype || gstate_c.spline_type_v != sp_vtype; - if (countsChanged || typesChanged) { - gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_count_u = sp_ucount; - gstate_c.spline_count_v = sp_vcount; - gstate_c.spline_type_u = sp_utype; - gstate_c.spline_type_v = sp_vtype; - } - } - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType, &bytesRead); - - if (gstate_c.spline) - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.spline = false; - - // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = sp_ucount * sp_vcount; - AdvanceVerts(gstate.vertType, count, bytesRead); -} - void GPU_GLES::Execute_TexSize0(u32 op, u32 diff) { // Render to texture may have overridden the width/height. // Don't reset it unless the size is different / the texture has changed. diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 347b331244..d95a1a6a67 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1324,7 +1324,11 @@ void GPUCommon::Execute_TexLevel(u32 op, u32 diff) { } void GPUCommon::Execute_Bezier(u32 op, u32 diff) { - Flush(); + drawEngineCommon_->DispatchFlush(); + + // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. + gstate_c.Dirty(DIRTY_UVSCALEOFFSET); + // This also make skipping drawing very effective. framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { @@ -1355,20 +1359,41 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) { } GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); + SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); + int bz_ucount = op & 0xFF; int bz_vcount = (op >> 8) & 0xFF; bool computeNormals = gstate.isLightingEnabled(); bool patchFacing = gstate.patchfacing & 1; + + if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) { + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); + gstate_c.bezier = true; + if (gstate_c.spline_count_u != bz_ucount) { + gstate_c.Dirty(DIRTY_BEZIERSPLINE); + gstate_c.spline_count_u = bz_ucount; + } + } + int bytesRead = 0; + UpdateUVScaleOffset(); drawEngineCommon_->SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead); + if (gstate_c.bezier) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); + gstate_c.bezier = false; + // After drawing, we advance pointers - see SubmitPrim which does the same. int count = bz_ucount * bz_vcount; AdvanceVerts(gstate.vertType, count, bytesRead); } void GPUCommon::Execute_Spline(u32 op, u32 diff) { - Flush(); + drawEngineCommon_->DispatchFlush(); + + // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. + gstate_c.Dirty(DIRTY_UVSCALEOFFSET); + // This also make skipping drawing very effective. framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { @@ -1403,12 +1428,33 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) { int sp_utype = (op >> 16) & 0x3; int sp_vtype = (op >> 18) & 0x3; GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); + SetDrawType(DRAW_SPLINE, PatchPrimToPrim(patchPrim)); bool computeNormals = gstate.isLightingEnabled(); bool patchFacing = gstate.patchfacing & 1; u32 vertType = gstate.vertType; + + if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) { + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); + gstate_c.spline = true; + bool countsChanged = gstate_c.spline_count_u != sp_ucount || gstate_c.spline_count_v != sp_vcount; + bool typesChanged = gstate_c.spline_type_u != sp_utype || gstate_c.spline_type_v != sp_vtype; + if (countsChanged || typesChanged) { + gstate_c.Dirty(DIRTY_BEZIERSPLINE); + gstate_c.spline_count_u = sp_ucount; + gstate_c.spline_count_v = sp_vcount; + gstate_c.spline_type_u = sp_utype; + gstate_c.spline_type_v = sp_vtype; + } + } + int bytesRead = 0; + UpdateUVScaleOffset(); drawEngineCommon_->SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType, &bytesRead); + if (gstate_c.spline) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); + gstate_c.spline = false; + // After drawing, we advance pointers - see SubmitPrim which does the same. int count = sp_ucount * sp_vcount; AdvanceVerts(gstate.vertType, count, bytesRead); diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index de25539f92..7682e84e21 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -502,7 +502,7 @@ void DrawEngineVulkan::SetLineWidth(float lineWidth) { pipelineManager_->SetLineWidth(lineWidth); } -VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone) { +VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone, bool tess) { DescriptorSetKey key; key.imageView_ = imageView; key.sampler_ = sampler; @@ -514,8 +514,6 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView _dbg_assert_(G3D, light != VK_NULL_HANDLE); _dbg_assert_(G3D, bone != VK_NULL_HANDLE); - bool tess = gstate_c.bezier || gstate_c.spline; - FrameData *frame = &frame_[vulkan_->GetCurFrame()]; // See if we already have this descriptor set cached. if (!tess) { // Don't cache descriptors for HW tessellation. @@ -627,7 +625,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView vkUpdateDescriptorSets(vulkan_->GetDevice(), n, writes, 0, nullptr); - if (!(gstate_c.bezier || gstate_c.spline)) // Avoid caching when HW tessellation. + if (!tess) // Again, avoid caching when HW tessellation. frame->descSets.Insert(key, desc); return desc; } @@ -667,6 +665,8 @@ void DrawEngineVulkan::DoFlush() { FrameData *frame = &frame_[vulkan_->GetCurFrame()]; + bool tess = gstate_c.bezier || gstate_c.spline; + bool textureNeedsApply = false; if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { textureCache_->SetTexture(); @@ -908,7 +908,7 @@ void DrawEngineVulkan::DoFlush() { dirtyUniforms_ |= shaderManager_->UpdateUniforms(); UpdateUBOs(frame); - VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, boneBuf); + VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, boneBuf, tess); { PROFILE_THIS_SCOPE("renderman_q"); @@ -921,7 +921,7 @@ void DrawEngineVulkan::DoFlush() { if (useElements) { if (!ibuf) ibOffset = (uint32_t)frame->pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &ibuf); - int numInstances = (gstate_c.bezier || gstate_c.spline) ? numPatches : 1; + int numInstances = tess ? numPatches : 1; renderManager->DrawIndexed(pipelineLayout_, ds, 3, dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, numInstances, VK_INDEX_TYPE_UINT16); } else { renderManager->Draw(pipelineLayout_, ds, 3, dynamicUBOOffsets, vbuf, vbOffset, vertexCount); @@ -1008,7 +1008,7 @@ void DrawEngineVulkan::DoFlush() { // Even if the first draw is through-mode, make sure we at least have one copy of these uniforms buffered UpdateUBOs(frame); - VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, boneBuf); + VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, boneBuf, tess); const uint32_t dynamicUBOOffsets[3] = { baseUBOOffset, lightUBOOffset, boneUBOOffset, }; diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 8c0bcff4c4..e00a4b37ef 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -193,7 +193,7 @@ private: void DoFlush(); void UpdateUBOs(FrameData *frame); - VkDescriptorSet GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone); + VkDescriptorSet GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone, bool tess); VulkanContext *vulkan_; Draw::DrawContext *draw_; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 1aba78d76f..75e7faac1a 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -66,8 +66,8 @@ static const VulkanCommandTableEntry commandTable[] = { { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_Vulkan::Execute_VertexType }, { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Prim }, - { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Bezier }, - { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Spline }, + { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, + { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_LoadClut }, @@ -586,143 +586,6 @@ void GPU_Vulkan::Execute_VertexTypeSkinning(u32 op, u32 diff) { gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE); } -void GPU_Vulkan::Execute_Bezier(u32 op, u32 diff) { - Flush(); - - // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - - // This also make skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - // TODO: Should this eat some cycles? Probably yes. Not sure if important. - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - - if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { - DEBUG_LOG_REPORT(G3D, "Bezier + morph: %i", (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT); - } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Bezier + skinning: %i", vertTypeGetNumBoneWeights(gstate.vertType)); - } - - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); - - int bz_ucount = op & 0xFF; - int bz_vcount = (op >> 8) & 0xFF; - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - - if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) { - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.bezier = true; - if (gstate_c.spline_count_u != bz_ucount) { - gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_count_u = bz_ucount; - } - } - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead); - - if (gstate_c.bezier) - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.bezier = false; - - // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = bz_ucount * bz_vcount; - AdvanceVerts(gstate.vertType, count, bytesRead); -} - -void GPU_Vulkan::Execute_Spline(u32 op, u32 diff) { - Flush(); - - // We don't dirty on normal changes anymore as we prescale, but it's needed for splines/bezier. - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - - // This also make skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - // TODO: Should this eat some cycles? Probably yes. Not sure if important. - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *indices = NULL; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - - if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { - DEBUG_LOG_REPORT(G3D, "Spline + morph: %i", (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT); - } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Spline + skinning: %i", vertTypeGetNumBoneWeights(gstate.vertType)); - } - - int sp_ucount = op & 0xFF; - int sp_vcount = (op >> 8) & 0xFF; - int sp_utype = (op >> 16) & 0x3; - int sp_vtype = (op >> 18) & 0x3; - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_SPLINE, PatchPrimToPrim(patchPrim)); - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - u32 vertType = gstate.vertType; - - if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) { - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.spline = true; - bool countsChanged = gstate_c.spline_count_u != sp_ucount || gstate_c.spline_count_v != sp_vcount; - bool typesChanged = gstate_c.spline_type_u != sp_utype || gstate_c.spline_type_v != sp_vtype; - if (countsChanged || typesChanged) { - gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_count_u = sp_ucount; - gstate_c.spline_count_v = sp_vcount; - gstate_c.spline_type_u = sp_utype; - gstate_c.spline_type_v = sp_vtype; - } - } - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType, &bytesRead); - - if (gstate_c.spline) - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - gstate_c.spline = false; - - // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = sp_ucount * sp_vcount; - AdvanceVerts(gstate.vertType, count, bytesRead); -} - void GPU_Vulkan::Execute_TexSize0(u32 op, u32 diff) { // Render to texture may have overridden the width/height. // Don't reset it unless the size is different / the texture has changed. diff --git a/GPU/Vulkan/GPU_Vulkan.h b/GPU/Vulkan/GPU_Vulkan.h index d94c4ee768..962f6601a0 100644 --- a/GPU/Vulkan/GPU_Vulkan.h +++ b/GPU/Vulkan/GPU_Vulkan.h @@ -72,8 +72,6 @@ public: }; void Execute_Prim(u32 op, u32 diff); - void Execute_Bezier(u32 op, u32 diff); - void Execute_Spline(u32 op, u32 diff); void Execute_VertexType(u32 op, u32 diff); void Execute_VertexTypeSkinning(u32 op, u32 diff); void Execute_TexSize0(u32 op, u32 diff); diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 4f265e8f81..d578ac7335 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -11,7 +11,7 @@ #define VLOG(...) #endif -// TODO: Using a thread here is unfinished and does not work correctly. +// This works great. Not much reason to disable so let's not even bother with an option. const bool useThread = true; #ifndef UINT64_MAX