oizma / angleproject

Automatically exported from code.google.com/p/angleproject
Other
0 stars 0 forks source link

glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2048, 2048, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL) produces unwanted GL_INVALID_VALUE #29

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Execute function with following parameters
   glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2048, 2048, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   This will produce GL_INVALID_VALUE, because there is a check:

   if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
   {
      return error(GL_INVALID_VALUE);
   }
   inside src\libGLESv2\libGLESv2.cpp  (4438) 

What is the expected output? What do you see instead?
The OpenGL ES 2.0 documentation states:
"GL_INVALID_VALUE is generated if width or height is less than 0 or greater 
than GL_MAX_TEXTURE_SIZE when target is GL_TEXTURE_2D or 
GL_MAX_CUBE_MAP_TEXTURE_SIZE when target is not GL_TEXTURE_2D."

Nothing is mentioned that when specifying data for level = 1, the max width or 
max height supposed to be (gl::MAX_TEXTURE_SIZE >> level)...
It doesn't matter for what level-of-detail you're specifying texture data, the 
max width and max height stays the same.

So in short, GL_INVALID_VALUE should not be produced

What version of the product are you using? On what operating system?
Using rev 414

Please provide any additional information below.

Original issue reported on code.google.com by tom...@gmail.com on 9 Sep 2010 at 12:11

GoogleCodeExporter commented 9 years ago
The same problem exists when using cube maps

Original comment by tom...@gmail.com on 9 Sep 2010 at 12:19

GoogleCodeExporter commented 9 years ago
The specification states that "The maximum allowable width and height of a 
two-dimensional texture image must be at least 2^(k-lod) for image arrays of 
level zero through k, where k is the log base 2 of MAX_TEXTURE_SIZE. and lod is 
the level-of-detail of the image array. The error INVALID_VALUE is generated if 
the specified image is too large to be stored under any conditions."

So implementations are allowed to produce an INVALID_VALUE error is the 
dimensions exceed that of a mipmap 'pyramid' of size MAX_TEXTURE_SIZE.

Original comment by nicolas....@gmail.com on 24 Sep 2010 at 1:21

GoogleCodeExporter commented 9 years ago
I am sorry, but where did you find such specification.

The page http://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml 
clearly states in what cases GL_INVALID_VALUE should be returned.

Regarding this matter, this line is important:
"GL_INVALID_VALUE may be generated if level is greater than log 2 ⁡ max , 
where max is the returned value of GL_MAX_TEXTURE_SIZE when target is 
GL_TEXTURE_2D or GL_MAX_CUBE_MAP_TEXTURE_SIZE when target is not GL_TEXTURE_2D."

And if you run program on device which natively supports OpenGL ES 2.0 (for 
ex., iPhone or Android) GL_INVALID_VALUE won't be produced when calling:
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2048, 2048, 0, GL_RGBA, 
GL_UNSIGNED_BYTE, NULL);

Original comment by tomas%un...@gtempaccount.com on 24 Sep 2010 at 8:55

GoogleCodeExporter commented 9 years ago
I've quoted from the 'OpenGL ES 2.0.24 Full Specification' page 67 
(http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.24.pdf). But 
indeed the online 'OpenGL ES 2.0 Reference Pages' don't mention any similar 
restriction. Given that the latter is aimed more at application developers and 
less at OpenGL implementers, I'm inclined to assume it may need to be updated. 
I'll attempt to get the official version from Khronos...

Anyway, is there any significant use case for allowing images larger than 
2^(k-lod)? The full spec clearly states that textures are only considered 
complete (i.e. they can be used by the hardware) if the mipmaps form a 
well-defined pyramid. So while some implementations may allow you to 
temporarily store large images at the higher levels, they can't be used for 
rendering. Incomplete textures are stored in system memory so you may as well 
keep these large images entirely on the application side.

First and foremost the spec definitely needs clarification, and then I'll 
gather opinions whether or not the restriction should be lifted.

Original comment by nicolas....@gmail.com on 24 Sep 2010 at 10:29

GoogleCodeExporter commented 9 years ago
The ES2 specification is the normative reference here, not the man pages.  I 
believe this is allowable behaviour, although it may not strictly be required.

Is there actually a useful case where you can store a MAX_TEXTURE_SIZE x 
MAX_TEXTURE_SIZE image at level 1, but not something larger at level 0?  As is, 
this case will never end up with a complete texture, and thus it seems 
reasonable (and I'd even go so far as to say more user-friendly) to toss an 
error at specification time, instead of letting the draw-time completeness 
check fail. 

Is this is the real cause of the problem, or is your code assuming that 
MAX_TEXTURE_SIZE is greater than 2048?  When you tested on the iPhone or 
Android, did you test with a value of 2048 for the level 1 texture, or did you 
use the MAX_TEXTURE_SIZE for the appropriate platform?

Original comment by dan...@transgaming.com on 27 Sep 2010 at 5:42

GoogleCodeExporter commented 9 years ago
Yes, I've tested it on iPhone with OpenGL ES 2.0, there max texture size is 
2048, and the line 'glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2048, 2048, 0, 
GL_RGBA, GL_UNSIGNED_BYTE, NULL)' doesn't produce GL_INVALID_VALUE', I've also 
tested this stuff on http://www.imgtec.com/powervr/insider/powervr-sdk.asp 
OpenGL ES 2.0 emulator, there this line also works without error...

I just really would like Angle library to produce same functionality...

Original comment by tom...@gmail.com on 29 Sep 2010 at 12:47

GoogleCodeExporter commented 9 years ago
Thanks.  

However, I'd still like to have some understanding of how this is actually 
useful functionality.  Can you share an example how this functionality might be 
used?

Original comment by dan...@transgaming.com on 29 Sep 2010 at 12:57

GoogleCodeExporter commented 9 years ago
It's useful for debugging stuff, consider for example that you're making a 
game, to make life easier you do everything on Windows using an abstraction 
layer, then when the game is finished, you launch it on the native device. But 
if there are different error conditions for OpenGL ES 2.0 on Windows and native 
device, this produces additional debugging effort...

Besides, with current angle implementation I couldn't do mipmaps like
Level 0 - 2048x2048
Level 1 - 1024x2048
Level 2 - 512x2048
and so on...

I am not sure are these arguments are good , but you'll probably agree that 
having OpenGL ES 2.0 behave the same both in Angle library and other devices or 
emulators, is a good idea?

Original comment by tom...@gmail.com on 29 Sep 2010 at 1:26

GoogleCodeExporter commented 9 years ago
I fully understand how valuable using an abstraction layer and developing on 
Windows can be.  However, I don't believe that relaxing this error case is 
something that would aid in porting.  In my opinion it is more valuable to have 
a *stricter* abstraction layer as that will aid in increased portability 
between multiple platforms which may each have their own quirks.

The mipmap example you gave (2048x2048, 1024x2048, 512x2048, etc) is not a 
valid mipmap chain.  A valid mipmap chain would be 2048x2048, 1024x1024, 
512x512,... 1x1.  Section 3.7.7 of the ES2 spec (p79) states that: 
  "If the image array of level zero has dimensions w_b × h_b, then there are floor(log2(max(wb, hb))) + 1 image arrays in the mipmap. Each array subsequent to the array of level zero has dimensions max(1, floor(w_b/2^i)) × max(1, floor(h_b/2^i)) until the last array is reached with dimension 1 × 1. ....    
  "Level-of-detail numbers proceed from zero for the original texture array through q = floor(log2(max(wb,hb))) with each unit increase indicating an array of half the dimensions of the previous one (rounded down to the next integer if fractional) as already described."

The PVR emulator just layers on top of the desktop GL drivers, and in my 
experience with it, tends to allow some non-ES2 functionality to leak through. 
If the case you describe is valid under Desktop GL, I suspect this is what is 
happening.

In Desktop GL, I could envision some potential valid use cases for something 
like this:
 - you could use GL for storing data and reading it back later (ES2 does not support reading back texture data)
 - you could specify TEXTURE_MAX_LEVEL and TEXTURE_BASE_LEVEL appropriately to use only a single level/or a subset of levels (ES2 does not have TEXTURE_MAX_LEVEL or TEXTURE_BASE_LEVEL.  iOS has an extension to add TEXTURE_MAX_LEVEL, but I don't think it is sufficient to make this useful).

Even though some ES2 implementations may allow you to specify such an image, I 
don't believe it is possible to actually use it in anyway.  The texture either 
needs a) only 1 level, or b) all levels down to 1x1 defined consistently -- in 
order to be considered complete, depending on the type of filtering enabled.  
See the ES 2.0 specification sections 3.7.1, 3.7.7, 3.7.10, and 3.8.2 for all 
the details.

However, I am more than willing to make the change provided there is a 
compelling (or really *any*) use case where this enables desirable 
functionality and is not just covering up an application bug.  Perhaps I'm not 
imaginative enough, but I've been unable to come up with any use cases (in 
ES2.0) where this functionality would be useful.

Can you provide a more complete or specific example where this is useful?

Thanks,
Daniel

Original comment by dan...@transgaming.com on 5 Oct 2010 at 4:07

GoogleCodeExporter commented 9 years ago
FYI, I also found the following in the Full Specification 2.0.24:

"Effects of Completeness on Texture Image Specification

An implementation may allow a texture image array of level one or greater to be
created only if a complete set of image arrays consistent with the requested 
array
can be supported."

Althoug it doesn't mention the error it can return, it very explicitly says 
that image levels that can't result in a complete texture are not guaranteed to 
work. The previous spec text I quoted was a bit hazier but this should take 
away all doubt.

It means that even if we lift this restriction from ANGLE, there can definitely 
still be implementations that don't support it. This makes debugging a big 
pain: you've tested your application on ANGLE and various mobile devices, but 
months later you start getting crash reports for a new device. Even though 
nobody has worked on the application for months, you'll have to dig it up, buy 
the device it's crashing on, debug things, and release a new version. During 
this time you'll also have to provide support for people who bought the 
application but can't get it to run. All this costs time and money you could 
have saved by coding for a more strict specification.

So the usefulness of this capability should be offset against this risk.

Original comment by Nicolas....@gmail.com on 6 Oct 2010 at 12:31

GoogleCodeExporter commented 9 years ago
closing as wontfix.  Please re-open if you have a specific use case that this 
enables.

Original comment by dan...@transgaming.com on 27 Oct 2010 at 3:57