Refactor away SetImageData

This commit is contained in:
Henrik Rydgard 2017-02-19 11:02:24 +01:00
parent e42bce5568
commit eabcb22623
7 changed files with 117 additions and 111 deletions

View file

@ -58,15 +58,7 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
: GPUCommon(gfxCtx, draw) : GPUCommon(gfxCtx, draw)
{ {
using namespace Draw; using namespace Draw;
TextureDesc desc{}; fbTex = nullptr;
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);
InputLayoutDesc inputDesc = { InputLayoutDesc inputDesc = {
{ {
{ sizeof(Vertex), false }, { sizeof(Vertex), false },
@ -124,9 +116,10 @@ SoftGPU::~SoftGPU() {
texColor->Release(); texColor->Release();
texColor = nullptr; texColor = nullptr;
if (fbTex) {
fbTex->Release(); fbTex->Release();
fbTex = nullptr; fbTex = nullptr;
}
vdata->Release(); vdata->Release();
vdata = nullptr; vdata = nullptr;
idata->Release(); 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. // Copies RGBA8 data from RAM to the currently bound render target.
void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
using namespace Draw;
if (!draw_) if (!draw_)
return; return;
float dstwidth = (float)PSP_CoreParameter().pixelWidth; float dstwidth = (float)PSP_CoreParameter().pixelWidth;
float dstheight = (float)PSP_CoreParameter().pixelHeight; 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); draw_->SetViewports(1, &viewport);
SamplerState *sampler;
if (g_Config.iBufFilter == SCALE_NEAREST) {
sampler = samplerNearest;
} else {
sampler = samplerLinear;
}
draw_->SetScissorRect(0, 0, dstwidth, dstheight); draw_->SetScissorRect(0, 0, dstwidth, dstheight);
float u0 = 0.0f; float u0 = 0.0f;
float u1; 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; bool hasImage = true;
if (!Memory::IsValidAddress(displayFramebuf_)) { if (!Memory::IsValidAddress(displayFramebuf_)) {
hasImage = false; hasImage = false;
u1 = 1.0f; u1 = 1.0f;
} else if (displayFormat_ == GE_FORMAT_8888) { } else if (displayFormat_ == GE_FORMAT_8888) {
u8 *data = Memory::GetPointer(displayFramebuf_); 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_; u1 = (float)srcwidth / displayStride_;
} else { } else {
// TODO: This should probably be converted in a shader instead.. // 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; u1 = 1.0f;
} }
if (!hasImage) {
draw_->Clear(Draw::FB_COLOR_BIT, 0, 0, 0);
return;
}
fbTex = draw_->CreateTexture(desc);
float x, y, w, h; float x, y, w, h;
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, dstwidth, dstheight, ROTATION_LOCKED_HORIZONTAL); CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, dstwidth, dstheight, ROTATION_LOCKED_HORIZONTAL);
@ -224,7 +230,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
x2 -= 1.0f; x2 -= 1.0f;
y2 -= 1.0f; y2 -= 1.0f;
if (hasImage) {
float v0 = 1.0f; float v0 = 1.0f;
float v1 = 0.0f; float v1 = 0.0f;
@ -232,6 +237,12 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
std::swap(v0, v1); std::swap(v0, v1);
} }
Draw::SamplerState *sampler;
if (g_Config.iBufFilter == SCALE_NEAREST) {
sampler = samplerNearest;
} else {
sampler = samplerLinear;
}
draw_->BindSamplerStates(0, 1, &sampler); draw_->BindSamplerStates(0, 1, &sampler);
const Vertex verts[4] = { const Vertex verts[4] = {
@ -254,16 +265,13 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
}; };
VsTexColUB ub{}; Draw::VsTexColUB ub{};
memcpy(ub.WorldViewProj, identity4x4, sizeof(float) * 16); memcpy(ub.WorldViewProj, identity4x4, sizeof(float) * 16);
draw_->BindPipeline(texColor); draw_->BindPipeline(texColor);
draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub)); draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub));
draw_->BindVertexBuffers(0, 1, &vdata, nullptr); draw_->BindVertexBuffers(0, 1, &vdata, nullptr);
draw_->BindIndexBuffer(idata, 0); draw_->BindIndexBuffer(idata, 0);
draw_->DrawIndexed(6, 0); draw_->DrawIndexed(6, 0);
} else {
draw_->Clear(Draw::FB_COLOR_BIT, 0, 0, 0);
}
} }
void SoftGPU::CopyDisplayToOutput() void SoftGPU::CopyDisplayToOutput()

View file

@ -476,12 +476,11 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float
TextureDesc desc{}; TextureDesc desc{};
desc.type = TextureType::LINEAR2D; desc.type = TextureType::LINEAR2D;
desc.format = Draw::DataFormat::R4G4B4A4_UNORM_PACK16; desc.format = Draw::DataFormat::B4G4R4A4_UNORM_PACK16;
desc.width = entry->bmWidth; desc.width = entry->bmWidth;
desc.height = entry->bmHeight; desc.height = entry->bmHeight;
desc.depth = 1; desc.depth = 1;
desc.mipLevels = 1; desc.mipLevels = 1;
entry->texture = draw_->CreateTexture(desc);
uint16_t *bitmapData = new uint16_t[entry->bmWidth * entry->bmHeight]; uint16_t *bitmapData = new uint16_t[entry->bmWidth * entry->bmHeight];
for (int x = 0; x < entry->bmWidth; x++) { 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; 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; delete [] bitmapData;
cache_[entryHash] = std::unique_ptr<TextStringEntry>(entry); cache_[entryHash] = std::unique_ptr<TextStringEntry>(entry);
} }
float w = entry->bmWidth * fontScaleX_; float w = entry->bmWidth * fontScaleX_;

View file

@ -406,8 +406,6 @@ public:
class Texture : public RefCountedObject { class Texture : public RefCountedObject {
public: 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 Width() { return width_; }
int Height() { return height_; } int Height() { return height_; }
int Depth() { return depth_; } int Depth() { return depth_; }

View file

@ -647,10 +647,6 @@ public:
view->Release(); 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; ID3D11Texture2D *tex = nullptr;
ID3D11ShaderResourceView *view = nullptr; ID3D11ShaderResourceView *view = nullptr;
}; };

View file

@ -297,10 +297,10 @@ class D3D9Texture : public Texture {
public: public:
D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, const TextureDesc &desc); D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, const TextureDesc &desc);
~D3D9Texture(); ~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); void SetToSampler(LPDIRECT3DDEVICE9 device, int sampler);
private: 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); bool Create(const TextureDesc &desc);
LPDIRECT3DDEVICE9 device_; LPDIRECT3DDEVICE9 device_;
LPDIRECT3DDEVICE9EX deviceEx_; LPDIRECT3DDEVICE9EX deviceEx_;
@ -364,7 +364,7 @@ bool D3D9Texture::Create(const TextureDesc &desc) {
if (desc.initData.size()) { if (desc.initData.size()) {
for (int i = 0; i < desc.initData.size(); i++) { 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; return true;

View file

@ -656,7 +656,35 @@ inline bool isPowerOf2(int n) {
class OpenGLTexture : public Texture { class OpenGLTexture : public Texture {
public: public:
OpenGLTexture(const TextureDesc &desc) : tex_(0), target_(TypeToTarget(desc.type)), format_(desc.format), mipLevels_(desc.mipLevels) { OpenGLTexture(const TextureDesc &desc);
~OpenGLTexture();
void AutoGenMipmaps();
bool HasMips() {
return mipLevels_ > 1 || generatedMips_;
}
bool CanWrap() {
return canWrap_;
}
void Bind() {
glBindTexture(target_, tex_);
}
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_;
DataFormat format_;
int mipLevels_;
bool generatedMips_;
bool canWrap_;
};
OpenGLTexture::OpenGLTexture(const TextureDesc &desc) : tex_(0), target_(TypeToTarget(desc.type)), format_(desc.format), mipLevels_(desc.mipLevels) {
generatedMips_ = false; generatedMips_ = false;
canWrap_ = true; canWrap_ = true;
width_ = desc.width; width_ = desc.width;
@ -672,48 +700,26 @@ public:
int level = 0; int level = 0;
for (auto data : desc.initData) { for (auto data : desc.initData) {
SetImageData(0, 0, 0, width_, height_, depth_, level, 0, data); SetImageData(0, 0, 0, width_, height_, depth_, level, 0, data);
width_ = (width_ + 1) /2; width_ = (width_ + 1) / 2;
height_ = (height_ + 1) /2; height_ = (height_ + 1) / 2;
level++; 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) if (desc.initData.size() < desc.mipLevels)
AutoGenMipmaps(); AutoGenMipmaps();
} }
~OpenGLTexture() {
Destroy();
}
void Destroy() { OpenGLTexture::~OpenGLTexture() {
if (tex_) { if (tex_) {
glDeleteTextures(1, &tex_); glDeleteTextures(1, &tex_);
tex_ = 0; tex_ = 0;
generatedMips_ = false; 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() {
return mipLevels_ > 1 || generatedMips_;
}
bool CanWrap() {
return canWrap_;
}
void Bind() {
glBindTexture(target_, tex_);
}
private:
GLuint tex_;
GLuint target_;
DataFormat format_;
int mipLevels_;
bool generatedMips_;
bool canWrap_;
};
Texture *OpenGLContext::CreateTexture(const TextureDesc &desc) { Texture *OpenGLContext::CreateTexture(const TextureDesc &desc) {
return new OpenGLTexture(desc); return new OpenGLTexture(desc);

View file

@ -597,11 +597,11 @@ public:
Destroy(); 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(); } VkImageView GetImageView() { return vkTex_->GetImageView(); }
private: 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) { bool Create(const TextureDesc &desc) {
format_ = desc.format; format_ = desc.format;
mipLevels_ = desc.mipLevels; mipLevels_ = desc.mipLevels;