On Thursday 28 January 2010 23:40:25 Henri Verbeet wrote:
+static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info) +{
- unsigned int start, last, i;
- start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
- last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1,
WINED3D_HIGHEST_TEXTURE_STATE); + for (i = start; i <= last; ++i)
- {
state_table[i].representative = 0;
state_table[i].apply = state_undefined;
- }
Please use the number of texture blend stages reported from the fragment pipeline rather than gl_limits.texture_stages. texture_stages only works with the nvrc and ffp pipelines, but not arbfp or atifs(it works out ok by chance on most GL cards).
There's a deeper issue with how we manage texture limits, because currently the extension loading code picks limits.texture_stages, already anticipating which pipeline we'll choose later. We should handle this in the way shader constants are handled: Rename limits.texture_stages to limits.max_nv_general_combiners, make only the nvrc and nvts pipelines read this extension specific value, and use the pipeline reported d3d texture blend stages in fragment pipeline independent code. We're also (still) mixing up blend stages with fixed function vertex coordinates.
Regarding masking out unsupported / invalid states, Ivan once suggested the idea to make the pipeline template's needed extension field more powerful, e.g. via a callback function. That way the pipeline would have more control over which state handlers it registers. I am fine with a pipeline independent function, I guess it will work just fine for our needs, just digging out the old idea.
On 29 January 2010 00:27, Stefan Dösinger stefandoesinger@gmx.at wrote:
Please use the number of texture blend stages reported from the fragment pipeline rather than gl_limits.texture_stages. texture_stages only works with the nvrc and ffp pipelines, but not arbfp or atifs(it works out ok by chance on most GL cards).
If those aren't the same, the code initializing the texture_stages limit is broken, not the code using it.
There's a deeper issue with how we manage texture limits, because currently the extension loading code picks limits.texture_stages, already anticipating which pipeline we'll choose later. We should handle this in the way shader
True, but that code was there before the concept of a fragment pipeline was introduced in wined3d.
constants are handled: Rename limits.texture_stages to limits.max_nv_general_combiners, make only the nvrc and nvts pipelines read this extension specific value, and use the pipeline reported d3d texture blend stages in fragment pipeline independent code. We're also (still) mixing up blend stages with fixed function vertex coordinates.
Almost. The texture_stages limit is supposed to indicate the number of texture stages the GL implementation can support, I don't think there's a reason to change that. What needs to change is that we assign its value based on the fragment pipeline caps instead of based on the GL extensions.
On Friday 29 January 2010 00:55:19 Henri Verbeet wrote:
Almost. The texture_stages limit is supposed to indicate the number of texture stages the GL implementation can support, I don't think there's a reason to change that. What needs to change is that we assign its value based on the fragment pipeline caps instead of based on the GL extensions.
Texture stages are a direct3d concept. On the GL side we have MAX_GENERAL_COMBINERS_NV, 8(atifs extension hardcoded), MAX_TEXTURES(ffp) or the arbfp shader instruction limit. How those translate into the d3d limit is an implementation detail of the fragment pipeline and none of the GL extension loading code's business.
Plus, we need the raw GL limit intact as well. Let's take for example gl max_textures vs gl max_samplers vs d3d MaxSimultaneousTextures. Assume a geforce 7 card. max_textures = 4, arbfs pipeline.
In this situation this code will result in a GL error: glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_2D, tex); glEnable(GL_TEXTURE_2D);
However, on the d3d side this is perfectly valid and working OK: SetPixelShader(NULL); SetTexture(0, tex); SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(1, tex); SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(2, tex); SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(3, tex); SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(4, tex); SetTextureStageState(4, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(5, tex); SetTextureStageState(5, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTextureStageState(6, D3DTSS_COLOROP, D3DTOP_DISABLE);
So (gl)max_textures=4, (gl)max_samplers=16, (d3d)MaxSimultaneousTextures=8
Furthermore we can't store MaxSimultaneousTextures in the GL limits, as it can depend on the device creation parameters. E.g. the app creates the device with D3DCREATE_SOFTWARE_VERTEXPROCESSING. This way the vertex pipeline's limits don't have any relation to the GL vertex limits, and we don't know what the app will do when we initialize the adapter.
Please use the number of texture blend stages reported from the fragment pipeline rather than gl_limits.texture_stages. texture_stages only works with the nvrc and ffp pipelines, but not arbfp or atifs(it works out ok by chance on most GL cards).
If those aren't the same, the code initializing the texture_stages limit is broken, not the code using it.
Your code is manipulating the input into the pipeline code, it is talking in D3D terms, so the D3D limits apply, not the GL limits.
There's a deeper issue with how we manage texture limits, because currently the extension loading code picks limits.texture_stages, already anticipating which pipeline we'll choose later. We should handle this in the way shader
True, but that code was there before the concept of a fragment pipeline was introduced in wined3d.
I introduced the separation of d3d fragment pipeline limits from gl fragment pipeline limits when I introduced the different fragment piplines - see the pipeline.get_caps() function. Later on I did the same for shader limits. It is far from perfect though, on the vertex side we're still mixing them up.
I can't find the original patch in git since it was a long time ago in spring 08, here are a few following patches though: 9a6bc683e11bf508a37769640d56f201462b935a 462ddaa25404cd1a07135f5d7acdd2e298d7dfad
On 29 January 2010 11:01, Stefan Dösinger stefandoesinger@gmx.at wrote:
On Friday 29 January 2010 00:55:19 Henri Verbeet wrote:
Almost. The texture_stages limit is supposed to indicate the number of texture stages the GL implementation can support, I don't think there's a reason to change that. What needs to change is that we assign its value based on the fragment pipeline caps instead of based on the GL extensions.
Texture stages are a direct3d concept. On the GL side we have MAX_GENERAL_COMBINERS_NV, 8(atifs extension hardcoded), MAX_TEXTURES(ffp) or the arbfp shader instruction limit. How those translate into the d3d limit is an implementation detail of the fragment pipeline and none of the GL extension loading code's business.
Yes, that's why the value of limits.texture_stages should be based on the fragment pipe caps instead of the detected extensions. You also seem to have a problem with storing derived limits in wined3d_gl_limits, but I don't see why. Where the limit is stored is a separate issue from what it contains though.
Plus, we need the raw GL limit intact as well. Let's take for example gl
We could add e.g. the general combiner limit to wined3d_gl_limits if needed, but with that being a pipeline specific detail we might as well keep that internal to the specific implementation. If it means anything, I'm not entirely happy with shader backend specific limits being exposed through wined3d_gl_limits either.
max_textures vs gl max_samplers vs d3d MaxSimultaneousTextures. Assume a geforce 7 card. max_textures = 4, arbfs pipeline.
In this situation this code will result in a GL error: glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_2D, tex); glEnable(GL_TEXTURE_2D);
However, on the d3d side this is perfectly valid and working OK: SetPixelShader(NULL); SetTexture(0, tex); SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(1, tex); SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(2, tex); SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(3, tex); SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(4, tex); SetTextureStageState(4, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTexture(5, tex); SetTextureStageState(5, D3DTSS_COLOROP, D3DTOP_PREVIOUS); SetTextureStageState(6, D3DTSS_COLOROP, D3DTOP_DISABLE);
So (gl)max_textures=4, (gl)max_samplers=16, (d3d)MaxSimultaneousTextures=8
Sure, but I don't see how that's relevant? It's also a bit silly to enable fixed function texturing when you're using arbfs.
Furthermore we can't store MaxSimultaneousTextures in the GL limits, as it can depend on the device creation parameters. E.g. the app creates the device with D3DCREATE_SOFTWARE_VERTEXPROCESSING. This way the vertex pipeline's limits don't have any relation to the GL vertex limits, and we don't know what the app will do when we initialize the adapter.
Which we don't actually implement, and probably never will. In practice, all the limits are adapter limits, and things like shader backend and fragment pipe could be selected during adapter initialization instead of device initialization as well. If that ever changes it's of course trivial to split gl_info into a device specific part and an adapter specific part, or even move the entire thing to the device.
Please use the number of texture blend stages reported from the fragment pipeline rather than gl_limits.texture_stages. texture_stages only works with the nvrc and ffp pipelines, but not arbfp or atifs(it works out ok by chance on most GL cards).
If those aren't the same, the code initializing the texture_stages limit is broken, not the code using it.
Your code is manipulating the input into the pipeline code, it is talking in D3D terms, so the D3D limits apply, not the GL limits.
I think this is a silly distinction, D3D limits are clearly derived from the capabilities of the GL implementation. In fact, a number of limits in there are derived limits, because they take things like quirks and registry settings into account. I'd be willing to rename "struct wined3d_gl_limits" to "struct wined3d_limits" though.
I can't find the original patch in git since it was a long time ago in spring 08, here are a few following patches though: 9a6bc683e11bf508a37769640d56f201462b935a 462ddaa25404cd1a07135f5d7acdd2e298d7dfad
I guess those slipped by.
On Friday 29 January 2010 12:02:39 Henri Verbeet wrote:
You also seem to have a problem with storing derived limits in wined3d_gl_limits, but I don't see why. Where the limit is stored is a separate issue from what it contains though.
The name mostly. MaxSimultaneousTextures=8(with arbfp) doesn't come from any GL limit.
Plus, as a minor point, the initialization time. The d3d limits on paper depend on the device creation params, the gl limits do not.
E.g. the app creates the device with D3DCREATE_SOFTWARE_VERTEXPROCESSING. This way the vertex pipeline's limits don't have any relation to the GL vertex limit ...
Which we don't actually implement, and probably never will. In practice, all the limits are adapter limits, and things like shader backend and fragment pipe could be selected during adapter initialization instead of device initialization as well. If that ever changes it's of course trivial to split gl_info into a device specific part and an adapter specific part, or even move the entire thing to the device.
I think this is a silly distinction, D3D limits are clearly derived from the capabilities of the GL implementation. In fact, a number of limits in there are derived limits, because they take things like quirks and registry settings into account. I'd be willing to rename "struct wined3d_gl_limits" to "struct wined3d_limits" though.
My preference would be this:
Put max_ffp_textures, max_ffp_texture_stages, the shader constant limits into a device->limits structure and initialize it at device creation time based on what the pipeline and shader backends report.
Alternatively, I am fine with renaming wined3d_gl_limits and selecting the pipeline and shader backend during adapter initialization as you suggest, as long as we separate the nvrc combiner limit from the d3d texture stage limit. If we ever implement a software vertex processing pipeline moving the d3d limit initialization back to the device creation code will be the least concern.