PDA

View Full Version : compute shader and imageStore to image2D miplevel



mtnk4t
12-24-2012, 03:21 AM
Hi all, I have a very simple compute shader that I want to use to initialize all levels of a texture.



#version 430
#define TILE_WIDTH 16
#define TILE_HEIGHT 16

const ivec2 tileSize = ivec2(TILE_WIDTH, TILE_HEIGHT);

layout (binding=0, r32f) writeonly uniform image2D imageOUT;

layout (local_size_x = TILE_WIDTH, local_size_y = TILE_HEIGHT) in;

void main()
{
const ivec2 tile_xy = ivec2(gl_WorkGroupID);
const ivec2 thread_xy = ivec2(gl_LocalInvocationID);
const ivec2 samplePos = tile_xy * tileSize + thread_xy;
imageStore(imageOUT, samplePos, vec4(1,0,0,0));
}


the following C++ code invokes the shader:



glBindImageTexture(/*image*/ 0, image.id_GL(), /*level*/ myLevel, GL_FALSE, /*layer*/ 0, GL_WRITE_ONLY, GL_R32F);

auto subTex = image.mipMapSubTexture(myLevel);
int mipTextureWidth = subTex.width();
int mipTextureHeight = subTex.height();
int glDispatchX = (mipTextureWidth + 16 - 1)/16;
int glDispatchY = (mipTextureHeight + 16 - 1)/16;
glCheck ( glDispatchCompute(
glDispatchX,
glDispatchY,
1) );


Now, everything works fine if I am using `myLevel=0`, but not if I set `myLevel=1`.
The desired output upon visualization would be a "red image". But I see a "black image" for any other level except level 0.


Note, that I allocated the texture memory with this code (that has been proven to work for all other texture reliably):



uint w = this->width();
uint h = this->height();
for (int i = 0; i < numLevels; i++)
{
glCheck(glTexImage2D(target(), i, internalFormat, w, h, 0, this->parameter().pixelType().format(), this->parameter().pixelType().componentType(), NULL));
w /= 2;
h /= 2;
}


This is the code I use to visualize the texture:



#version 420
uniform sampler2D tex;
uniform int mipLevel;

in PerVertexData
{
vec2 TexCoord0;
} In;

out vec4 outColor;

void main()
{
ivec2 texSize = textureSize(tex, mipLevel);
ivec2 samplePos = ivec2(texSize*In.TexCoord0);

outColor = texelFetch(tex, samplePos, mipLevel);

}


I am somewhat afraid that I hit a driver bug: I use the NVIDIA ForceWare 310.70 on Win7 64.

solong

m.

mtnk4t
12-25-2012, 04:43 PM
I found a way around the problem:
I was trying to be smart and did not allocate the full mipmap pyramid but only upto 16x16 because I am using a compute shader group size of 16x16.
Consequently, I allocate now all the levels (one can also use glTexStorage2D to do this) and it works. I am however not sure whether I really _have_ to allocate all the mip levels or whether this can still be considered a driver bug (?).

regards

m.