浏览代码

drm/radeon/kms: allow rendering while no colorbuffer is set on r300

Because hardware cannot disable all colorbuffers directly to do depth-only
rendering, a user should:
- disable reading from a colorbuffer in blending
- disable fastfill
- set the color channel mask to 0 to prevent writing to a colorbuffer

Signed-off-by: Dave Airlie <airlied@redhat.com>
Marek Olšák 15 年之前
父节点
当前提交
46c64d4bfa
共有 3 个文件被更改,包括 19 次插入1 次删除
  1. 4 0
      drivers/gpu/drm/radeon/r100.c
  2. 3 1
      drivers/gpu/drm/radeon/r100_track.h
  3. 12 0
      drivers/gpu/drm/radeon/r300.c

+ 4 - 0
drivers/gpu/drm/radeon/r100.c

@@ -2881,6 +2881,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
 
 	for (i = 0; i < track->num_cb; i++) {
 		if (track->cb[i].robj == NULL) {
+			if (!(track->fastfill || track->color_channel_mask ||
+			      track->blend_read_enable)) {
+				continue;
+			}
 			DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
 			return -EINVAL;
 		}

+ 3 - 1
drivers/gpu/drm/radeon/r100_track.h

@@ -67,13 +67,15 @@ struct r100_cs_track {
 	unsigned			immd_dwords;
 	unsigned			num_arrays;
 	unsigned			max_indx;
+	unsigned			color_channel_mask;
 	struct r100_cs_track_array	arrays[11];
 	struct r100_cs_track_cb 	cb[R300_MAX_CB];
 	struct r100_cs_track_cb 	zb;
 	struct r100_cs_track_texture	textures[R300_TRACK_MAX_TEXTURE];
 	bool				z_enabled;
 	bool                            separate_cube;
-
+	bool				fastfill;
+	bool				blend_read_enable;
 };
 
 int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);

+ 12 - 0
drivers/gpu/drm/radeon/r300.c

@@ -992,6 +992,18 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
 		}
 		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
 		break;
+	case 0x4e0c:
+		/* RB3D_COLOR_CHANNEL_MASK */
+		track->color_channel_mask = idx_value;
+		break;
+	case 0x4d1c:
+		/* ZB_BW_CNTL */
+		track->fastfill = !!(idx_value & (1 << 2));
+		break;
+	case 0x4e04:
+		/* RB3D_BLENDCNTL */
+		track->blend_read_enable = !!(idx_value & (1 << 2));
+		break;
 	case 0x4be8:
 		/* valid register only on RV530 */
 		if (p->rdev->family == CHIP_RV530)