Commit 7db45ad0 authored by kbr's avatar kbr Committed by Commit bot

Add disable_program_caching_for_transform_feedback workaround.

All current Qualcomm GPUs are affected by a bug where program binaries
don't cache transform feedback varyings. Work around this by avoiding
the use of the in-memory and disk program caches when the transform
feedback varyings are non-empty.

BUG=658074
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel

Review-Url: https://codereview.chromium.org/2615573002
Cr-Commit-Position: refs/heads/master@{#441433}
parent 69682c5c
...@@ -202,10 +202,14 @@ void RunShaderCallback(const ShaderCacheCallback& callback, ...@@ -202,10 +202,14 @@ void RunShaderCallback(const ShaderCacheCallback& callback,
} // namespace } // namespace
MemoryProgramCache::MemoryProgramCache(size_t max_cache_size_bytes, MemoryProgramCache::MemoryProgramCache(
bool disable_gpu_shader_disk_cache) size_t max_cache_size_bytes,
bool disable_gpu_shader_disk_cache,
bool disable_program_caching_for_transform_feedback)
: max_size_bytes_(max_cache_size_bytes), : max_size_bytes_(max_cache_size_bytes),
disable_gpu_shader_disk_cache_(disable_gpu_shader_disk_cache), disable_gpu_shader_disk_cache_(disable_gpu_shader_disk_cache),
disable_program_caching_for_transform_feedback_(
disable_program_caching_for_transform_feedback),
curr_size_bytes_(0), curr_size_bytes_(0),
store_(ProgramMRUCache::NO_AUTO_EVICT) { store_(ProgramMRUCache::NO_AUTO_EVICT) {
} }
...@@ -291,6 +295,10 @@ void MemoryProgramCache::SaveLinkedProgram( ...@@ -291,6 +295,10 @@ void MemoryProgramCache::SaveLinkedProgram(
const std::vector<std::string>& transform_feedback_varyings, const std::vector<std::string>& transform_feedback_varyings,
GLenum transform_feedback_buffer_mode, GLenum transform_feedback_buffer_mode,
const ShaderCacheCallback& shader_callback) { const ShaderCacheCallback& shader_callback) {
if (disable_program_caching_for_transform_feedback_ &&
!transform_feedback_varyings.empty()) {
return;
}
GLenum format; GLenum format;
GLsizei length = 0; GLsizei length = 0;
glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH_OES, &length); glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH_OES, &length);
......
...@@ -26,7 +26,8 @@ namespace gles2 { ...@@ -26,7 +26,8 @@ namespace gles2 {
class GPU_EXPORT MemoryProgramCache : public ProgramCache { class GPU_EXPORT MemoryProgramCache : public ProgramCache {
public: public:
MemoryProgramCache(size_t max_cache_size_bytes, MemoryProgramCache(size_t max_cache_size_bytes,
bool disable_gpu_shader_disk_cache); bool disable_gpu_shader_disk_cache,
bool disable_program_caching_for_transform_feedback);
~MemoryProgramCache() override; ~MemoryProgramCache() override;
ProgramLoadResult LoadLinkedProgram( ProgramLoadResult LoadLinkedProgram(
...@@ -164,6 +165,7 @@ class GPU_EXPORT MemoryProgramCache : public ProgramCache { ...@@ -164,6 +165,7 @@ class GPU_EXPORT MemoryProgramCache : public ProgramCache {
const size_t max_size_bytes_; const size_t max_size_bytes_;
const bool disable_gpu_shader_disk_cache_; const bool disable_gpu_shader_disk_cache_;
const bool disable_program_caching_for_transform_feedback_;
size_t curr_size_bytes_; size_t curr_size_bytes_;
ProgramMRUCache store_; ProgramMRUCache store_;
......
...@@ -70,13 +70,15 @@ class MemoryProgramCacheTest : public GpuServiceTest { ...@@ -70,13 +70,15 @@ class MemoryProgramCacheTest : public GpuServiceTest {
public: public:
static const size_t kCacheSizeBytes = 1024; static const size_t kCacheSizeBytes = 1024;
static const bool kDisableGpuDiskCache = false; static const bool kDisableGpuDiskCache = false;
static const bool kDisableCachingForTransformFeedback = false;
static const GLuint kVertexShaderClientId = 90; static const GLuint kVertexShaderClientId = 90;
static const GLuint kVertexShaderServiceId = 100; static const GLuint kVertexShaderServiceId = 100;
static const GLuint kFragmentShaderClientId = 91; static const GLuint kFragmentShaderClientId = 91;
static const GLuint kFragmentShaderServiceId = 100; static const GLuint kFragmentShaderServiceId = 100;
MemoryProgramCacheTest() MemoryProgramCacheTest()
: cache_(new MemoryProgramCache(kCacheSizeBytes, kDisableGpuDiskCache)), : cache_(new MemoryProgramCache(kCacheSizeBytes, kDisableGpuDiskCache,
kDisableCachingForTransformFeedback)),
shader_manager_(nullptr), shader_manager_(nullptr),
vertex_shader_(nullptr), vertex_shader_(nullptr),
fragment_shader_(nullptr), fragment_shader_(nullptr),
...@@ -537,6 +539,40 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentTransformFeedbackVaryings) { ...@@ -537,6 +539,40 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentTransformFeedbackVaryings) {
base::Unretained(this)))); base::Unretained(this))));
} }
TEST_F(MemoryProgramCacheTest, LoadFailIfTransformFeedbackCachingDisabled) {
const GLenum kFormat = 1;
const int kProgramId = 10;
const int kBinaryLength = 20;
char test_binary[kBinaryLength];
for (int i = 0; i < kBinaryLength; ++i) {
test_binary[i] = i;
}
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
// Forcibly reset the program cache so we can disable caching of
// programs which include transform feedback varyings.
cache_.reset(new MemoryProgramCache(
kCacheSizeBytes, kDisableGpuDiskCache, true));
varyings_.push_back("test");
cache_->SaveLinkedProgram(kProgramId,
vertex_shader_,
fragment_shader_,
NULL,
varyings_,
GL_INTERLEAVED_ATTRIBS,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
kProgramId,
vertex_shader_,
fragment_shader_,
NULL,
varyings_,
GL_INTERLEAVED_ATTRIBS,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this))));
}
TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) {
const GLenum kFormat = 1; const GLenum kFormat = 1;
const int kProgramId = 10; const int kProgramId = 10;
......
...@@ -19,7 +19,7 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( ...@@ -19,7 +19,7 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST(
{ {
"name": "gpu driver bug list", "name": "gpu driver bug list",
// Please update the version number whenever you change this file. // Please update the version number whenever you change this file.
"version": "9.26", "version": "9.27",
"entries": [ "entries": [
{ {
"id": 1, "id": 1,
...@@ -2301,6 +2301,18 @@ LONG_STRING_CONST( ...@@ -2301,6 +2301,18 @@ LONG_STRING_CONST(
"features": [ "features": [
"rewrite_float_unary_minus_operator" "rewrite_float_unary_minus_operator"
] ]
},
{
"id": 212,
"description": "Program binaries don't contain transform feedback varyings on Qualcomm GPUs",
"cr_bugs": [658074],
"os": {
"type": "android"
},
"gl_renderer": "Adreno.*",
"features": [
"disable_program_caching_for_transform_feedback"
]
} }
] ]
// Please update the version number at beginning of this file whenever you // Please update the version number at beginning of this file whenever you
......
...@@ -73,6 +73,8 @@ ...@@ -73,6 +73,8 @@
disable_post_sub_buffers_for_onscreen_surfaces) \ disable_post_sub_buffers_for_onscreen_surfaces) \
GPU_OP(DISABLE_PROGRAM_CACHE, \ GPU_OP(DISABLE_PROGRAM_CACHE, \
disable_program_cache) \ disable_program_cache) \
GPU_OP(DISABLE_PROGRAM_CACHING_FOR_TRANSFORM_FEEDBACK, \
disable_program_caching_for_transform_feedback) \
GPU_OP(DISABLE_PROGRAM_DISK_CACHE, \ GPU_OP(DISABLE_PROGRAM_DISK_CACHE, \
disable_program_disk_cache) \ disable_program_disk_cache) \
GPU_OP(DISABLE_TEXTURE_CUBE_MAP_SEAMLESS, \ GPU_OP(DISABLE_TEXTURE_CUBE_MAP_SEAMLESS, \
......
...@@ -169,11 +169,14 @@ gpu::gles2::ProgramCache* InProcessCommandBuffer::Service::program_cache() { ...@@ -169,11 +169,14 @@ gpu::gles2::ProgramCache* InProcessCommandBuffer::Service::program_cache() {
(gl::g_driver_gl.ext.b_GL_ARB_get_program_binary || (gl::g_driver_gl.ext.b_GL_ARB_get_program_binary ||
gl::g_driver_gl.ext.b_GL_OES_get_program_binary) && gl::g_driver_gl.ext.b_GL_OES_get_program_binary) &&
!gpu_preferences().disable_gpu_program_cache) { !gpu_preferences().disable_gpu_program_cache) {
const GpuDriverBugWorkarounds& workarounds = gpu_driver_bug_workarounds_;
bool disable_disk_cache = bool disable_disk_cache =
gpu_preferences_.disable_gpu_shader_disk_cache || gpu_preferences_.disable_gpu_shader_disk_cache ||
gpu_driver_bug_workarounds_.disable_program_disk_cache; workarounds.disable_program_disk_cache;
program_cache_.reset(new gles2::MemoryProgramCache( program_cache_.reset(new gles2::MemoryProgramCache(
gpu_preferences_.gpu_program_cache_size, disable_disk_cache)); gpu_preferences_.gpu_program_cache_size,
disable_disk_cache,
workarounds.disable_program_caching_for_transform_feedback));
} }
return program_cache_.get(); return program_cache_.get();
} }
......
...@@ -87,11 +87,14 @@ gles2::ProgramCache* GpuChannelManager::program_cache() { ...@@ -87,11 +87,14 @@ gles2::ProgramCache* GpuChannelManager::program_cache() {
(gl::g_driver_gl.ext.b_GL_ARB_get_program_binary || (gl::g_driver_gl.ext.b_GL_ARB_get_program_binary ||
gl::g_driver_gl.ext.b_GL_OES_get_program_binary) && gl::g_driver_gl.ext.b_GL_OES_get_program_binary) &&
!gpu_preferences_.disable_gpu_program_cache) { !gpu_preferences_.disable_gpu_program_cache) {
const GpuDriverBugWorkarounds& workarounds = gpu_driver_bug_workarounds_;
bool disable_disk_cache = bool disable_disk_cache =
gpu_preferences_.disable_gpu_shader_disk_cache || gpu_preferences_.disable_gpu_shader_disk_cache ||
gpu_driver_bug_workarounds_.disable_program_disk_cache; workarounds.disable_program_disk_cache;
program_cache_.reset(new gles2::MemoryProgramCache( program_cache_.reset(new gles2::MemoryProgramCache(
gpu_preferences_.gpu_program_cache_size, disable_disk_cache)); gpu_preferences_.gpu_program_cache_size,
disable_disk_cache,
workarounds.disable_program_caching_for_transform_feedback));
} }
return program_cache_.get(); return program_cache_.get();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment