summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends
diff options
context:
space:
mode:
authorRodolfo Bogado <rodolfoosvaldobogado@gmail.com>2015-06-29 22:19:19 -0300
committerRodolfo Bogado <rodolfoosvaldobogado@gmail.com>2015-07-02 08:53:40 -0300
commitd8cd2c3252ab6f2ce6c1656b5eb194863e834f52 (patch)
treebfefa30392b15403d1792f83cd5ea8cd709a397e /Source/Core/VideoBackends
parent8d69c2b4b722e2c4f9f0496b9ff1912c1a10d9e1 (diff)
Implement scaled partial texture updates
Diffstat (limited to 'Source/Core/VideoBackends')
-rw-r--r--Source/Core/VideoBackends/D3D/TextureCache.cpp62
-rw-r--r--Source/Core/VideoBackends/D3D/TextureCache.h5
-rw-r--r--Source/Core/VideoBackends/OGL/TextureCache.cpp69
-rw-r--r--Source/Core/VideoBackends/OGL/TextureCache.h5
4 files changed, 129 insertions, 12 deletions
diff --git a/Source/Core/VideoBackends/D3D/TextureCache.cpp b/Source/Core/VideoBackends/D3D/TextureCache.cpp
index 2c820849d5..de204fa2af 100644
--- a/Source/Core/VideoBackends/D3D/TextureCache.cpp
+++ b/Source/Core/VideoBackends/D3D/TextureCache.cpp
@@ -77,11 +77,67 @@ bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int l
return saved_png;
}
-void TextureCache::TCacheEntry::DoPartialTextureUpdate(TCacheEntryBase* entry_, u32 x, u32 y)
+void TextureCache::TCacheEntry::CopyRectangleFromTexture(
+ const TCacheEntryBase* source,
+ const MathUtil::Rectangle<int> &srcrect,
+ const MathUtil::Rectangle<int> &dstrect)
{
- TCacheEntry* entry = (TCacheEntry*)entry_;
+ TCacheEntry* srcentry = (TCacheEntry*)source;
+ if (srcrect.GetWidth() == dstrect.GetWidth()
+ && srcrect.GetHeight() == dstrect.GetHeight())
+ {
+ const D3D11_BOX *psrcbox = nullptr;
+ D3D11_BOX srcbox;
+ if (srcrect.left != 0 || srcrect.top != 0)
+ {
+ srcbox.left = srcrect.left;
+ srcbox.top = srcrect.top;
+ srcbox.right = srcrect.right;
+ srcbox.bottom = srcrect.bottom;
+ psrcbox = &srcbox;
+ }
+ D3D::context->CopySubresourceRegion(
+ texture->GetTex(),
+ 0,
+ dstrect.left,
+ dstrect.top,
+ 0,
+ srcentry->texture->GetTex(),
+ 0,
+ psrcbox);
+ return;
+ }
+ else if (!config.rendertarget)
+ {
+ return;
+ }
+ g_renderer->ResetAPIState(); // reset any game specific settings
- D3D::context->CopySubresourceRegion(texture->GetTex(), 0, x , y , 0, entry->texture->GetTex(), 0, NULL);
+ const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(
+ float(dstrect.left),
+ float(dstrect.top),
+ float(dstrect.GetWidth()),
+ float(dstrect.GetHeight()));
+
+ D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr);
+ D3D::context->RSSetViewports(1, &vp);
+ D3D::SetLinearCopySampler();
+ D3D11_RECT srcRC;
+ srcRC.left = srcrect.left;
+ srcRC.right = srcrect.right;
+ srcRC.top = srcrect.top;
+ srcRC.bottom = srcrect.bottom;
+ D3D::drawShadedTexQuad(srcentry->texture->GetSRV(), &srcRC,
+ srcentry->config.width, srcentry->config.height,
+ PixelShaderCache::GetColorCopyProgram(false),
+ VertexShaderCache::GetSimpleVertexShader(),
+ VertexShaderCache::GetSimpleInputLayout(), nullptr, 1.0, 0);
+
+ D3D::context->OMSetRenderTargets(1,
+ &FramebufferManager::GetEFBColorTexture()->GetRTV(),
+ FramebufferManager::GetEFBDepthTexture()->GetDSV());
+
+ g_renderer->RestoreAPIState();
}
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
diff --git a/Source/Core/VideoBackends/D3D/TextureCache.h b/Source/Core/VideoBackends/D3D/TextureCache.h
index d6cb7eeef0..608fa47044 100644
--- a/Source/Core/VideoBackends/D3D/TextureCache.h
+++ b/Source/Core/VideoBackends/D3D/TextureCache.h
@@ -26,7 +26,10 @@ private:
TCacheEntry(const TCacheEntryConfig& config, D3DTexture2D *_tex) : TCacheEntryBase(config), texture(_tex) {}
~TCacheEntry();
- void DoPartialTextureUpdate(TCacheEntryBase* entry, u32 x, u32 y) override;
+ void CopyRectangleFromTexture(
+ const TCacheEntryBase* source,
+ const MathUtil::Rectangle<int> &srcrect,
+ const MathUtil::Rectangle<int> &dstrect) override;
void Load(unsigned int width, unsigned int height,
unsigned int expanded_width, unsigned int levels) override;
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp
index cefc8017d6..ebc3a672f1 100644
--- a/Source/Core/VideoBackends/OGL/TextureCache.cpp
+++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp
@@ -33,11 +33,13 @@
namespace OGL
{
+static SHADER s_ColorCopyProgram;
static SHADER s_ColorMatrixProgram;
static SHADER s_DepthMatrixProgram;
static GLuint s_ColorMatrixUniform;
static GLuint s_DepthMatrixUniform;
static GLuint s_ColorCopyPositionUniform;
+static GLuint s_ColorMatrixPositionUniform;
static GLuint s_DepthCopyPositionUniform;
static u32 s_ColorCbufid;
static u32 s_DepthCbufid;
@@ -137,12 +139,53 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConf
return entry;
}
-void TextureCache::TCacheEntry::DoPartialTextureUpdate(TCacheEntryBase* entry_, u32 x, u32 y)
+void TextureCache::TCacheEntry::CopyRectangleFromTexture(
+ const TCacheEntryBase* source,
+ const MathUtil::Rectangle<int> &srcrect,
+ const MathUtil::Rectangle<int> &dstrect)
{
-
- TCacheEntry* entry = (TCacheEntry*)entry_;
-
- glCopyImageSubData(entry->texture, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, texture, GL_TEXTURE_2D_ARRAY, 0, x, y, 0, entry->native_width, entry->native_height, 1);
+ TCacheEntry* srcentry = (TCacheEntry*)source;
+ if (srcrect.GetWidth() == dstrect.GetWidth()
+ && srcrect.GetHeight() == dstrect.GetHeight()
+ && g_ActiveConfig.backend_info.bSupportsCopySubImage)
+ {
+ glCopyImageSubData(
+ srcentry->texture,
+ GL_TEXTURE_2D_ARRAY,
+ 0,
+ srcrect.left,
+ srcrect.top,
+ 0,
+ texture,
+ GL_TEXTURE_2D_ARRAY,
+ 0,
+ dstrect.left,
+ dstrect.top,
+ 0,
+ dstrect.GetWidth(),
+ dstrect.GetHeight(),
+ 1);
+ return;
+ }
+ else if (!config.rendertarget)
+ {
+ return;
+ }
+ g_renderer->ResetAPIState();
+ FramebufferManager::SetFramebuffer(framebuffer);
+ glActiveTexture(GL_TEXTURE9);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, srcentry->texture);
+ g_sampler_cache->BindLinearSampler(9);
+ glViewport(dstrect.left, dstrect.top, dstrect.GetWidth(), dstrect.GetHeight());
+ s_ColorCopyProgram.Bind();
+ glUniform4f(s_ColorCopyPositionUniform,
+ float(srcrect.left),
+ float(srcrect.top),
+ float(srcrect.GetWidth()),
+ float(srcrect.GetHeight()));
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ FramebufferManager::SetFramebuffer(0);
+ g_renderer->RestoreAPIState();
}
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
@@ -208,7 +251,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
if (s_ColorCbufid != cbufid)
glUniform4fv(s_ColorMatrixUniform, 7, colmat);
s_ColorCbufid = cbufid;
- uniform_location = s_ColorCopyPositionUniform;
+ uniform_location = s_ColorMatrixPositionUniform;
}
TargetRectangle R = g_renderer->ConvertEFBRectangle(srcRect);
@@ -286,6 +329,16 @@ void TextureCache::SetStage()
void TextureCache::CompileShaders()
{
+ const char *pColorCopyProg =
+ "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
+ "in vec3 f_uv0;\n"
+ "out vec4 ocol0;\n"
+ "\n"
+ "void main(){\n"
+ " vec4 texcol = texture(samp9, f_uv0);\n"
+ " ocol0 = texcol;\n"
+ "}\n";
+
const char *pColorMatrixProg =
"SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
"uniform vec4 colmat[7];\n"
@@ -357,6 +410,7 @@ void TextureCache::CompileShaders()
const char* prefix = (GProgram == nullptr) ? "f" : "v";
const char* depth_layer = (g_ActiveConfig.bStereoEFBMonoDepth) ? "0.0" : "f_uv0.z";
+ ProgramShaderCache::CompileShader(s_ColorCopyProgram, StringFromFormat(VProgram, prefix, prefix).c_str(), pColorCopyProg, GProgram);
ProgramShaderCache::CompileShader(s_ColorMatrixProgram, StringFromFormat(VProgram, prefix, prefix).c_str(), pColorMatrixProg, GProgram);
ProgramShaderCache::CompileShader(s_DepthMatrixProgram, StringFromFormat(VProgram, prefix, prefix).c_str(), StringFromFormat(pDepthMatrixProg, depth_layer).c_str(), GProgram);
@@ -365,7 +419,8 @@ void TextureCache::CompileShaders()
s_ColorCbufid = -1;
s_DepthCbufid = -1;
- s_ColorCopyPositionUniform = glGetUniformLocation(s_ColorMatrixProgram.glprogid, "copy_position");
+ s_ColorCopyPositionUniform = glGetUniformLocation(s_ColorCopyProgram.glprogid, "copy_position");
+ s_ColorMatrixPositionUniform = glGetUniformLocation(s_ColorMatrixProgram.glprogid, "copy_position");
s_DepthCopyPositionUniform = glGetUniformLocation(s_DepthMatrixProgram.glprogid, "copy_position");
std::string palette_shader =
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.h b/Source/Core/VideoBackends/OGL/TextureCache.h
index 42c83d8dda..1ed85b0539 100644
--- a/Source/Core/VideoBackends/OGL/TextureCache.h
+++ b/Source/Core/VideoBackends/OGL/TextureCache.h
@@ -33,7 +33,10 @@ private:
TCacheEntry(const TCacheEntryConfig& config);
~TCacheEntry();
- void DoPartialTextureUpdate(TCacheEntryBase* entry, u32 x, u32 y) override;
+ void CopyRectangleFromTexture(
+ const TCacheEntryBase* source,
+ const MathUtil::Rectangle<int> &srcrect,
+ const MathUtil::Rectangle<int> &dstrect) override;
void Load(unsigned int width, unsigned int height,
unsigned int expanded_width, unsigned int level) override;