mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-03 23:46:08 +00:00
Use draws for alpha/stencil only clear in Vulkan.
This commit is contained in:
parent
ba7deb7c9a
commit
8efbcf8d42
@ -129,8 +129,14 @@ static bool IsReallyAClear(const TransformedVertex *transformed, int numVerts) {
|
||||
}
|
||||
|
||||
void SoftwareTransform(
|
||||
int prim, u8 *decoded, int vertexCount, u32 vertType, u16 *&inds, int indexType,
|
||||
const DecVtxFormat &decVtxFormat, int &maxIndex, FramebufferManagerCommon *fbman, TextureCacheCommon *texCache, TransformedVertex *transformed, TransformedVertex *transformedExpanded, TransformedVertex *&drawBuffer, int &numTrans, bool &drawIndexed, SoftwareTransformResult *result, float ySign) {
|
||||
int prim, int vertexCount, u32 vertType, u16 *&inds, int indexType,
|
||||
const DecVtxFormat &decVtxFormat, int &maxIndex, TransformedVertex *&drawBuffer, int &numTrans, bool &drawIndexed, const SoftwareTransformParams *params, SoftwareTransformResult *result) {
|
||||
u8 *decoded = params->decoded;
|
||||
FramebufferManagerCommon *fbman = params->fbman;
|
||||
TextureCacheCommon *texCache = params->texCache;
|
||||
TransformedVertex *transformed = params->transformed;
|
||||
TransformedVertex *transformedExpanded = params->transformedExpanded;
|
||||
float ySign = 1.0f;
|
||||
bool throughmode = (vertType & GE_VTYPE_THROUGH_MASK) != 0;
|
||||
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
|
||||
|
||||
@ -406,11 +412,14 @@ void SoftwareTransform(
|
||||
// Experiment: Disable on PowerVR (see issue #6290)
|
||||
// TODO: This bleeds outside the play area in non-buffered mode. Big deal? Probably not.
|
||||
if (maxIndex > 1 && gstate.isModeClear() && prim == GE_PRIM_RECTANGLES && IsReallyAClear(transformed, maxIndex) && gl_extensions.gpuVendor != GPU_VENDOR_POWERVR) { // && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) {
|
||||
result->color = transformed[1].color0_32;
|
||||
// Need to rescale from a [0, 1] float. This is the final transformed value.
|
||||
result->depth = ToScaledDepth((s16)(int)(transformed[1].z * 65535.0f));
|
||||
result->action = SW_CLEAR;
|
||||
return;
|
||||
bool separateAlphaClear = gstate.isClearModeColorMask() != gstate.isClearModeAlphaMask();
|
||||
if (params->allowSeparateAlphaClear || !separateAlphaClear) {
|
||||
result->color = transformed[1].color0_32;
|
||||
// Need to rescale from a [0, 1] float. This is the final transformed value.
|
||||
result->depth = ToScaledDepth((s16)(int)(transformed[1].z * 65535.0f));
|
||||
result->action = SW_CLEAR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This means we're using a framebuffer (and one that isn't big enough.)
|
||||
|
@ -38,5 +38,14 @@ struct SoftwareTransformResult {
|
||||
u8 stencilValue;
|
||||
};
|
||||
|
||||
void SoftwareTransform(int prim, u8 *decoded, int vertexCount, u32 vertexType, u16 *&inds, int indexType, const DecVtxFormat &decVtxFormat, int &maxIndex, FramebufferManagerCommon *fbman, TextureCacheCommon *texCache, TransformedVertex *transformed, TransformedVertex *transformedExpanded, TransformedVertex *&drawBuffer,
|
||||
int &numTrans, bool &drawIndexed, SoftwareTransformResult *result, float ySign);
|
||||
struct SoftwareTransformParams {
|
||||
u8 *decoded;
|
||||
TransformedVertex *transformed;
|
||||
TransformedVertex *transformedExpanded;
|
||||
FramebufferManagerCommon *fbman;
|
||||
TextureCacheCommon *texCache;
|
||||
bool allowSeparateAlphaClear;
|
||||
};
|
||||
|
||||
void SoftwareTransform(int prim, int vertexCount, u32 vertexType, u16 *&inds, int indexType, const DecVtxFormat &decVtxFormat, int &maxIndex, TransformedVertex *&drawBuffer,
|
||||
int &numTrans, bool &drawIndexed, const SoftwareTransformParams *params, SoftwareTransformResult *result);
|
||||
|
@ -828,11 +828,20 @@ rotateVBO:
|
||||
SoftwareTransformResult result;
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
SoftwareTransformParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.decoded = decoded;
|
||||
params.transformed = transformed;
|
||||
params.transformedExpanded = transformedExpanded;
|
||||
params.fbman = framebufferManager_;
|
||||
params.texCache = textureCache_;
|
||||
params.allowSeparateAlphaClear = true;
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
SoftwareTransform(
|
||||
prim, decoded, indexGen.VertexCount(),
|
||||
prim, indexGen.VertexCount(),
|
||||
dec_->VertexType(), inds, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(),
|
||||
maxIndex, framebufferManager_, textureCache_, transformed, transformedExpanded, drawBuffer, numTrans, drawIndexed, &result, 1.0f);
|
||||
maxIndex, drawBuffer, numTrans, drawIndexed, ¶ms, &result);
|
||||
|
||||
ApplyDrawStateLate();
|
||||
vshader = shaderManager_->ApplyShader(prim, lastVType_);
|
||||
|
@ -890,11 +890,21 @@ rotateVBO:
|
||||
SoftwareTransformResult result;
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
// TODO: Keep this static? Faster than repopulating?
|
||||
SoftwareTransformParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.decoded = decoded;
|
||||
params.transformed = transformed;
|
||||
params.transformedExpanded = transformedExpanded;
|
||||
params.fbman = framebufferManager_;
|
||||
params.texCache = textureCache_;
|
||||
params.allowSeparateAlphaClear = true;
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
SoftwareTransform(
|
||||
prim, decoded, indexGen.VertexCount(),
|
||||
prim, indexGen.VertexCount(),
|
||||
dec_->VertexType(), inds, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(),
|
||||
maxIndex, framebufferManager_, textureCache_, transformed, transformedExpanded, drawBuffer, numTrans, drawIndexed, &result, 1.0);
|
||||
maxIndex, drawBuffer, numTrans, drawIndexed, ¶ms, &result);
|
||||
ApplyDrawStateLate();
|
||||
|
||||
LinkedShader *program = shaderManager_->ApplyFragmentShader(vsid, vshader, lastVType_, prim);
|
||||
|
@ -591,11 +591,20 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
||||
SoftwareTransformResult result;
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
SoftwareTransformParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.decoded = decoded;
|
||||
params.transformed = transformed;
|
||||
params.transformedExpanded = transformedExpanded;
|
||||
params.fbman = framebufferManager_;
|
||||
params.texCache = textureCache_;
|
||||
params.allowSeparateAlphaClear = false;
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
SoftwareTransform(
|
||||
prim, decoded, indexGen.VertexCount(),
|
||||
prim, indexGen.VertexCount(),
|
||||
dec_->VertexType(), inds, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(),
|
||||
maxIndex, framebufferManager_, textureCache_, transformed, transformedExpanded, drawBuffer, numTrans, drawIndexed, &result, 1.0f);
|
||||
maxIndex, drawBuffer, numTrans, drawIndexed, ¶ms, &result);
|
||||
|
||||
// Only here, where we know whether to clear or to draw primitives, should we actually set the current framebuffer! Because that gives use the opportunity
|
||||
// to use a "pre-clear" render pass, for high efficiency on tilers.
|
||||
@ -657,8 +666,9 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
||||
vkCmdDraw(cmd_, numTrans, 1, 0, 0);
|
||||
}
|
||||
} else if (result.action == SW_CLEAR) {
|
||||
// TODO: Support clearing only color and not alpha, or vice versa. This is not supported (probably for good reason) by vkCmdClearColorAttachment
|
||||
// so we will have to simply draw a rectangle instead.
|
||||
// Note: we won't get here if the clear is alpha but not color, or color but not alpha.
|
||||
// A rectangle will be used instead.
|
||||
// TODO: If this is the first clear in a frame, translate to a cleared attachment load instead.
|
||||
|
||||
int mask = gstate.isClearModeColorMask() ? 1 : 0;
|
||||
if (gstate.isClearModeAlphaMask()) mask |= 2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user