<html>
<head>
<base href="https://bugs.freedesktop.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - glGenerateMipmap makes deepest level far from average texel value for NPOT textures"
href="https://bugs.freedesktop.org/show_bug.cgi?id=109816">109816</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>glGenerateMipmap makes deepest level far from average texel value for NPOT textures
</td>
</tr>
<tr>
<th>Product</th>
<td>Mesa
</td>
</tr>
<tr>
<th>Version</th>
<td>18.2
</td>
</tr>
<tr>
<th>Hardware</th>
<td>Other
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>medium
</td>
</tr>
<tr>
<th>Component</th>
<td>Mesa core
</td>
</tr>
<tr>
<th>Assignee</th>
<td>mesa-dev@lists.freedesktop.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>b7.10110111@gmail.com
</td>
</tr>
<tr>
<th>QA Contact</th>
<td>mesa-dev@lists.freedesktop.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=143513" name="attach_143513" title="Test project">attachment 143513</a> <a href="attachment.cgi?id=143513&action=edit" title="Test project">[details]</a></span>
Test project
Trying to get an average of the pixels I rendered in the scene, I've come
across a problem with the way Mesa's implementation of glGenerateMipmap works
with NPOT textures.
To estimate the average, I render the scene to an FBO texture, and then use the
following C++ code (full compilable test project is attached to this bug
report):
// BEGIN code
void getMeanPixelValue(int texW, int texH)
{
// Get average value of the rendered pixels as the value of the deepest
mipmap level
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texFBO);
glGenerateMipmap(GL_TEXTURE_2D);
using namespace std;
// Formula from the glspec, "Mipmapping" subsection in section 3.8.11
Texture Minification
const auto totalMipmapLevels = 1+floor(log2(max(texW,texH)));
const auto deepestLevel=totalMipmapLevels-1;
// Sanity check
int deepestMipmapLevelWidth=-1, deepestMipmapLevelHeight=-1;
glGetTexLevelParameteriv(GL_TEXTURE_2D, deepestLevel,
GL_TEXTURE_WIDTH, &deepestMipmapLevelWidth);
glGetTexLevelParameteriv(GL_TEXTURE_2D, deepestLevel,
GL_TEXTURE_HEIGHT, &deepestMipmapLevelHeight);
assert(deepestMipmapLevelWidth==1);
assert(deepestMipmapLevelHeight==1);
vec4 pixel;
glGetTexImage(GL_TEXTURE_2D, deepestLevel, GL_RGBA, GL_FLOAT, &pixel[0]);
// Get average value in an actual summing loop over all the pixels
std::vector<vec4> data(texW*texH);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data.data());
vec4 avg(0,0,0,0);
for(auto const& v : data)
avg+=v;
avg/=texW*texH;
std::cerr << "Mipmap value: " << pixel[0] << ", " << pixel[1]
<< ", " << pixel[2] << ", " << pixel[3] << "\n";
std::cerr << "True average: " << avg[0] << ", " << avg[1]
<< ", " << avg[2] << ", " << avg[3] << "\n";
}
// END code
What I get from this code on Mesa Software renderer (using
LIBGL_ALWAYS_SOFTWARE=1):
New size: 512x512
Mipmap value: 0.195312, 0.390625, 0.585938, 0.78125
True average: 0.195312, 0.390625, 0.585938, 0.78125
New size: 512x511
Mipmap value: 0, 1.19209e-07, 1, 1
True average: 0.195695, 0.391389, 0.587084, 0.782779
With Intel Haswell (Core i7-4765T) hardware acceleration, the 1.19209e-07 value
becomes simply 0.
For comparison, below is what I get on an NVidia GPU with the proprietary
"nvidia" driver. This is what I would expect from Mesa and any other decent
OpenGL implementation.
New size: 512x512
Mipmap value: 0.195312, 0.390625, 0.585938, 0.78125
True average: 0.195312, 0.390625, 0.585938, 0.78125
New size: 512x511
Mipmap value: 0.195606, 0.39101, 0.586946, 0.782537
True average: 0.195695, 0.391389, 0.587084, 0.782779</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are the QA Contact for the bug.</li>
<li>You are the assignee for the bug.</li>
</ul>
</body>
</html>