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

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

Issue 2570823002: Reland [Command buffer]: Generate INVALID_OPERATION if designated attachments in read fb miss image (Closed)
Patch Set: A small fix for back buffer Created 4 years 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/gles2_cmd_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <stdio.h> 10 #include <stdio.h>
(...skipping 7892 matching lines...) Expand 10 before | Expand all | Expand 10 after
7903 } 7903 }
7904 7904
7905 GLsizei read_buffer_samples = GetBoundFramebufferSamples(GL_READ_FRAMEBUFFER); 7905 GLsizei read_buffer_samples = GetBoundFramebufferSamples(GL_READ_FRAMEBUFFER);
7906 if (read_buffer_samples > 0 && 7906 if (read_buffer_samples > 0 &&
7907 (srcX0 != dstX0 || srcY0 != dstY0 || srcX1 != dstX1 || srcY1 != dstY1)) { 7907 (srcX0 != dstX0 || srcY0 != dstY0 || srcX1 != dstX1 || srcY1 != dstY1)) {
7908 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 7908 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
7909 "src framebuffer is multisampled, but src/dst regions are different"); 7909 "src framebuffer is multisampled, but src/dst regions are different");
7910 return; 7910 return;
7911 } 7911 }
7912 7912
7913 // Detect that designated read/depth/stencil buffer in read framebuffer miss
7914 // image, and the corresponding buffers in draw framebuffer have image.
7915 bool read_framebuffer_miss_image = false;
7916
7913 // Check whether read framebuffer and draw framebuffer have identical image 7917 // Check whether read framebuffer and draw framebuffer have identical image
7914 // TODO(yunchao): consider doing something like CheckFramebufferStatus(). 7918 // TODO(yunchao): consider doing something like CheckFramebufferStatus().
7915 // We cache the validation results, and if read_framebuffer doesn't change, 7919 // We cache the validation results, and if read_framebuffer doesn't change,
7916 // draw_framebuffer doesn't change, then use the cached status. 7920 // draw_framebuffer doesn't change, then use the cached status.
7917 enum FeedbackLoopState { 7921 enum FeedbackLoopState {
7918 FeedbackLoopTrue, 7922 FeedbackLoopTrue,
7919 FeedbackLoopFalse, 7923 FeedbackLoopFalse,
7920 FeedbackLoopUnknown 7924 FeedbackLoopUnknown
7921 }; 7925 };
7922 7926
7923 FeedbackLoopState is_feedback_loop = FeedbackLoopUnknown; 7927 FeedbackLoopState is_feedback_loop = FeedbackLoopUnknown;
7924 Framebuffer* read_framebuffer = 7928 Framebuffer* read_framebuffer =
7925 framebuffer_state_.bound_read_framebuffer.get(); 7929 framebuffer_state_.bound_read_framebuffer.get();
7926 Framebuffer* draw_framebuffer = 7930 Framebuffer* draw_framebuffer =
7927 framebuffer_state_.bound_draw_framebuffer.get(); 7931 framebuffer_state_.bound_draw_framebuffer.get();
7928 // If both read framebuffer and draw framebuffer are default framebuffer, 7932 // If both read framebuffer and draw framebuffer are default framebuffer,
7929 // They always have identical image. Otherwise, if one of read framebuffer 7933 // They always have identical image. Otherwise, if one of read framebuffer
7930 // and draw framebuffe is default framebuffer, but the other is fbo, they 7934 // and draw framebuffe is default framebuffer, but the other is fbo, they
7931 // always have no identical image. 7935 // always have no identical image.
7932 if (!read_framebuffer && !draw_framebuffer) { 7936 if (!read_framebuffer && !draw_framebuffer) {
7933 is_feedback_loop = FeedbackLoopTrue; 7937 is_feedback_loop = FeedbackLoopTrue;
7934 } else if (!read_framebuffer || !draw_framebuffer) { 7938 } else if (!read_framebuffer || !draw_framebuffer) {
7935 is_feedback_loop = FeedbackLoopFalse; 7939 is_feedback_loop = FeedbackLoopFalse;
7940 if (read_framebuffer) {
7941 if (((mask & GL_COLOR_BUFFER_BIT) != 0 &&
7942 !GetBoundReadFramebufferInternalFormat()) ||
7943 ((mask & GL_DEPTH_BUFFER_BIT) != 0 &&
7944 !read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT) &&
7945 BoundFramebufferHasDepthAttachment()) ||
Zhenyao Mo 2016/12/13 19:21:37 This is unnecessary. This is under !read_framebuf
yunchao 2016/12/14 02:04:44 That's true. draw_framebuffer should be null here.
7946 ((mask & GL_STENCIL_BUFFER_BIT) != 0 &&
7947 !read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT) &&
Zhenyao Mo 2016/12/13 19:21:37 Same here.
7948 BoundFramebufferHasStencilAttachment())) {
7949 read_framebuffer_miss_image = true;
7950 }
7951 }
7936 } else { 7952 } else {
7937 DCHECK(read_framebuffer && draw_framebuffer); 7953 DCHECK(read_framebuffer && draw_framebuffer);
7938 if ((mask & GL_DEPTH_BUFFER_BIT) != 0) { 7954 if ((mask & GL_DEPTH_BUFFER_BIT) != 0) {
7939 const Framebuffer::Attachment* depth_buffer_read = 7955 const Framebuffer::Attachment* depth_buffer_read =
7940 read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); 7956 read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT);
7941 const Framebuffer::Attachment* depth_buffer_draw = 7957 const Framebuffer::Attachment* depth_buffer_draw =
7942 draw_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); 7958 draw_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT);
7943 if (!depth_buffer_draw || !depth_buffer_read) { 7959 if (!depth_buffer_draw || !depth_buffer_read) {
7944 mask &= ~GL_DEPTH_BUFFER_BIT; 7960 mask &= ~GL_DEPTH_BUFFER_BIT;
7961 if (depth_buffer_draw) {
7962 read_framebuffer_miss_image = true;
7963 }
7945 } else if (depth_buffer_draw->IsSameAttachment(depth_buffer_read)) { 7964 } else if (depth_buffer_draw->IsSameAttachment(depth_buffer_read)) {
7946 is_feedback_loop = FeedbackLoopTrue; 7965 is_feedback_loop = FeedbackLoopTrue;
7947 } 7966 }
7948 } 7967 }
7949 if ((mask & GL_STENCIL_BUFFER_BIT) != 0) { 7968 if ((mask & GL_STENCIL_BUFFER_BIT) != 0) {
7950 const Framebuffer::Attachment* stencil_buffer_read = 7969 const Framebuffer::Attachment* stencil_buffer_read =
7951 read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); 7970 read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT);
7952 const Framebuffer::Attachment* stencil_buffer_draw = 7971 const Framebuffer::Attachment* stencil_buffer_draw =
7953 draw_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); 7972 draw_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT);
7954 if (!stencil_buffer_draw || !stencil_buffer_read) { 7973 if (!stencil_buffer_draw || !stencil_buffer_read) {
7955 mask &= ~GL_STENCIL_BUFFER_BIT; 7974 mask &= ~GL_STENCIL_BUFFER_BIT;
7975 if (stencil_buffer_draw) {
7976 read_framebuffer_miss_image = true;
7977 }
7956 } else if (stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) { 7978 } else if (stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) {
7957 is_feedback_loop = FeedbackLoopTrue; 7979 is_feedback_loop = FeedbackLoopTrue;
7958 } 7980 }
7959 } 7981 }
7960 if (!mask) 7982 if (!mask && !read_framebuffer_miss_image)
7961 return; 7983 return;
7962 } 7984 }
7963 7985
7964 GLenum src_internal_format = GetBoundReadFramebufferInternalFormat(); 7986 GLenum src_internal_format = GetBoundReadFramebufferInternalFormat();
7965 GLenum src_type = GetBoundReadFramebufferTextureType(); 7987 GLenum src_type = GetBoundReadFramebufferTextureType();
7966 7988
7967 bool read_buffer_has_srgb = 7989 bool read_buffer_has_srgb =
7968 GetColorEncodingFromInternalFormat(src_internal_format) == GL_SRGB; 7990 GetColorEncodingFromInternalFormat(src_internal_format) == GL_SRGB;
7969 bool draw_buffers_has_srgb = false; 7991 bool draw_buffers_has_srgb = false;
7970 if ((mask & GL_COLOR_BUFFER_BIT) != 0) { 7992 if ((mask & GL_COLOR_BUFFER_BIT) != 0) {
(...skipping 14 matching lines...) Expand all
7985 DCHECK(read_framebuffer || (is_feedback_loop != FeedbackLoopUnknown)); 8007 DCHECK(read_framebuffer || (is_feedback_loop != FeedbackLoopUnknown));
7986 const Framebuffer::Attachment* read_buffer = 8008 const Framebuffer::Attachment* read_buffer =
7987 is_feedback_loop == FeedbackLoopUnknown ? 8009 is_feedback_loop == FeedbackLoopUnknown ?
7988 read_framebuffer->GetReadBufferAttachment() : nullptr; 8010 read_framebuffer->GetReadBufferAttachment() : nullptr;
7989 for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { 8011 for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) {
7990 GLenum dst_format = GetBoundColorDrawBufferInternalFormat( 8012 GLenum dst_format = GetBoundColorDrawBufferInternalFormat(
7991 static_cast<GLint>(ii)); 8013 static_cast<GLint>(ii));
7992 GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii)); 8014 GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii));
7993 if (dst_format == 0) 8015 if (dst_format == 0)
7994 continue; 8016 continue;
8017 if (!src_internal_format) {
8018 read_framebuffer_miss_image = true;
8019 }
7995 if (GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB) 8020 if (GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB)
7996 draw_buffers_has_srgb = true; 8021 draw_buffers_has_srgb = true;
7997 if (read_buffer_samples > 0 && 8022 if (read_buffer_samples > 0 &&
7998 (src_sized_format != 8023 (src_sized_format !=
7999 GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) { 8024 GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) {
8000 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 8025 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8001 "src and dst formats differ for color"); 8026 "src and dst formats differ for color");
8002 return; 8027 return;
8003 } 8028 }
8004 bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format); 8029 bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format);
(...skipping 19 matching lines...) Expand all
8024 break; 8049 break;
8025 } 8050 }
8026 } 8051 }
8027 } 8052 }
8028 } 8053 }
8029 if (is_feedback_loop == FeedbackLoopTrue) { 8054 if (is_feedback_loop == FeedbackLoopTrue) {
8030 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 8055 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8031 "source buffer and destination buffers are identical"); 8056 "source buffer and destination buffers are identical");
8032 return; 8057 return;
8033 } 8058 }
8059 if (read_framebuffer_miss_image == true) {
8060 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8061 "The designated attachment point(s) in read framebuffer miss image");
8062 return;
8063 }
8034 8064
8035 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { 8065 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) {
8036 if (filter != GL_NEAREST) { 8066 if (filter != GL_NEAREST) {
8037 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 8067 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8038 "invalid filter for depth/stencil"); 8068 "invalid filter for depth/stencil");
8039 return; 8069 return;
8040 } 8070 }
8041 8071
8042 if ((GetBoundFramebufferDepthFormat(GL_READ_FRAMEBUFFER) != 8072 if ((GetBoundFramebufferDepthFormat(GL_READ_FRAMEBUFFER) !=
8043 GetBoundFramebufferDepthFormat(GL_DRAW_FRAMEBUFFER)) || 8073 GetBoundFramebufferDepthFormat(GL_DRAW_FRAMEBUFFER)) ||
(...skipping 10927 matching lines...) Expand 10 before | Expand all | Expand 10 after
18971 } 19001 }
18972 19002
18973 // Include the auto-generated part of this file. We split this because it means 19003 // Include the auto-generated part of this file. We split this because it means
18974 // we can easily edit the non-auto generated parts right here in this file 19004 // we can easily edit the non-auto generated parts right here in this file
18975 // instead of having to edit some template or the code generator. 19005 // instead of having to edit some template or the code generator.
18976 #include "base/macros.h" 19006 #include "base/macros.h"
18977 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 19007 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
18978 19008
18979 } // namespace gles2 19009 } // namespace gles2
18980 } // namespace gpu 19010 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698