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

Unified Diff: gpu/command_buffer/service/texture_manager.cc

Issue 1505343003: Updating texture validation to account for sampler objects in ES3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed issue on devices without TEXTURE_FLOAT_LINEAR Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/texture_manager.cc
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index d428c376a54635794bdf14fe743de67548c1a4e9..9828c1ff09e43175e81a2fd66d9349f734f96c4b 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -71,20 +71,12 @@ struct TextureSignature {
// of relying on compilers adhering to this deep dark corner specification.
TextureSignature(GLenum target,
GLint level,
- GLenum min_filter,
- GLenum mag_filter,
- GLenum wrap_r,
- GLenum wrap_s,
- GLenum wrap_t,
+ const SamplerState& sampler_state,
GLenum usage,
GLenum internal_format,
- GLenum compare_func,
- GLenum compare_mode,
GLsizei width,
GLsizei height,
GLsizei depth,
- GLfloat max_lod,
- GLfloat min_lod,
GLint base_level,
GLint border,
GLint max_level,
@@ -97,20 +89,20 @@ struct TextureSignature {
memset(this, 0, sizeof(TextureSignature));
target_ = target;
level_ = level;
- min_filter_ = min_filter;
- mag_filter_ = mag_filter;
- wrap_r_ = wrap_r;
- wrap_s_ = wrap_s;
- wrap_t_ = wrap_t;
+ min_filter_ = sampler_state.min_filter;
+ mag_filter_ = sampler_state.mag_filter;
+ wrap_r_ = sampler_state.wrap_r;
+ wrap_s_ = sampler_state.wrap_s;
+ wrap_t_ = sampler_state.wrap_t;
usage_ = usage;
internal_format_ = internal_format;
- compare_func_ = compare_func;
- compare_mode_ = compare_mode;
+ compare_func_ = sampler_state.compare_func;
+ compare_mode_ = sampler_state.compare_mode;
width_ = width;
height_ = height;
depth_ = depth;
- max_lod_ = max_lod;
- min_lod_ = min_lod;
+ max_lod_ = sampler_state.max_lod;
+ min_lod_ = sampler_state.min_lod;
base_level_ = base_level;
border_ = border;
max_level_ = max_level;
@@ -289,7 +281,6 @@ TextureManager::~TextureManager() {
// a Texture belonging to this.
CHECK_EQ(texture_count_, 0u);
- DCHECK_EQ(0, num_unrenderable_textures_);
DCHECK_EQ(0, num_unsafe_textures_);
DCHECK_EQ(0, num_uncleared_mips_);
DCHECK_EQ(0, num_images_);
@@ -321,16 +312,7 @@ Texture::Texture(GLuint service_id)
num_uncleared_mips_(0),
num_npot_faces_(0),
target_(0),
- min_filter_(GL_NEAREST_MIPMAP_LINEAR),
- mag_filter_(GL_LINEAR),
- wrap_r_(GL_REPEAT),
- wrap_s_(GL_REPEAT),
- wrap_t_(GL_REPEAT),
usage_(GL_NONE),
- compare_func_(GL_LEQUAL),
- compare_mode_(GL_NONE),
- max_lod_(1000.0f),
- min_lod_(-1000.0f),
base_level_(0),
max_level_(1000),
max_level_set_(-1),
@@ -441,39 +423,67 @@ Texture::CanRenderCondition Texture::GetCanRenderCondition() const {
}
}
- bool needs_mips = NeedsMips();
- if (needs_mips) {
- if (!texture_complete())
- return CAN_RENDER_NEVER;
- }
-
if (target_ == GL_TEXTURE_CUBE_MAP && !cube_complete())
return CAN_RENDER_NEVER;
- bool is_npot_compatible = !needs_mips &&
- wrap_s_ == GL_CLAMP_TO_EDGE &&
- wrap_t_ == GL_CLAMP_TO_EDGE;
-
- if (!is_npot_compatible) {
- if (target_ == GL_TEXTURE_RECTANGLE_ARB)
- return CAN_RENDER_NEVER;
- else if (npot())
- return CAN_RENDER_ONLY_IF_NPOT;
- }
-
- return CAN_RENDER_ALWAYS;
+ // Texture may be renderable, but it depends on the sampler it's used with,
+ // the context that's using it, and the extensions available.
+ return CAN_RENDER_NEEDS_VALIDATION;
}
bool Texture::CanRender(const FeatureInfo* feature_info) const {
+ return CanRenderWithSampler(feature_info, sampler_state());
+}
+
+bool Texture::CanRenderWithSampler(const FeatureInfo* feature_info,
+ const SamplerState& sampler_state) const {
switch (can_render_condition_) {
case CAN_RENDER_ALWAYS:
return true;
case CAN_RENDER_NEVER:
return false;
- case CAN_RENDER_ONLY_IF_NPOT:
+ case CAN_RENDER_NEEDS_VALIDATION:
break;
}
- return feature_info->feature_flags().npot_ok;
+
+ bool needs_mips = sampler_state.min_filter != GL_NEAREST &&
+ sampler_state.min_filter != GL_LINEAR;
+ if (needs_mips) {
+ if (static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size())
+ return false;
+
+ const Texture::LevelInfo& first_level =
+ face_infos_[0].level_infos[base_level_];
+
+ if (!texture_complete()) {
+ return false;
+ } else if (first_level.type == GL_FLOAT &&
+ !feature_info->feature_flags().enable_texture_float_linear &&
+ (sampler_state.min_filter != GL_NEAREST_MIPMAP_NEAREST ||
+ sampler_state.mag_filter != GL_NEAREST)) {
+ return false;
+ } else if (first_level.type == GL_HALF_FLOAT_OES &&
+ !feature_info->feature_flags().enable_texture_half_float_linear &&
+ (sampler_state.min_filter != GL_NEAREST_MIPMAP_NEAREST ||
+ sampler_state.mag_filter != GL_NEAREST)) {
+ return false;
+ }
+ }
+
+ if (!feature_info->IsES3Enabled()) {
+ bool is_npot_compatible = !needs_mips &&
+ sampler_state.wrap_s == GL_CLAMP_TO_EDGE &&
+ sampler_state.wrap_t == GL_CLAMP_TO_EDGE;
+
+ if (!is_npot_compatible) {
+ if (target_ == GL_TEXTURE_RECTANGLE_ARB)
+ return false;
+ else if (npot())
+ return feature_info->feature_flags().npot_ok;
+ }
+ }
+
+ return true;
}
void Texture::AddToSignature(
@@ -495,20 +505,12 @@ void Texture::AddToSignature(
TextureSignature signature_data(target,
level,
- min_filter_,
- mag_filter_,
- wrap_r_,
- wrap_s_,
- wrap_t_,
+ sampler_state_,
usage_,
info.internal_format,
- compare_func_,
- compare_mode_,
info.width,
info.height,
info.depth,
- max_lod_,
- min_lod_,
base_level_,
info.border,
max_level_,
@@ -565,8 +567,8 @@ void Texture::SetTarget(
}
if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) {
- min_filter_ = GL_LINEAR;
- wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE;
+ sampler_state_.min_filter = GL_LINEAR;
+ sampler_state_.wrap_s = sampler_state_.wrap_t = GL_CLAMP_TO_EDGE;
}
if (target == GL_TEXTURE_EXTERNAL_OES) {
@@ -750,13 +752,7 @@ void Texture::UpdateMipCleared(LevelInfo* info,
}
void Texture::UpdateCanRenderCondition() {
- CanRenderCondition can_render_condition = GetCanRenderCondition();
- if (can_render_condition_ == can_render_condition)
- return;
- for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
- (*it)->manager()->UpdateCanRenderCondition(can_render_condition_,
- can_render_condition);
- can_render_condition_ = can_render_condition;
+ can_render_condition_ = GetCanRenderCondition();
}
void Texture::UpdateHasImages() {
@@ -995,43 +991,43 @@ GLenum Texture::SetParameteri(
if (!feature_info->validators()->texture_min_filter_mode.IsValid(param)) {
return GL_INVALID_ENUM;
}
- min_filter_ = param;
+ sampler_state_.min_filter = param;
break;
case GL_TEXTURE_MAG_FILTER:
if (!feature_info->validators()->texture_mag_filter_mode.IsValid(param)) {
return GL_INVALID_ENUM;
}
- mag_filter_ = param;
+ sampler_state_.mag_filter = param;
break;
case GL_TEXTURE_WRAP_R:
if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) {
return GL_INVALID_ENUM;
}
- wrap_r_ = param;
+ sampler_state_.wrap_r = param;
break;
case GL_TEXTURE_WRAP_S:
if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) {
return GL_INVALID_ENUM;
}
- wrap_s_ = param;
+ sampler_state_.wrap_s = param;
break;
case GL_TEXTURE_WRAP_T:
if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) {
return GL_INVALID_ENUM;
}
- wrap_t_ = param;
+ sampler_state_.wrap_t = param;
break;
case GL_TEXTURE_COMPARE_FUNC:
if (!feature_info->validators()->texture_compare_func.IsValid(param)) {
return GL_INVALID_ENUM;
}
- compare_func_ = param;
+ sampler_state_.compare_func = param;
break;
case GL_TEXTURE_COMPARE_MODE:
if (!feature_info->validators()->texture_compare_mode.IsValid(param)) {
return GL_INVALID_ENUM;
}
- compare_mode_ = param;
+ sampler_state_.compare_mode = param;
break;
case GL_TEXTURE_BASE_LEVEL:
if (param < 0) {
@@ -1084,10 +1080,10 @@ GLenum Texture::SetParameterf(
return SetParameteri(feature_info, pname, iparam);
}
case GL_TEXTURE_MIN_LOD:
- min_lod_ = param;
+ sampler_state_.min_lod = param;
break;
case GL_TEXTURE_MAX_LOD:
- max_lod_ = param;
+ sampler_state_.max_lod = param;
break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (param < 1.f) {
@@ -1126,16 +1122,6 @@ void Texture::Update(const FeatureInfo* feature_info) {
if (first_level.width == 0 || first_level.height == 0) {
texture_complete_ = false;
- } else if (first_level.type == GL_FLOAT &&
- !feature_info->feature_flags().enable_texture_float_linear &&
- (min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
- mag_filter_ != GL_NEAREST)) {
- texture_complete_ = false;
- } else if (first_level.type == GL_HALF_FLOAT_OES &&
- !feature_info->feature_flags().enable_texture_half_float_linear &&
- (min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
- mag_filter_ != GL_NEAREST)) {
- texture_complete_ = false;
}
bool texture_level0_complete = true;
@@ -1456,7 +1442,6 @@ TextureManager::TextureManager(MemoryTracker* memory_tracker,
max_3d_texture_size,
max_3d_texture_size)),
use_default_textures_(use_default_textures),
- num_unrenderable_textures_(0),
num_unsafe_textures_(0),
num_uncleared_mips_(0),
num_images_(0),
@@ -1744,8 +1729,6 @@ void TextureManager::StartTracking(TextureRef* ref) {
num_uncleared_mips_ += texture->num_uncleared_mips();
if (!texture->SafeToRenderFrom())
++num_unsafe_textures_;
- if (!texture->CanRender(feature_info_.get()))
- ++num_unrenderable_textures_;
if (texture->HasImages())
++num_images_;
}
@@ -1765,10 +1748,6 @@ void TextureManager::StopTracking(TextureRef* ref) {
DCHECK_NE(0, num_images_);
--num_images_;
}
- if (!texture->CanRender(feature_info_.get())) {
- DCHECK_NE(0, num_unrenderable_textures_);
- --num_unrenderable_textures_;
- }
if (!texture->SafeToRenderFrom()) {
DCHECK_NE(0, num_unsafe_textures_);
--num_unsafe_textures_;
@@ -1836,21 +1815,6 @@ void TextureManager::UpdateUnclearedMips(int delta) {
DCHECK_GE(num_uncleared_mips_, 0);
}
-void TextureManager::UpdateCanRenderCondition(
- Texture::CanRenderCondition old_condition,
- Texture::CanRenderCondition new_condition) {
- if (old_condition == Texture::CAN_RENDER_NEVER ||
- (old_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
- !feature_info_->feature_flags().npot_ok)) {
- DCHECK_GT(num_unrenderable_textures_, 0);
- --num_unrenderable_textures_;
- }
- if (new_condition == Texture::CAN_RENDER_NEVER ||
- (new_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
- !feature_info_->feature_flags().npot_ok))
- ++num_unrenderable_textures_;
-}
-
void TextureManager::UpdateNumImages(int delta) {
num_images_ += delta;
DCHECK_GE(num_images_, 0);
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | gpu/command_buffer/service/texture_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698