GPUCodegen: Keep copy of attribute name in the GPUCodegenCreateInfo

This is to avoid use after free when the `GPUPass` gets compiled after the
original `GPUMaterial` used to create it was freed.

The issue was introduced by rBfa3bd17ae873
This commit is contained in:
Clément Foucault
2022-04-27 15:59:18 +02:00
parent c01e33d6ca
commit 478eb3a0e6

View File

@@ -47,8 +47,16 @@
using namespace blender::gpu::shader;
/**
* IMPORTANT: Never add external reference. The GPUMaterial used to create the GPUPass (and its
* GPUCodegenCreateInfo) can be free before actually compiling. This happens if there is an update
* before deferred compilation happens and the GPUPass gets picked up by another GPUMaterial
* (because of GPUPass reuse).
*/
struct GPUCodegenCreateInfo : ShaderCreateInfo {
struct NameBuffer {
/** Duplicate attribute names to avoid reference the GPUNodeGraph directly. */
char attr_names[16][GPU_MAX_SAFE_ATTR_NAME + 1];
char var_names[16][8];
};
@@ -290,9 +298,14 @@ void GPUCodegen::generate_attribs()
int slot = 15;
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph.attributes) {
if (slot == -1) {
BLI_assert_msg(0, "Too many attributes");
break;
}
STRNCPY(info.name_buffer->attr_names[slot], attr->name);
SNPRINTF(info.name_buffer->var_names[slot], "v%d", attr->id);
blender::StringRefNull attr_name = attr->input_name;
blender::StringRefNull attr_name = info.name_buffer->attr_names[slot];
blender::StringRefNull var_name = info.name_buffer->var_names[slot];
eGPUType input_type, iface_type;