summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp141
1 files changed, 111 insertions, 30 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 1a44de332..e9fd67d00 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -245,7 +245,8 @@ static bool IsFormatBCn(PixelFormat format) {
245} 245}
246 246
247template <bool morton_to_gl, PixelFormat format> 247template <bool morton_to_gl, PixelFormat format>
248void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer, VAddr addr) { 248void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, size_t gl_buffer_size,
249 VAddr addr) {
249 constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT; 250 constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT;
250 constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); 251 constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format);
251 252
@@ -255,18 +256,18 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_bu
255 const u32 tile_size{IsFormatBCn(format) ? 4U : 1U}; 256 const u32 tile_size{IsFormatBCn(format) ? 4U : 1U};
256 const std::vector<u8> data = Tegra::Texture::UnswizzleTexture( 257 const std::vector<u8> data = Tegra::Texture::UnswizzleTexture(
257 addr, tile_size, bytes_per_pixel, stride, height, block_height); 258 addr, tile_size, bytes_per_pixel, stride, height, block_height);
258 const size_t size_to_copy{std::min(gl_buffer.size(), data.size())}; 259 const size_t size_to_copy{std::min(gl_buffer_size, data.size())};
259 gl_buffer.assign(data.begin(), data.begin() + size_to_copy); 260 memcpy(gl_buffer, data.data(), size_to_copy);
260 } else { 261 } else {
261 // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should 262 // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should
262 // check the configuration for this and perform more generic un/swizzle 263 // check the configuration for this and perform more generic un/swizzle
263 LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); 264 LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!");
264 VideoCore::MortonCopyPixels128(stride, height, bytes_per_pixel, gl_bytes_per_pixel, 265 VideoCore::MortonCopyPixels128(stride, height, bytes_per_pixel, gl_bytes_per_pixel,
265 Memory::GetPointer(addr), gl_buffer.data(), morton_to_gl); 266 Memory::GetPointer(addr), gl_buffer, morton_to_gl);
266 } 267 }
267} 268}
268 269
269static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, VAddr), 270static constexpr std::array<void (*)(u32, u32, u32, u8*, size_t, VAddr),
270 SurfaceParams::MaxPixelFormat> 271 SurfaceParams::MaxPixelFormat>
271 morton_to_gl_fns = { 272 morton_to_gl_fns = {
272 // clang-format off 273 // clang-format off
@@ -323,7 +324,7 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, VAddr),
323 // clang-format on 324 // clang-format on
324}; 325};
325 326
326static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, VAddr), 327static constexpr std::array<void (*)(u32, u32, u32, u8*, size_t, VAddr),
327 SurfaceParams::MaxPixelFormat> 328 SurfaceParams::MaxPixelFormat>
328 gl_to_morton_fns = { 329 gl_to_morton_fns = {
329 // clang-format off 330 // clang-format off
@@ -441,29 +442,51 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
441 texture.Create(); 442 texture.Create();
442 const auto& rect{params.GetRect()}; 443 const auto& rect{params.GetRect()};
443 444
445 // Keep track of previous texture bindings
444 OpenGLState cur_state = OpenGLState::GetCurState(); 446 OpenGLState cur_state = OpenGLState::GetCurState();
447 const auto& old_tex = cur_state.texture_units[0];
448 SCOPE_EXIT({
449 cur_state.texture_units[0] = old_tex;
450 cur_state.Apply();
451 });
445 452
446 // Keep track of previous texture bindings
447 GLuint old_tex = cur_state.texture_units[0].texture;
448 cur_state.texture_units[0].texture = texture.handle; 453 cur_state.texture_units[0].texture = texture.handle;
454 cur_state.texture_units[0].target = SurfaceTargetToGL(params.target);
449 cur_state.Apply(); 455 cur_state.Apply();
450 glActiveTexture(GL_TEXTURE0); 456 glActiveTexture(GL_TEXTURE0);
451 457
452 const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type); 458 const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type);
453 if (!format_tuple.compressed) { 459 if (!format_tuple.compressed) {
454 // Only pre-create the texture for non-compressed textures. 460 // Only pre-create the texture for non-compressed textures.
455 glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, rect.GetWidth(), 461 switch (params.target) {
456 rect.GetHeight(), 0, format_tuple.format, format_tuple.type, nullptr); 462 case SurfaceParams::SurfaceTarget::Texture1D:
463 glTexImage1D(SurfaceTargetToGL(params.target), 0, format_tuple.internal_format,
464 rect.GetWidth(), 0, format_tuple.format, format_tuple.type, nullptr);
465 break;
466 case SurfaceParams::SurfaceTarget::Texture2D:
467 glTexImage2D(SurfaceTargetToGL(params.target), 0, format_tuple.internal_format,
468 rect.GetWidth(), rect.GetHeight(), 0, format_tuple.format,
469 format_tuple.type, nullptr);
470 break;
471 case SurfaceParams::SurfaceTarget::Texture3D:
472 case SurfaceParams::SurfaceTarget::Texture2DArray:
473 glTexImage3D(SurfaceTargetToGL(params.target), 0, format_tuple.internal_format,
474 rect.GetWidth(), rect.GetHeight(), params.depth, 0, format_tuple.format,
475 format_tuple.type, nullptr);
476 break;
477 default:
478 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
479 static_cast<u32>(params.target));
480 UNREACHABLE();
481 glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, rect.GetWidth(),
482 rect.GetHeight(), 0, format_tuple.format, format_tuple.type, nullptr);
483 }
457 } 484 }
458 485
459 glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAX_LEVEL, 0); 486 glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAX_LEVEL, 0);
460 glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MIN_FILTER, GL_LINEAR); 487 glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
461 glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 488 glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
462 glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 489 glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
463
464 // Restore previous texture bindings
465 cur_state.texture_units[0].texture = old_tex;
466 cur_state.Apply();
467} 490}
468 491
469static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) { 492static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) {
@@ -548,13 +571,24 @@ void CachedSurface::LoadGLBuffer() {
548 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); 571 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad);
549 572
550 if (params.is_tiled) { 573 if (params.is_tiled) {
551 gl_buffer.resize(copy_size); 574 // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do
575 // this for 3D textures, etc.
576 switch (params.target) {
577 case SurfaceParams::SurfaceTarget::Texture2D:
578 // Pass impl. to the fallback code below
579 break;
580 default:
581 LOG_CRITICAL(HW_GPU, "Unimplemented tiled load for target={}",
582 static_cast<u32>(params.target));
583 UNREACHABLE();
584 }
552 585
586 gl_buffer.resize(params.depth * copy_size);
553 morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( 587 morton_to_gl_fns[static_cast<size_t>(params.pixel_format)](
554 params.width, params.block_height, params.height, gl_buffer, params.addr); 588 params.width, params.block_height, params.height, gl_buffer.data(), copy_size,
589 params.addr);
555 } else { 590 } else {
556 const u8* const texture_src_data_end = texture_src_data + copy_size; 591 const u8* const texture_src_data_end{texture_src_data + (params.depth * copy_size)};
557
558 gl_buffer.assign(texture_src_data, texture_src_data_end); 592 gl_buffer.assign(texture_src_data, texture_src_data_end);
559 } 593 }
560 594
@@ -574,7 +608,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
574 MICROPROFILE_SCOPE(OpenGL_TextureUL); 608 MICROPROFILE_SCOPE(OpenGL_TextureUL);
575 609
576 ASSERT(gl_buffer.size() == 610 ASSERT(gl_buffer.size() ==
577 params.width * params.height * GetGLBytesPerPixel(params.pixel_format)); 611 params.width * params.height * GetGLBytesPerPixel(params.pixel_format) * params.depth);
578 612
579 const auto& rect{params.GetRect()}; 613 const auto& rect{params.GetRect()};
580 614
@@ -587,8 +621,13 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
587 GLuint target_tex = texture.handle; 621 GLuint target_tex = texture.handle;
588 OpenGLState cur_state = OpenGLState::GetCurState(); 622 OpenGLState cur_state = OpenGLState::GetCurState();
589 623
590 GLuint old_tex = cur_state.texture_units[0].texture; 624 const auto& old_tex = cur_state.texture_units[0];
625 SCOPE_EXIT({
626 cur_state.texture_units[0] = old_tex;
627 cur_state.Apply();
628 });
591 cur_state.texture_units[0].texture = target_tex; 629 cur_state.texture_units[0].texture = target_tex;
630 cur_state.texture_units[0].target = SurfaceTargetToGL(params.target);
592 cur_state.Apply(); 631 cur_state.Apply();
593 632
594 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT 633 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT
@@ -597,20 +636,62 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
597 636
598 glActiveTexture(GL_TEXTURE0); 637 glActiveTexture(GL_TEXTURE0);
599 if (tuple.compressed) { 638 if (tuple.compressed) {
600 glCompressedTexImage2D( 639 switch (params.target) {
601 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width), 640 case SurfaceParams::SurfaceTarget::Texture2D:
602 static_cast<GLsizei>(params.height), 0, static_cast<GLsizei>(params.size_in_bytes), 641 glCompressedTexImage2D(
603 &gl_buffer[buffer_offset]); 642 SurfaceTargetToGL(params.target), 0, tuple.internal_format,
643 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0,
644 static_cast<GLsizei>(params.size_in_bytes), &gl_buffer[buffer_offset]);
645 break;
646 case SurfaceParams::SurfaceTarget::Texture3D:
647 case SurfaceParams::SurfaceTarget::Texture2DArray:
648 glCompressedTexImage3D(
649 SurfaceTargetToGL(params.target), 0, tuple.internal_format,
650 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height),
651 static_cast<GLsizei>(params.depth), 0, static_cast<GLsizei>(params.size_in_bytes),
652 &gl_buffer[buffer_offset]);
653 break;
654 default:
655 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
656 static_cast<u32>(params.target));
657 UNREACHABLE();
658 glCompressedTexImage2D(
659 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width),
660 static_cast<GLsizei>(params.height), 0, static_cast<GLsizei>(params.size_in_bytes),
661 &gl_buffer[buffer_offset]);
662 }
604 } else { 663 } else {
605 glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), 664
606 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, 665 switch (params.target) {
607 &gl_buffer[buffer_offset]); 666 case SurfaceParams::SurfaceTarget::Texture1D:
667 glTexSubImage1D(SurfaceTargetToGL(params.target), 0, x0,
668 static_cast<GLsizei>(rect.GetWidth()), tuple.format, tuple.type,
669 &gl_buffer[buffer_offset]);
670 break;
671 case SurfaceParams::SurfaceTarget::Texture2D:
672 glTexSubImage2D(SurfaceTargetToGL(params.target), 0, x0, y0,
673 static_cast<GLsizei>(rect.GetWidth()),
674 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
675 &gl_buffer[buffer_offset]);
676 break;
677 case SurfaceParams::SurfaceTarget::Texture3D:
678 case SurfaceParams::SurfaceTarget::Texture2DArray:
679 glTexSubImage3D(SurfaceTargetToGL(params.target), 0, x0, y0, 0,
680 static_cast<GLsizei>(rect.GetWidth()),
681 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
682 tuple.type, &gl_buffer[buffer_offset]);
683 break;
684 default:
685 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
686 static_cast<u32>(params.target));
687 UNREACHABLE();
688 glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
689 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
690 &gl_buffer[buffer_offset]);
691 }
608 } 692 }
609 693
610 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 694 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
611
612 cur_state.texture_units[0].texture = old_tex;
613 cur_state.Apply();
614} 695}
615 696
616RasterizerCacheOpenGL::RasterizerCacheOpenGL() { 697RasterizerCacheOpenGL::RasterizerCacheOpenGL() {