diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2012-11-20 07:19:37 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-11-20 16:47:09 -0500 |
commit | 7e8d9da32ea02f02a23f998cd2013408a4fe49bb (patch) | |
tree | 0ca21f5ffe4c5ec426962d89df8d8fe6d07ddc7f /drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | |
parent | 543831cfc976669b8da963b3e94933e21e051846 (diff) |
drm/vmwgfx: Add and make use of a header for surface size calculation.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Dmitry Torokhov <dtor@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_surface.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 113 |
1 files changed, 19 insertions, 94 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index c4a7bcdabd48..582814339748 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "vmwgfx_drv.h" | 28 | #include "vmwgfx_drv.h" |
29 | #include "vmwgfx_resource_priv.h" | 29 | #include "vmwgfx_resource_priv.h" |
30 | #include <ttm/ttm_placement.h> | 30 | #include <ttm/ttm_placement.h> |
31 | #include "svga3d_surfacedefs.h" | ||
31 | 32 | ||
32 | /** | 33 | /** |
33 | * struct vmw_user_surface - User-space visible surface resource | 34 | * struct vmw_user_surface - User-space visible surface resource |
@@ -93,85 +94,6 @@ static const struct vmw_res_func vmw_legacy_surface_func = { | |||
93 | }; | 94 | }; |
94 | 95 | ||
95 | /** | 96 | /** |
96 | * struct vmw_bpp - Bits per pixel info for surface storage size computation. | ||
97 | * | ||
98 | * @bpp: Bits per pixel. | ||
99 | * @s_bpp: Stride bits per pixel. See definition below. | ||
100 | * | ||
101 | */ | ||
102 | struct vmw_bpp { | ||
103 | uint8_t bpp; | ||
104 | uint8_t s_bpp; | ||
105 | }; | ||
106 | |||
107 | /* | ||
108 | * Size table for the supported SVGA3D surface formats. It consists of | ||
109 | * two values. The bpp value and the s_bpp value which is short for | ||
110 | * "stride bits per pixel" The values are given in such a way that the | ||
111 | * minimum stride for the image is calculated using | ||
112 | * | ||
113 | * min_stride = w*s_bpp | ||
114 | * | ||
115 | * and the total memory requirement for the image is | ||
116 | * | ||
117 | * h*min_stride*bpp/s_bpp | ||
118 | * | ||
119 | */ | ||
120 | static const struct vmw_bpp vmw_sf_bpp[] = { | ||
121 | [SVGA3D_FORMAT_INVALID] = {0, 0}, | ||
122 | [SVGA3D_X8R8G8B8] = {32, 32}, | ||
123 | [SVGA3D_A8R8G8B8] = {32, 32}, | ||
124 | [SVGA3D_R5G6B5] = {16, 16}, | ||
125 | [SVGA3D_X1R5G5B5] = {16, 16}, | ||
126 | [SVGA3D_A1R5G5B5] = {16, 16}, | ||
127 | [SVGA3D_A4R4G4B4] = {16, 16}, | ||
128 | [SVGA3D_Z_D32] = {32, 32}, | ||
129 | [SVGA3D_Z_D16] = {16, 16}, | ||
130 | [SVGA3D_Z_D24S8] = {32, 32}, | ||
131 | [SVGA3D_Z_D15S1] = {16, 16}, | ||
132 | [SVGA3D_LUMINANCE8] = {8, 8}, | ||
133 | [SVGA3D_LUMINANCE4_ALPHA4] = {8, 8}, | ||
134 | [SVGA3D_LUMINANCE16] = {16, 16}, | ||
135 | [SVGA3D_LUMINANCE8_ALPHA8] = {16, 16}, | ||
136 | [SVGA3D_DXT1] = {4, 16}, | ||
137 | [SVGA3D_DXT2] = {8, 32}, | ||
138 | [SVGA3D_DXT3] = {8, 32}, | ||
139 | [SVGA3D_DXT4] = {8, 32}, | ||
140 | [SVGA3D_DXT5] = {8, 32}, | ||
141 | [SVGA3D_BUMPU8V8] = {16, 16}, | ||
142 | [SVGA3D_BUMPL6V5U5] = {16, 16}, | ||
143 | [SVGA3D_BUMPX8L8V8U8] = {32, 32}, | ||
144 | [SVGA3D_ARGB_S10E5] = {16, 16}, | ||
145 | [SVGA3D_ARGB_S23E8] = {32, 32}, | ||
146 | [SVGA3D_A2R10G10B10] = {32, 32}, | ||
147 | [SVGA3D_V8U8] = {16, 16}, | ||
148 | [SVGA3D_Q8W8V8U8] = {32, 32}, | ||
149 | [SVGA3D_CxV8U8] = {16, 16}, | ||
150 | [SVGA3D_X8L8V8U8] = {32, 32}, | ||
151 | [SVGA3D_A2W10V10U10] = {32, 32}, | ||
152 | [SVGA3D_ALPHA8] = {8, 8}, | ||
153 | [SVGA3D_R_S10E5] = {16, 16}, | ||
154 | [SVGA3D_R_S23E8] = {32, 32}, | ||
155 | [SVGA3D_RG_S10E5] = {16, 16}, | ||
156 | [SVGA3D_RG_S23E8] = {32, 32}, | ||
157 | [SVGA3D_BUFFER] = {8, 8}, | ||
158 | [SVGA3D_Z_D24X8] = {32, 32}, | ||
159 | [SVGA3D_V16U16] = {32, 32}, | ||
160 | [SVGA3D_G16R16] = {32, 32}, | ||
161 | [SVGA3D_A16B16G16R16] = {64, 64}, | ||
162 | [SVGA3D_UYVY] = {12, 12}, | ||
163 | [SVGA3D_YUY2] = {12, 12}, | ||
164 | [SVGA3D_NV12] = {12, 8}, | ||
165 | [SVGA3D_AYUV] = {32, 32}, | ||
166 | [SVGA3D_BC4_UNORM] = {4, 16}, | ||
167 | [SVGA3D_BC5_UNORM] = {8, 32}, | ||
168 | [SVGA3D_Z_DF16] = {16, 16}, | ||
169 | [SVGA3D_Z_DF24] = {24, 24}, | ||
170 | [SVGA3D_Z_D24S8_INT] = {32, 32} | ||
171 | }; | ||
172 | |||
173 | |||
174 | /** | ||
175 | * struct vmw_surface_dma - SVGA3D DMA command | 97 | * struct vmw_surface_dma - SVGA3D DMA command |
176 | */ | 98 | */ |
177 | struct vmw_surface_dma { | 99 | struct vmw_surface_dma { |
@@ -307,9 +229,9 @@ static void vmw_surface_dma_encode(struct vmw_surface *srf, | |||
307 | bool to_surface) | 229 | bool to_surface) |
308 | { | 230 | { |
309 | uint32_t i; | 231 | uint32_t i; |
310 | uint32_t bpp = vmw_sf_bpp[srf->format].bpp; | ||
311 | uint32_t stride_bpp = vmw_sf_bpp[srf->format].s_bpp; | ||
312 | struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space; | 232 | struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space; |
233 | const struct svga3d_surface_desc *desc = | ||
234 | svga3dsurface_get_desc(srf->format); | ||
313 | 235 | ||
314 | for (i = 0; i < srf->num_sizes; ++i) { | 236 | for (i = 0; i < srf->num_sizes; ++i) { |
315 | SVGA3dCmdHeader *header = &cmd->header; | 237 | SVGA3dCmdHeader *header = &cmd->header; |
@@ -324,7 +246,8 @@ static void vmw_surface_dma_encode(struct vmw_surface *srf, | |||
324 | 246 | ||
325 | body->guest.ptr = *ptr; | 247 | body->guest.ptr = *ptr; |
326 | body->guest.ptr.offset += cur_offset->bo_offset; | 248 | body->guest.ptr.offset += cur_offset->bo_offset; |
327 | body->guest.pitch = (cur_size->width * stride_bpp + 7) >> 3; | 249 | body->guest.pitch = svga3dsurface_calculate_pitch(desc, |
250 | cur_size); | ||
328 | body->host.sid = srf->res.id; | 251 | body->host.sid = srf->res.id; |
329 | body->host.face = cur_offset->face; | 252 | body->host.face = cur_offset->face; |
330 | body->host.mipmap = cur_offset->mip; | 253 | body->host.mipmap = cur_offset->mip; |
@@ -341,8 +264,9 @@ static void vmw_surface_dma_encode(struct vmw_surface *srf, | |||
341 | cb->d = cur_size->depth; | 264 | cb->d = cur_size->depth; |
342 | 265 | ||
343 | suffix->suffixSize = sizeof(*suffix); | 266 | suffix->suffixSize = sizeof(*suffix); |
344 | suffix->maximumOffset = body->guest.pitch*cur_size->height* | 267 | suffix->maximumOffset = |
345 | cur_size->depth*bpp / stride_bpp; | 268 | svga3dsurface_get_image_buffer_size(desc, cur_size, |
269 | body->guest.pitch); | ||
346 | suffix->flags.discard = 0; | 270 | suffix->flags.discard = 0; |
347 | suffix->flags.unsynchronized = 0; | 271 | suffix->flags.unsynchronized = 0; |
348 | suffix->flags.reserved = 0; | 272 | suffix->flags.reserved = 0; |
@@ -743,11 +667,10 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | |||
743 | uint32_t cur_bo_offset; | 667 | uint32_t cur_bo_offset; |
744 | struct drm_vmw_size *cur_size; | 668 | struct drm_vmw_size *cur_size; |
745 | struct vmw_surface_offset *cur_offset; | 669 | struct vmw_surface_offset *cur_offset; |
746 | uint32_t stride_bpp; | ||
747 | uint32_t bpp; | ||
748 | uint32_t num_sizes; | 670 | uint32_t num_sizes; |
749 | uint32_t size; | 671 | uint32_t size; |
750 | struct vmw_master *vmaster = vmw_master(file_priv->master); | 672 | struct vmw_master *vmaster = vmw_master(file_priv->master); |
673 | const struct svga3d_surface_desc *desc; | ||
751 | 674 | ||
752 | if (unlikely(vmw_user_surface_size == 0)) | 675 | if (unlikely(vmw_user_surface_size == 0)) |
753 | vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) + | 676 | vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) + |
@@ -766,6 +689,12 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | |||
766 | ttm_round_pot(num_sizes * sizeof(struct vmw_surface_offset)); | 689 | ttm_round_pot(num_sizes * sizeof(struct vmw_surface_offset)); |
767 | 690 | ||
768 | 691 | ||
692 | desc = svga3dsurface_get_desc(req->format); | ||
693 | if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) { | ||
694 | DRM_ERROR("Invalid surface format for surface creation.\n"); | ||
695 | return -EINVAL; | ||
696 | } | ||
697 | |||
769 | ret = ttm_read_lock(&vmaster->lock, true); | 698 | ret = ttm_read_lock(&vmaster->lock, true); |
770 | if (unlikely(ret != 0)) | 699 | if (unlikely(ret != 0)) |
771 | return ret; | 700 | return ret; |
@@ -826,25 +755,21 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | |||
826 | cur_offset = srf->offsets; | 755 | cur_offset = srf->offsets; |
827 | cur_size = srf->sizes; | 756 | cur_size = srf->sizes; |
828 | 757 | ||
829 | bpp = vmw_sf_bpp[srf->format].bpp; | ||
830 | stride_bpp = vmw_sf_bpp[srf->format].s_bpp; | ||
831 | |||
832 | for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { | 758 | for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { |
833 | for (j = 0; j < srf->mip_levels[i]; ++j) { | 759 | for (j = 0; j < srf->mip_levels[i]; ++j) { |
834 | uint32_t stride = | 760 | uint32_t stride = svga3dsurface_calculate_pitch |
835 | (cur_size->width * stride_bpp + 7) >> 3; | 761 | (desc, cur_size); |
836 | 762 | ||
837 | cur_offset->face = i; | 763 | cur_offset->face = i; |
838 | cur_offset->mip = j; | 764 | cur_offset->mip = j; |
839 | cur_offset->bo_offset = cur_bo_offset; | 765 | cur_offset->bo_offset = cur_bo_offset; |
840 | cur_bo_offset += stride * cur_size->height * | 766 | cur_bo_offset += svga3dsurface_get_image_buffer_size |
841 | cur_size->depth * bpp / stride_bpp; | 767 | (desc, cur_size, stride); |
842 | ++cur_offset; | 768 | ++cur_offset; |
843 | ++cur_size; | 769 | ++cur_size; |
844 | } | 770 | } |
845 | } | 771 | } |
846 | res->backup_size = cur_bo_offset; | 772 | res->backup_size = cur_bo_offset; |
847 | |||
848 | if (srf->scanout && | 773 | if (srf->scanout && |
849 | srf->num_sizes == 1 && | 774 | srf->num_sizes == 1 && |
850 | srf->sizes[0].width == 64 && | 775 | srf->sizes[0].width == 64 && |