Merge pull request #2679 from Tinob/master

Implement scaled partial texture updates
This commit is contained in:
Markus Wick
2015-07-22 19:04:04 +02:00
7 changed files with 211 additions and 43 deletions

View File

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

View File

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

View File

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

View File

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