Merge pull request #10115 from hrydgard/unify-spline-bezier

Unify Execute_Spline and Execute_Bezier
This commit is contained in:
Henrik Rydgård
2017-11-13 11:21:38 +01:00
committed by GitHub
11 changed files with 65 additions and 538 deletions
+2 -138
View File
@@ -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.
-2
View File
@@ -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);
+2 -105
View File
@@ -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.
-2
View File
@@ -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);
+2 -139
View File
@@ -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.
+48 -2
View File
@@ -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);
+7 -7
View File
@@ -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,
};
+1 -1
View File
@@ -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_;
+2 -139
View File
@@ -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.
-2
View File
@@ -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);
+1 -1
View File
@@ -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