v3dv: implement support for shader spilling

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga 2020-06-26 12:45:09 +02:00 committed by Marge Bot
parent 182e7c2d96
commit 91907560d5
3 changed files with 40 additions and 4 deletions

View file

@ -130,6 +130,11 @@ v3dv_destroy_pipeline(struct v3dv_pipeline *pipeline,
destroy_pipeline_stage(device, pipeline->fs, pAllocator);
destroy_pipeline_stage(device, pipeline->cs, pAllocator);
if (pipeline->spill.bo) {
assert(pipeline->spill.size_per_thread > 0);
v3dv_bo_free(device, pipeline->spill.bo);
}
if (pipeline->default_attribute_values) {
v3dv_bo_free(device, pipeline->default_attribute_values);
pipeline->default_attribute_values = NULL;
@ -1253,7 +1258,8 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
return entry->data;
}
struct v3dv_device *device = p_stage->pipeline->device;
struct v3dv_pipeline *pipeline = p_stage->pipeline;
struct v3dv_device *device = pipeline->device;
struct v3dv_shader_variant *variant =
vk_zalloc(&device->alloc, sizeof(*variant), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
@ -1264,7 +1270,7 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
}
struct v3dv_physical_device *physical_device =
&p_stage->pipeline->device->instance->physicalDevice;
&pipeline->device->instance->physicalDevice;
const struct v3d_compiler *compiler = physical_device->compiler;
uint32_t variant_id = p_atomic_inc_return(&p_stage->compiled_variant_count);
@ -1313,8 +1319,22 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
_mesa_hash_table_insert(ht, dup_key, variant);
}
/* FIXME: pending provide scratch space for register spilling */
assert(variant->prog_data.base->spill_size == 0);
if (variant->prog_data.base->spill_size > pipeline->spill.size_per_thread) {
/* The TIDX register we use for choosing the area to access
* for scratch space is: (core << 6) | (qpu << 2) | thread.
* Even at minimum threadcount in a particular shader, that
* means we still multiply by qpus by 4.
*/
const uint32_t total_spill_size =
4 * device->devinfo.qpu_count * variant->prog_data.base->spill_size;
if (pipeline->spill.bo) {
assert(pipeline->spill.size_per_thread > 0);
v3dv_bo_free(device, pipeline->spill.bo);
}
pipeline->spill.bo =
v3dv_bo_alloc(device, total_spill_size, "spill", true);
pipeline->spill.size_per_thread = variant->prog_data.base->spill_size;
}
*out_vk_result = VK_SUCCESS;
return variant;

View file

@ -1426,6 +1426,12 @@ struct v3dv_pipeline {
struct v3dv_pipeline_stage *fs;
struct v3dv_pipeline_stage *cs;
/* Spilling memory requirements */
struct {
struct v3dv_bo *bo;
uint32_t size_per_thread;
} spill;
struct v3dv_dynamic_state dynamic_state;
struct v3dv_pipeline_layout *layout;

View file

@ -349,6 +349,16 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
cl_aligned_reloc(&job->indirect, &uniforms, job->csd.shared_memory, 0);
break;
case QUNIFORM_SPILL_OFFSET:
assert(pipeline->spill.bo);
cl_aligned_reloc(&job->indirect, &uniforms, pipeline->spill.bo, 0);
break;
case QUNIFORM_SPILL_SIZE_PER_THREAD:
assert(pipeline->spill.size_per_thread > 0);
cl_aligned_u32(&uniforms, pipeline->spill.size_per_thread);
break;
default:
unreachable("unsupported quniform_contents uniform type\n");
}