Courtney Goeltzenleuchter | 5ab50d7 | 2014-09-01 16:35:58 -0600 | [diff] [blame] | 1 | // XGL tests |
| 2 | // |
| 3 | // Copyright (C) 2014 LunarG, Inc. |
| 4 | // |
| 5 | // Permission is hereby granted, free of charge, to any person obtaining a |
| 6 | // copy of this software and associated documentation files (the "Software"), |
| 7 | // to deal in the Software without restriction, including without limitation |
| 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 9 | // and/or sell copies of the Software, and to permit persons to whom the |
| 10 | // Software is furnished to do so, subject to the following conditions: |
| 11 | // |
| 12 | // The above copyright notice and this permission notice shall be included |
| 13 | // in all copies or substantial portions of the Software. |
| 14 | // |
| 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| 21 | // DEALINGS IN THE SOFTWARE. |
| 22 | |
Courtney Goeltzenleuchter | 62928d1 | 2014-08-13 17:53:57 -0600 | [diff] [blame] | 23 | #include "xglimage.h" |
| 24 | |
Courtney Goeltzenleuchter | 5ab50d7 | 2014-09-01 16:35:58 -0600 | [diff] [blame] | 25 | #include <stdlib.h> |
| 26 | #include <stdio.h> |
| 27 | #include <stdbool.h> |
| 28 | #include <string.h> |
| 29 | #include <iostream> |
| 30 | #include <fstream> |
| 31 | using namespace std; |
| 32 | |
| 33 | XglImage::XglImage(XglDevice *dev) : |
| 34 | m_image( XGL_NULL_HANDLE ), |
| 35 | m_targetView( XGL_NULL_HANDLE ), |
| 36 | m_memory( XGL_NULL_HANDLE ), |
| 37 | m_offset( 0 ), |
| 38 | m_mipCount( 0 ), |
| 39 | m_width( 0 ), |
| 40 | m_height( 0 ) |
Courtney Goeltzenleuchter | 62928d1 | 2014-08-13 17:53:57 -0600 | [diff] [blame] | 41 | { |
Courtney Goeltzenleuchter | 5ab50d7 | 2014-09-01 16:35:58 -0600 | [diff] [blame] | 42 | m_device = dev; |
| 43 | m_format.channelFormat = XGL_CH_FMT_UNDEFINED; |
| 44 | m_format.numericFormat = XGL_NUM_FMT_UNDEFINED; |
| 45 | m_imageInfo.view = XGL_NULL_HANDLE; |
| 46 | m_imageInfo.state = XGL_IMAGE_STATE_UNINITIALIZED_TARGET; |
Courtney Goeltzenleuchter | 62928d1 | 2014-08-13 17:53:57 -0600 | [diff] [blame] | 47 | } |
Courtney Goeltzenleuchter | 5ab50d7 | 2014-09-01 16:35:58 -0600 | [diff] [blame] | 48 | |
| 49 | XglImage::~XglImage() |
| 50 | { |
| 51 | if (m_memory != XGL_NULL_HANDLE) xglFreeMemory(m_memory); |
| 52 | if (m_image != XGL_NULL_HANDLE) xglDestroyObject(m_image); |
| 53 | if (m_targetView != XGL_NULL_HANDLE) xglDestroyObject(m_targetView); |
| 54 | if (m_imageInfo.view != XGL_NULL_HANDLE) xglDestroyObject(m_imageInfo.view); |
| 55 | } |
| 56 | |
| 57 | void XglImage::init(XGL_UINT32 w, XGL_UINT32 h, |
| 58 | XGL_FORMAT fmt, XGL_FLAGS usage) |
| 59 | { |
| 60 | XGL_RESULT err; |
| 61 | XGL_UINT mipCount; |
| 62 | XGL_SIZE size; |
| 63 | XGL_FORMAT_PROPERTIES image_fmt; |
| 64 | |
| 65 | mipCount = 0; |
| 66 | |
| 67 | m_width = w; |
| 68 | m_height = h; |
| 69 | m_format = fmt; |
| 70 | // m_screen.Init(true, w, h); |
| 71 | |
| 72 | XGL_UINT _w = w; |
| 73 | XGL_UINT _h = h; |
| 74 | while( ( _w > 0 ) || ( _h > 0 ) ) |
| 75 | { |
| 76 | _w >>= 1; |
| 77 | _h >>= 1; |
| 78 | mipCount++; |
| 79 | } |
| 80 | |
| 81 | // fmt.channelFormat = XGL_CH_FMT_R8G8B8A8; |
| 82 | // fmt.numericFormat = XGL_NUM_FMT_UNORM; |
| 83 | // TODO: Pick known good format rather than just expect common format |
| 84 | /* |
| 85 | * XXX: What should happen if given NULL HANDLE for the pData argument? |
| 86 | * We're not requesting XGL_INFO_TYPE_MEMORY_REQUIREMENTS so there is |
| 87 | * an expectation that pData is a valid pointer. |
| 88 | * However, why include a returned size value? That implies that the |
| 89 | * amount of data may vary and that doesn't work well for using a |
| 90 | * fixed structure. |
| 91 | */ |
| 92 | |
| 93 | err = xglGetFormatInfo(this->m_device->device(), fmt, |
| 94 | XGL_INFO_TYPE_FORMAT_PROPERTIES, |
| 95 | &size, &image_fmt); |
| 96 | ASSERT_XGL_SUCCESS(err); |
| 97 | |
| 98 | // typedef struct _XGL_IMAGE_CREATE_INFO |
| 99 | // { |
| 100 | // XGL_STRUCTURE_TYPE sType; // Must be XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO |
| 101 | // const XGL_VOID* pNext; // Pointer to next structure. |
| 102 | // XGL_IMAGE_TYPE imageType; |
| 103 | // XGL_FORMAT format; |
| 104 | // XGL_EXTENT3D extent; |
| 105 | // XGL_UINT mipLevels; |
| 106 | // XGL_UINT arraySize; |
| 107 | // XGL_UINT samples; |
| 108 | // XGL_IMAGE_TILING tiling; |
| 109 | // XGL_FLAGS usage; // XGL_IMAGE_USAGE_FLAGS |
| 110 | // XGL_FLAGS flags; // XGL_IMAGE_CREATE_FLAGS |
| 111 | // } XGL_IMAGE_CREATE_INFO; |
| 112 | |
| 113 | |
| 114 | XGL_IMAGE_CREATE_INFO imageCreateInfo = {}; |
| 115 | imageCreateInfo.sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO; |
| 116 | imageCreateInfo.imageType = XGL_IMAGE_2D; |
| 117 | imageCreateInfo.format = fmt; |
| 118 | imageCreateInfo.arraySize = 1; |
| 119 | imageCreateInfo.extent.width = w; |
| 120 | imageCreateInfo.extent.height = h; |
| 121 | imageCreateInfo.extent.depth = 1; |
| 122 | imageCreateInfo.mipLevels = mipCount; |
| 123 | imageCreateInfo.samples = 1; |
| 124 | imageCreateInfo.tiling = XGL_LINEAR_TILING; |
| 125 | |
| 126 | // Image usage flags |
| 127 | // typedef enum _XGL_IMAGE_USAGE_FLAGS |
| 128 | // { |
| 129 | // XGL_IMAGE_USAGE_SHADER_ACCESS_READ_BIT = 0x00000001, |
| 130 | // XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT = 0x00000002, |
| 131 | // XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000004, |
| 132 | // XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT = 0x00000008, |
| 133 | // } XGL_IMAGE_USAGE_FLAGS; |
| 134 | // imageCreateInfo.usage = XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT | XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| 135 | imageCreateInfo.usage = usage; |
| 136 | |
| 137 | // XGL_RESULT XGLAPI xglCreateImage( |
| 138 | // XGL_DEVICE device, |
| 139 | // const XGL_IMAGE_CREATE_INFO* pCreateInfo, |
| 140 | // XGL_IMAGE* pImage); |
| 141 | err = xglCreateImage(device(), &imageCreateInfo, &m_image); |
| 142 | ASSERT_XGL_SUCCESS(err); |
| 143 | |
| 144 | XGL_MEMORY_REQUIREMENTS mem_req; |
| 145 | XGL_UINT data_size; |
| 146 | err = xglGetObjectInfo(m_image, XGL_INFO_TYPE_MEMORY_REQUIREMENTS, |
| 147 | &data_size, &mem_req); |
| 148 | ASSERT_XGL_SUCCESS(err); |
| 149 | ASSERT_EQ(data_size, sizeof(mem_req)); |
| 150 | ASSERT_NE(0, mem_req.size) << "xglGetObjectInfo (Event): Failed - expect images to require memory"; |
| 151 | |
| 152 | m_imageInfo.state = XGL_IMAGE_STATE_UNINITIALIZED_TARGET; |
| 153 | |
| 154 | // XGL_RESULT XGLAPI xglAllocMemory( |
| 155 | // XGL_DEVICE device, |
| 156 | // const XGL_MEMORY_ALLOC_INFO* pAllocInfo, |
| 157 | // XGL_GPU_MEMORY* pMem); |
| 158 | XGL_MEMORY_ALLOC_INFO mem_info; |
| 159 | |
| 160 | memset(&mem_info, 0, sizeof(mem_info)); |
| 161 | mem_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO; |
| 162 | mem_info.allocationSize = mem_req.size; |
| 163 | mem_info.alignment = mem_req.alignment; |
| 164 | mem_info.heapCount = mem_req.heapCount; |
| 165 | memcpy(mem_info.heaps, mem_req.heaps, sizeof(XGL_UINT)*XGL_MAX_MEMORY_HEAPS); |
| 166 | mem_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL; |
| 167 | mem_info.flags = XGL_MEMORY_ALLOC_SHAREABLE_BIT; |
| 168 | err = xglAllocMemory(device(), &mem_info, &m_memory); |
| 169 | ASSERT_XGL_SUCCESS(err); |
| 170 | |
| 171 | err = xglBindObjectMemory(m_image, m_memory, 0); |
| 172 | ASSERT_XGL_SUCCESS(err); |
| 173 | |
| 174 | XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO createView = { |
| 175 | XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, |
| 176 | XGL_NULL_HANDLE, |
| 177 | m_image, |
| 178 | {XGL_CH_FMT_R8G8B8A8, XGL_NUM_FMT_UNORM}, |
| 179 | 0, |
| 180 | 0, |
| 181 | 1 |
| 182 | }; |
| 183 | |
| 184 | err = xglCreateColorAttachmentView(device(), &createView, &m_targetView); |
| 185 | ASSERT_XGL_SUCCESS(err); |
| 186 | } |
| 187 | |
| 188 | void XglImage::WritePPM( const char *basename ) |
| 189 | { |
| 190 | string filename; |
| 191 | XGL_RESULT err; |
| 192 | int x, y; |
| 193 | |
| 194 | filename.append(basename); |
| 195 | filename.append(".ppm"); |
| 196 | |
| 197 | const XGL_IMAGE_SUBRESOURCE sr = { |
| 198 | XGL_IMAGE_ASPECT_COLOR, 0, 0 |
| 199 | }; |
| 200 | XGL_SUBRESOURCE_LAYOUT sr_layout; |
| 201 | XGL_UINT data_size; |
| 202 | |
| 203 | err = xglGetImageSubresourceInfo( m_image, &sr, XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, |
| 204 | &data_size, &sr_layout); |
| 205 | ASSERT_XGL_SUCCESS( err ); |
| 206 | ASSERT_EQ(data_size, sizeof(sr_layout)); |
| 207 | |
| 208 | const char *ptr; |
| 209 | |
| 210 | err = xglMapMemory( m_memory, 0, (XGL_VOID **) &ptr ); |
| 211 | ASSERT_XGL_SUCCESS( err ); |
| 212 | |
| 213 | ptr += sr_layout.offset; |
| 214 | |
| 215 | ofstream file (filename.c_str()); |
| 216 | ASSERT_TRUE(file.is_open()) << "Unable to open file: " << filename; |
| 217 | |
| 218 | file << "P6\n"; |
| 219 | file << m_width << "\n"; |
| 220 | file << m_height << "\n"; |
| 221 | file << 255 << "\n"; |
| 222 | |
| 223 | for (y = 0; y < m_height; y++) { |
| 224 | const char *row = ptr; |
| 225 | |
| 226 | for (x = 0; x < m_width; x++) { |
| 227 | file.write(row, 3); |
| 228 | row += 4; |
| 229 | } |
| 230 | |
| 231 | ptr += sr_layout.rowPitch; |
| 232 | } |
| 233 | |
| 234 | file.close(); |
| 235 | |
| 236 | err = xglUnmapMemory( m_memory ); |
| 237 | ASSERT_XGL_SUCCESS( err ); |
| 238 | } |
| 239 | |