From 9fb70b99db4f9a6eb0a585243666751ad1209137 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Wed, 7 Nov 2007 23:03:15 +0100 Subject: [PATCH] wined3d: Load GLSL sampler uniforms at shader link time. --- dlls/wined3d/directx.c | 23 +++++++++++++++++++++++ dlls/wined3d/glsl_shader.c | 34 ++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index aff5bee56d..5401ff5fea 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -738,6 +738,29 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { gl_info->max_vertex_samplers = tmp; glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp); gl_info->max_combined_samplers = tmp; + + /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup + * is known at shader link time. In a vertex shader + pixel shader combination this isn't + * an issue because then the sampler setup only depends on the two shaders. If a pixel + * shader is used with fixed function vertex processing we're fine too because fixed function + * vertex processing doesn't use any samplers. If fixed function fragment processing is + * used we have to make sure that all vertex sampler setups are valid together with all + * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES + * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards). + * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and + * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have + * a fixed function pipeline anymore. + * + * So this is just a check to check that our assumption holds true. If not, write a warning + * and reduce the number of vertex samplers or propably disable vertex texture fetch. + */ + if(gl_info->max_vertex_samplers && + MAX_TEXTURES + gl_info->max_vertex_samplers > gl_info->max_combined_samplers) { + FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers\n", + gl_info->max_vertex_samplers, gl_info->max_combined_samplers); + FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers\n"); + gl_info->max_vertex_samplers = max(0, gl_info->max_combined_samplers - MAX_TEXTURES); + } } else { gl_info->max_combined_samplers = gl_info->max_fragment_samplers; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index ee9403789a..adfaa9f868 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -77,10 +77,10 @@ void print_glsl_info_log(WineD3D_GL_Info *gl_info, GLhandleARB obj) { */ static void shader_glsl_load_psamplers( WineD3D_GL_Info *gl_info, - IWineD3DStateBlock* iface) { + IWineD3DStateBlock* iface, + GLhandleARB programId) { IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface; - GLhandleARB programId = stateBlock->glsl_program->programId; GLhandleARB name_loc; int i; char sampler_name[20]; @@ -101,9 +101,8 @@ static void shader_glsl_load_psamplers( } } -static void shader_glsl_load_vsamplers(WineD3D_GL_Info *gl_info, IWineD3DStateBlock* iface) { +static void shader_glsl_load_vsamplers(WineD3D_GL_Info *gl_info, IWineD3DStateBlock* iface, GLhandleARB programId) { IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface; - GLhandleARB programId = stateBlock->glsl_program->programId; GLhandleARB name_loc; char sampler_name[20]; int i; @@ -354,9 +353,6 @@ void shader_glsl_load_constants( constant_locations = prog->vuniformF_locations; constant_list = &stateBlock->set_vconstantsF; - /* Load vertex shader samplers */ - shader_glsl_load_vsamplers(gl_info, (IWineD3DStateBlock*)stateBlock); - /* Load DirectX 9 float constants/uniforms for vertex shader */ shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF), stateBlock->vertexShaderConstantF, constant_locations, constant_list); @@ -384,9 +380,6 @@ void shader_glsl_load_constants( constant_locations = prog->puniformF_locations; constant_list = &stateBlock->set_pconstantsF; - /* Load pixel shader samplers */ - shader_glsl_load_psamplers(gl_info, (IWineD3DStateBlock*) stateBlock); - /* Load DirectX 9 float constants/uniforms for pixel shader */ shader_glsl_load_constantsF(pshader, gl_info, GL_LIMITS(pshader_constantsF), stateBlock->pixelShaderConstantF, constant_locations, constant_list); @@ -3047,6 +3040,27 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use entry->srgb_mul_low_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_mul_low")); entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection")); checkGLcall("Find glsl program uniform locations"); + + /* Set the shader to allow uniform loading on it */ + GL_EXTCALL(glUseProgramObjectARB(programId)); + checkGLcall("glUseProgramObjectARB(programId)"); + + /* Load the vertex and pixel samplers now. The function that finds the mappings makes sure + * that it stays the same for each vertexshader-pixelshader pair(=linked glsl program). If + * a pshader with fixed function pipeline is used there are no vertex samplers, and if a + * vertex shader with fixed function pixel processing is used we make sure that the card + * supports enough samplers to allow the max number of vertex samplers with all possible + * fixed function fragment processing setups. So once the program is linked these samplers + * won't change. + */ + if(vshader_id) { + /* Load vertex shader samplers */ + shader_glsl_load_vsamplers(gl_info, (IWineD3DStateBlock*)This->stateBlock, programId); + } + if(pshader_id) { + /* Load pixel shader samplers */ + shader_glsl_load_psamplers(gl_info, (IWineD3DStateBlock*)This->stateBlock, programId); + } } static GLhandleARB create_glsl_blt_shader(WineD3D_GL_Info *gl_info) { -- 2.32.0.93.g670b81a890