From eabcb22623494b35745c4f8f3c0255fc8c59c69b Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 19 Feb 2017 11:02:24 +0100 Subject: [PATCH] Refactor away SetImageData --- GPU/Software/SoftGpu.cpp | 130 +++++++++++++++------------- ext/native/gfx_es2/draw_text.cpp | 8 +- ext/native/thin3d/thin3d.h | 2 - ext/native/thin3d/thin3d_d3d11.cpp | 4 - ext/native/thin3d/thin3d_d3d9.cpp | 4 +- ext/native/thin3d/thin3d_gl.cpp | 76 ++++++++-------- ext/native/thin3d/thin3d_vulkan.cpp | 4 +- 7 files changed, 117 insertions(+), 111 deletions(-) diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 776873afc0..6cbf267782 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -58,15 +58,7 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : GPUCommon(gfxCtx, draw) { using namespace Draw; - TextureDesc desc{}; - desc.type = TextureType::LINEAR2D; - desc.format = DataFormat::R8G8B8A8_UNORM; - desc.width = 480; - desc.height = 272; - desc.depth = 1; - desc.mipLevels = 1; - fbTex = draw_->CreateTexture(desc); - + fbTex = nullptr; InputLayoutDesc inputDesc = { { { sizeof(Vertex), false }, @@ -124,9 +116,10 @@ SoftGPU::~SoftGPU() { texColor->Release(); texColor = nullptr; - fbTex->Release(); - fbTex = nullptr; - + if (fbTex) { + fbTex->Release(); + fbTex = nullptr; + } vdata->Release(); vdata = nullptr; idata->Release(); @@ -147,32 +140,38 @@ void SoftGPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for // Copies RGBA8 data from RAM to the currently bound render target. void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { - using namespace Draw; - if (!draw_) return; float dstwidth = (float)PSP_CoreParameter().pixelWidth; float dstheight = (float)PSP_CoreParameter().pixelHeight; - Viewport viewport = {0.0f, 0.0f, dstwidth, dstheight, 0.0f, 1.0f}; + Draw::Viewport viewport = {0.0f, 0.0f, dstwidth, dstheight, 0.0f, 1.0f}; draw_->SetViewports(1, &viewport); - SamplerState *sampler; - if (g_Config.iBufFilter == SCALE_NEAREST) { - sampler = samplerNearest; - } else { - sampler = samplerLinear; - } draw_->SetScissorRect(0, 0, dstwidth, dstheight); float u0 = 0.0f; float u1; + + if (fbTex) { + fbTex->Release(); + fbTex = nullptr; + } + + Draw::TextureDesc desc{}; + desc.type = Draw::TextureType::LINEAR2D; + desc.format = Draw::DataFormat::R8G8B8A8_UNORM; + desc.depth = 1; + desc.mipLevels = 1; bool hasImage = true; if (!Memory::IsValidAddress(displayFramebuf_)) { hasImage = false; u1 = 1.0f; } else if (displayFormat_ == GE_FORMAT_8888) { u8 *data = Memory::GetPointer(displayFramebuf_); - fbTex->SetImageData(0, 0, 0, displayStride_, srcheight, 1, 0, displayStride_ * 4, data); + desc.width = displayStride_; + desc.height = srcheight; + desc.initData.push_back(data); + desc.format = Draw::DataFormat::R8G8B8A8_UNORM; u1 = (float)srcwidth / displayStride_; } else { // TODO: This should probably be converted in a shader instead.. @@ -201,9 +200,16 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { } } - fbTex->SetImageData(0, 0, 0, srcwidth, srcheight, 1, 0, srcwidth * 4, (const uint8_t *)&fbTexBuffer[0]); + desc.width = srcwidth; + desc.height = srcheight; u1 = 1.0f; } + if (!hasImage) { + draw_->Clear(Draw::FB_COLOR_BIT, 0, 0, 0); + return; + } + + fbTex = draw_->CreateTexture(desc); float x, y, w, h; CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, dstwidth, dstheight, ROTATION_LOCKED_HORIZONTAL); @@ -224,46 +230,48 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { x2 -= 1.0f; y2 -= 1.0f; - if (hasImage) { - float v0 = 1.0f; - float v1 = 0.0f; + float v0 = 1.0f; + float v1 = 0.0f; - if (GetGPUBackend() == GPUBackend::VULKAN) { - std::swap(v0, v1); - } - - draw_->BindSamplerStates(0, 1, &sampler); - - const Vertex verts[4] = { - { x, y, 0, u0, v0, 0xFFFFFFFF }, // TL - { x, y2, 0, u0, v1, 0xFFFFFFFF }, // BL - { x2, y2, 0, u1, v1, 0xFFFFFFFF }, // BR - { x2, y, 0, u1, v0, 0xFFFFFFFF }, // TR - }; - draw_->UpdateBuffer(vdata, (const uint8_t *)verts, 0, sizeof(verts), Draw::UPDATE_DISCARD); - - int indexes[] = { 0, 1, 2, 0, 2, 3 }; - draw_->UpdateBuffer(idata, (const uint8_t *)indexes, 0, sizeof(indexes), Draw::UPDATE_DISCARD); - - draw_->BindTexture(0, fbTex); - - static const float identity4x4[16] = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - }; - - VsTexColUB ub{}; - memcpy(ub.WorldViewProj, identity4x4, sizeof(float) * 16); - draw_->BindPipeline(texColor); - draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub)); - draw_->BindVertexBuffers(0, 1, &vdata, nullptr); - draw_->BindIndexBuffer(idata, 0); - draw_->DrawIndexed(6, 0); - } else { - draw_->Clear(Draw::FB_COLOR_BIT, 0, 0, 0); + if (GetGPUBackend() == GPUBackend::VULKAN) { + std::swap(v0, v1); } + + Draw::SamplerState *sampler; + if (g_Config.iBufFilter == SCALE_NEAREST) { + sampler = samplerNearest; + } else { + sampler = samplerLinear; + } + draw_->BindSamplerStates(0, 1, &sampler); + + const Vertex verts[4] = { + { x, y, 0, u0, v0, 0xFFFFFFFF }, // TL + { x, y2, 0, u0, v1, 0xFFFFFFFF }, // BL + { x2, y2, 0, u1, v1, 0xFFFFFFFF }, // BR + { x2, y, 0, u1, v0, 0xFFFFFFFF }, // TR + }; + draw_->UpdateBuffer(vdata, (const uint8_t *)verts, 0, sizeof(verts), Draw::UPDATE_DISCARD); + + int indexes[] = { 0, 1, 2, 0, 2, 3 }; + draw_->UpdateBuffer(idata, (const uint8_t *)indexes, 0, sizeof(indexes), Draw::UPDATE_DISCARD); + + draw_->BindTexture(0, fbTex); + + static const float identity4x4[16] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + + Draw::VsTexColUB ub{}; + memcpy(ub.WorldViewProj, identity4x4, sizeof(float) * 16); + draw_->BindPipeline(texColor); + draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub)); + draw_->BindVertexBuffers(0, 1, &vdata, nullptr); + draw_->BindIndexBuffer(idata, 0); + draw_->DrawIndexed(6, 0); } void SoftGPU::CopyDisplayToOutput() diff --git a/ext/native/gfx_es2/draw_text.cpp b/ext/native/gfx_es2/draw_text.cpp index 7454364f8e..54e67246bd 100644 --- a/ext/native/gfx_es2/draw_text.cpp +++ b/ext/native/gfx_es2/draw_text.cpp @@ -476,12 +476,11 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float TextureDesc desc{}; desc.type = TextureType::LINEAR2D; - desc.format = Draw::DataFormat::R4G4B4A4_UNORM_PACK16; + desc.format = Draw::DataFormat::B4G4R4A4_UNORM_PACK16; desc.width = entry->bmWidth; desc.height = entry->bmHeight; desc.depth = 1; desc.mipLevels = 1; - entry->texture = draw_->CreateTexture(desc); uint16_t *bitmapData = new uint16_t[entry->bmWidth * entry->bmHeight]; for (int x = 0; x < entry->bmWidth; x++) { @@ -489,10 +488,9 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float bitmapData[entry->bmWidth * y + x] = 0xfff0 | image.pixel(x, y) >> 28; } } - entry->texture->SetImageData(0, 0, 0, entry->bmWidth, entry->bmHeight, 1, 0, entry->bmWidth * 2, (const uint8_t *)bitmapData); - + desc.initData.push_back(bitmapData); + entry->texture = draw_->CreateTexture(desc); delete [] bitmapData; - cache_[entryHash] = std::unique_ptr(entry); } float w = entry->bmWidth * fontScaleX_; diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 4676f880ac..ceac009c5a 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -406,8 +406,6 @@ public: class Texture : public RefCountedObject { public: - virtual void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) = 0; - int Width() { return width_; } int Height() { return height_; } int Depth() { return depth_; } diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 480fdcaf40..d10383a6fd 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -647,10 +647,6 @@ public: view->Release(); } - void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) { - ELOG("SetImageData not supported, create a new texture instead"); - } - ID3D11Texture2D *tex = nullptr; ID3D11ShaderResourceView *view = nullptr; }; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index a9785acf2d..d84e841e31 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -297,10 +297,10 @@ class D3D9Texture : public Texture { public: D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, const TextureDesc &desc); ~D3D9Texture(); - void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override; void SetToSampler(LPDIRECT3DDEVICE9 device, int sampler); private: + void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data); bool Create(const TextureDesc &desc); LPDIRECT3DDEVICE9 device_; LPDIRECT3DDEVICE9EX deviceEx_; @@ -364,7 +364,7 @@ bool D3D9Texture::Create(const TextureDesc &desc) { if (desc.initData.size()) { for (int i = 0; i < desc.initData.size(); i++) { - this->SetImageData(0, 0, 0, width_, height_, depth_, i, 0, desc.initData[i]); + SetImageData(0, 0, 0, width_, height_, depth_, i, 0, desc.initData[i]); } } return true; diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 6c34d00b47..bc049a6ee6 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -656,42 +656,9 @@ inline bool isPowerOf2(int n) { class OpenGLTexture : public Texture { public: - OpenGLTexture(const TextureDesc &desc) : tex_(0), target_(TypeToTarget(desc.type)), format_(desc.format), mipLevels_(desc.mipLevels) { - generatedMips_ = false; - canWrap_ = true; - width_ = desc.width; - height_ = desc.height; - depth_ = desc.depth; - canWrap_ = !isPowerOf2(width_) || !isPowerOf2(height_); + OpenGLTexture(const TextureDesc &desc); + ~OpenGLTexture(); - glGenTextures(1, &tex_); - - if (!desc.initData.size()) - return; - - int level = 0; - for (auto data : desc.initData) { - SetImageData(0, 0, 0, width_, height_, depth_, level, 0, data); - width_ = (width_ + 1) /2; - height_ = (height_ + 1) /2; - level++; - } - if (desc.initData.size() < desc.mipLevels) - AutoGenMipmaps(); - } - ~OpenGLTexture() { - Destroy(); - } - - void Destroy() { - if (tex_) { - glDeleteTextures(1, &tex_); - tex_ = 0; - generatedMips_ = false; - } - } - - void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override; void AutoGenMipmaps(); bool HasMips() { @@ -706,6 +673,8 @@ public: } private: + void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data); + GLuint tex_; GLuint target_; @@ -715,6 +684,43 @@ private: bool canWrap_; }; +OpenGLTexture::OpenGLTexture(const TextureDesc &desc) : tex_(0), target_(TypeToTarget(desc.type)), format_(desc.format), mipLevels_(desc.mipLevels) { + generatedMips_ = false; + canWrap_ = true; + width_ = desc.width; + height_ = desc.height; + depth_ = desc.depth; + canWrap_ = !isPowerOf2(width_) || !isPowerOf2(height_); + + glGenTextures(1, &tex_); + + if (!desc.initData.size()) + return; + + int level = 0; + for (auto data : desc.initData) { + SetImageData(0, 0, 0, width_, height_, depth_, level, 0, data); + width_ = (width_ + 1) / 2; + height_ = (height_ + 1) / 2; + level++; + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, level > 1 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if (desc.initData.size() < desc.mipLevels) + AutoGenMipmaps(); +} + +OpenGLTexture::~OpenGLTexture() { + if (tex_) { + glDeleteTextures(1, &tex_); + tex_ = 0; + generatedMips_ = false; + } +} + Texture *OpenGLContext::CreateTexture(const TextureDesc &desc) { return new OpenGLTexture(desc); } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 8dc545193b..07da6fc8dd 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -597,11 +597,11 @@ public: Destroy(); } - void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override; - VkImageView GetImageView() { return vkTex_->GetImageView(); } private: + void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data); + bool Create(const TextureDesc &desc) { format_ = desc.format; mipLevels_ = desc.mipLevels;