Avoid constant register reloads while emitting IBs by using a local write pointer and only updating the size at the end of each helper.
Signed-off-by: Tvrtko Ursulin <[email protected]> Cc: Timur Kristóf <[email protected]> Cc: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 106 +++++++++++++------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index ab4123ddbb94..86319810e16e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -1477,8 +1477,8 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; + u32 tmp, *ptr; int r, i; - u32 tmp; unsigned total_size, vgpr_offset, sgpr_offset; u64 gpu_addr; @@ -1524,92 +1524,92 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) ib = &job->ibs[0]; /* load the compute shaders */ - for (i = 0; i < ARRAY_SIZE(vgpr_init_compute_shader); i++) - ib->ptr[i + (vgpr_offset / 4)] = vgpr_init_compute_shader[i]; + memcpy(&ib->ptr[vgpr_offset / sizeof(u32)], vgpr_init_compute_shader, + sizeof(vgpr_init_compute_shader)); + memcpy(&ib->ptr[sgpr_offset / sizeof(u32)], sgpr_init_compute_shader, + sizeof(sgpr_init_compute_shader)); - for (i = 0; i < ARRAY_SIZE(sgpr_init_compute_shader); i++) - ib->ptr[i + (sgpr_offset / 4)] = sgpr_init_compute_shader[i]; - - /* init the ib length to 0 */ - ib->length_dw = 0; + ptr = ib->ptr; /* VGPR */ /* write the register state for the compute dispatch */ for (i = 0; i < ARRAY_SIZE(vgpr_init_regs); i += 2) { - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1); - ib->ptr[ib->length_dw++] = vgpr_init_regs[i] - PACKET3_SET_SH_REG_START; - ib->ptr[ib->length_dw++] = vgpr_init_regs[i + 1]; + *ptr++ = PACKET3(PACKET3_SET_SH_REG, 1); + *ptr++ = vgpr_init_regs[i] - PACKET3_SET_SH_REG_START; + *ptr++ = vgpr_init_regs[i + 1]; } /* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */ gpu_addr = (ib->gpu_addr + (u64)vgpr_offset) >> 8; - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2); - ib->ptr[ib->length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; - ib->ptr[ib->length_dw++] = lower_32_bits(gpu_addr); - ib->ptr[ib->length_dw++] = upper_32_bits(gpu_addr); + *ptr++ = PACKET3(PACKET3_SET_SH_REG, 2); + *ptr++ = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; + *ptr++ = lower_32_bits(gpu_addr); + *ptr++ = upper_32_bits(gpu_addr); /* write dispatch packet */ - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3); - ib->ptr[ib->length_dw++] = 8; /* x */ - ib->ptr[ib->length_dw++] = 1; /* y */ - ib->ptr[ib->length_dw++] = 1; /* z */ - ib->ptr[ib->length_dw++] = - REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1); + *ptr++ = PACKET3(PACKET3_DISPATCH_DIRECT, 3); + *ptr++ = 8; /* x */ + *ptr++ = 1; /* y */ + *ptr++ = 1; /* z */ + *ptr++ = REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, + 1); /* write CS partial flush packet */ - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0); - ib->ptr[ib->length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4); + *ptr++ = PACKET3(PACKET3_EVENT_WRITE, 0); + *ptr++ = EVENT_TYPE(7) | EVENT_INDEX(4); /* SGPR1 */ /* write the register state for the compute dispatch */ for (i = 0; i < ARRAY_SIZE(sgpr1_init_regs); i += 2) { - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1); - ib->ptr[ib->length_dw++] = sgpr1_init_regs[i] - PACKET3_SET_SH_REG_START; - ib->ptr[ib->length_dw++] = sgpr1_init_regs[i + 1]; + *ptr++ = PACKET3(PACKET3_SET_SH_REG, 1); + *ptr++ = sgpr1_init_regs[i] - PACKET3_SET_SH_REG_START; + *ptr++ = sgpr1_init_regs[i + 1]; } /* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */ gpu_addr = (ib->gpu_addr + (u64)sgpr_offset) >> 8; - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2); - ib->ptr[ib->length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; - ib->ptr[ib->length_dw++] = lower_32_bits(gpu_addr); - ib->ptr[ib->length_dw++] = upper_32_bits(gpu_addr); + *ptr++ = PACKET3(PACKET3_SET_SH_REG, 2); + *ptr++ = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; + *ptr++ = lower_32_bits(gpu_addr); + *ptr++ = upper_32_bits(gpu_addr); /* write dispatch packet */ - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3); - ib->ptr[ib->length_dw++] = 8; /* x */ - ib->ptr[ib->length_dw++] = 1; /* y */ - ib->ptr[ib->length_dw++] = 1; /* z */ - ib->ptr[ib->length_dw++] = - REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1); + *ptr++ = PACKET3(PACKET3_DISPATCH_DIRECT, 3); + *ptr++ = 8; /* x */ + *ptr++ = 1; /* y */ + *ptr++ = 1; /* z */ + *ptr++ = REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, + 1); /* write CS partial flush packet */ - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0); - ib->ptr[ib->length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4); + *ptr++ = PACKET3(PACKET3_EVENT_WRITE, 0); + *ptr++ = EVENT_TYPE(7) | EVENT_INDEX(4); /* SGPR2 */ /* write the register state for the compute dispatch */ for (i = 0; i < ARRAY_SIZE(sgpr2_init_regs); i += 2) { - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1); - ib->ptr[ib->length_dw++] = sgpr2_init_regs[i] - PACKET3_SET_SH_REG_START; - ib->ptr[ib->length_dw++] = sgpr2_init_regs[i + 1]; + *ptr++ = PACKET3(PACKET3_SET_SH_REG, 1); + *ptr++ = sgpr2_init_regs[i] - PACKET3_SET_SH_REG_START; + *ptr++ = sgpr2_init_regs[i + 1]; } /* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */ gpu_addr = (ib->gpu_addr + (u64)sgpr_offset) >> 8; - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2); - ib->ptr[ib->length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; - ib->ptr[ib->length_dw++] = lower_32_bits(gpu_addr); - ib->ptr[ib->length_dw++] = upper_32_bits(gpu_addr); + *ptr++ = PACKET3(PACKET3_SET_SH_REG, 2); + *ptr++ = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; + *ptr++ = lower_32_bits(gpu_addr); + *ptr++ = upper_32_bits(gpu_addr); /* write dispatch packet */ - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3); - ib->ptr[ib->length_dw++] = 8; /* x */ - ib->ptr[ib->length_dw++] = 1; /* y */ - ib->ptr[ib->length_dw++] = 1; /* z */ - ib->ptr[ib->length_dw++] = - REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1); + *ptr++ = PACKET3(PACKET3_DISPATCH_DIRECT, 3); + *ptr++ = 8; /* x */ + *ptr++ = 1; /* y */ + *ptr++ = 1; /* z */ + *ptr++ = REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, + 1); /* write CS partial flush packet */ - ib->ptr[ib->length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0); - ib->ptr[ib->length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4); + *ptr++ = PACKET3(PACKET3_EVENT_WRITE, 0); + *ptr++ = EVENT_TYPE(7) | EVENT_INDEX(4); + + ib->length_dw = ptr - ib->ptr; /* schedule the ib on the ring */ r = amdgpu_job_submit_direct(job, ring, &f); -- 2.55.0
