|
View previous topic :: View next topic
|
| Author |
Message |
BrianKaris
Joined: 05 May 2009 Posts: 3 Location: Madison
|
| |
Posted: Tue May 05, 2009 4:27 pm Post subject: Simplest Trilinear Shader |
 |
|
Sean,
I am trying to implement the fastest version of these shaders. While digging through your notes I found this piece of code labeled as the simplest trilinear shader.
| Code: | TEX p , vtc , tex0, 2D
MAD phys.xy, vtc , p.x , p.yzyz
TEX phys.w , vtc , tex1, 2D
MAD phys.w , p.w , c16 , p.w
TXL color , phys, tex2, 2D |
I understand the gist of it. tex0 is the page table. tex1 is a texture with each mip level storing the number of the mip level it is. tex2 is the physical texture. Doing one texture lookup to derive the lod level I believe will be faster than computing gradients and a tex2dgrad. Another example of this is here for cubemaps in the last few slides http://developer.amd.com/media/gpu_assets/GDC2005_CubeMapGen.pdf.
There are some things I don't understand. The second MAD seems like a typo. One of those p.w's should be phys.w or otherwise the previous line was useless. I am also unsure what c16 is. If this is working like I think with mip levels colored, to get the correct lod the texel scale of the mip texture would need to match the scale of the virtual texture. If you are sampling into this with vtc tex1 would need to be the size of the entire virtual texture. That is obviously not going to work.
Since there is only one mip level in the physical tiles, all that you care about is how much of that next mip level you need to use for this pixel. You can get this with a 2x2 texture with an additional 1x1 mip level. Color the first mip black and the second mip white. You can use it like this:
phys.w = tex2d( mipTex, vtc * (pageTableSize * virtualPageSize / 2) )
You can use the spare w component of the page table for a fade in amount. This can either be used to scale vtc before sampling or adding a bias to the result. Biasing is preferred to reduce dependencies. Either way I can't think of how to do this without adding another instruction. Then again this isn't required. Using lodbias to try and fade things in is a pain in the ass in my experience but perhaps since the output is inherently clamped to [0,1] it won't be much of an issue.
That is the best I have made sense of that piece of code. My simplest trilinear shader would be 5 instructions just not those 5. p.w doesn't factor in at all unless another page fading instruction is added. Any insight into making the fastest SVT trilinear shader would be helpful. It feels like I must be missing something. |
|
| Back to top |
|
 |
sean
Joined: 01 Feb 2005 Posts: 1392 Location: Kirkland WA
|
| |
Posted: Tue May 05, 2009 8:02 pm Post subject: |
 |
|
I believe I just sketched that out quickly, based on Carmack's bilinear one, so it's buggy.
I'm not sure what the intention was, precisely. What I was trying to do, I believe, is use a texture that's the same resolution as the page table (since that's the limit to how far you can mipmap anyway, the same # of mipmap levels as the page table). However, you need to rescale the texture coordinates to force that texture to trilerp in the right way, so I'm not sure what I was thinking when I sampled tex1 by the vtc, instead of vtc*PAGESIZE (which would require another instruction).
The output of the "LOD-computing-texture" will be, abstractly, a number from 0..16 (whatever the max # of mipmaps is), with fractional values representing the amount of lerp between the mip levels. However, I believe I was assuming that, for efficiency, it was coming from an 8-bit texture so it's actually a number from [0,1], so it needs to be multipled by 16 (or whatever number of mipmaps).
However, what we want to hand to the final TXL instruction needs to just be a lerp factor from [0..1] (because the physical texture only has 2 mipmaps), so the idea is that you store the (integer) level in the page table, in the w field.
So the actual texture LOD level should be:
.... lod = phys.w*16 - p.w
So you actually store p.w negated in tex0, and I end up with:
| Code: | TEX p , vtc , tex0, 2D
MAD phys.xy, vtc , p.x , p.yzyz
MUL miptc , vtc , PAGE_SIZE
TEX phys.w , miptc , tex1, 2D // very large texture
MAD phys.w , phys.w, c16 , p.w
TXL color , phys , tex2, 2D
|
I'm not quite sure what you're proposing to compute a miplevel. If you try to use a 2x2 texture appropriately scaled, the scaling depends on which page table you've loaded, so you'd need to compensate for it:
| Code: | TEX p , vtc , tex0, 2D
MAD phys.xy, vtc , p.x , p.yzyz
MUL miptc , vtc , p.w
TEX phys.w , miptc , tex1, 2D // 2x2 texture?
TXL color , phys , tex2, 2D
|
But this doesn't quite work right; at pixels at mipmap boundaries, p.w will fetch different values there, and the derivative for p.w and hence the derivatives for miptc will blow up. Since we're relying on the derivatives of miptc to get the right miplevel factor out of tex1, the upshot will be that at pixels where the mip level (fetched from the page table) changes, it'll always peg to the low-res mip level. I believe this would happen on both sides of the mip boundary; on the higher-res side, forcing it to the lowest-res matched, but on the low-res side, you'll see a streak of next-lower-level texels.
I'm not sure how bad an artifact that would be, but I assume bad.
Then again, my first code has a problem, which is that the mipmap computation might mismatch between the page table operation and the trilerp factor lookup, so when you subtract them you get a totally wrong value. Since they're powers-of-two apart I think it wouldn't happen, though.
| Quote: | | You can use the spare w component of the page table for a fade in amount. |
You mean to fade-in stuff that you've just downloaded? Yeah, I dunno, that's pretty gross. The problem is in practice you're constantly streaming stuff down, so having to touch extra page table entries to update fading is kinda lame. |
|
| Back to top |
|
 |
BrianKaris
Joined: 05 May 2009 Posts: 3 Location: Madison
|
| |
Posted: Wed May 06, 2009 12:23 am Post subject: |
 |
|
Yeah, you are right. I keep forgetting that the page table points to pages of different scales. I've made that same mistake a few times already .
For the 2x2 texture my thinking is that all you need is that 0 to 1 lod factor. That should only need a mip texture with 2 levels so long as its sampled correctly. As you point out I would only sample it correctly for pages at full resolution.
As far as changing that scaling with p.w not only would that have problems on the boundaries it also introduces another level of dependency.
Your new code looks good to me. I don't see any obvious ways to simplify it further. The extra mul instruction will probably be masked in the dependent read so it shouldn't make much difference. What is stored in this mip texture looks to be the same as what you would use in the pass to find what pages to load. With a reasonably sized page table this looks like definitely the way to go. |
|
| Back to top |
|
 |
sean
Joined: 01 Feb 2005 Posts: 1392 Location: Kirkland WA
|
| |
Posted: Thu May 07, 2009 4:17 am Post subject: |
 |
|
Actually, I believe somebody else (here?) suggested that the lod-computing texture can be a lot smaller.
The idea is that, say your page table size is 1024x1024, so theoretically your mip-level-computing texture tex1 needs to be 1024x1024 as well (and you scale up the original coordinates by the page size (Edit: used to say "page table size")).
I believe the trick is that the way mipmapping math is defined, if you use a 2D texture that is 1024x1, then obviously the mipmapping works correctly along one axis. If you scale the other texture coordinate by 1024 before sampling, that will cause the other texture coordinate to also trigger the appropriate mipmapping.
You can think of this by figuring that the way it normally works to mipmap a, say, 1024x128 texture is to compute the mipmapping for the s paramter 'normally', and for the t parameter by dividing the t coordinate by 8 (or, equivalently, just bumping the lod computed for t down by 3). So even though once you hit 1-pixel in a given axis, so that axis shouldn't really have *any* mipmapping effect anymore, the same math is still applied.
(It's possible some hardware might not allow a 1024x1 texture, e.g. you can't have that large an aspect ratio? If so, you might have to use a 1024x8 or something like that.)
Last edited by sean on Thu May 07, 2009 4:59 pm; edited 1 time in total |
|
| Back to top |
|
 |
BrianKaris
Joined: 05 May 2009 Posts: 3 Location: Madison
|
| |
Posted: Thu May 07, 2009 6:28 am Post subject: |
 |
|
Yeah, I read that but I wasn't clear what happened when the scales of s and t weren't the same or if there was sheering. What you described sounds like it should handle those cases fine.
If you need a page id texture that is the size of the page table for the find needed pages pass, it can have this info in it to. It would be sampled then by vtc and not vtc * vPageSize but the same texture can be used.
For the next 2 weeks or so I don't have time to start work on implementing this stuff so until them I'm just doing research. Once I have my hands dirty I should be able to talk about this with a lot less uncertainty.
Thanks for the help. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|