Fix #134586: EEVEE: Crash when rendering large resolutions
EEVEE crashes when it is not able to allocate buffers. Previously we had a message showing to the user that it tries to allocate a texture larger than supported by the GPU. But was not implemented for EEVEE-next. This fix will add back this error message.  Pull Request: https://projects.blender.org/blender/blender/pulls/134725
This commit is contained in:
@@ -331,6 +331,21 @@ void Film::init(const int2 &extent, const rcti *output_rect)
|
||||
data_.overscan = overscan_pixels_get(inst_.camera.overscan(), data_.render_extent);
|
||||
data_.render_extent += data_.overscan * 2;
|
||||
|
||||
is_valid_render_extent_ = data_.render_extent.x <= GPU_max_texture_size() &&
|
||||
data_.render_extent.y <= GPU_max_texture_size();
|
||||
if (!is_valid_render_extent_) {
|
||||
inst_.info_append_i18n(
|
||||
"Required render size ({}px) is larger than reported texture size limit ({}px).",
|
||||
max_ii(data_.render_extent.x, data_.render_extent.y),
|
||||
GPU_max_texture_size());
|
||||
|
||||
data_.extent = int2(4, 4);
|
||||
data_.render_extent = int2(4, 4);
|
||||
data_.extent_inv = 1.0f / float2(data_.extent);
|
||||
data_.offset = int2(0, 0);
|
||||
data_.overscan = 0;
|
||||
}
|
||||
|
||||
data_.filter_radius = clamp_f(scene.r.gauss, 0.0f, 100.0f);
|
||||
if (sampling.sample_count() == 1) {
|
||||
/* Disable filtering if sample count is 1. */
|
||||
|
||||
@@ -91,6 +91,7 @@ class Film {
|
||||
eViewLayerEEVEEPassType viewport_compositor_enabled_passes_ = eViewLayerEEVEEPassType(0);
|
||||
PassCategory enabled_categories_ = PassCategory(0);
|
||||
bool use_reprojection_ = false;
|
||||
bool is_valid_render_extent_ = true;
|
||||
|
||||
public:
|
||||
Film(Instance &inst, FilmData &data) : inst_(inst), data_(data){};
|
||||
@@ -130,6 +131,10 @@ class Film {
|
||||
{
|
||||
return data_.render_extent;
|
||||
}
|
||||
inline bool is_valid_render_extent() const
|
||||
{
|
||||
return is_valid_render_extent_;
|
||||
}
|
||||
|
||||
/** Size and offset of the film (taking into account render region). */
|
||||
int2 film_extent_get() const
|
||||
|
||||
@@ -75,6 +75,7 @@ void Instance::init(const int2 &output_res,
|
||||
|
||||
shaders_are_ready_ = shaders.is_ready(is_image_render());
|
||||
if (!shaders_are_ready_) {
|
||||
skip_render_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,7 +126,8 @@ void Instance::init(const int2 &output_res,
|
||||
/* Pre-compile specialization constants in parallel (if supported). */
|
||||
shaders.precompile_specializations(
|
||||
render_buffers.data.shadow_id, shadows.get_data().ray_count, shadows.get_data().step_count);
|
||||
shaders_are_ready_ = shaders.is_ready(is_image_render());
|
||||
shaders_are_ready_ = shaders.is_ready(is_image_render()) || !film.is_valid_render_extent();
|
||||
skip_render_ = !shaders_are_ready_ || !film.is_valid_render_extent();
|
||||
}
|
||||
|
||||
void Instance::init_light_bake(Depsgraph *depsgraph, draw::Manager *manager)
|
||||
@@ -200,7 +202,7 @@ void Instance::view_update()
|
||||
|
||||
void Instance::begin_sync()
|
||||
{
|
||||
if (!shaders_are_ready_) {
|
||||
if (skip_render_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -244,7 +246,7 @@ void Instance::begin_sync()
|
||||
|
||||
void Instance::object_sync(ObjectRef &ob_ref)
|
||||
{
|
||||
if (!shaders_are_ready_) {
|
||||
if (skip_render_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -320,7 +322,7 @@ void Instance::object_sync_render(void *instance_,
|
||||
|
||||
void Instance::end_sync()
|
||||
{
|
||||
if (!shaders_are_ready_) {
|
||||
if (skip_render_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -507,6 +509,13 @@ void Instance::render_read_result(RenderLayer *render_layer, const char *view_na
|
||||
|
||||
void Instance::render_frame(RenderEngine *engine, RenderLayer *render_layer, const char *view_name)
|
||||
{
|
||||
if (skip_render_) {
|
||||
if (!info_.empty()) {
|
||||
RE_engine_set_error_message(engine, info_.c_str());
|
||||
info_ = "";
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* TODO: Break on RE_engine_test_break(engine) */
|
||||
while (!sampling.finished()) {
|
||||
this->render_sample();
|
||||
@@ -558,11 +567,13 @@ void Instance::render_frame(RenderEngine *engine, RenderLayer *render_layer, con
|
||||
|
||||
void Instance::draw_viewport()
|
||||
{
|
||||
if (!shaders_are_ready_) {
|
||||
if (skip_render_) {
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
GPU_framebuffer_clear_color_depth(dfbl->default_fb, float4(0.0f), 1.0f);
|
||||
info_append_i18n("Compiling EEVEE engine shaders");
|
||||
DRW_viewport_request_redraw();
|
||||
if (!shaders_are_ready_) {
|
||||
info_append_i18n("Compiling EEVEE engine shaders");
|
||||
DRW_viewport_request_redraw();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -599,6 +610,9 @@ void Instance::draw_viewport()
|
||||
|
||||
void Instance::draw_viewport_image_render()
|
||||
{
|
||||
if (skip_render_) {
|
||||
return;
|
||||
}
|
||||
while (!sampling.finished_viewport()) {
|
||||
this->render_sample();
|
||||
}
|
||||
@@ -611,6 +625,9 @@ void Instance::draw_viewport_image_render()
|
||||
|
||||
void Instance::store_metadata(RenderResult *render_result)
|
||||
{
|
||||
if (skip_render_) {
|
||||
return;
|
||||
}
|
||||
cryptomatte.store_metadata(render_result);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ class Instance {
|
||||
|
||||
uint64_t depsgraph_last_update_ = 0;
|
||||
bool overlays_enabled_ = false;
|
||||
|
||||
bool shaders_are_ready_ = true;
|
||||
bool skip_render_ = false;
|
||||
|
||||
/** Info string displayed at the top of the render / viewport, or the console when baking. */
|
||||
std::string info_ = "";
|
||||
|
||||
Reference in New Issue
Block a user