summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------externals/dynarmic0
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp429
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h43
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp30
-rw-r--r--src/video_core/textures/texture.h2
-rw-r--r--src/yuzu/main.cpp18
7 files changed, 388 insertions, 141 deletions
diff --git a/externals/dynarmic b/externals/dynarmic
Subproject 171d11659d760a4d4674d3a90698fe31ea407e2 Subproject 4e6848d1c9e8dadc70595c15b5589f8b14aad47
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 1fcd13f04..587d9dffb 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -738,7 +738,7 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
738 } 738 }
739 739
740 texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); 740 texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc);
741 Surface surface = res_cache.GetTextureSurface(texture); 741 Surface surface = res_cache.GetTextureSurface(texture, entry);
742 if (surface != nullptr) { 742 if (surface != nullptr) {
743 state.texture_units[current_bindpoint].texture = surface->Texture().handle; 743 state.texture_units[current_bindpoint].texture = surface->Texture().handle;
744 state.texture_units[current_bindpoint].target = surface->Target(); 744 state.texture_units[current_bindpoint].target = surface->Target();
@@ -909,7 +909,10 @@ void RasterizerOpenGL::SyncTransformFeedback() {
909void RasterizerOpenGL::SyncPointState() { 909void RasterizerOpenGL::SyncPointState() {
910 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 910 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
911 911
912 state.point.size = regs.point_size; 912 // TODO(Rodrigo): Most games do not set a point size. I think this is a case of a
913 // register carrying a default value. For now, if the point size is zero, assume it's
914 // OpenGL's default (1).
915 state.point.size = regs.point_size == 0 ? 1 : regs.point_size;
913} 916}
914 917
915} // namespace OpenGL 918} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 24a540258..ce967c4d6 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -41,7 +41,7 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
41} 41}
42 42
43/*static*/ SurfaceParams SurfaceParams::CreateForTexture( 43/*static*/ SurfaceParams SurfaceParams::CreateForTexture(
44 const Tegra::Texture::FullTextureInfo& config) { 44 const Tegra::Texture::FullTextureInfo& config, const GLShader::SamplerEntry& entry) {
45 SurfaceParams params{}; 45 SurfaceParams params{};
46 params.addr = TryGetCpuAddr(config.tic.Address()); 46 params.addr = TryGetCpuAddr(config.tic.Address());
47 params.is_tiled = config.tic.IsTiled(); 47 params.is_tiled = config.tic.IsTiled();
@@ -60,9 +60,23 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
60 case SurfaceTarget::Texture2D: 60 case SurfaceTarget::Texture2D:
61 params.depth = 1; 61 params.depth = 1;
62 break; 62 break;
63 case SurfaceTarget::TextureCubemap:
64 params.depth = config.tic.Depth() * 6;
65 break;
63 case SurfaceTarget::Texture3D: 66 case SurfaceTarget::Texture3D:
67 params.depth = config.tic.Depth();
68 break;
64 case SurfaceTarget::Texture2DArray: 69 case SurfaceTarget::Texture2DArray:
65 params.depth = config.tic.Depth(); 70 params.depth = config.tic.Depth();
71 if (!entry.IsArray()) {
72 // TODO(bunnei): We have seen games re-use a Texture2D as Texture2DArray with depth of
73 // one, but sample the texture in the shader as if it were not an array texture. This
74 // probably is valid on hardware, but we still need to write a test to confirm this. In
75 // emulation, the workaround here is to continue to treat this as a Texture2D. An
76 // example game that does this is Super Mario Odyssey (in Cloud Kingdom).
77 ASSERT(params.depth == 1);
78 params.target = SurfaceTarget::Texture2D;
79 }
66 break; 80 break;
67 default: 81 default:
68 LOG_CRITICAL(HW_GPU, "Unknown depth for target={}", static_cast<u32>(params.target)); 82 LOG_CRITICAL(HW_GPU, "Unknown depth for target={}", static_cast<u32>(params.target));
@@ -71,7 +85,11 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
71 break; 85 break;
72 } 86 }
73 87
74 params.size_in_bytes = params.SizeInBytes(); 88 params.size_in_bytes_total = params.SizeInBytesTotal();
89 params.size_in_bytes_2d = params.SizeInBytes2D();
90 params.max_mip_level = config.tic.max_mip_level + 1;
91 params.rt = {};
92
75 return params; 93 return params;
76} 94}
77 95
@@ -89,7 +107,16 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
89 params.unaligned_height = config.height; 107 params.unaligned_height = config.height;
90 params.target = SurfaceTarget::Texture2D; 108 params.target = SurfaceTarget::Texture2D;
91 params.depth = 1; 109 params.depth = 1;
92 params.size_in_bytes = params.SizeInBytes(); 110 params.size_in_bytes_total = params.SizeInBytesTotal();
111 params.size_in_bytes_2d = params.SizeInBytes2D();
112 params.max_mip_level = 0;
113
114 // Render target specific parameters, not used for caching
115 params.rt.index = static_cast<u32>(index);
116 params.rt.array_mode = config.array_mode;
117 params.rt.layer_stride = config.layer_stride;
118 params.rt.base_layer = config.base_layer;
119
93 return params; 120 return params;
94} 121}
95 122
@@ -108,7 +135,11 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
108 params.unaligned_height = zeta_height; 135 params.unaligned_height = zeta_height;
109 params.target = SurfaceTarget::Texture2D; 136 params.target = SurfaceTarget::Texture2D;
110 params.depth = 1; 137 params.depth = 1;
111 params.size_in_bytes = params.SizeInBytes(); 138 params.size_in_bytes_total = params.SizeInBytesTotal();
139 params.size_in_bytes_2d = params.SizeInBytes2D();
140 params.max_mip_level = 0;
141 params.rt = {};
142
112 return params; 143 return params;
113} 144}
114 145
@@ -400,9 +431,13 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, std::size_t, VAddr),
400 // clang-format on 431 // clang-format on
401}; 432};
402 433
403static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, GLuint dst_tex, 434static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
404 const MathUtil::Rectangle<u32>& dst_rect, SurfaceType type, 435 GLuint read_fb_handle, GLuint draw_fb_handle, GLenum src_attachment = 0,
405 GLuint read_fb_handle, GLuint draw_fb_handle) { 436 GLenum dst_attachment = 0, std::size_t cubemap_face = 0) {
437
438 const auto& src_params{src_surface->GetSurfaceParams()};
439 const auto& dst_params{dst_surface->GetSurfaceParams()};
440
406 OpenGLState prev_state{OpenGLState::GetCurState()}; 441 OpenGLState prev_state{OpenGLState::GetCurState()};
407 SCOPE_EXIT({ prev_state.Apply(); }); 442 SCOPE_EXIT({ prev_state.Apply(); });
408 443
@@ -413,47 +448,203 @@ static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rec
413 448
414 u32 buffers{}; 449 u32 buffers{};
415 450
416 if (type == SurfaceType::ColorTexture) { 451 if (src_params.type == SurfaceType::ColorTexture) {
417 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_tex, 452 switch (src_params.target) {
418 0); 453 case SurfaceParams::SurfaceTarget::Texture2D:
419 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 454 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
420 0); 455 GL_TEXTURE_2D, src_surface->Texture().handle, 0);
456 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
457 0, 0);
458 break;
459 case SurfaceParams::SurfaceTarget::TextureCubemap:
460 glFramebufferTexture2D(
461 GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
462 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face),
463 src_surface->Texture().handle, 0);
464 glFramebufferTexture2D(
465 GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
466 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0);
467 break;
468 case SurfaceParams::SurfaceTarget::Texture2DArray:
469 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
470 src_surface->Texture().handle, 0, 0);
471 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
472 break;
473 case SurfaceParams::SurfaceTarget::Texture3D:
474 glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
475 SurfaceTargetToGL(src_params.target),
476 src_surface->Texture().handle, 0, 0);
477 glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
478 SurfaceTargetToGL(src_params.target), 0, 0, 0);
479 break;
480 default:
481 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
482 GL_TEXTURE_2D, src_surface->Texture().handle, 0);
483 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
484 0, 0);
485 break;
486 }
487
488 switch (dst_params.target) {
489 case SurfaceParams::SurfaceTarget::Texture2D:
490 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
491 GL_TEXTURE_2D, dst_surface->Texture().handle, 0);
492 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
493 0, 0);
494 break;
495 case SurfaceParams::SurfaceTarget::TextureCubemap:
496 glFramebufferTexture2D(
497 GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
498 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face),
499 dst_surface->Texture().handle, 0);
500 glFramebufferTexture2D(
501 GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
502 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0);
503 break;
504 case SurfaceParams::SurfaceTarget::Texture2DArray:
505 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
506 dst_surface->Texture().handle, 0, 0);
507 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
508 break;
421 509
422 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, 510 case SurfaceParams::SurfaceTarget::Texture3D:
423 0); 511 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
424 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 512 SurfaceTargetToGL(dst_params.target),
425 0); 513 dst_surface->Texture().handle, 0, 0);
514 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
515 SurfaceTargetToGL(dst_params.target), 0, 0, 0);
516 break;
517 default:
518 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
519 GL_TEXTURE_2D, dst_surface->Texture().handle, 0);
520 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
521 0, 0);
522 break;
523 }
426 524
427 buffers = GL_COLOR_BUFFER_BIT; 525 buffers = GL_COLOR_BUFFER_BIT;
428 } else if (type == SurfaceType::Depth) { 526 } else if (src_params.type == SurfaceType::Depth) {
429 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 527 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
430 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, src_tex, 0); 528 GL_TEXTURE_2D, 0, 0);
529 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
530 src_surface->Texture().handle, 0);
431 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); 531 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
432 532
433 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 533 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
434 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, dst_tex, 0); 534 GL_TEXTURE_2D, 0, 0);
535 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
536 dst_surface->Texture().handle, 0);
435 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); 537 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
436 538
437 buffers = GL_DEPTH_BUFFER_BIT; 539 buffers = GL_DEPTH_BUFFER_BIT;
438 } else if (type == SurfaceType::DepthStencil) { 540 } else if (src_params.type == SurfaceType::DepthStencil) {
439 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 541 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
542 GL_TEXTURE_2D, 0, 0);
440 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 543 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
441 src_tex, 0); 544 src_surface->Texture().handle, 0);
442 545
443 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 546 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
547 GL_TEXTURE_2D, 0, 0);
444 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 548 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
445 dst_tex, 0); 549 dst_surface->Texture().handle, 0);
446 550
447 buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; 551 buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
448 } 552 }
449 553
450 glBlitFramebuffer(src_rect.left, src_rect.bottom, src_rect.right, src_rect.top, dst_rect.left, 554 const auto& rect{src_params.GetRect()};
451 dst_rect.bottom, dst_rect.right, dst_rect.top, buffers, 555 glBlitFramebuffer(rect.left, rect.bottom, rect.right, rect.top, rect.left, rect.bottom,
556 rect.right, rect.top, buffers,
452 buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); 557 buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST);
453 558
454 return true; 559 return true;
455} 560}
456 561
562static void CopySurface(const Surface& src_surface, const Surface& dst_surface,
563 GLuint copy_pbo_handle, GLenum src_attachment = 0,
564 GLenum dst_attachment = 0, std::size_t cubemap_face = 0) {
565 ASSERT_MSG(dst_attachment == 0, "Unimplemented");
566
567 const auto& src_params{src_surface->GetSurfaceParams()};
568 const auto& dst_params{dst_surface->GetSurfaceParams()};
569
570 auto source_format = GetFormatTuple(src_params.pixel_format, src_params.component_type);
571 auto dest_format = GetFormatTuple(dst_params.pixel_format, dst_params.component_type);
572
573 std::size_t buffer_size =
574 std::max(src_params.size_in_bytes_total, dst_params.size_in_bytes_total);
575
576 glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo_handle);
577 glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB);
578 if (source_format.compressed) {
579 glGetCompressedTextureImage(src_surface->Texture().handle, src_attachment,
580 static_cast<GLsizei>(src_params.size_in_bytes_total), nullptr);
581 } else {
582 glGetTextureImage(src_surface->Texture().handle, src_attachment, source_format.format,
583 source_format.type, static_cast<GLsizei>(src_params.size_in_bytes_total),
584 nullptr);
585 }
586 // If the new texture is bigger than the previous one, we need to fill in the rest with data
587 // from the CPU.
588 if (src_params.size_in_bytes_total < dst_params.size_in_bytes_total) {
589 // Upload the rest of the memory.
590 if (dst_params.is_tiled) {
591 // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest
592 // of the data in this case. Games like Super Mario Odyssey seem to hit this case
593 // when drawing, it re-uses the memory of a previous texture as a bigger framebuffer
594 // but it doesn't clear it beforehand, the texture is already full of zeros.
595 LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during "
596 "reinterpretation but the texture is tiled.");
597 }
598 std::size_t remaining_size =
599 dst_params.size_in_bytes_total - src_params.size_in_bytes_total;
600 std::vector<u8> data(remaining_size);
601 Memory::ReadBlock(dst_params.addr + src_params.size_in_bytes_total, data.data(),
602 data.size());
603 glBufferSubData(GL_PIXEL_PACK_BUFFER, src_params.size_in_bytes_total, remaining_size,
604 data.data());
605 }
606
607 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
608
609 const GLsizei width{static_cast<GLsizei>(
610 std::min(src_params.GetRect().GetWidth(), dst_params.GetRect().GetWidth()))};
611 const GLsizei height{static_cast<GLsizei>(
612 std::min(src_params.GetRect().GetHeight(), dst_params.GetRect().GetHeight()))};
613
614 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, copy_pbo_handle);
615 if (dest_format.compressed) {
616 LOG_CRITICAL(HW_GPU, "Compressed copy is unimplemented!");
617 UNREACHABLE();
618 } else {
619 switch (dst_params.target) {
620 case SurfaceParams::SurfaceTarget::Texture1D:
621 glTextureSubImage1D(dst_surface->Texture().handle, 0, 0, width, dest_format.format,
622 dest_format.type, nullptr);
623 break;
624 case SurfaceParams::SurfaceTarget::Texture2D:
625 glTextureSubImage2D(dst_surface->Texture().handle, 0, 0, 0, width, height,
626 dest_format.format, dest_format.type, nullptr);
627 break;
628 case SurfaceParams::SurfaceTarget::Texture3D:
629 case SurfaceParams::SurfaceTarget::Texture2DArray:
630 glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0, 0, width, height,
631 static_cast<GLsizei>(dst_params.depth), dest_format.format,
632 dest_format.type, nullptr);
633 break;
634 case SurfaceParams::SurfaceTarget::TextureCubemap:
635 glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0,
636 static_cast<GLint>(cubemap_face), width, height, 1,
637 dest_format.format, dest_format.type, nullptr);
638 break;
639 default:
640 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
641 static_cast<u32>(dst_params.target));
642 UNREACHABLE();
643 }
644 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
645 }
646}
647
457CachedSurface::CachedSurface(const SurfaceParams& params) 648CachedSurface::CachedSurface(const SurfaceParams& params)
458 : params(params), gl_target(SurfaceTargetToGL(params.target)) { 649 : params(params), gl_target(SurfaceTargetToGL(params.target)) {
459 texture.Create(); 650 texture.Create();
@@ -481,6 +672,7 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
481 rect.GetWidth()); 672 rect.GetWidth());
482 break; 673 break;
483 case SurfaceParams::SurfaceTarget::Texture2D: 674 case SurfaceParams::SurfaceTarget::Texture2D:
675 case SurfaceParams::SurfaceTarget::TextureCubemap:
484 glTexStorage2D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format, 676 glTexStorage2D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format,
485 rect.GetWidth(), rect.GetHeight()); 677 rect.GetWidth(), rect.GetHeight());
486 break; 678 break;
@@ -585,29 +777,39 @@ void CachedSurface::LoadGLBuffer() {
585 777
586 const u32 bytes_per_pixel = GetGLBytesPerPixel(params.pixel_format); 778 const u32 bytes_per_pixel = GetGLBytesPerPixel(params.pixel_format);
587 const u32 copy_size = params.width * params.height * bytes_per_pixel; 779 const u32 copy_size = params.width * params.height * bytes_per_pixel;
780 const std::size_t total_size = copy_size * params.depth;
588 781
589 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); 782 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad);
590 783
591 if (params.is_tiled) { 784 if (params.is_tiled) {
785 gl_buffer.resize(total_size);
786
592 // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do 787 // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do
593 // this for 3D textures, etc. 788 // this for 3D textures, etc.
594 switch (params.target) { 789 switch (params.target) {
595 case SurfaceParams::SurfaceTarget::Texture2D: 790 case SurfaceParams::SurfaceTarget::Texture2D:
596 // Pass impl. to the fallback code below 791 // Pass impl. to the fallback code below
597 break; 792 break;
793 case SurfaceParams::SurfaceTarget::Texture2DArray:
794 case SurfaceParams::SurfaceTarget::TextureCubemap:
795 for (std::size_t index = 0; index < params.depth; ++index) {
796 const std::size_t offset{index * copy_size};
797 morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)](
798 params.width, params.block_height, params.height, gl_buffer.data() + offset,
799 copy_size, params.addr + offset);
800 }
801 break;
598 default: 802 default:
599 LOG_CRITICAL(HW_GPU, "Unimplemented tiled load for target={}", 803 LOG_CRITICAL(HW_GPU, "Unimplemented tiled load for target={}",
600 static_cast<u32>(params.target)); 804 static_cast<u32>(params.target));
601 UNREACHABLE(); 805 UNREACHABLE();
602 } 806 }
603 807
604 gl_buffer.resize(static_cast<std::size_t>(params.depth) * copy_size);
605 morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)]( 808 morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)](
606 params.width, params.block_height, params.height, gl_buffer.data(), copy_size, 809 params.width, params.block_height, params.height, gl_buffer.data(), copy_size,
607 params.addr); 810 params.addr);
608 } else { 811 } else {
609 const u8* const texture_src_data_end{texture_src_data + 812 const u8* const texture_src_data_end{texture_src_data + total_size};
610 (static_cast<std::size_t>(params.depth) * copy_size)};
611 gl_buffer.assign(texture_src_data, texture_src_data_end); 813 gl_buffer.assign(texture_src_data, texture_src_data_end);
612 } 814 }
613 815
@@ -634,7 +836,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
634 // Load data from memory to the surface 836 // Load data from memory to the surface
635 const GLint x0 = static_cast<GLint>(rect.left); 837 const GLint x0 = static_cast<GLint>(rect.left);
636 const GLint y0 = static_cast<GLint>(rect.bottom); 838 const GLint y0 = static_cast<GLint>(rect.bottom);
637 const std::size_t buffer_offset = 839 std::size_t buffer_offset =
638 static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.width + 840 static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.width +
639 static_cast<std::size_t>(x0)) * 841 static_cast<std::size_t>(x0)) *
640 GetGLBytesPerPixel(params.pixel_format); 842 GetGLBytesPerPixel(params.pixel_format);
@@ -663,15 +865,25 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
663 glCompressedTexImage2D( 865 glCompressedTexImage2D(
664 SurfaceTargetToGL(params.target), 0, tuple.internal_format, 866 SurfaceTargetToGL(params.target), 0, tuple.internal_format,
665 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0, 867 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0,
666 static_cast<GLsizei>(params.size_in_bytes), &gl_buffer[buffer_offset]); 868 static_cast<GLsizei>(params.size_in_bytes_2d), &gl_buffer[buffer_offset]);
667 break; 869 break;
668 case SurfaceParams::SurfaceTarget::Texture3D: 870 case SurfaceParams::SurfaceTarget::Texture3D:
669 case SurfaceParams::SurfaceTarget::Texture2DArray: 871 case SurfaceParams::SurfaceTarget::Texture2DArray:
670 glCompressedTexImage3D( 872 glCompressedTexImage3D(
671 SurfaceTargetToGL(params.target), 0, tuple.internal_format, 873 SurfaceTargetToGL(params.target), 0, tuple.internal_format,
672 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 874 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height),
673 static_cast<GLsizei>(params.depth), 0, static_cast<GLsizei>(params.size_in_bytes), 875 static_cast<GLsizei>(params.depth), 0,
674 &gl_buffer[buffer_offset]); 876 static_cast<GLsizei>(params.size_in_bytes_total), &gl_buffer[buffer_offset]);
877 break;
878 case SurfaceParams::SurfaceTarget::TextureCubemap:
879 for (std::size_t face = 0; face < params.depth; ++face) {
880 glCompressedTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face),
881 0, tuple.internal_format, static_cast<GLsizei>(params.width),
882 static_cast<GLsizei>(params.height), 0,
883 static_cast<GLsizei>(params.size_in_bytes_2d),
884 &gl_buffer[buffer_offset]);
885 buffer_offset += params.size_in_bytes_2d;
886 }
675 break; 887 break;
676 default: 888 default:
677 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", 889 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
@@ -679,8 +891,8 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
679 UNREACHABLE(); 891 UNREACHABLE();
680 glCompressedTexImage2D( 892 glCompressedTexImage2D(
681 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width), 893 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width),
682 static_cast<GLsizei>(params.height), 0, static_cast<GLsizei>(params.size_in_bytes), 894 static_cast<GLsizei>(params.height), 0,
683 &gl_buffer[buffer_offset]); 895 static_cast<GLsizei>(params.size_in_bytes_2d), &gl_buffer[buffer_offset]);
684 } 896 }
685 } else { 897 } else {
686 898
@@ -703,6 +915,15 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
703 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format, 915 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
704 tuple.type, &gl_buffer[buffer_offset]); 916 tuple.type, &gl_buffer[buffer_offset]);
705 break; 917 break;
918 case SurfaceParams::SurfaceTarget::TextureCubemap:
919 for (std::size_t face = 0; face < params.depth; ++face) {
920 glTexSubImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), 0, x0,
921 y0, static_cast<GLsizei>(rect.GetWidth()),
922 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
923 &gl_buffer[buffer_offset]);
924 buffer_offset += params.size_in_bytes_2d;
925 }
926 break;
706 default: 927 default:
707 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", 928 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
708 static_cast<u32>(params.target)); 929 static_cast<u32>(params.target));
@@ -722,8 +943,9 @@ RasterizerCacheOpenGL::RasterizerCacheOpenGL() {
722 copy_pbo.Create(); 943 copy_pbo.Create();
723} 944}
724 945
725Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) { 946Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config,
726 return GetSurface(SurfaceParams::CreateForTexture(config)); 947 const GLShader::SamplerEntry& entry) {
948 return GetSurface(SurfaceParams::CreateForTexture(config, entry));
727} 949}
728 950
729Surface RasterizerCacheOpenGL::GetDepthBufferSurface(bool preserve_contents) { 951Surface RasterizerCacheOpenGL::GetDepthBufferSurface(bool preserve_contents) {
@@ -811,98 +1033,69 @@ Surface RasterizerCacheOpenGL::GetUncachedSurface(const SurfaceParams& params) {
811 return surface; 1033 return surface;
812} 1034}
813 1035
814Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, 1036Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
815 const SurfaceParams& new_params) { 1037 const SurfaceParams& new_params) {
816 // Verify surface is compatible for blitting 1038 // Verify surface is compatible for blitting
817 const auto& params{surface->GetSurfaceParams()}; 1039 auto old_params{old_surface->GetSurfaceParams()};
818 1040
819 // Get a new surface with the new parameters, and blit the previous surface to it 1041 // Get a new surface with the new parameters, and blit the previous surface to it
820 Surface new_surface{GetUncachedSurface(new_params)}; 1042 Surface new_surface{GetUncachedSurface(new_params)};
821 1043
822 if (params.pixel_format == new_params.pixel_format || 1044 // If the format is the same, just do a framebuffer blit. This is significantly faster than
823 !Settings::values.use_accurate_framebuffers) { 1045 // using PBOs. The is also likely less accurate, as textures will be converted rather than
824 // If the format is the same, just do a framebuffer blit. This is significantly faster than 1046 // reinterpreted. When use_accurate_framebuffers setting is enabled, perform a more accurate
825 // using PBOs. The is also likely less accurate, as textures will be converted rather than 1047 // surface copy, where pixels are reinterpreted as a new format (without conversion). This
826 // reinterpreted. 1048 // code path uses OpenGL PBOs and is quite slow.
827 1049 const bool is_blit{old_params.pixel_format == new_params.pixel_format ||
828 BlitTextures(surface->Texture().handle, params.GetRect(), new_surface->Texture().handle, 1050 !Settings::values.use_accurate_framebuffers};
829 params.GetRect(), params.type, read_framebuffer.handle,
830 draw_framebuffer.handle);
831 } else {
832 // When use_accurate_framebuffers setting is enabled, perform a more accurate surface copy,
833 // where pixels are reinterpreted as a new format (without conversion). This code path uses
834 // OpenGL PBOs and is quite slow.
835
836 auto source_format = GetFormatTuple(params.pixel_format, params.component_type);
837 auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type);
838
839 std::size_t buffer_size = std::max(params.SizeInBytes(), new_params.SizeInBytes());
840 1051
841 glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo.handle); 1052 switch (new_params.target) {
842 glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); 1053 case SurfaceParams::SurfaceTarget::Texture2D:
843 if (source_format.compressed) { 1054 if (is_blit) {
844 glGetCompressedTextureImage(surface->Texture().handle, 0, 1055 BlitSurface(old_surface, new_surface, read_framebuffer.handle, draw_framebuffer.handle);
845 static_cast<GLsizei>(params.SizeInBytes()), nullptr);
846 } else { 1056 } else {
847 glGetTextureImage(surface->Texture().handle, 0, source_format.format, 1057 CopySurface(old_surface, new_surface, copy_pbo.handle);
848 source_format.type, static_cast<GLsizei>(params.SizeInBytes()),
849 nullptr);
850 } 1058 }
851 // If the new texture is bigger than the previous one, we need to fill in the rest with data 1059 break;
852 // from the CPU. 1060 case SurfaceParams::SurfaceTarget::TextureCubemap: {
853 if (params.SizeInBytes() < new_params.SizeInBytes()) { 1061 if (old_params.rt.array_mode != 1) {
854 // Upload the rest of the memory. 1062 // TODO(bunnei): This is used by Breath of the Wild, I'm not sure how to implement this
855 if (new_params.is_tiled) { 1063 // yet (array rendering used as a cubemap texture).
856 // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest 1064 LOG_CRITICAL(HW_GPU, "Unhandled rendertarget array_mode {}", old_params.rt.array_mode);
857 // of the data in this case. Games like Super Mario Odyssey seem to hit this case 1065 UNREACHABLE();
858 // when drawing, it re-uses the memory of a previous texture as a bigger framebuffer 1066 return new_surface;
859 // but it doesn't clear it beforehand, the texture is already full of zeros.
860 LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during "
861 "reinterpretation but the texture is tiled.");
862 }
863 std::size_t remaining_size = new_params.SizeInBytes() - params.SizeInBytes();
864 std::vector<u8> data(remaining_size);
865 Memory::ReadBlock(new_params.addr + params.SizeInBytes(), data.data(), data.size());
866 glBufferSubData(GL_PIXEL_PACK_BUFFER, params.SizeInBytes(), remaining_size,
867 data.data());
868 } 1067 }
869 1068
870 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 1069 // This seems to be used for render-to-cubemap texture
871 1070 ASSERT_MSG(old_params.target == SurfaceParams::SurfaceTarget::Texture2D, "Unexpected");
872 const auto& dest_rect{new_params.GetRect()}; 1071 ASSERT_MSG(old_params.pixel_format == new_params.pixel_format, "Unexpected");
873 1072 ASSERT_MSG(old_params.rt.base_layer == 0, "Unimplemented");
874 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, copy_pbo.handle); 1073
875 if (dest_format.compressed) { 1074 // TODO(bunnei): Verify the below - this stride seems to be in 32-bit words, not pixels.
876 LOG_CRITICAL(HW_GPU, "Compressed copy is unimplemented!"); 1075 // Tested with Splatoon 2, Super Mario Odyssey, and Breath of the Wild.
877 UNREACHABLE(); 1076 const std::size_t byte_stride{old_params.rt.layer_stride * sizeof(u32)};
878 } else { 1077
879 switch (new_params.target) { 1078 for (std::size_t index = 0; index < new_params.depth; ++index) {
880 case SurfaceParams::SurfaceTarget::Texture1D: 1079 Surface face_surface{TryGetReservedSurface(old_params)};
881 glTextureSubImage1D(new_surface->Texture().handle, 0, 0, 1080 ASSERT_MSG(face_surface, "Unexpected");
882 static_cast<GLsizei>(dest_rect.GetWidth()), dest_format.format, 1081
883 dest_format.type, nullptr); 1082 if (is_blit) {
884 break; 1083 BlitSurface(face_surface, new_surface, read_framebuffer.handle,
885 case SurfaceParams::SurfaceTarget::Texture2D: 1084 draw_framebuffer.handle, face_surface->GetSurfaceParams().rt.index,
886 glTextureSubImage2D(new_surface->Texture().handle, 0, 0, 0, 1085 new_params.rt.index, index);
887 static_cast<GLsizei>(dest_rect.GetWidth()), 1086 } else {
888 static_cast<GLsizei>(dest_rect.GetHeight()), dest_format.format, 1087 CopySurface(face_surface, new_surface, copy_pbo.handle,
889 dest_format.type, nullptr); 1088 face_surface->GetSurfaceParams().rt.index, new_params.rt.index, index);
890 break;
891 case SurfaceParams::SurfaceTarget::Texture3D:
892 case SurfaceParams::SurfaceTarget::Texture2DArray:
893 glTextureSubImage3D(new_surface->Texture().handle, 0, 0, 0, 0,
894 static_cast<GLsizei>(dest_rect.GetWidth()),
895 static_cast<GLsizei>(dest_rect.GetHeight()),
896 static_cast<GLsizei>(new_params.depth), dest_format.format,
897 dest_format.type, nullptr);
898 break;
899 default:
900 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
901 static_cast<u32>(params.target));
902 UNREACHABLE();
903 } 1089 }
1090
1091 old_params.addr += byte_stride;
904 } 1092 }
905 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 1093 break;
1094 }
1095 default:
1096 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
1097 static_cast<u32>(new_params.target));
1098 UNREACHABLE();
906 } 1099 }
907 1100
908 return new_surface; 1101 return new_surface;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 80c5f324b..49025a3fe 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -9,12 +9,14 @@
9#include <memory> 9#include <memory>
10#include <vector> 10#include <vector>
11 11
12#include "common/alignment.h"
12#include "common/common_types.h" 13#include "common/common_types.h"
13#include "common/hash.h" 14#include "common/hash.h"
14#include "common/math_util.h" 15#include "common/math_util.h"
15#include "video_core/engines/maxwell_3d.h" 16#include "video_core/engines/maxwell_3d.h"
16#include "video_core/rasterizer_cache.h" 17#include "video_core/rasterizer_cache.h"
17#include "video_core/renderer_opengl/gl_resource_manager.h" 18#include "video_core/renderer_opengl/gl_resource_manager.h"
19#include "video_core/renderer_opengl/gl_shader_gen.h"
18#include "video_core/textures/texture.h" 20#include "video_core/textures/texture.h"
19 21
20namespace OpenGL { 22namespace OpenGL {
@@ -126,6 +128,8 @@ struct SurfaceParams {
126 case Tegra::Texture::TextureType::Texture2D: 128 case Tegra::Texture::TextureType::Texture2D:
127 case Tegra::Texture::TextureType::Texture2DNoMipmap: 129 case Tegra::Texture::TextureType::Texture2DNoMipmap:
128 return SurfaceTarget::Texture2D; 130 return SurfaceTarget::Texture2D;
131 case Tegra::Texture::TextureType::TextureCubemap:
132 return SurfaceTarget::TextureCubemap;
129 case Tegra::Texture::TextureType::Texture1DArray: 133 case Tegra::Texture::TextureType::Texture1DArray:
130 return SurfaceTarget::Texture1DArray; 134 return SurfaceTarget::Texture1DArray;
131 case Tegra::Texture::TextureType::Texture2DArray: 135 case Tegra::Texture::TextureType::Texture2DArray:
@@ -689,17 +693,23 @@ struct SurfaceParams {
689 /// Returns the rectangle corresponding to this surface 693 /// Returns the rectangle corresponding to this surface
690 MathUtil::Rectangle<u32> GetRect() const; 694 MathUtil::Rectangle<u32> GetRect() const;
691 695
692 /// Returns the size of this surface in bytes, adjusted for compression 696 /// Returns the size of this surface as a 2D texture in bytes, adjusted for compression
693 std::size_t SizeInBytes() const { 697 std::size_t SizeInBytes2D() const {
694 const u32 compression_factor{GetCompressionFactor(pixel_format)}; 698 const u32 compression_factor{GetCompressionFactor(pixel_format)};
695 ASSERT(width % compression_factor == 0); 699 ASSERT(width % compression_factor == 0);
696 ASSERT(height % compression_factor == 0); 700 ASSERT(height % compression_factor == 0);
697 return (width / compression_factor) * (height / compression_factor) * 701 return (width / compression_factor) * (height / compression_factor) *
698 GetFormatBpp(pixel_format) * depth / CHAR_BIT; 702 GetFormatBpp(pixel_format) / CHAR_BIT;
703 }
704
705 /// Returns the total size of this surface in bytes, adjusted for compression
706 std::size_t SizeInBytesTotal() const {
707 return SizeInBytes2D() * depth;
699 } 708 }
700 709
701 /// Creates SurfaceParams from a texture configuration 710 /// Creates SurfaceParams from a texture configuration
702 static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config); 711 static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config,
712 const GLShader::SamplerEntry& entry);
703 713
704 /// Creates SurfaceParams from a framebuffer configuration 714 /// Creates SurfaceParams from a framebuffer configuration
705 static SurfaceParams CreateForFramebuffer(std::size_t index); 715 static SurfaceParams CreateForFramebuffer(std::size_t index);
@@ -711,8 +721,9 @@ struct SurfaceParams {
711 721
712 /// Checks if surfaces are compatible for caching 722 /// Checks if surfaces are compatible for caching
713 bool IsCompatibleSurface(const SurfaceParams& other) const { 723 bool IsCompatibleSurface(const SurfaceParams& other) const {
714 return std::tie(pixel_format, type, width, height) == 724 return std::tie(pixel_format, type, width, height, target, depth) ==
715 std::tie(other.pixel_format, other.type, other.width, other.height); 725 std::tie(other.pixel_format, other.type, other.width, other.height, other.target,
726 other.depth);
716 } 727 }
717 728
718 VAddr addr; 729 VAddr addr;
@@ -725,8 +736,18 @@ struct SurfaceParams {
725 u32 height; 736 u32 height;
726 u32 depth; 737 u32 depth;
727 u32 unaligned_height; 738 u32 unaligned_height;
728 std::size_t size_in_bytes; 739 std::size_t size_in_bytes_total;
740 std::size_t size_in_bytes_2d;
729 SurfaceTarget target; 741 SurfaceTarget target;
742 u32 max_mip_level;
743
744 // Render target specific parameters, not used in caching
745 struct {
746 u32 index;
747 u32 array_mode;
748 u32 layer_stride;
749 u32 base_layer;
750 } rt;
730}; 751};
731 752
732}; // namespace OpenGL 753}; // namespace OpenGL
@@ -736,6 +757,7 @@ struct SurfaceReserveKey : Common::HashableStruct<OpenGL::SurfaceParams> {
736 static SurfaceReserveKey Create(const OpenGL::SurfaceParams& params) { 757 static SurfaceReserveKey Create(const OpenGL::SurfaceParams& params) {
737 SurfaceReserveKey res; 758 SurfaceReserveKey res;
738 res.state = params; 759 res.state = params;
760 res.state.rt = {}; // Ignore rt config in caching
739 return res; 761 return res;
740 } 762 }
741}; 763};
@@ -759,7 +781,7 @@ public:
759 } 781 }
760 782
761 std::size_t GetSizeInBytes() const { 783 std::size_t GetSizeInBytes() const {
762 return params.size_in_bytes; 784 return params.size_in_bytes_total;
763 } 785 }
764 786
765 const OGLTexture& Texture() const { 787 const OGLTexture& Texture() const {
@@ -800,7 +822,8 @@ public:
800 RasterizerCacheOpenGL(); 822 RasterizerCacheOpenGL();
801 823
802 /// Get a surface based on the texture configuration 824 /// Get a surface based on the texture configuration
803 Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config); 825 Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config,
826 const GLShader::SamplerEntry& entry);
804 827
805 /// Get the depth surface based on the framebuffer configuration 828 /// Get the depth surface based on the framebuffer configuration
806 Surface GetDepthBufferSurface(bool preserve_contents); 829 Surface GetDepthBufferSurface(bool preserve_contents);
@@ -822,7 +845,7 @@ private:
822 Surface GetUncachedSurface(const SurfaceParams& params); 845 Surface GetUncachedSurface(const SurfaceParams& params);
823 846
824 /// Recreates a surface with new parameters 847 /// Recreates a surface with new parameters
825 Surface RecreateSurface(const Surface& surface, const SurfaceParams& new_params); 848 Surface RecreateSurface(const Surface& old_surface, const SurfaceParams& new_params);
826 849
827 /// Reserves a unique surface that can be reused later 850 /// Reserves a unique surface that can be reused later
828 void ReserveSurface(const Surface& surface); 851 void ReserveSurface(const Surface& surface);
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index b3e95187e..579a78702 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -2000,6 +2000,14 @@ private:
2000 } 2000 }
2001 break; 2001 break;
2002 } 2002 }
2003 case Tegra::Shader::TextureType::TextureCube: {
2004 ASSERT_MSG(!is_array, "Unimplemented");
2005 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2006 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2007 std::string z = regs.GetRegisterAsFloat(instr.gpr20);
2008 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");";
2009 break;
2010 }
2003 default: 2011 default:
2004 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}", 2012 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}",
2005 static_cast<u32>(texture_type)); 2013 static_cast<u32>(texture_type));
@@ -2018,9 +2026,12 @@ private:
2018 break; 2026 break;
2019 } 2027 }
2020 case OpCode::Id::TLDS: { 2028 case OpCode::Id::TLDS: {
2021 ASSERT(instr.tlds.GetTextureType() == Tegra::Shader::TextureType::Texture2D);
2022 ASSERT(instr.tlds.IsArrayTexture() == false);
2023 std::string coord; 2029 std::string coord;
2030 const Tegra::Shader::TextureType texture_type{instr.tlds.GetTextureType()};
2031 const bool is_array{instr.tlds.IsArrayTexture()};
2032
2033 ASSERT(texture_type == Tegra::Shader::TextureType::Texture2D);
2034 ASSERT(is_array == false);
2024 2035
2025 ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2036 ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2026 "NODEP is not implemented"); 2037 "NODEP is not implemented");
@@ -2029,9 +2040,14 @@ private:
2029 ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::MZ), 2040 ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::MZ),
2030 "MZ is not implemented"); 2041 "MZ is not implemented");
2031 2042
2032 switch (instr.tlds.GetTextureType()) { 2043 switch (texture_type) {
2044 case Tegra::Shader::TextureType::Texture1D: {
2045 const std::string x = regs.GetRegisterAsInteger(instr.gpr8);
2046 coord = "int coords = " + x + ';';
2047 break;
2048 }
2033 case Tegra::Shader::TextureType::Texture2D: { 2049 case Tegra::Shader::TextureType::Texture2D: {
2034 if (instr.tlds.IsArrayTexture()) { 2050 if (is_array) {
2035 LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture"); 2051 LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture");
2036 UNREACHABLE(); 2052 UNREACHABLE();
2037 } else { 2053 } else {
@@ -2043,11 +2059,11 @@ private:
2043 } 2059 }
2044 default: 2060 default:
2045 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}", 2061 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}",
2046 static_cast<u32>(instr.tlds.GetTextureType())); 2062 static_cast<u32>(texture_type));
2047 UNREACHABLE(); 2063 UNREACHABLE();
2048 } 2064 }
2049 const std::string sampler = GetSampler(instr.sampler, instr.tlds.GetTextureType(), 2065
2050 instr.tlds.IsArrayTexture()); 2066 const std::string sampler = GetSampler(instr.sampler, texture_type, is_array);
2051 const std::string texture = "texelFetch(" + sampler + ", coords, 0)"; 2067 const std::string texture = "texelFetch(" + sampler + ", coords, 0)";
2052 WriteTexsInstruction(instr, coord, texture); 2068 WriteTexsInstruction(instr, coord, texture);
2053 break; 2069 break;
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index c2fb824b2..14aea4838 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -165,6 +165,8 @@ struct TICEntry {
165 165
166 // High 16 bits of the pitch value 166 // High 16 bits of the pitch value
167 BitField<0, 16, u32> pitch_high; 167 BitField<0, 16, u32> pitch_high;
168
169 BitField<28, 4, u32> max_mip_level;
168 }; 170 };
169 union { 171 union {
170 BitField<0, 16, u32> width_minus_1; 172 BitField<0, 16, u32> width_minus_1;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 681758ad2..27015d02c 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1055,11 +1055,21 @@ void GMainWindow::OnMenuInstallToNAND() {
1055 return; 1055 return;
1056 } 1056 }
1057 1057
1058 if (index >= 5) 1058 // If index is equal to or past Game, add the jump in TitleType.
1059 index += 0x7B; 1059 if (index >= 5) {
1060 index += static_cast<size_t>(FileSys::TitleType::Application) -
1061 static_cast<size_t>(FileSys::TitleType::FirmwarePackageB);
1062 }
1063
1064 FileSys::InstallResult res;
1065 if (index >= static_cast<size_t>(FileSys::TitleType::Application)) {
1066 res = Service::FileSystem::GetUserNANDContents()->InstallEntry(
1067 nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy);
1068 } else {
1069 res = Service::FileSystem::GetSystemNANDContents()->InstallEntry(
1070 nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy);
1071 }
1060 1072
1061 const auto res = Service::FileSystem::GetUserNANDContents()->InstallEntry(
1062 nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy);
1063 if (res == FileSys::InstallResult::Success) { 1073 if (res == FileSys::InstallResult::Success) {
1064 success(); 1074 success();
1065 } else if (res == FileSys::InstallResult::ErrorAlreadyExists) { 1075 } else if (res == FileSys::InstallResult::ErrorAlreadyExists) {