mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 17:49:29 +01:00
Merge pull request #11128 from unknownbrackets/gpu-minor
Minor framebuffer code cleanup
This commit is contained in:
11 files changed
+88
-307
No files matched your search
@@ -1100,7 +1100,7 @@ void FramebufferManagerCommon::DecimateFBOs() {
|
||||
int age = frameLastFramebufUsed_ - it->second.last_frame_used;
|
||||
if (age > FBO_OLD_AGE) {
|
||||
it->second.fbo->Release();
|
||||
tempFBOs_.erase(it++);
|
||||
it = tempFBOs_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/MemMap.h"
|
||||
@@ -412,7 +412,7 @@ protected:
|
||||
int last_frame_used;
|
||||
};
|
||||
|
||||
std::map<u64, TempFBOInfo> tempFBOs_;
|
||||
std::unordered_map<u64, TempFBOInfo> tempFBOs_;
|
||||
|
||||
std::vector<Draw::Framebuffer *> fbosToDelete_;
|
||||
|
||||
|
||||
@@ -161,10 +161,7 @@ FramebufferManagerD3D11::~FramebufferManagerD3D11() {
|
||||
postInputLayout_->Release();
|
||||
}
|
||||
|
||||
// FBO cleanup
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
it->second.fbo->Release();
|
||||
}
|
||||
// Temp FBOs cleared by FramebufferCommon.
|
||||
delete[] convBuf;
|
||||
|
||||
// Stencil cleanup
|
||||
@@ -266,8 +263,6 @@ void FramebufferManagerD3D11::CompilePostShader() {
|
||||
}
|
||||
|
||||
void FramebufferManagerD3D11::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) {
|
||||
u8 *convBuf = nullptr;
|
||||
|
||||
// TODO: Check / use D3DCAPS2_DYNAMICTEXTURES?
|
||||
if (drawPixelsTex_ && (drawPixelsTexW_ != width || drawPixelsTexH_ != height)) {
|
||||
drawPixelsTex_->Release();
|
||||
@@ -301,54 +296,35 @@ void FramebufferManagerD3D11::MakePixelTexture(const u8 *srcPixels, GEBufferForm
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
context_->Map(drawPixelsTex_, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
|
||||
convBuf = (u8*)map.pData;
|
||||
|
||||
if (srcPixelFormat != GE_FORMAT_8888 || srcStride != 512) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
switch (srcPixelFormat) {
|
||||
case GE_FORMAT_565:
|
||||
{
|
||||
const u16_le *src = (const u16_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)(convBuf + map.RowPitch * y);
|
||||
ConvertRGB565ToBGRA8888(dst, src, width);
|
||||
}
|
||||
break;
|
||||
// faster
|
||||
case GE_FORMAT_5551:
|
||||
{
|
||||
const u16_le *src = (const u16_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)(convBuf + map.RowPitch * y);
|
||||
ConvertRGBA5551ToBGRA8888(dst, src, width);
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_4444:
|
||||
{
|
||||
const u16_le *src = (const u16_le *)srcPixels + srcStride * y;
|
||||
u8 *dst = (u8 *)(convBuf + map.RowPitch * y);
|
||||
ConvertRGBA4444ToBGRA8888((u32 *)dst, src, width);
|
||||
}
|
||||
for (int y = 0; y < height; y++) {
|
||||
const u16_le *src16 = (const u16_le *)srcPixels + srcStride * y;
|
||||
const u32_le *src32 = (const u32_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)((u8 *)map.pData + map.RowPitch * y);
|
||||
switch (srcPixelFormat) {
|
||||
case GE_FORMAT_565:
|
||||
ConvertRGB565ToBGRA8888(dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_8888:
|
||||
{
|
||||
const u32_le *src = (const u32_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)(convBuf + map.RowPitch * y);
|
||||
ConvertRGBA8888ToBGRA8888(dst, src, width);
|
||||
}
|
||||
case GE_FORMAT_5551:
|
||||
ConvertRGBA5551ToBGRA8888(dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_4444:
|
||||
ConvertRGBA4444ToBGRA8888(dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_8888:
|
||||
ConvertRGBA8888ToBGRA8888(dst, src32, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_INVALID:
|
||||
_dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels().");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < height; y++) {
|
||||
const u32_le *src = (const u32_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)(convBuf + map.RowPitch * y);
|
||||
ConvertRGBA8888ToBGRA8888(dst, src, width);
|
||||
}
|
||||
}
|
||||
|
||||
context_->Unmap(drawPixelsTex_, 0);
|
||||
context_->PSSetShaderResources(0, 1, &drawPixelsTexView_);
|
||||
// D3DXSaveTextureToFile("game:\\cc.png", D3DXIFF_PNG, drawPixelsTex_, NULL);
|
||||
}
|
||||
|
||||
void FramebufferManagerD3D11::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags) {
|
||||
@@ -718,8 +694,8 @@ void FramebufferManagerD3D11::DestroyAllFBOs() {
|
||||
}
|
||||
bvfbs_.clear();
|
||||
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
it->second.fbo->Release();
|
||||
for (auto &tempFB : tempFBOs_) {
|
||||
tempFB.second.fbo->Release();
|
||||
}
|
||||
tempFBOs_.clear();
|
||||
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
// Keeps track of allocated FBOs.
|
||||
@@ -122,9 +118,4 @@ private:
|
||||
ID3D11InputLayout *postInputLayout_ = nullptr;
|
||||
ID3D11Buffer *postConstants_ = nullptr;
|
||||
static const D3D11_INPUT_ELEMENT_DESC g_PostVertexElements[2];
|
||||
|
||||
#if 0
|
||||
AsyncPBO *pixelBufObj_; //this isn't that large
|
||||
u8 currentPBO_;
|
||||
#endif
|
||||
};
|
||||
@@ -82,12 +82,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
||||
};
|
||||
|
||||
FramebufferManagerDX9::FramebufferManagerDX9(Draw::DrawContext *draw)
|
||||
: FramebufferManagerCommon(draw),
|
||||
drawPixelsTex_(0),
|
||||
convBuf(0),
|
||||
stencilUploadPS_(nullptr),
|
||||
stencilUploadVS_(nullptr),
|
||||
stencilUploadFailed_(false) {
|
||||
: FramebufferManagerCommon(draw) {
|
||||
|
||||
device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE);
|
||||
deviceEx_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX);
|
||||
@@ -119,8 +114,8 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
||||
if (drawPixelsTex_) {
|
||||
drawPixelsTex_->Release();
|
||||
}
|
||||
for (auto it = offscreenSurfaces_.begin(), end = offscreenSurfaces_.end(); it != end; ++it) {
|
||||
it->second.surface->Release();
|
||||
for (auto &it : offscreenSurfaces_) {
|
||||
it.second.surface->Release();
|
||||
}
|
||||
delete [] convBuf;
|
||||
if (stencilUploadPS_) {
|
||||
@@ -534,16 +529,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
||||
const u32 *src32 = (const u32 *)src;
|
||||
|
||||
if (format == GE_FORMAT_8888) {
|
||||
u32 *dst32 = (u32 *)dst;
|
||||
if (src == dst) {
|
||||
return;
|
||||
} else {
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
ConvertBGRA8888ToRGBA8888(dst32, src32, width);
|
||||
src32 += srcStride;
|
||||
dst32 += dstStride;
|
||||
}
|
||||
}
|
||||
ConvertFromBGRA8888(dst, src, dstStride, srcStride, width, height, Draw::DataFormat::R8G8B8A8_UNORM);
|
||||
} else {
|
||||
// But here it shouldn't matter if they do intersect
|
||||
u16 *dst16 = (u16 *)dst;
|
||||
@@ -680,7 +666,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
||||
int age = frameLastFramebufUsed_ - it->second.last_frame_used;
|
||||
if (age > FBO_OLD_AGE) {
|
||||
it->second.surface->Release();
|
||||
offscreenSurfaces_.erase(it++);
|
||||
it = offscreenSurfaces_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
@@ -706,8 +692,8 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
||||
}
|
||||
bvfbs_.clear();
|
||||
|
||||
for (auto it = offscreenSurfaces_.begin(), end = offscreenSurfaces_.end(); it != end; ++it) {
|
||||
it->second.surface->Release();
|
||||
for (auto &it : offscreenSurfaces_) {
|
||||
it.second.surface->Release();
|
||||
}
|
||||
offscreenSurfaces_.clear();
|
||||
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <d3d9.h>
|
||||
|
||||
@@ -91,20 +89,20 @@ private:
|
||||
LPDIRECT3DDEVICE9 deviceEx_;
|
||||
|
||||
// Used by DrawPixels
|
||||
LPDIRECT3DTEXTURE9 drawPixelsTex_;
|
||||
LPDIRECT3DTEXTURE9 drawPixelsTex_ = nullptr;
|
||||
int drawPixelsTexW_;
|
||||
int drawPixelsTexH_;
|
||||
|
||||
LPDIRECT3DVERTEXSHADER9 pFramebufferVertexShader;
|
||||
LPDIRECT3DPIXELSHADER9 pFramebufferPixelShader;
|
||||
LPDIRECT3DVERTEXDECLARATION9 pFramebufferVertexDecl;
|
||||
LPDIRECT3DVERTEXSHADER9 pFramebufferVertexShader = nullptr;
|
||||
LPDIRECT3DPIXELSHADER9 pFramebufferPixelShader = nullptr;
|
||||
LPDIRECT3DVERTEXDECLARATION9 pFramebufferVertexDecl = nullptr;
|
||||
|
||||
u8 *convBuf;
|
||||
u8 *convBuf = nullptr;
|
||||
|
||||
int plainColorLoc_;
|
||||
LPDIRECT3DPIXELSHADER9 stencilUploadPS_;
|
||||
LPDIRECT3DVERTEXSHADER9 stencilUploadVS_;
|
||||
bool stencilUploadFailed_;
|
||||
LPDIRECT3DPIXELSHADER9 stencilUploadPS_ = nullptr;
|
||||
LPDIRECT3DVERTEXSHADER9 stencilUploadVS_ = nullptr;
|
||||
bool stencilUploadFailed_ = false;
|
||||
|
||||
TextureCacheDX9 *textureCacheDX9_;
|
||||
ShaderManagerDX9 *shaderManagerDX9_;
|
||||
@@ -115,12 +113,7 @@ private:
|
||||
int last_frame_used;
|
||||
};
|
||||
|
||||
std::map<u64, OffscreenSurface> offscreenSurfaces_;
|
||||
|
||||
#if 0
|
||||
AsyncPBO *pixelBufObj_; //this isn't that large
|
||||
u8 currentPBO_;
|
||||
#endif
|
||||
std::unordered_map<u64, OffscreenSurface> offscreenSurfaces_;
|
||||
};
|
||||
|
||||
};
|
||||
@@ -76,10 +76,6 @@ static const char basic_vs[] =
|
||||
" gl_Position = a_position;\n"
|
||||
"}\n";
|
||||
|
||||
const int MAX_PBO = 2;
|
||||
|
||||
void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format);
|
||||
|
||||
void FramebufferManagerGLES::CompileDraw2DProgram() {
|
||||
if (!draw2dprogram_) {
|
||||
std::string errorString;
|
||||
@@ -336,62 +332,39 @@ FramebufferManagerGLES::~FramebufferManagerGLES() {
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) {
|
||||
// Optimization: skip a copy if possible in a common case.
|
||||
int texWidth = width;
|
||||
if (srcPixelFormat == GE_FORMAT_8888 && width < srcStride) {
|
||||
// Don't up the upload requirements too much if subimages are unsupported.
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE) || width >= 480) {
|
||||
texWidth = srcStride;
|
||||
u1 *= (float)width / texWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (drawPixelsTex_) {
|
||||
render_->DeleteTexture(drawPixelsTex_);
|
||||
}
|
||||
|
||||
drawPixelsTex_ = render_->CreateTexture(GL_TEXTURE_2D);
|
||||
drawPixelsTexW_ = texWidth;
|
||||
drawPixelsTexW_ = width;
|
||||
drawPixelsTexH_ = height;
|
||||
|
||||
drawPixelsTexFormat_ = srcPixelFormat;
|
||||
|
||||
// TODO: We can just change the texture format and flip some bits around instead of this.
|
||||
// Could share code with the texture cache perhaps.
|
||||
u32 neededSize = texWidth * height * 4;
|
||||
u32 neededSize = width * height * 4;
|
||||
u8 *convBuf = new u8[neededSize];
|
||||
for (int y = 0; y < height; y++) {
|
||||
const u16_le *src16 = (const u16_le *)srcPixels + srcStride * y;
|
||||
const u32_le *src32 = (const u32_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)convBuf + width * y;
|
||||
switch (srcPixelFormat) {
|
||||
case GE_FORMAT_565:
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf + 4 * texWidth * y;
|
||||
ConvertRGBA565ToRGBA8888((u32 *)dst, src, width);
|
||||
}
|
||||
ConvertRGBA565ToRGBA8888((u32 *)dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_5551:
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf + 4 * texWidth * y;
|
||||
ConvertRGBA5551ToRGBA8888((u32 *)dst, src, width);
|
||||
}
|
||||
ConvertRGBA5551ToRGBA8888((u32 *)dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_4444:
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf + 4 * texWidth * y;
|
||||
ConvertRGBA4444ToRGBA8888((u32 *)dst, src, width);
|
||||
}
|
||||
ConvertRGBA4444ToRGBA8888((u32 *)dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_8888:
|
||||
{
|
||||
const u8 *src = srcPixels + srcStride * 4 * y;
|
||||
u8 *dst = convBuf + 4 * texWidth * y;
|
||||
memcpy(dst, src, 4 * width);
|
||||
}
|
||||
memcpy(dst, src32, 4 * width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_INVALID:
|
||||
@@ -399,7 +372,7 @@ void FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferForma
|
||||
break;
|
||||
}
|
||||
}
|
||||
render_->TextureImage(drawPixelsTex_, 0, texWidth, height, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, convBuf, GLRAllocType::NEW, false);
|
||||
render_->TextureImage(drawPixelsTex_, 0, width, height, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, convBuf, GLRAllocType::NEW, false);
|
||||
render_->FinalizeTexture(drawPixelsTex_, 0, false);
|
||||
|
||||
// TODO: Return instead?
|
||||
@@ -679,61 +652,6 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
|
||||
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE);
|
||||
}
|
||||
|
||||
void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format) {
|
||||
// Must skip stride in the cases below. Some games pack data into the cracks, like MotoGP.
|
||||
const u32 *src32 = (const u32 *)src;
|
||||
|
||||
if (format == GE_FORMAT_8888) {
|
||||
u32 *dst32 = (u32 *)dst;
|
||||
if (src == dst) {
|
||||
return;
|
||||
} else {
|
||||
// Here let's assume they don't intersect
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
memcpy(dst32, src32, width * 4);
|
||||
src32 += srcStride;
|
||||
dst32 += dstStride;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// But here it shouldn't matter if they do intersect
|
||||
u16 *dst16 = (u16 *)dst;
|
||||
switch (format) {
|
||||
case GE_FORMAT_565: // BGR 565
|
||||
{
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
ConvertRGBA8888ToRGB565(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_5551: // ABGR 1555
|
||||
{
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
ConvertRGBA8888ToRGBA5551(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_4444: // ABGR 4444
|
||||
{
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
ConvertRGBA8888ToRGBA4444(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_8888:
|
||||
case GE_FORMAT_INVALID:
|
||||
// Not possible.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
|
||||
if (!vfb->fbo) {
|
||||
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0");
|
||||
@@ -809,8 +727,8 @@ void FramebufferManagerGLES::DestroyAllFBOs() {
|
||||
}
|
||||
bvfbs_.clear();
|
||||
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
it->second.fbo->Release();
|
||||
for (auto &tempFB : tempFBOs_) {
|
||||
tempFB.second.fbo->Release();
|
||||
}
|
||||
tempFBOs_.clear();
|
||||
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ext/native/thin3d/thin3d.h"
|
||||
// Keeps track of allocated FBOs.
|
||||
// Also provides facilities for drawing and later converting raw
|
||||
|
||||
@@ -80,18 +80,9 @@ void main() {
|
||||
}
|
||||
)";
|
||||
|
||||
void ConvertFromRGBA8888_Vulkan(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format);
|
||||
|
||||
FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan) :
|
||||
FramebufferManagerCommon(draw),
|
||||
vulkan_(vulkan),
|
||||
drawPixelsTex_(nullptr),
|
||||
drawPixelsTexFormat_(GE_FORMAT_INVALID),
|
||||
convBuf_(nullptr),
|
||||
convBufSize_(0),
|
||||
textureCacheVulkan_(nullptr),
|
||||
shaderManagerVulkan_(nullptr),
|
||||
pipelinePostShader_(VK_NULL_HANDLE) {
|
||||
vulkan_(vulkan) {
|
||||
|
||||
InitDeviceObjects();
|
||||
|
||||
@@ -217,7 +208,7 @@ void FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, GEBufferFor
|
||||
|
||||
// TODO: We can just change the texture format and flip some bits around instead of this.
|
||||
// Could share code with the texture cache perhaps.
|
||||
// Could also convert directly into the pushbuffer easily.
|
||||
// TODO: Could also convert directly into the pushbuffer easily.
|
||||
const uint8_t *data = srcPixels;
|
||||
if (srcPixelFormat != GE_FORMAT_8888 || srcStride != width) {
|
||||
u32 neededSize = width * height * 4;
|
||||
@@ -228,38 +219,25 @@ void FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, GEBufferFor
|
||||
}
|
||||
data = convBuf_;
|
||||
for (int y = 0; y < height; y++) {
|
||||
const u16_le *src16 = (const u16_le *)srcPixels + srcStride * y;
|
||||
const u32_le *src32 = (const u32_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)convBuf_ + width * y;
|
||||
switch (srcPixelFormat) {
|
||||
case GE_FORMAT_565:
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf_ + 4 * width * y;
|
||||
ConvertRGBA565ToRGBA8888((u32 *)dst, src, width);
|
||||
}
|
||||
break;
|
||||
ConvertRGBA565ToRGBA8888((u32 *)dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_5551:
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf_ + 4 * width * y;
|
||||
ConvertRGBA5551ToRGBA8888((u32 *)dst, src, width);
|
||||
}
|
||||
break;
|
||||
ConvertRGBA5551ToRGBA8888((u32 *)dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_4444:
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf_ + 4 * width * y;
|
||||
ConvertRGBA4444ToRGBA8888((u32 *)dst, src, width);
|
||||
}
|
||||
break;
|
||||
ConvertRGBA4444ToRGBA8888((u32 *)dst, src16, width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_8888:
|
||||
{
|
||||
const u8 *src = srcPixels + srcStride * 4 * y;
|
||||
u8 *dst = convBuf_ + 4 * width * y;
|
||||
memcpy(dst, src, 4 * width);
|
||||
}
|
||||
break;
|
||||
memcpy(dst, src32, 4 * width);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_INVALID:
|
||||
_dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels().");
|
||||
@@ -535,57 +513,6 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: SSE/NEON
|
||||
// Could also make C fake-simd for 64-bit, two 8888 pixels fit in a register :)
|
||||
void ConvertFromRGBA8888_Vulkan(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format) {
|
||||
// Must skip stride in the cases below. Some games pack data into the cracks, like MotoGP.
|
||||
const u32 *src32 = (const u32 *)src;
|
||||
|
||||
if (format == GE_FORMAT_8888) {
|
||||
u32 *dst32 = (u32 *)dst;
|
||||
if (src == dst) {
|
||||
return;
|
||||
} else {
|
||||
// Here let's assume they don't intersect
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
memcpy(dst32, src32, width * 4);
|
||||
src32 += srcStride;
|
||||
dst32 += dstStride;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// But here it shouldn't matter if they do intersect
|
||||
u16 *dst16 = (u16 *)dst;
|
||||
switch (format) {
|
||||
case GE_FORMAT_565: // BGR 565
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
ConvertRGBA8888ToRGB565(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_5551: // ABGR 1555
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
ConvertBGRA8888ToRGBA5551(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_4444: // ABGR 4444
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
ConvertRGBA8888ToRGBA4444(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_8888:
|
||||
case GE_FORMAT_INVALID:
|
||||
// Not possible.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerVulkan::BeginFrameVulkan() {
|
||||
BeginFrame();
|
||||
}
|
||||
@@ -624,8 +551,8 @@ void FramebufferManagerVulkan::DestroyAllFBOs() {
|
||||
}
|
||||
bvfbs_.clear();
|
||||
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
it->second.fbo->Release();
|
||||
for (auto &tempFB : tempFBOs_) {
|
||||
tempFB.second.fbo->Release();
|
||||
}
|
||||
tempFBOs_.clear();
|
||||
|
||||
|
||||
@@ -24,14 +24,6 @@
|
||||
#include "GPU/Vulkan/VulkanUtil.h"
|
||||
#include "GPU/Vulkan/DepalettizeShaderVulkan.h"
|
||||
|
||||
// TODO: Remove?
|
||||
enum VulkanFBOColorDepth {
|
||||
VK_FBO_8888,
|
||||
VK_FBO_565,
|
||||
VK_FBO_4444,
|
||||
VK_FBO_5551,
|
||||
};
|
||||
|
||||
class TextureCacheVulkan;
|
||||
class DrawEngineVulkan;
|
||||
class VulkanContext;
|
||||
@@ -39,14 +31,6 @@ class ShaderManagerVulkan;
|
||||
class VulkanTexture;
|
||||
class VulkanPushBuffer;
|
||||
|
||||
static const char *ub_post_shader =
|
||||
R"( vec2 texelDelta;
|
||||
vec2 pixelDelta;
|
||||
vec4 time;
|
||||
)";
|
||||
|
||||
class VulkanPushBuffer;
|
||||
|
||||
class FramebufferManagerVulkan : public FramebufferManagerCommon {
|
||||
public:
|
||||
FramebufferManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan);
|
||||
@@ -112,9 +96,9 @@ private:
|
||||
u8 *convBuf_ = nullptr;
|
||||
u32 convBufSize_ = 0;
|
||||
|
||||
TextureCacheVulkan *textureCacheVulkan_;
|
||||
ShaderManagerVulkan *shaderManagerVulkan_;
|
||||
DrawEngineVulkan *drawEngineVulkan_;
|
||||
TextureCacheVulkan *textureCacheVulkan_ = nullptr;
|
||||
ShaderManagerVulkan *shaderManagerVulkan_ = nullptr;
|
||||
DrawEngineVulkan *drawEngineVulkan_ = nullptr;
|
||||
VulkanPushBuffer *push_;
|
||||
|
||||
enum {
|
||||
|
||||
@@ -428,12 +428,22 @@ void ConvertFromBGRA8888(uint8_t *dst, const uint8_t *src, uint32_t dstStride, u
|
||||
src32 += srcStride;
|
||||
dst32 += dstStride;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Don't even bother with these, this path only happens in screenshots and we don't save those to 16-bit.
|
||||
assert(false);
|
||||
} else if (format == Draw::DataFormat::R8G8B8_UNORM) {
|
||||
for (uint32_t y = 0; y < height; ++y) {
|
||||
for (uint32_t x = 0; x < width; ++x) {
|
||||
uint32_t c = src32[x];
|
||||
dst[x * 3 + 0] = (c >> 16) & 0xFF;
|
||||
dst[x * 3 + 1] = (c >> 8) & 0xFF;
|
||||
dst[x * 3 + 2] = (c >> 0) & 0xFF;
|
||||
}
|
||||
src32 += srcStride;
|
||||
dst += dstStride * 3;
|
||||
}
|
||||
} else {
|
||||
WARN_LOG_REPORT_ONCE(convFromBGRA, G3D, "Unable to convert from format to BGRA: %d", (int)format);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertToD32F(uint8_t *dst, const uint8_t *src, uint32_t dstStride, uint32_t srcStride, uint32_t width, uint32_t height, DataFormat format) {
|
||||
if (format == Draw::DataFormat::D32F) {
|
||||
const float *src32 = (const float *)src;
|
||||
|
||||
Reference in new issue
Block a user