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
|
// playing all pmp_queue frames
|
||||||
ctx->mediaengine->m_pFrameRGB = pmp_queue.front();
|
ctx->mediaengine->m_pFrameRGB = pmp_queue.front();
|
||||||
int bufferSize = ctx->mediaengine->writeVideoImage(buffer, frameWidth, 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->avc.avcFrameStatus = 1;
|
||||||
ctx->videoFrameCount++;
|
ctx->videoFrameCount++;
|
||||||
|
|
||||||
@ -1105,7 +1105,7 @@ static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr
|
|||||||
}
|
}
|
||||||
else if(ctx->mediaengine->stepVideo(ctx->videoPixelMode)) {
|
else if(ctx->mediaengine->stepVideo(ctx->videoPixelMode)) {
|
||||||
int bufferSize = ctx->mediaengine->writeVideoImage(buffer, frameWidth, 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->avc.avcFrameStatus = 1;
|
||||||
ctx->videoFrameCount++;
|
ctx->videoFrameCount++;
|
||||||
} else {
|
} else {
|
||||||
@ -1872,7 +1872,8 @@ static u32 sceMpegAvcCsc(u32 mpeg, u32 sourceAddr, u32 rangeAddr, int frameWidth
|
|||||||
int height = Memory::Read_U32(rangeAddr + 12);
|
int height = Memory::Read_U32(rangeAddr + 12);
|
||||||
int destSize = ctx->mediaengine->writeVideoImageWithRange(destAddr, frameWidth, ctx->videoPixelMode, x, y, width, height);
|
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
|
// Do not use avcDecodeDelayMs 's value
|
||||||
// Will cause video 's screen dislocation in Bleach heat of soul 6
|
// Will cause video 's screen dislocation in Bleach heat of soul 6
|
||||||
// https://github.com/hrydgard/ppsspp/issues/5535
|
// 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;
|
int bufw = videoData->frameWidth == 0 ? 512 : videoData->frameWidth & ~1;
|
||||||
// Always write the video frame, even after the video has ended.
|
// Always write the video frame, even after the video has ended.
|
||||||
int displaybufSize = psmfplayer->mediaengine->writeVideoImage(videoData->displaybuf, bufw, videoPixelMode);
|
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);
|
__PsmfUpdatePts(psmfplayer, videoData);
|
||||||
|
|
||||||
_PsmfPlayerFillRingbuffer(psmfplayer);
|
_PsmfPlayerFillRingbuffer(psmfplayer);
|
||||||
|
@ -799,7 +799,8 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
|
|||||||
delete [] imgbuf;
|
delete [] imgbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
return videoImageSize;
|
// Account for the y offset as well.
|
||||||
|
return videoImageSize + videoLineSize * ypos;
|
||||||
#endif // USE_FFMPEG
|
#endif // USE_FFMPEG
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -487,6 +487,26 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
|||||||
return vfb;
|
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) {
|
void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) {
|
||||||
addr &= ~0x40000000;
|
addr &= ~0x40000000;
|
||||||
// TODO: Could go through all FBOs, but probably not important?
|
// TODO: Could go through all FBOs, but probably not important?
|
||||||
|
@ -160,6 +160,7 @@ public:
|
|||||||
virtual void RebindFramebuffer() = 0;
|
virtual void RebindFramebuffer() = 0;
|
||||||
|
|
||||||
bool NotifyFramebufferCopy(u32 src, u32 dest, int size, bool isMemset, u32 skipDrawReason);
|
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);
|
void UpdateFromMemory(u32 addr, int size, bool safe);
|
||||||
virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) = 0;
|
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.
|
// 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 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);
|
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.
|
// No need to download if we already have it.
|
||||||
if (!vfb->memoryUpdated && vfb->clutUpdatedBytes < loadBytes) {
|
if (!vfb->memoryUpdated && vfb->clutUpdatedBytes < loadBytes) {
|
||||||
// We intentionally don't call OptimizeDownloadRange() here - we don't want to over download.
|
// 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) {
|
void DIRECTX9_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||||
// We use a little hack for Download/Upload using a VRAM mirror.
|
// We use a little hack for Download/Upload using a VRAM mirror.
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
void BeginFrame() override;
|
void BeginFrame() override;
|
||||||
void UpdateStats() override;
|
void UpdateStats() override;
|
||||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) 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 PerformMemoryCopy(u32 dest, u32 src, int size) override;
|
||||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||||
bool PerformMemoryDownload(u32 dest, 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 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);
|
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.
|
// No need to download if we already have it.
|
||||||
if (!vfb->memoryUpdated && vfb->clutUpdatedBytes < loadBytes) {
|
if (!vfb->memoryUpdated && vfb->clutUpdatedBytes < loadBytes) {
|
||||||
// We intentionally don't call OptimizeDownloadRange() here - we don't want to over download.
|
// 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) {
|
void GLES_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||||
// We use a little hack for Download/Upload using a VRAM mirror.
|
// We use a little hack for Download/Upload using a VRAM mirror.
|
||||||
|
@ -52,6 +52,7 @@ public:
|
|||||||
void BeginFrame() override;
|
void BeginFrame() override;
|
||||||
void UpdateStats() override;
|
void UpdateStats() override;
|
||||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) 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 PerformMemoryCopy(u32 dest, u32 src, int size) override;
|
||||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||||
bool PerformMemoryDownload(u32 dest, int size) override;
|
bool PerformMemoryDownload(u32 dest, int size) override;
|
||||||
|
@ -253,6 +253,7 @@ public:
|
|||||||
// Invalidate any cached content sourced from the specified range.
|
// Invalidate any cached content sourced from the specified range.
|
||||||
// If size = -1, invalidate everything.
|
// If size = -1, invalidate everything.
|
||||||
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type) = 0;
|
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.
|
// 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 PerformMemoryCopy(u32 dest, u32 src, int size) = 0;
|
||||||
virtual bool PerformMemorySet(u32 dest, u8 v, 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.
|
// 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) {
|
bool NullGPU::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||||
// Nothing to update.
|
// Nothing to update.
|
||||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||||
|
@ -34,6 +34,7 @@ public:
|
|||||||
void CopyDisplayToOutput() override {}
|
void CopyDisplayToOutput() override {}
|
||||||
void UpdateStats() override;
|
void UpdateStats() override;
|
||||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) 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 PerformMemoryCopy(u32 dest, u32 src, int size) override;
|
||||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||||
bool PerformMemoryDownload(u32 dest, 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.
|
// Nothing to invalidate.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftGPU::NotifyVideoUpload(u32 addr, int size, int width, int format)
|
||||||
|
{
|
||||||
|
// Ignore.
|
||||||
|
}
|
||||||
|
|
||||||
bool SoftGPU::PerformMemoryCopy(u32 dest, u32 src, int size)
|
bool SoftGPU::PerformMemoryCopy(u32 dest, u32 src, int size)
|
||||||
{
|
{
|
||||||
// Nothing to update.
|
// Nothing to update.
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
void CopyDisplayToOutput() override;
|
void CopyDisplayToOutput() override;
|
||||||
void UpdateStats() override;
|
void UpdateStats() override;
|
||||||
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) 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 PerformMemoryCopy(u32 dest, u32 src, int size) override;
|
||||||
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
bool PerformMemorySet(u32 dest, u8 v, int size) override;
|
||||||
bool PerformMemoryDownload(u32 dest, int size) override;
|
bool PerformMemoryDownload(u32 dest, int size) override;
|
||||||
|
@ -55,7 +55,7 @@ extern PFNGLDRAWTEXTURENVPROC glDrawTextureNV;
|
|||||||
typedef void (EGLAPIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (
|
typedef void (EGLAPIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (
|
||||||
GLint srcX0, GLint srcY0, GLint srcX1, GLuint srcY1,
|
GLint srcX0, GLint srcY0, GLint srcX1, GLuint srcY1,
|
||||||
GLint dstX0, GLint dstY0, GLint dstX1, GLuint dstY1,
|
GLint dstX0, GLint dstY0, GLint dstX1, GLuint dstY1,
|
||||||
GLint mask, GLenum filter);
|
GLbitfield mask, GLenum filter);
|
||||||
#endif
|
#endif
|
||||||
extern PFNGLBLITFRAMEBUFFERNVPROC glBlitFramebufferNV;
|
extern PFNGLBLITFRAMEBUFFERNVPROC glBlitFramebufferNV;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user