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

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

Issue 1684343002: Upgrade TexSubImage3D and TexStorage3D. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1832 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 return NULL; 1843 return NULL;
1844 } 1844 }
1845 1845
1846 GLsizei TextureManager::ComputeMipMapCount(GLenum target, 1846 GLsizei TextureManager::ComputeMipMapCount(GLenum target,
1847 GLsizei width, 1847 GLsizei width,
1848 GLsizei height, 1848 GLsizei height,
1849 GLsizei depth) { 1849 GLsizei depth) {
1850 switch (target) { 1850 switch (target) {
1851 case GL_TEXTURE_EXTERNAL_OES: 1851 case GL_TEXTURE_EXTERNAL_OES:
1852 return 1; 1852 return 1;
1853 case GL_TEXTURE_3D:
1854 return 1 +
1855 base::bits::Log2Floor(std::max(std::max(width, height), depth));
1853 default: 1856 default:
1854 return 1 + 1857 return 1 +
1855 base::bits::Log2Floor(std::max(std::max(width, height), depth)); 1858 base::bits::Log2Floor(std::max(width, height));
1856 } 1859 }
1857 } 1860 }
1858 1861
1859 void TextureManager::SetLevelImage(TextureRef* ref, 1862 void TextureManager::SetLevelImage(TextureRef* ref,
1860 GLenum target, 1863 GLenum target,
1861 GLint level, 1864 GLint level,
1862 gl::GLImage* image, 1865 gl::GLImage* image,
1863 Texture::ImageState state) { 1866 Texture::ImageState state) {
1864 DCHECK(ref); 1867 DCHECK(ref);
1865 ref->texture()->SetLevelImage(target, level, image, state); 1868 ref->texture()->SetLevelImage(target, level, image, state);
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
2120 function_name, texture_ref, args); 2123 function_name, texture_ref, args);
2121 } 2124 }
2122 2125
2123 bool TextureManager::ValidateTexSubImage(ContextState* state, 2126 bool TextureManager::ValidateTexSubImage(ContextState* state,
2124 const char* function_name, 2127 const char* function_name,
2125 const DoTexSubImageArguments& args, 2128 const DoTexSubImageArguments& args,
2126 TextureRef** texture_ref) { 2129 TextureRef** texture_ref) {
2127 ErrorState* error_state = state->GetErrorState(); 2130 ErrorState* error_state = state->GetErrorState();
2128 const Validators* validators = feature_info_->validators(); 2131 const Validators* validators = feature_info_->validators();
2129 2132
2130 if (!validators->texture_target.IsValid(args.target)) { 2133 if ((args.command_type == DoTexSubImageArguments::kTexSubImage2D &&
2134 !validators->texture_target.IsValid(args.target)) ||
2135 (args.command_type == DoTexSubImageArguments::kTexSubImage3D &&
2136 !validators->texture_3_d_target.IsValid(args.target))) {
2131 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name, 2137 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name,
2132 args.target, "target"); 2138 args.target, "target");
2133 return false; 2139 return false;
2134 } 2140 }
2135 if (args.width < 0) { 2141 if (args.width < 0) {
2136 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name, 2142 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2137 "width < 0"); 2143 "width < 0");
2138 return false; 2144 return false;
2139 } 2145 }
2140 if (args.height < 0) { 2146 if (args.height < 0) {
2141 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name, 2147 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2142 "height < 0"); 2148 "height < 0");
2143 return false; 2149 return false;
2144 } 2150 }
2151 if (args.depth < 0) {
2152 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2153 "depth < 0");
2154 return false;
2155 }
2145 TextureRef* local_texture_ref = GetTextureInfoForTarget(state, args.target); 2156 TextureRef* local_texture_ref = GetTextureInfoForTarget(state, args.target);
2146 if (!local_texture_ref) { 2157 if (!local_texture_ref) {
2147 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name, 2158 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
2148 "unknown texture for target"); 2159 "unknown texture for target");
2149 return false; 2160 return false;
2150 } 2161 }
2151 Texture* texture = local_texture_ref->texture(); 2162 Texture* texture = local_texture_ref->texture();
2152 GLenum current_type = 0; 2163 GLenum current_type = 0;
2153 GLenum internal_format = 0; 2164 GLenum internal_format = 0;
2154 if (!texture->GetLevelType(args.target, args.level, &current_type, 2165 if (!texture->GetLevelType(args.target, args.level, &current_type,
2155 &internal_format)) { 2166 &internal_format)) {
2156 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name, 2167 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
2157 "level does not exist."); 2168 "level does not exist.");
2158 return false; 2169 return false;
2159 } 2170 }
2160 if (!ValidateTextureParameters(error_state, function_name, args.format, 2171 if (!ValidateTextureParameters(error_state, function_name, args.format,
2161 args.type, internal_format, args.level)) { 2172 args.type, internal_format, args.level)) {
2162 return false; 2173 return false;
2163 } 2174 }
2164 if (args.type != current_type && !feature_info_->IsES3Enabled()) { 2175 if (args.type != current_type && !feature_info_->IsES3Enabled()) {
2176 // It isn't explicitly required in the ES2 spec, but some drivers generate
2177 // an error. It is better to be consistent across drivers.
2165 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name, 2178 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
2166 "type does not match type of texture."); 2179 "type does not match type of texture.");
2167 return false; 2180 return false;
2168 } 2181 }
2169 if (!texture->ValidForTexture(args.target, args.level, args.xoffset, 2182 if (!texture->ValidForTexture(args.target, args.level,
2170 args.yoffset, 0, args.width, args.height, 1)) { 2183 args.xoffset, args.yoffset, args.zoffset,
2184 args.width, args.height, args.depth)) {
2171 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name, 2185 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2172 "bad dimensions."); 2186 "bad dimensions.");
2173 return false; 2187 return false;
2174 } 2188 }
2175 if ((GLES2Util::GetChannelsForFormat(args.format) & 2189 if ((GLES2Util::GetChannelsForFormat(args.format) &
2176 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && 2190 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 &&
2177 !feature_info_->IsES3Enabled()) { 2191 !feature_info_->IsES3Enabled()) {
2178 ERRORSTATE_SET_GL_ERROR( 2192 ERRORSTATE_SET_GL_ERROR(
2179 error_state, GL_INVALID_OPERATION, function_name, 2193 error_state, GL_INVALID_OPERATION, function_name,
2180 "can not supply data for depth or stencil textures"); 2194 "can not supply data for depth or stencil textures");
(...skipping 13 matching lines...) Expand all
2194 const DoTexSubImageArguments& args) { 2208 const DoTexSubImageArguments& args) {
2195 ErrorState* error_state = state->GetErrorState(); 2209 ErrorState* error_state = state->GetErrorState();
2196 TextureRef* texture_ref; 2210 TextureRef* texture_ref;
2197 if (!ValidateTexSubImage(state, function_name, args, &texture_ref)) { 2211 if (!ValidateTexSubImage(state, function_name, args, &texture_ref)) {
2198 return; 2212 return;
2199 } 2213 }
2200 2214
2201 Texture* texture = texture_ref->texture(); 2215 Texture* texture = texture_ref->texture();
2202 GLsizei tex_width = 0; 2216 GLsizei tex_width = 0;
2203 GLsizei tex_height = 0; 2217 GLsizei tex_height = 0;
2218 GLsizei tex_depth = 0;
2204 bool ok = texture->GetLevelSize(args.target, args.level, &tex_width, 2219 bool ok = texture->GetLevelSize(args.target, args.level, &tex_width,
2205 &tex_height, nullptr); 2220 &tex_height, &tex_depth);
2206 DCHECK(ok); 2221 DCHECK(ok);
2207 if (args.xoffset != 0 || args.yoffset != 0 || args.width != tex_width || 2222 if (args.xoffset != 0 || args.yoffset != 0 || args.zoffset != 0 ||
2208 args.height != tex_height) { 2223 args.width != tex_width || args.height != tex_height ||
2224 args.depth != tex_depth) {
2225 // TODO(zmo): Implement clearing of 3D textures. crbug.com/597201.
2209 gfx::Rect cleared_rect; 2226 gfx::Rect cleared_rect;
2210 if (CombineAdjacentRects( 2227 if (CombineAdjacentRects(
2211 texture->GetLevelClearedRect(args.target, args.level), 2228 texture->GetLevelClearedRect(args.target, args.level),
2212 gfx::Rect(args.xoffset, args.yoffset, args.width, args.height), 2229 gfx::Rect(args.xoffset, args.yoffset, args.width, args.height),
2213 &cleared_rect)) { 2230 &cleared_rect)) {
2214 DCHECK_GE(cleared_rect.size().GetArea(), 2231 DCHECK_GE(cleared_rect.size().GetArea(),
2215 texture->GetLevelClearedRect(args.target, args.level) 2232 texture->GetLevelClearedRect(args.target, args.level)
2216 .size() 2233 .size()
2217 .GetArea()); 2234 .GetArea());
2218 SetLevelClearedRect(texture_ref, args.target, args.level, cleared_rect); 2235 SetLevelClearedRect(texture_ref, args.target, args.level, cleared_rect);
2219 } else { 2236 } else {
2220 // Otherwise clear part of texture level that is not already cleared. 2237 // Otherwise clear part of texture level that is not already cleared.
2221 if (!ClearTextureLevel(decoder, texture_ref, args.target, args.level)) { 2238 if (!ClearTextureLevel(decoder, texture_ref, args.target, args.level)) {
2222 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, 2239 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY,
2223 "glTexSubImage2D", "dimensions too big"); 2240 function_name, "dimensions too big");
2224 return; 2241 return;
2225 } 2242 }
2226 } 2243 }
2227 ScopedTextureUploadTimer timer(texture_state); 2244 ScopedTextureUploadTimer timer(texture_state);
2228 glTexSubImage2D(args.target, args.level, args.xoffset, args.yoffset, 2245 if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) {
2229 args.width, args.height, AdjustTexFormat(args.format), 2246 glTexSubImage3D(args.target, args.level, args.xoffset, args.yoffset,
2230 args.type, args.pixels); 2247 args.zoffset, args.width, args.height, args.depth,
2231 return; 2248 AdjustTexFormat(args.format), args.type, args.pixels);
2249 } else {
2250 glTexSubImage2D(args.target, args.level, args.xoffset, args.yoffset,
2251 args.width, args.height, AdjustTexFormat(args.format),
2252 args.type, args.pixels);
2253 return;
2254 }
2232 } 2255 }
2233 2256
2234 if (!texture_state->texsubimage_faster_than_teximage && 2257 if (!texture_state->texsubimage_faster_than_teximage &&
2235 !texture->IsImmutable() && !texture->HasImages()) { 2258 !texture->IsImmutable() && !texture->HasImages()) {
2236 ScopedTextureUploadTimer timer(texture_state); 2259 ScopedTextureUploadTimer timer(texture_state);
2237 GLenum internal_format; 2260 GLenum internal_format;
2238 GLenum tex_type; 2261 GLenum tex_type;
2239 texture->GetLevelType(args.target, args.level, &tex_type, &internal_format); 2262 texture->GetLevelType(args.target, args.level, &tex_type, &internal_format);
2240 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need 2263 // NOTE: In OpenGL ES 2/3 border is always zero. If that changes we'll need
2241 // to look it up. 2264 // to look it up.
2242 glTexImage2D(args.target, args.level, internal_format, args.width, 2265 if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) {
2243 args.height, 0, AdjustTexFormat(args.format), args.type, 2266 glTexImage3D(args.target, args.level, internal_format, args.width,
2244 args.pixels); 2267 args.height, args.depth, 0, AdjustTexFormat(args.format),
2268 args.type, args.pixels);
2269 } else {
2270 glTexImage2D(args.target, args.level, internal_format, args.width,
2271 args.height, 0, AdjustTexFormat(args.format), args.type,
2272 args.pixels);
2273 }
2245 } else { 2274 } else {
2246 ScopedTextureUploadTimer timer(texture_state); 2275 ScopedTextureUploadTimer timer(texture_state);
2247 glTexSubImage2D(args.target, args.level, args.xoffset, args.yoffset, 2276 if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) {
2248 args.width, args.height, AdjustTexFormat(args.format), 2277 glTexSubImage3D(args.target, args.level, args.xoffset, args.yoffset,
2249 args.type, args.pixels); 2278 args.zoffset, args.width, args.height, args.depth,
2279 AdjustTexFormat(args.format), args.type, args.pixels);
2280 } else {
2281 glTexSubImage2D(args.target, args.level, args.xoffset, args.yoffset,
2282 args.width, args.height, AdjustTexFormat(args.format),
2283 args.type, args.pixels);
2284 }
2250 } 2285 }
2251 SetLevelCleared(texture_ref, args.target, args.level, true); 2286 SetLevelCleared(texture_ref, args.target, args.level, true);
2252 return; 2287 return;
2253 } 2288 }
2254 2289
2255 GLenum TextureManager::AdjustTexFormat(GLenum format) const { 2290 GLenum TextureManager::AdjustTexFormat(GLenum format) const {
2256 // TODO(bajones): GLES 3 allows for internal format and format to differ. 2291 // TODO(bajones): GLES 3 allows for internal format and format to differ.
2257 // This logic may need to change as a result. 2292 // This logic may need to change as a result.
2258 if (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) { 2293 if (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
2259 if (format == GL_SRGB_EXT) 2294 if (format == GL_SRGB_EXT)
(...skipping 20 matching lines...) Expand all
2280 bool level_is_same = 2315 bool level_is_same =
2281 texture->GetLevelSize( 2316 texture->GetLevelSize(
2282 args.target, args.level, &tex_width, &tex_height, &tex_depth) && 2317 args.target, args.level, &tex_width, &tex_height, &tex_depth) &&
2283 texture->GetLevelType(args.target, args.level, &tex_type, &tex_format) && 2318 texture->GetLevelType(args.target, args.level, &tex_type, &tex_format) &&
2284 args.width == tex_width && args.height == tex_height && 2319 args.width == tex_width && args.height == tex_height &&
2285 args.depth == tex_depth && args.type == tex_type && 2320 args.depth == tex_depth && args.type == tex_type &&
2286 args.format == tex_format; 2321 args.format == tex_format;
2287 2322
2288 if (level_is_same && !args.pixels) { 2323 if (level_is_same && !args.pixels) {
2289 // Just set the level texture but mark the texture as uncleared. 2324 // Just set the level texture but mark the texture as uncleared.
2290 SetLevelInfo(texture_ref, args.target, args.level, args.internal_format, 2325 // TODO(zmo): Implement clearing of 3D textures. crbug.com/597201.
2291 args.width, args.height, args.depth, args.border, args.format, 2326 bool set_as_cleared =
2292 args.type, gfx::Rect()); 2327 (args.command_type == DoTexImageArguments::kTexImage3D);
2328 SetLevelInfo(
2329 texture_ref, args.target, args.level, args.internal_format, args.width,
2330 args.height, args.depth, args.border, args.format, args.type,
2331 set_as_cleared ? gfx::Rect(args.width, args.height) : gfx::Rect());
2293 texture_state->tex_image_failed = false; 2332 texture_state->tex_image_failed = false;
2294 return; 2333 return;
2295 } 2334 }
2296 2335
2297 if (texture->IsAttachedToFramebuffer()) { 2336 if (texture->IsAttachedToFramebuffer()) {
2298 framebuffer_state->clear_state_dirty = true; 2337 framebuffer_state->clear_state_dirty = true;
2299 } 2338 }
2300 2339
2301 if (texture_state->texsubimage_faster_than_teximage && 2340 if (texture_state->texsubimage_faster_than_teximage &&
2302 level_is_same && args.pixels) { 2341 level_is_same && args.pixels) {
(...skipping 30 matching lines...) Expand all
2333 } 2372 }
2334 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name); 2373 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name);
2335 if (args.command_type == DoTexImageArguments::kTexImage3D) { 2374 if (args.command_type == DoTexImageArguments::kTexImage3D) {
2336 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage3D", error, 2375 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage3D", error,
2337 GetAllGLErrors()); 2376 GetAllGLErrors());
2338 } else { 2377 } else {
2339 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage2D", error, 2378 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage2D", error,
2340 GetAllGLErrors()); 2379 GetAllGLErrors());
2341 } 2380 }
2342 if (error == GL_NO_ERROR) { 2381 if (error == GL_NO_ERROR) {
2382 // TODO(zmo): Implement clearing of 3D textures. crbug.com/597201.
2383 bool set_as_cleared = (args.pixels != nullptr ||
2384 args.command_type == DoTexImageArguments::kTexImage3D);
2343 SetLevelInfo( 2385 SetLevelInfo(
2344 texture_ref, args.target, args.level, args.internal_format, args.width, 2386 texture_ref, args.target, args.level, args.internal_format, args.width,
2345 args.height, args.depth, args.border, args.format, args.type, 2387 args.height, args.depth, args.border, args.format, args.type,
2346 args.pixels != NULL ? gfx::Rect(args.width, args.height) : gfx::Rect()); 2388 set_as_cleared ? gfx::Rect(args.width, args.height) : gfx::Rect());
2347 texture_state->tex_image_failed = false; 2389 texture_state->tex_image_failed = false;
2348 } 2390 }
2349 } 2391 }
2350 2392
2351 bool TextureManager::CombineAdjacentRects(const gfx::Rect& rect1, 2393 bool TextureManager::CombineAdjacentRects(const gfx::Rect& rect1,
2352 const gfx::Rect& rect2, 2394 const gfx::Rect& rect2,
2353 gfx::Rect* result) { 2395 gfx::Rect* result) {
2354 // Return |rect2| if |rect1| is empty or |rect2| contains |rect1|. 2396 // Return |rect2| if |rect1| is empty or |rect2| contains |rect1|.
2355 if (rect1.IsEmpty() || rect2.Contains(rect1)) { 2397 if (rect1.IsEmpty() || rect2.Contains(rect1)) {
2356 *result = rect2; 2398 *result = rect2;
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
2706 uint32_t TextureManager::GetServiceIdGeneration() const { 2748 uint32_t TextureManager::GetServiceIdGeneration() const {
2707 return current_service_id_generation_; 2749 return current_service_id_generation_;
2708 } 2750 }
2709 2751
2710 void TextureManager::IncrementServiceIdGeneration() { 2752 void TextureManager::IncrementServiceIdGeneration() {
2711 current_service_id_generation_++; 2753 current_service_id_generation_++;
2712 } 2754 }
2713 2755
2714 } // namespace gles2 2756 } // namespace gles2
2715 } // namespace gpu 2757 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698