The depth test is not in action if we use image_store to write to framebuffer. Early z testing would throw away pixel so that imagestore is not called.
We used to analyze the program to determine the size of memory uniform buffer. However, this method will require tons of works when dealing with ldr with temporary register for base field. (this can happen)
From my observation, uniform parameters of memory uniform buffer are not stripped away. Utilizing this, I tried to determine uniform buffer size from uniform paramters. I also observed half register half memory uniform buffer. (this seems to happen in large default uniform buffer) In this case the size_in_f32 is less than the total size of uniform buffer, and the ldr instruction will be used to access fields not available in register. Also, the base of ldr instruction should start from the end of "register block " of uniform buffer. I updated recompiler to consider this information.
First bug: When the component size is not 4, the vertext shader will create out variable with the actual size (that is not 4), but fragment shader always uses 4 for input variable size.
Second bug: Wen the copmponent size is 1, fragment shader will load the variable as vector with size 4. (since it's not finalized) However, util::store uses the spirv function to get components to write (it doesn't utilize dest_mask for determining size)
With these bugs fixed, we can safely remove the assert(number_of_comp_vec != 1) that we had for a long time.
We were loading and storing using normalized float before, but this can be quite troublesome when we start to seriously implement int instructions.
1. The rounding error can result in the change in value. The error caused by rounding error assuming 0.5 ulp is +-(1/2)*2^(1-23) * 2^16 * x = +-x*1.1920929e-7*2^16 = +-0.0078125*x where x is the value we want to store. It can be serious enough to change the value after one store & load.
2. We will need a paramter that decides the final type of load that can be normalized float, float, and integer. But, we're already specifying type by op.type! Load function is given another responsibility: type conversion. This becomes more confusing in store function. The function doesn't know whether source is normalized or not, so we need another parameter. And, this parameter should mean nothing in immediate register bank, etc. aaaaa
For this reason, I'm moving to integer loading and storing using ivec & uvec. This way load and store function has less side effect. The ouput and input type of oprand is just decided by the op.type and dest_type. Instructions using load and store is in charge of type conversion now and it wouldn't be insane because they have more context.
* io: create parent directories of saves if they don't exist
* sceapputil: fix creating slotparam files
* scecommondialog: fix progress bar and add checks
We need parsed parameters in many applications such as analyzer/fuzzer/debugger. I separated parsing part from recompiler. In the way, I fixed some bugs that are not apparent because of parsing code mixed with spirv generation code.