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)
{
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()

View file

@ -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<TextStringEntry>(entry);
}
float w = entry->bmWidth * fontScaleX_;

View file

@ -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_; }

View file

@ -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;
};

View file

@ -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;

View file

@ -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);
}

View file

@ -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;