Sign in to follow this  
guokai

Beard Corruption Of The Quartermaster Observed In The Slums Chapter On Amd Graphics Card

Recommended Posts

Hi Friends,
 
I saw this bug with AMD graphics card on Ubuntu 14.04, and the beard is render to black color instead of white. It seems I can not upload my local picture here, so If anybody need, I can send it to your email.

 

To figure out the root cause, I dumped the API calls and shaders, and finally located the corrupted draw and its fragment shader.

 

Here is the shader source:

 

void main ( void )
{
    vec4 o_nrm ;
    vec4 o_spc = vec4 ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
    vec4 o_dif = SwizzleXXXX ( 0.0 ) ;
    vec2 uv_0 = x_uv_0 ;
    vec4 dif_tex = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ) ;
    dif_tex = Sample ( t_dif_0 , s_dif_0 , uv_0 ) ;
    vec4 spc_tex = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ) ;
    spc_tex = Sample ( t_spc_0 , s_spc_0 , uv_0 ) ;
    vec4 msk_tex = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ) ;
    vec4 nrm_tex = vec4 ( 0.5 , 0.5 , 1.0 , 1.0 ) ;
    nrm_tex = Sample ( t_nrm_0 , s_nrm_0 , uv_0 ) ;
    vec4 dye_tex = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ) ;
    vec4 vertex = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ) ;
    vec3 dif = vec3 ( dif_tex . rgb ) ;
    float spc_lum = Luminance ( vec3 ( spc_tex . rgb ) ) ;
    float clip_mask = 1.0 ;
    clip_mask = SwizzleX ( dif_tex . a ) - SwizzleX ( CONST_110 . w ) ;
    clip ( clip_mask ) ;
    vec3 E2T_XFORM [ 3 ] ;
    E2T_XFORM [ 0 ] = x_tng_cs ;
    E2T_XFORM [ 1 ] = x_bnr_cs ;
    E2T_XFORM [ 2 ] = x_nrm_cs ;
    vec3 nrm_ts = vec3 ( 0.0 , 0.0 , 1.0 ) ;
    nrm_ts . xy = nrm_tex . ag * CONST_112 . x + CONST_112 . y ;
    vec3 nrm_cs = Mul33T ( nrm_ts , E2T_XFORM ) ;
    vec3 nrm_n_cs = normalize ( nrm_cs ) ;
    nrm_n_cs = ! gl_FrontFacing ? nrm_n_cs : - nrm_n_cs ;
    o_nrm = nrm_n_cs . xyzx * CONST_111 . xyz . xxxy + CONST_111 . xyz . xxxz ;
    float tint_specular_on = 0.0 ;
    o_spc . xyz = SwizzleXXX ( pow ( abs ( spc_lum * CONST_110 . z ) , 1.0 / 2.2 ) ) ;
    o_dif . xyz = dif ;
    o_spc . w = SwizzleX ( spc_tex . a ) ;
    o_spc . w = clamp ( o_spc . w * CONST_110 . x + CONST_110 . y , 0 , 1 ) ;
    _O_SPC = o_spc ;
    _O_DIF = o_dif ;
    _O_NRM = o_nrm ;
    _O_VEL . xy = x_vel . xy ;
}
 
There are four outputs in the shader, specular and diffuse looks like the main parts to determine the color, normal may be used to calculate the lighting. Here, I paid more attention to the specular and diffuse, both of them come from texture sampling, and the texture ID are 9161 and 9160. By further searching the API logs, I found these two textures are specified by application, so I believe the texture content should be correct. Besides this, the only special thing is the format of the textures are sRGB, so I began to investigate the things related to Gamma Correction. In this shader, specular is calculated by Gamma Encoding, but diffuse not. Based on this, I guess the content of these two textures input should be in linear space, which means they do not need Gamma Decoding for sampling. To prove this, I double checked the sampler objects used by the shader, they are:
 
glBindSampler(0, 31);
glBindSampler(1, 31);
glBindSampler(2, 26);
 
All of these three samplers have set the GL_TEXTURE_SRGB_DECODE_EXT to GL_SKIP_DECODE_EXT explicitly. So far, I can confirm my guess.
 
If application uses these three samplers to draw the beard, the rendering result should be correct. But one more API is called unexpectedly after these sampler settings:
 
glBindSampler(0, 0);
 
It means default sampler will be used for texture unit 0 instead of the previously specified one, but the default texture sampler has never been set by glTexParameter explicitly for 9160 in the API logs, so the final value of GL_TEXTURE_SRGB_DECODE_EXT that takes effect is the default value, which is GL_DECODE_EXT instead of GL_SKIP_DECODE_EXT.
 
I guess this might be the root cause, and besides removing the unexpected API call, I believe we can also fix it in the shader by adding following code to the diffuse:
 
vec4 Gamma_Encode ( vec4 v_clr ) { return vec4 ( pow ( v_clr , vec4 ( 1.0 / 2.2 , 1.0 / 2.2 , 1.0 / 2.2 , 1.0 / 2.2 ) ) ) ; }
_O_DIF = Gamma_Encode(o_dif);
 
Can anybody help me solve this issue together?
 

Thanks,

Kai

Edited by guokai

Share this post


Link to post
Share on other sites

Been like 10 years since i edited shader's... mainly for PS one emulator...did you tried to open it in Notepad ++ i was usually worked there and just dump it in DL folder, most games have feature that when you copy/paste same file name with original one it loads that one ergo modding. Try that. 
Srry i cant be any more help to you but 10 years is loooong time xD.

Edited by XeNoN

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this