Compare commits

..

2 Commits

Author SHA1 Message Date
Subv
f22e090b86 GLCache: Use the full uncompressed size when blitting from one texture to another.
This avoids the problem of only copying a tiny piece of the textures when they are compressed.
2018-06-06 23:26:36 -05:00
Subv
218a08df93 GLCache: Simplify the logic to copy from one texture to another in BlitTextures.
We now use glCopyImageSubData, this should avoid errors with trying to attach a compressed texture as a framebuffer's color attachment and then blitting to it.

Maybe in the future we can change this to glCopyTextureSubImage which only requires GL_ARB_direct_state_access.
2018-06-06 23:25:24 -05:00
3 changed files with 17 additions and 80 deletions

View File

@@ -390,9 +390,6 @@ class OpCode {
public:
enum class Id {
KIL,
BFE_C,
BFE_R,
BFE_IMM,
BRA,
LD_A,
LD_C,
@@ -447,9 +444,6 @@ public:
FMNMX_C,
FMNMX_R,
FMNMX_IMM,
IMNMX_C,
IMNMX_R,
IMNMX_IMM,
FSETP_C, // Set Predicate
FSETP_R,
FSETP_IMM,
@@ -460,10 +454,6 @@ public:
ISETP_IMM,
ISETP_R,
PSETP,
XMAD_IMM,
XMAD_CR,
XMAD_RC,
XMAD_RR,
};
enum class Type {
@@ -575,9 +565,6 @@ private:
std::vector<Matcher> table = {
#define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name)
INST("111000110011----", Id::KIL, Type::Flow, "KIL"),
INST("0100110000000---", Id::BFE_C, Type::Flow, "BFE_C"),
INST("0101110000000---", Id::BFE_R, Type::Flow, "BFE_R"),
INST("0011100-00000---", Id::BFE_IMM, Type::Flow, "BFE_IMM"),
INST("111000100100----", Id::BRA, Type::Flow, "BRA"),
INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"),
INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"),
@@ -619,9 +606,6 @@ private:
INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"),
INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"),
INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"),
INST("0100110000100---", Id::IMNMX_C, Type::Arithmetic, "FMNMX_IMM"),
INST("0101110000100---", Id::IMNMX_R, Type::Arithmetic, "FMNMX_IMM"),
INST("0011100-00100---", Id::IMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"),
INST("000001----------", Id::LOP32I, Type::Logic, "LOP32I"),
INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"),
INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"),
@@ -645,10 +629,6 @@ private:
INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"),
INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"),
INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
INST("0011011-00------", Id::XMAD_IMM, Type::Arithmetic, "XMAD_IMM"),
INST("0100111---------", Id::XMAD_CR, Type::Arithmetic, "XMAD_CR"),
INST("010100010-------", Id::XMAD_RC, Type::Arithmetic, "XMAD_RC"),
INST("0101101100------", Id::XMAD_RR, Type::Arithmetic, "XMAD_RR"),
};
#undef INST
std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) {

View File

@@ -169,60 +169,10 @@ static void AllocateSurfaceTexture(GLuint texture, const FormatTuple& format_tup
static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, GLuint dst_tex,
const MathUtil::Rectangle<u32>& dst_rect, SurfaceType type,
GLuint read_fb_handle, GLuint draw_fb_handle) {
OpenGLState state = OpenGLState::GetCurState();
OpenGLState prev_state = state;
SCOPE_EXIT({ prev_state.Apply(); });
// Make sure textures aren't bound to texture units, since going to bind them to framebuffer
// components
state.ResetTexture(src_tex);
state.ResetTexture(dst_tex);
state.draw.read_framebuffer = read_fb_handle;
state.draw.draw_framebuffer = draw_fb_handle;
state.Apply();
u32 buffers = 0;
if (type == SurfaceType::ColorTexture) {
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_tex,
0);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex,
0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
0);
buffers = GL_COLOR_BUFFER_BIT;
} else if (type == SurfaceType::Depth) {
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, src_tex, 0);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, dst_tex, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
buffers = GL_DEPTH_BUFFER_BIT;
} else if (type == SurfaceType::DepthStencil) {
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
src_tex, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
dst_tex, 0);
buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
}
glBlitFramebuffer(src_rect.left, src_rect.bottom, src_rect.right, src_rect.top, dst_rect.left,
dst_rect.bottom, dst_rect.right, dst_rect.top, buffers,
buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST);
glCopyImageSubData(src_tex, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, 0, dst_tex,
GL_TEXTURE_2D, 0, dst_rect.left, dst_rect.bottom, 0, src_rect.GetWidth(),
src_rect.GetHeight(), 0);
return true;
}
@@ -1102,16 +1052,19 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
params.UpdateParams();
if (config.tic.Width() % 8 != 0 || config.tic.Height() % 8 != 0 ||
if (params.GetActualWidth() % 8 != 0 || params.GetActualHeight() % 8 != 0 ||
params.stride != params.width) {
Surface src_surface;
MathUtil::Rectangle<u32> rect;
std::tie(src_surface, rect) = GetSurfaceSubRect(params, ScaleMatch::Ignore, true);
rect = rect.Scale(params.GetCompresssionFactor());
params.res_scale = src_surface->res_scale;
Surface tmp_surface = CreateSurface(params);
BlitTextures(src_surface->texture.handle, rect, tmp_surface->texture.handle,
tmp_surface->GetScaledRect(),
auto dst_rect = tmp_surface->GetScaledRect().Scale(params.GetCompresssionFactor());
BlitTextures(src_surface->texture.handle, rect, tmp_surface->texture.handle, dst_rect,
SurfaceParams::GetFormatType(params.pixel_format), read_framebuffer.handle,
draw_framebuffer.handle);

View File

@@ -1112,11 +1112,13 @@ private:
break;
}
case OpCode::Type::Memory: {
const Attribute::Index attribute = instr.attribute.fmt20.index;
switch (opcode->GetId()) {
case OpCode::Id::LD_A: {
ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested");
regs.SetRegisterToInputAttibute(instr.gpr0, instr.attribute.fmt20.element,
instr.attribute.fmt20.index);
attribute);
break;
}
case OpCode::Id::LD_C: {
@@ -1148,11 +1150,12 @@ private:
}
case OpCode::Id::ST_A: {
ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested");
regs.SetOutputAttributeToRegister(instr.attribute.fmt20.index,
instr.attribute.fmt20.element, instr.gpr0);
regs.SetOutputAttributeToRegister(attribute, instr.attribute.fmt20.element,
instr.gpr0);
break;
}
case OpCode::Id::TEX: {
ASSERT_MSG(instr.attribute.fmt20.size == 4, "untested");
const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
const std::string op_b = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
const std::string sampler = GetSampler(instr.sampler);
@@ -1165,7 +1168,7 @@ private:
const std::string texture = "texture(" + sampler + ", coords)";
size_t dest_elem{};
for (size_t elem = 0; elem < 4; ++elem) {
for (size_t elem = 0; elem < instr.attribute.fmt20.size; ++elem) {
if (!instr.tex.IsComponentEnabled(elem)) {
// Skip disabled components
continue;
@@ -1178,6 +1181,7 @@ private:
break;
}
case OpCode::Id::TEXS: {
ASSERT_MSG(instr.attribute.fmt20.size == 4, "untested");
const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20);
const std::string sampler = GetSampler(instr.sampler);