GPU: Use postshader for direct VRAM draws again.

Also centralize the pixel texture code while at it.
This commit is contained in:
Unknown W. Brackets committed 2020-05-13 18:10:09 -07:00
1 parent 762b656ea2
commit 2faab0e082
13 files changed
+82 -212

No files matched your search

+69 -6
View File
@@ -700,6 +700,71 @@ void FramebufferManagerCommon::CopyFramebufferForColorTexture(VirtualFramebuffer
}
}
Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) {
// TODO: We can just change the texture format and flip some bits around instead of this.
// Could share code with the texture cache perhaps.
auto generateTexture = [&](uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride) {
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 *)(data + byteStride * y);
switch (srcPixelFormat) {
case GE_FORMAT_565:
if (preferredPixelsFormat_ == Draw::DataFormat::B8G8R8A8_UNORM)
ConvertRGB565ToBGRA8888(dst, src16, width);
else
ConvertRGBA565ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_5551:
if (preferredPixelsFormat_ == Draw::DataFormat::B8G8R8A8_UNORM)
ConvertRGBA5551ToBGRA8888(dst, src16, width);
else
ConvertRGBA5551ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_4444:
if (preferredPixelsFormat_ == Draw::DataFormat::B8G8R8A8_UNORM)
ConvertRGBA4444ToBGRA8888(dst, src16, width);
else
ConvertRGBA4444ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_8888:
if (preferredPixelsFormat_ == Draw::DataFormat::B8G8R8A8_UNORM)
ConvertRGBA8888ToBGRA8888(dst, src32, width);
else
memcpy(dst, src32, 4 * width);
break;
case GE_FORMAT_INVALID:
_dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels().");
break;
}
}
};
Draw::TextureDesc desc{
Draw::TextureType::LINEAR2D,
preferredPixelsFormat_,
width,
height,
1,
1,
false,
"DrawPixels",
{ (uint8_t *)srcPixels },
generateTexture,
};
// TODO: On Vulkan, use a custom allocator? Important to use an allocator:
// Hot Shot Golf (#12355) does tons of these in a frame in some situations! So actually,
// we do use an allocator. In fact, I've now banned allocator-less textures.
Draw::Texture *tex = draw_->CreateTexture(desc);
if (!tex)
ERROR_LOG(G3D, "Failed to create drawpixels texture");
return tex;
}
void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) {
textureCache_->ForgetLastTexture();
shaderManager_->DirtyLastShader();
@@ -712,8 +777,7 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu
draw_->BindTextures(0, 1, &pixelsTex);
int uvRotation = useBufferedRendering_ ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
// TODO: Currently we can't access the texture from Draw.
//if (!applyPostShader) {
if (!applyPostShader) {
// TODO: Does this need to bind the backbuffer? What is this doing?
float x, y, w, h;
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation);
@@ -727,7 +791,7 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu
flags = flags | DRAWTEX_TO_BACKBUFFER;
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
/*} else {
} else {
OutputFlags flags = g_Config.iBufFilter == SCALE_LINEAR ? OutputFlags::LINEAR : OutputFlags::NEAREST;
if (needBackBufferYSwap_) {
flags |= OutputFlags::BACKBUFFER_FLIPPED;
@@ -741,10 +805,9 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu
std::swap(v0, v1);
}
// TODO
presentation_->SourceTexture();
presentation_->SourceTexture(pixelsTex);
presentation_->CopyToOutput(flags, uvRotation, u0, v0, u1, v1, uniforms);
}*/
}
pixelsTex->Release();
+2 -1
View File
@@ -308,7 +308,7 @@ public:
protected:
virtual void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h);
void SetViewport2D(int x, int y, int w, int h);
virtual Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) = 0;
Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1);
virtual void 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) = 0;
virtual void Bind2DShader() = 0;
@@ -397,6 +397,7 @@ protected:
int bloomHack_ = 0;
bool needGLESRebinds_ = false;
Draw::DataFormat preferredPixelsFormat_ = Draw::DataFormat::R8G8B8A8_UNORM;
struct TempFBOInfo {
Draw::Framebuffer *fbo;
+1 -48
View File
@@ -129,6 +129,7 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
ShaderTranslationInit();
presentation_->SetLanguage(HLSL_D3D11);
preferredPixelsFormat_ = Draw::DataFormat::B8G8R8A8_UNORM;
}
FramebufferManagerD3D11::~FramebufferManagerD3D11() {
@@ -178,54 +179,6 @@ void FramebufferManagerD3D11::SetDrawEngine(DrawEngineD3D11 *td) {
drawEngine_ = td;
}
Draw::Texture *FramebufferManagerD3D11::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) {
auto generateTexture = [&](uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride) {
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 *)(data + byteStride * y);
switch (srcPixelFormat) {
case GE_FORMAT_565:
ConvertRGB565ToBGRA8888(dst, src16, width);
break;
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;
}
}
};
Draw::TextureDesc desc{
Draw::TextureType::LINEAR2D,
Draw::DataFormat::B8G8R8A8_UNORM,
width,
height,
1,
1,
false,
"DrawPixels",
{ (uint8_t *)srcPixels },
generateTexture,
};
Draw::Texture *tex = draw_->CreateTexture(desc);
if (!tex)
ERROR_LOG(G3D, "Failed to create drawpixels texture");
return tex;
}
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) {
struct Coord {
Lin::Vec3 pos; float u, v;
-1
View File
@@ -68,7 +68,6 @@ protected:
private:
void Bind2DShader() override;
Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) override;
void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h);
void SimpleBlit(
Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2,
+1 -48
View File
@@ -117,6 +117,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
ShaderTranslationInit();
presentation_->SetLanguage(HLSL_DX9);
preferredPixelsFormat_ = Draw::DataFormat::B8G8R8A8_UNORM;
}
FramebufferManagerDX9::~FramebufferManagerDX9() {
@@ -159,54 +160,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
drawEngine_ = td;
}
Draw::Texture *FramebufferManagerDX9::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) {
auto generateTexture = [&](uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride) {
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 *)(data + byteStride * y);
switch (srcPixelFormat) {
case GE_FORMAT_565:
ConvertRGB565ToBGRA8888(dst, src16, width);
break;
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;
}
}
};
Draw::TextureDesc desc{
Draw::TextureType::LINEAR2D,
Draw::DataFormat::B8G8R8A8_UNORM,
width,
height,
1,
1,
false,
"DrawPixels",
{ (uint8_t *)srcPixels },
generateTexture,
};
Draw::Texture *tex = draw_->CreateTexture(desc);
if (!tex)
ERROR_LOG(G3D, "Failed to create drawpixels texture");
return tex;
}
void FramebufferManagerDX9::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) {
// TODO: StretchRect instead when possible?
float coord[20] = {
-1
View File
@@ -76,7 +76,6 @@ protected:
void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
private:
Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) override;
void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) override;
void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h);
bool GetRenderTargetFramebuffer(LPDIRECT3DSURFACE9 renderTarget, LPDIRECT3DSURFACE9 offscreen, int w, int h, GPUDebugBuffer &buffer);
+2
View File
@@ -202,6 +202,8 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer
float u1 = 1.0f;
float v1 = 1.0f;
Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1);
if (!tex)
return false;
device_->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, D3DCOLOR_RGBA(0, 0, 0, 0), 0.0f, 0);
-50
View File
@@ -166,56 +166,6 @@ FramebufferManagerGLES::~FramebufferManagerGLES() {
delete [] convBuf_;
}
Draw::Texture *FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) {
// TODO: We can just change the texture format and flip some bits around instead of this.
// Could share code with the texture cache perhaps.
auto generateTexture = [&](uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride) {
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 *)(data + byteStride * y);
switch (srcPixelFormat) {
case GE_FORMAT_565:
ConvertRGBA565ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_5551:
ConvertRGBA5551ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_4444:
ConvertRGBA4444ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_8888:
memcpy(dst, src32, 4 * width);
break;
case GE_FORMAT_INVALID:
_dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels().");
break;
}
}
};
Draw::TextureDesc desc{
Draw::TextureType::LINEAR2D,
Draw::DataFormat::R8G8B8A8_UNORM,
width,
height,
1,
1,
false,
"DrawPixels",
{ (uint8_t *)srcPixels },
generateTexture,
};
Draw::Texture *tex = draw_->CreateTexture(desc);
if (!tex)
ERROR_LOG(G3D, "Failed to create drawpixels texture");
return tex;
}
// x, y, w, h are relative coordinates against destW/destH, which is not very intuitive.
// TODO: This could totally use fbo_blit in many cases.
void FramebufferManagerGLES::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) {
-1
View File
@@ -73,7 +73,6 @@ private:
void CreateDeviceObjects();
void DestroyDeviceObjects();
Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) override;
void Bind2DShader() override;
void CompileDraw2DProgram();
+4 -1
View File
@@ -177,8 +177,11 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
float u1 = 1.0f;
float v1 = 1.0f;
Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstBuffer->height, u1, v1);
textureCacheGL_->ForgetLastTexture();
Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstBuffer->height, u1, v1);
if (!tex)
return false;
draw_->BindTextures(TEX_SLOT_PSP_TEXTURE, 1, &tex);
// We must bind the program after starting the render pass, and set the color mask after clearing.
-52
View File
@@ -176,58 +176,6 @@ void FramebufferManagerVulkan::Init() {
Resized();
}
Draw::Texture *FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) {
auto generateTexture = [&](uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride) {
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 *)(data + byteStride * y);
switch (srcPixelFormat) {
case GE_FORMAT_565:
ConvertRGBA565ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_5551:
ConvertRGBA5551ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_4444:
ConvertRGBA4444ToRGBA8888(dst, src16, width);
break;
case GE_FORMAT_8888:
memcpy(dst, src32, 4 * width);
break;
case GE_FORMAT_INVALID:
_dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels().");
break;
}
}
};
// Hot Shot Golf (#12355) does tons of these in a frame in some situations! So actually,
// we do use an allocator. In fact, I've now banned allocator-less textures.
Draw::TextureDesc desc{
Draw::TextureType::LINEAR2D,
Draw::DataFormat::R8G8B8A8_UNORM,
width,
height,
1,
1,
false,
"DrawPixels",
{ (uint8_t *)srcPixels },
generateTexture,
};
// TODO: Use allocator_ somehow?
Draw::Texture *tex = draw_->CreateTexture(desc);
if (!tex)
ERROR_LOG(G3D, "Failed to create drawpixels texture");
return tex;
}
void FramebufferManagerVulkan::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) {
float texCoords[8] = {
u0,v0,
-3
View File
@@ -78,9 +78,6 @@ protected:
void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
private:
// The returned texture does not need to be free'd, might be returned from a pool (currently single entry)
Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) override;
void InitDeviceObjects();
void DestroyDeviceObjects();
+3
View File
@@ -164,6 +164,9 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skip
float u1 = 1.0f;
float v1 = 1.0f;
Draw::Texture *tex = MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1);
if (!tex)
return false;
if (dstBuffer->fbo) {
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR });
} else {