예제 #1
0
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;
}
예제 #2
0
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;
}