Merge pull request #8441 from unknownbrackets/gpu-mpeg

Use video format when uploading directly to framebuffers
This commit is contained in:
Henrik Rydgård 2016-01-17 22:01:56 +01:00
commit c19335ff98
17 changed files with 63 additions and 6 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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?

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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;