Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: gpu/command_buffer/service/texture_manager.cc

Issue 1963683002: Fix unpacking overlapping unpack buffer rows on NVIDIA GL (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/texture_manager.h" 5 #include "gpu/command_buffer/service/texture_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 2376 matching lines...) Expand 10 before | Expand all | Expand 10 after
2387 memset(zero.get(), 0, args.pixels_size); 2387 memset(zero.get(), 0, args.pixels_size);
2388 for (GLenum face : undefined_faces) { 2388 for (GLenum face : undefined_faces) {
2389 new_args.target = face; 2389 new_args.target = face;
2390 new_args.pixels = zero.get(); 2390 new_args.pixels = zero.get();
2391 DoTexImage(texture_state, state, framebuffer_state, 2391 DoTexImage(texture_state, state, framebuffer_state,
2392 function_name, texture_ref, new_args); 2392 function_name, texture_ref, new_args);
2393 texture->MarkLevelAsInternalWorkaround(face, args.level); 2393 texture->MarkLevelAsInternalWorkaround(face, args.level);
2394 } 2394 }
2395 } 2395 }
2396 2396
2397 if (texture_state->unpack_overlapping_rows_separately_unpack_buffer &&
2398 buffer) {
2399 ContextState::Dimension dimension =
2400 (args.command_type == DoTexImageArguments::kTexImage3D)
2401 ? ContextState::k3D
2402 : ContextState::k2D;
2403 const PixelStoreParams unpack_params(state->GetUnpackParams(dimension));
2404 if (unpack_params.row_length != 0 &&
2405 unpack_params.row_length < args.width) {
2406 // The rows overlap in unpack memory. Upload the texture row by row to
2407 // work around driver bug.
2408
2409 // Reserve memory for the texture and set its attributes so it can be
2410 // filled with TexSubImage.
oetuaho-nv 2016/05/09 14:22:30 This part here could maybe be refactored into a co
2411 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
2412 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr);
2413 DoTexImageArguments new_args = args;
2414 new_args.pixels = nullptr;
2415 // pixels_size might be incorrect, but it's not used in this case.
2416 DoTexImage(texture_state, state, framebuffer_state, function_name,
2417 texture_ref, new_args);
2418 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->service_id());
2419 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
2420
2421 DoTexSubImageArguments sub_args = {
2422 args.target, args.level, 0, 0, 0, args.width, args.height, args.depth,
2423 args.format, args.type, args.pixels, args.pixels_size, args.padding,
2424 args.command_type == DoTexImageArguments::kTexImage3D
2425 ? DoTexSubImageArguments::kTexSubImage3D
2426 : DoTexSubImageArguments::kTexSubImage2D};
2427 DoTexSubImageRowByRowWorkaround(texture_state, state, sub_args,
2428 unpack_params);
2429
2430 SetLevelCleared(texture_ref, args.target, args.level, true);
2431 return;
2432 }
2433 }
2434
2397 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { 2435 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) {
2398 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); 2436 uint32_t buffer_size = static_cast<uint32_t>(buffer->size());
2399 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { 2437 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) {
2400 // In ValidateTexImage(), we already made sure buffer size is no less 2438 // In ValidateTexImage(), we already made sure buffer size is no less
2401 // than offset + pixels_size. 2439 // than offset + pixels_size.
2402 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 2440 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
2403 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr); 2441 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr);
2404 DoTexImageArguments new_args = args; 2442 DoTexImageArguments new_args = args;
2405 new_args.pixels = nullptr; 2443 new_args.pixels = nullptr;
2406 // pixels_size might be incorrect, but it's not used in this case. 2444 // pixels_size might be incorrect, but it's not used in this case.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2565 return; 2603 return;
2566 } 2604 }
2567 } 2605 }
2568 full_image = false; 2606 full_image = false;
2569 } else { 2607 } else {
2570 SetLevelCleared(texture_ref, args.target, args.level, true); 2608 SetLevelCleared(texture_ref, args.target, args.level, true);
2571 full_image = true; 2609 full_image = true;
2572 } 2610 }
2573 2611
2574 Buffer* buffer = state->bound_pixel_unpack_buffer.get(); 2612 Buffer* buffer = state->bound_pixel_unpack_buffer.get();
2613
2614 if (texture_state->unpack_overlapping_rows_separately_unpack_buffer &&
2615 buffer) {
2616 ContextState::Dimension dimension =
2617 (args.command_type == DoTexSubImageArguments::kTexSubImage3D)
2618 ? ContextState::k3D
2619 : ContextState::k2D;
2620 const PixelStoreParams unpack_params(state->GetUnpackParams(dimension));
2621 if (unpack_params.row_length != 0 &&
2622 unpack_params.row_length < args.width) {
2623 // The rows overlap in unpack memory. Upload the texture row by row to
2624 // work around driver bug.
2625 DoTexSubImageRowByRowWorkaround(texture_state, state, args,
2626 unpack_params);
2627 return;
2628 }
2629 }
2630
2575 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { 2631 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) {
2576 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); 2632 uint32_t buffer_size = static_cast<uint32_t>(buffer->size());
2577 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { 2633 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) {
2578 DoTexSubImageWithAlignmentWorkaround(texture_state, state, args); 2634 DoTexSubImageWithAlignmentWorkaround(texture_state, state, args);
2579 return; 2635 return;
2580 } 2636 }
2581 } 2637 }
2582 2638
2583 if (full_image && !texture_state->texsubimage_faster_than_teximage && 2639 if (full_image && !texture_state->texsubimage_faster_than_teximage &&
2584 !texture->IsImmutable() && !texture->HasImages()) { 2640 !texture->IsImmutable() && !texture->HasImages()) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2712 args.format, args.type, 2768 args.format, args.type,
2713 params, 2769 params,
2714 &size, 2770 &size,
2715 nullptr, nullptr, nullptr, nullptr); 2771 nullptr, nullptr, nullptr, nullptr);
2716 offset += size; 2772 offset += size;
2717 } 2773 }
2718 } 2774 }
2719 DCHECK_EQ(ToGLuint(args.pixels) + args.pixels_size, offset); 2775 DCHECK_EQ(ToGLuint(args.pixels) + args.pixels_size, offset);
2720 } 2776 }
2721 2777
2778 void TextureManager::DoTexSubImageRowByRowWorkaround(
2779 DecoderTextureState* texture_state,
2780 ContextState* state,
2781 const DoTexSubImageArguments& args,
2782 const PixelStoreParams& unpack_params) {
2783 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2784 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2785 DCHECK_EQ(0, state->unpack_skip_pixels);
2786 DCHECK_EQ(0, state->unpack_skip_rows);
2787 DCHECK_EQ(0, state->unpack_skip_images);
2788
2789 GLenum format = AdjustTexFormat(args.format);
2790
2791 GLsizei row_bytes = unpack_params.row_length *
2792 GLES2Util::ComputeImageGroupSize(format, args.type);
2793 GLsizei alignment_diff = row_bytes % unpack_params.alignment;
2794 if (alignment_diff != 0) {
2795 row_bytes += unpack_params.alignment - alignment_diff;
2796 }
2797 DCHECK_EQ(0, row_bytes % unpack_params.alignment);
2798 if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) {
2799 GLsizei image_height = args.height;
2800 if (unpack_params.image_height != 0) {
2801 image_height = unpack_params.image_height;
2802 }
2803 GLsizei image_bytes = row_bytes * image_height;
2804 for (GLsizei image = 0; image < args.depth; ++image) {
2805 GLsizei image_byte_offset = image * image_bytes;
2806 for (GLsizei row = 0; row < args.height; ++row) {
2807 GLsizei byte_offset = image_byte_offset + row * row_bytes;
2808 const GLubyte* row_pixels =
2809 reinterpret_cast<const GLubyte*>(args.pixels) + byte_offset;
2810 glTexSubImage3D(args.target, args.level, args.xoffset,
2811 row + args.yoffset, image + args.zoffset, args.width, 1,
2812 1, format, args.type, row_pixels);
2813 }
2814 }
2815 } else {
2816 for (GLsizei row = 0; row < args.height; ++row) {
2817 GLsizei byte_offset = row * row_bytes;
2818 const GLubyte* row_pixels =
2819 reinterpret_cast<const GLubyte*>(args.pixels) + byte_offset;
2820 glTexSubImage2D(args.target, args.level, args.xoffset, row + args.yoffset,
2821 args.width, 1, format, args.type, row_pixels);
2822 }
2823 }
2824
2825 // Restore unpack state
2826 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_params.alignment);
2827 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_params.row_length);
2828 }
2829
2722 GLenum TextureManager::AdjustTexInternalFormat(GLenum format) const { 2830 GLenum TextureManager::AdjustTexInternalFormat(GLenum format) const {
2723 if (feature_info_->gl_version_info().is_desktop_core_profile) { 2831 if (feature_info_->gl_version_info().is_desktop_core_profile) {
2724 const Texture::CompatibilitySwizzle* swizzle = 2832 const Texture::CompatibilitySwizzle* swizzle =
2725 GetCompatibilitySwizzle(format); 2833 GetCompatibilitySwizzle(format);
2726 if (swizzle) 2834 if (swizzle)
2727 return swizzle->dest_format; 2835 return swizzle->dest_format;
2728 } 2836 }
2729 return format; 2837 return format;
2730 } 2838 }
2731 2839
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
3198 uint32_t TextureManager::GetServiceIdGeneration() const { 3306 uint32_t TextureManager::GetServiceIdGeneration() const {
3199 return current_service_id_generation_; 3307 return current_service_id_generation_;
3200 } 3308 }
3201 3309
3202 void TextureManager::IncrementServiceIdGeneration() { 3310 void TextureManager::IncrementServiceIdGeneration() {
3203 current_service_id_generation_++; 3311 current_service_id_generation_++;
3204 } 3312 }
3205 3313
3206 } // namespace gles2 3314 } // namespace gles2
3207 } // namespace gpu 3315 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698