mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-24 14:00:03 +00:00
Merge pull request #8441 from unknownbrackets/gpu-mpeg
Use video format when uploading directly to framebuffers
This commit is contained in:
commit
c19335ff98
@ -1094,7 +1094,7 @@ static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr
|
||||
// playing all pmp_queue frames
|
||||
ctx->mediaengine->m_pFrameRGB = pmp_queue.front();
|
||||
int bufferSize = ctx->mediaengine->writeVideoImage(buffer, frameWidth, ctx->videoPixelMode);
|
||||
gpu->InvalidateCache(buffer, bufferSize, GPU_INVALIDATE_SAFE);
|
||||
gpu->NotifyVideoUpload(buffer, bufferSize, frameWidth, ctx->videoPixelMode);
|
||||
ctx->avc.avcFrameStatus = 1;
|
||||
ctx->videoFrameCount++;
|
||||
|
||||
@ -1105,7 +1105,7 @@ static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr
|
||||
}
|
||||
else if(ctx->mediaengine->stepVideo(ctx->videoPixelMode)) {
|
||||
int bufferSize = ctx->mediaengine->writeVideoImage(buffer, frameWidth, ctx->videoPixelMode);
|
||||
gpu->InvalidateCache(buffer, bufferSize, GPU_INVALIDATE_SAFE);
|
||||
gpu->NotifyVideoUpload(buffer, bufferSize, frameWidth, ctx->videoPixelMode);
|
||||
ctx->avc.avcFrameStatus = 1;
|
||||
ctx->videoFrameCount++;
|
||||
} else {
|
||||
@ -1872,7 +1872,8 @@ static u32 sceMpegAvcCsc(u32 mpeg, u32 sourceAddr, u32 rangeAddr, int frameWidth
|
||||
int height = Memory::Read_U32(rangeAddr + 12);
|
||||
int destSize = ctx->mediaengine->writeVideoImageWithRange(destAddr, frameWidth, ctx->videoPixelMode, x, y, width, height);
|
||||
|
||||
gpu->InvalidateCache(destAddr, destSize, GPU_INVALIDATE_SAFE);
|
||||
gpu->NotifyVideoUpload(destAddr, destSize, frameWidth, ctx->videoPixelMode);
|
||||
|
||||
// Do not use avcDecodeDelayMs 's value
|
||||
// Will cause video 's screen dislocation in Bleach heat of soul 6
|
||||
// https://github.com/hrydgard/ppsspp/issues/5535
|
||||
|
@ -1540,7 +1540,7 @@ static int scePsmfPlayerGetVideoData(u32 psmfPlayer, u32 videoDataAddr)
|
||||
int bufw = videoData->frameWidth == 0 ? 512 : videoData->frameWidth & ~1;
|
||||
// Always write the video frame, even after the video has ended.
|
||||
int displaybufSize = psmfplayer->mediaengine->writeVideoImage(videoData->displaybuf, bufw, videoPixelMode);
|
||||
gpu->InvalidateCache(videoData->displaybuf, displaybufSize, GPU_INVALIDATE_SAFE);
|
||||
gpu->NotifyVideoUpload(videoData->displaybuf, displaybufSize, bufw, videoPixelMode);
|
||||
__PsmfUpdatePts(psmfplayer, videoData);
|
||||
|
||||
_PsmfPlayerFillRingbuffer(psmfplayer);
|
||||
|
@ -799,7 +799,8 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
|
||||
delete [] imgbuf;
|
||||
}
|
||||
|
||||
return videoImageSize;
|
||||
// Account for the y offset as well.
|
||||
return videoImageSize + videoLineSize * ypos;
|
||||
#endif // USE_FFMPEG
|
||||
return 0;
|
||||
}
|
||||
|
@ -487,6 +487,26 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
||||
return vfb;
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt) {
|
||||
// Note: UpdateFromMemory() is still called later.
|
||||
// This is a special case where we have extra information prior to the invalidation.
|
||||
|
||||
// TODO: Could possibly be an offset...
|
||||
VirtualFramebuffer *vfb = GetVFBAt(addr);
|
||||
if (vfb) {
|
||||
if (vfb->format != fmt || vfb->drawnFormat != fmt) {
|
||||
DEBUG_LOG(ME, "Changing format for %08x from %d to %d", addr, vfb->drawnFormat, fmt);
|
||||
vfb->format = fmt;
|
||||
vfb->drawnFormat = fmt;
|
||||
|
||||
// Let's count this as a "render". This will also force us to use the correct format.
|
||||
vfb->last_frame_render = gpuStats.numFlips;
|
||||
}
|
||||
|
||||
// TODO: Check width?
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) {
|
||||
addr &= ~0x40000000;
|
||||
// TODO: Could go through all FBOs, but probably not important?
|
||||
|
@ -160,6 +160,7 @@ public:
|
||||
virtual void RebindFramebuffer() = 0;
|
||||
|
||||
bool NotifyFramebufferCopy(u32 src, u32 dest, int size, bool isMemset, u32 skipDrawReason);
|
||||
void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt);
|
||||
void UpdateFromMemory(u32 addr, int size, bool safe);
|
||||
virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) = 0;
|
||||
// Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it.
|
||||
|
@ -862,6 +862,9 @@ namespace DX9 {
|
||||
int w = std::min(pixels % vfb->fb_stride, (int)vfb->width);
|
||||
int h = std::min((pixels + vfb->fb_stride - 1) / vfb->fb_stride, (int)vfb->height);
|
||||
|
||||
// We might still have a pending draw to the fb in question, flush if so.
|
||||
FlushBeforeCopy();
|
||||
|
||||
// No need to download if we already have it.
|
||||
if (!vfb->memoryUpdated && vfb->clutUpdatedBytes < loadBytes) {
|
||||
// We intentionally don't call OptimizeDownloadRange() here - we don't want to over download.
|
||||
|
@ -1952,6 +1952,13 @@ void DIRECTX9_GPU::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationTy
|
||||
}
|
||||
}
|
||||
|
||||
void DIRECTX9_GPU::NotifyVideoUpload(u32 addr, int size, int width, int format) {
|
||||
if (Memory::IsVRAMAddress(addr)) {
|
||||
framebufferManager_.NotifyVideoUpload(addr, size, width, (GEBufferFormat)format);
|
||||
}
|
||||
InvalidateCache(addr, size, GPU_INVALIDATE_SAFE);
|
||||
}
|
||||
|
||||
void DIRECTX9_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||
// We use a little hack for Download/Upload using a VRAM mirror.
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
void BeginFrame() override;
|
||||
void UpdateStats() override;
|
||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override;
|
||||
void NotifyVideoUpload(u32 addr, int size, int width, int format) override;
|
||||
bool PerformMemoryCopy(u32 dest, u32 src, int size) override;
|
||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||
bool PerformMemoryDownload(u32 dest, int size) override;
|
||||
|
@ -1173,6 +1173,9 @@ void FramebufferManager::DownloadFramebufferForClut(u32 fb_address, u32 loadByte
|
||||
int w = std::min(pixels % vfb->fb_stride, (int)vfb->width);
|
||||
int h = std::min((pixels + vfb->fb_stride - 1) / vfb->fb_stride, (int)vfb->height);
|
||||
|
||||
// We might still have a pending draw to the fb in question, flush if so.
|
||||
FlushBeforeCopy();
|
||||
|
||||
// No need to download if we already have it.
|
||||
if (!vfb->memoryUpdated && vfb->clutUpdatedBytes < loadBytes) {
|
||||
// We intentionally don't call OptimizeDownloadRange() here - we don't want to over download.
|
||||
|
@ -2201,6 +2201,13 @@ void GLES_GPU::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType t
|
||||
}
|
||||
}
|
||||
|
||||
void GLES_GPU::NotifyVideoUpload(u32 addr, int size, int width, int format) {
|
||||
if (Memory::IsVRAMAddress(addr)) {
|
||||
framebufferManager_.NotifyVideoUpload(addr, size, width, (GEBufferFormat)format);
|
||||
}
|
||||
InvalidateCache(addr, size, GPU_INVALIDATE_SAFE);
|
||||
}
|
||||
|
||||
void GLES_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||
// We use a little hack for Download/Upload using a VRAM mirror.
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
void BeginFrame() override;
|
||||
void UpdateStats() override;
|
||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override;
|
||||
void NotifyVideoUpload(u32 addr, int size, int width, int format) override;
|
||||
bool PerformMemoryCopy(u32 dest, u32 src, int size) override;
|
||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||
bool PerformMemoryDownload(u32 dest, int size) override;
|
||||
|
@ -253,6 +253,7 @@ public:
|
||||
// Invalidate any cached content sourced from the specified range.
|
||||
// If size = -1, invalidate everything.
|
||||
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type) = 0;
|
||||
virtual void NotifyVideoUpload(u32 addr, int size, int width, int format) = 0;
|
||||
// Update either RAM from VRAM, or VRAM from RAM... or even VRAM from VRAM.
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size) = 0;
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size) = 0;
|
||||
|
@ -687,6 +687,10 @@ void NullGPU::InvalidateCache(u32 addr, int size, GPUInvalidationType type) {
|
||||
// Nothing to invalidate.
|
||||
}
|
||||
|
||||
void NullGPU::NotifyVideoUpload(u32 addr, int size, int width, int format) {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
bool NullGPU::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
// Nothing to update.
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
void CopyDisplayToOutput() override {}
|
||||
void UpdateStats() override;
|
||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override;
|
||||
void NotifyVideoUpload(u32 addr, int size, int width, int format) override;
|
||||
bool PerformMemoryCopy(u32 dest, u32 src, int size) override;
|
||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||
bool PerformMemoryDownload(u32 dest, int size) override;
|
||||
|
@ -873,6 +873,11 @@ void SoftGPU::InvalidateCache(u32 addr, int size, GPUInvalidationType type)
|
||||
// Nothing to invalidate.
|
||||
}
|
||||
|
||||
void SoftGPU::NotifyVideoUpload(u32 addr, int size, int width, int format)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
bool SoftGPU::PerformMemoryCopy(u32 dest, u32 src, int size)
|
||||
{
|
||||
// Nothing to update.
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
void CopyDisplayToOutput() override;
|
||||
void UpdateStats() override;
|
||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override;
|
||||
void NotifyVideoUpload(u32 addr, int size, int width, int format) override;
|
||||
bool PerformMemoryCopy(u32 dest, u32 src, int size) override;
|
||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||
bool PerformMemoryDownload(u32 dest, int size) override;
|
||||
|
@ -55,7 +55,7 @@ extern PFNGLDRAWTEXTURENVPROC glDrawTextureNV;
|
||||
typedef void (EGLAPIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (
|
||||
GLint srcX0, GLint srcY0, GLint srcX1, GLuint srcY1,
|
||||
GLint dstX0, GLint dstY0, GLint dstX1, GLuint dstY1,
|
||||
GLint mask, GLenum filter);
|
||||
GLbitfield mask, GLenum filter);
|
||||
#endif
|
||||
extern PFNGLBLITFRAMEBUFFERNVPROC glBlitFramebufferNV;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user