Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make precision of time_step consistently float. #41853

Closed

Conversation

madmiraal
Copy link
Contributor

The precision of time_step is float. However, there are a number of locations where time_step is converted to a double. This PR makes the uses of time_step consistently a float.

Note: The driver for this change is to avoid lgtm warning about potential float overflows: If the reason for a conversion to a double were the need to increase the maximum size of the float, and the conversion to a double was done after a calculation, there is a risk of a float overflow that would go unnoticed. In other words, if there is actually a need for a double when using time_step in a calculation to prevent a float overflow (or a loss of precision, for example, when the numbers are larger) then the conversion to a double should be done earlier and made explicit.

The only place I have found where the conversion to a double may be required is when storing RasterizerCanvasRD::State.time:

double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
time = Math::fmod(time, time_roll_over);
canvas->set_time(time);

However, I think it's unlikely this needs to be a double, because, at most the size is limited to the size of rendering/limits/time/time_rollover_secs, which, by default, is 3,600, and even within RasterizerCanvasRD::State the RasterizerCanvasRD::State.Buffer.time uses a float too:
struct State {
//state buffer
struct Buffer {
float canvas_transform[16];
float screen_transform[16];
float canvas_normal_transform[16];
float canvas_modulate[4];
float screen_pixel_size[2];
float time;
float pad;
//uint32_t light_count;
//uint32_t pad[3];
};
LightUniform *light_uniforms;
RID lights_uniform_buffer;
RID canvas_state_buffer;
RID shadow_sampler;
uint32_t max_lights_per_render;
uint32_t max_lights_per_item;
double time;
} state;

@aaronfranke
Copy link
Member

I think we should do the opposite, make all time-related code consistently double: #38880 and #38878.

@madmiraal
Copy link
Contributor Author

Rebased following 179e6fa in #42178.

@madmiraal
Copy link
Contributor Author

Rebased following #43052.

@madmiraal
Copy link
Contributor Author

Rebased following #44094.

@madmiraal
Copy link
Contributor Author

Rebased following merge of #44593 and #44838.

@reduz
Copy link
Member

reduz commented Jan 11, 2021

I agree with @aaronfranke that we should probably use double everywhere there. There is no extra cost for doing that and it is common to accumulate time over some frames sometimes. I know that in practice it wont really make a difference, but given the choice it sounds like the better one.

@lawnjelly
Copy link
Member

I also agree on doubles, if in doubt.

The purist in me would use an encapsulated 64 (or 128) bit integer timer class and only convert to floating point for differences where required, because this offers completely stable behaviour over time. This is why operating systems use integers for timers instead of double. But I can see that might be hard to understand for most contributors, and simply using a double might be a good compromise.

In this particular case of course, the situation is even worse (irrespective of what precision time is fed in), because the time value is being passed to shaders which may be using less precision than 32 bits, hence the need for a wraparound. But I guess that can't be helped easily.

@madmiraal
Copy link
Contributor Author

Whether to use doubles or, as @lawnjelly suggests, ints to track time is beyond the scope of this PR. This PR was addressing the fact that the current precision is float and to make that consistent.

@aaronfranke
Copy link
Member

@madmiraal No, it's not beyond the scope of this PR. Merging #38880 would make this PR obsolete (as would merging an int change). Therefore the discussion of which to merge is absolutely 100% inside the scope of this PR.

@madmiraal
Copy link
Contributor Author

Rebased following merge of #45672.

@madmiraal
Copy link
Contributor Author

Rebased following merge of #45852.

@akien-mga
Copy link
Member

Superseded by #38880.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants