static void build_shader_save_restore_cmds(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { unsigned int *cmd = tmp_ctx.cmd; unsigned int *save, *restore, *fixup; unsigned int *startSizeVtx, *startSizePix, *startSizeShared; unsigned int *partition1; unsigned int *shaderBases, *partition2; /* compute vertex, pixel and shared instruction shadow GPU addresses */ tmp_ctx.shader_vertex = drawctxt->gpustate.gpuaddr + SHADER_OFFSET; tmp_ctx.shader_pixel = tmp_ctx.shader_vertex + _shader_shadow_size(adreno_dev); tmp_ctx.shader_shared = tmp_ctx.shader_pixel + _shader_shadow_size(adreno_dev); /* restore shader partitioning and instructions */ restore = cmd; /* start address */ /* Invalidate Vertex & Pixel instruction code address and sizes */ *cmd++ = cp_type3_packet(CP_INVALIDATE_STATE, 1); *cmd++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */ /* Restore previous shader vertex & pixel instruction bases. */ *cmd++ = cp_type3_packet(CP_SET_SHADER_BASES, 1); shaderBases = cmd++; /* TBD #5: shader bases (from fixup) */ /* write the shader partition information to a scratch register */ *cmd++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1); partition1 = cmd++; /* TBD #4a: partition info (from save) */ /* load vertex shader instructions from the shadow. */ *cmd++ = cp_type3_packet(CP_IM_LOAD, 2); *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */ startSizeVtx = cmd++; /* TBD #1: start/size (from save) */ /* load pixel shader instructions from the shadow. */ *cmd++ = cp_type3_packet(CP_IM_LOAD, 2); *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */ startSizePix = cmd++; /* TBD #2: start/size (from save) */ /* load shared shader instructions from the shadow. */ *cmd++ = cp_type3_packet(CP_IM_LOAD, 2); *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */ startSizeShared = cmd++; /* TBD #3: start/size (from save) */ /* create indirect buffer command for above command sequence */ create_ib1(drawctxt, drawctxt->shader_restore, restore, cmd); /* * fixup SET_SHADER_BASES data * * since self-modifying PM4 code is being used here, a seperate * command buffer is used for this fixup operation, to ensure the * commands are not read by the PM4 engine before the data fields * have been written. */ fixup = cmd; /* start address */ /* write the shader partition information to a scratch register */ *cmd++ = cp_type0_packet(REG_SCRATCH_REG2, 1); partition2 = cmd++; /* TBD #4b: partition info (from save) */ /* mask off unused bits, then OR with shader instruction memory size */ *cmd++ = cp_type3_packet(CP_REG_RMW, 3); *cmd++ = REG_SCRATCH_REG2; /* AND off invalid bits. */ *cmd++ = 0x0FFF0FFF; /* OR in instruction memory size. */ *cmd++ = adreno_encode_istore_size(adreno_dev); /* write the computed value to the SET_SHADER_BASES data field */ *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2); *cmd++ = REG_SCRATCH_REG2; /* TBD #5: shader bases (to restore) */ *cmd++ = virt2gpu(shaderBases, &drawctxt->gpustate); /* create indirect buffer command for above command sequence */ create_ib1(drawctxt, drawctxt->shader_fixup, fixup, cmd); /* save shader partitioning and instructions */ save = cmd; /* start address */ *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1); *cmd++ = 0; /* fetch the SQ_INST_STORE_MANAGMENT register value, * store the value in the data fields of the SET_CONSTANT commands * above. */ *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2); *cmd++ = REG_SQ_INST_STORE_MANAGMENT; /* TBD #4a: partition info (to restore) */ *cmd++ = virt2gpu(partition1, &drawctxt->gpustate); *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2); *cmd++ = REG_SQ_INST_STORE_MANAGMENT; /* TBD #4b: partition info (to fixup) */ *cmd++ = virt2gpu(partition2, &drawctxt->gpustate); /* store the vertex shader instructions */ *cmd++ = cp_type3_packet(CP_IM_STORE, 2); *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */ /* TBD #1: start/size (to restore) */ *cmd++ = virt2gpu(startSizeVtx, &drawctxt->gpustate); /* store the pixel shader instructions */ *cmd++ = cp_type3_packet(CP_IM_STORE, 2); *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */ /* TBD #2: start/size (to restore) */ *cmd++ = virt2gpu(startSizePix, &drawctxt->gpustate); /* store the shared shader instructions if vertex base is nonzero */ *cmd++ = cp_type3_packet(CP_IM_STORE, 2); *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */ /* TBD #3: start/size (to restore) */ *cmd++ = virt2gpu(startSizeShared, &drawctxt->gpustate); *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1); *cmd++ = 0; /* create indirect buffer command for above command sequence */ create_ib1(drawctxt, drawctxt->shader_save, save, cmd); tmp_ctx.cmd = cmd; }
static inline int _context_size(struct adreno_device *adreno_dev) { return SHADER_OFFSET + 3*_shader_shadow_size(adreno_dev); }
static void build_shader_save_restore_cmds(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { unsigned int *cmd = tmp_ctx.cmd; unsigned int *save, *restore, *fixup; unsigned int *startSizeVtx, *startSizePix, *startSizeShared; unsigned int *partition1; unsigned int *shaderBases, *partition2; tmp_ctx.shader_vertex = drawctxt->gpustate.gpuaddr + SHADER_OFFSET; tmp_ctx.shader_pixel = tmp_ctx.shader_vertex + _shader_shadow_size(adreno_dev); tmp_ctx.shader_shared = tmp_ctx.shader_pixel + _shader_shadow_size(adreno_dev); restore = cmd; *cmd++ = cp_type3_packet(CP_INVALIDATE_STATE, 1); *cmd++ = 0x00000300; *cmd++ = cp_type3_packet(CP_SET_SHADER_BASES, 1); shaderBases = cmd++; *cmd++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1); partition1 = cmd++; *cmd++ = cp_type3_packet(CP_IM_LOAD, 2); *cmd++ = tmp_ctx.shader_vertex + 0x0; startSizeVtx = cmd++; *cmd++ = cp_type3_packet(CP_IM_LOAD, 2); *cmd++ = tmp_ctx.shader_pixel + 0x1; startSizePix = cmd++; *cmd++ = cp_type3_packet(CP_IM_LOAD, 2); *cmd++ = tmp_ctx.shader_shared + 0x2; startSizeShared = cmd++; create_ib1(drawctxt, drawctxt->shader_restore, restore, cmd); /* * fixup SET_SHADER_BASES data * * since self-modifying PM4 code is being used here, a seperate * command buffer is used for this fixup operation, to ensure the * commands are not read by the PM4 engine before the data fields * have been written. */ fixup = cmd; *cmd++ = cp_type0_packet(REG_SCRATCH_REG2, 1); partition2 = cmd++; *cmd++ = cp_type3_packet(CP_REG_RMW, 3); *cmd++ = REG_SCRATCH_REG2; *cmd++ = 0x0FFF0FFF; *cmd++ = adreno_encode_istore_size(adreno_dev); *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2); *cmd++ = REG_SCRATCH_REG2; *cmd++ = virt2gpu(shaderBases, &drawctxt->gpustate); create_ib1(drawctxt, drawctxt->shader_fixup, fixup, cmd); save = cmd; *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1); *cmd++ = 0; *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2); *cmd++ = REG_SQ_INST_STORE_MANAGMENT; *cmd++ = virt2gpu(partition1, &drawctxt->gpustate); *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2); *cmd++ = REG_SQ_INST_STORE_MANAGMENT; *cmd++ = virt2gpu(partition2, &drawctxt->gpustate); *cmd++ = cp_type3_packet(CP_IM_STORE, 2); *cmd++ = tmp_ctx.shader_vertex + 0x0; *cmd++ = virt2gpu(startSizeVtx, &drawctxt->gpustate); *cmd++ = cp_type3_packet(CP_IM_STORE, 2); *cmd++ = tmp_ctx.shader_pixel + 0x1; *cmd++ = virt2gpu(startSizePix, &drawctxt->gpustate); *cmd++ = cp_type3_packet(CP_IM_STORE, 2); *cmd++ = tmp_ctx.shader_shared + 0x2; *cmd++ = virt2gpu(startSizeShared, &drawctxt->gpustate); *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1); *cmd++ = 0; create_ib1(drawctxt, drawctxt->shader_save, save, cmd); tmp_ctx.cmd = cmd; }