| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 1 | /* | 
|  | 2 | * XGL Tests | 
|  | 3 | * | 
|  | 4 | * Copyright (C) 2014 LunarG, Inc. | 
|  | 5 | * | 
|  | 6 | * Permission is hereby granted, free of charge, to any person obtaining a | 
|  | 7 | * copy of this software and associated documentation files (the "Software"), | 
|  | 8 | * to deal in the Software without restriction, including without limitation | 
|  | 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | 
|  | 10 | * and/or sell copies of the Software, and to permit persons to whom the | 
|  | 11 | * Software is furnished to do so, subject to the following conditions: | 
|  | 12 | * | 
|  | 13 | * The above copyright notice and this permission notice shall be included | 
|  | 14 | * in all copies or substantial portions of the Software. | 
|  | 15 | * | 
|  | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
|  | 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
|  | 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | 
|  | 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
|  | 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | 
|  | 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
|  | 22 | * DEALINGS IN THE SOFTWARE. | 
|  | 23 | * | 
|  | 24 | * Authors: | 
|  | 25 | *   Courtney Goeltzenleuchter <courtney@lunarg.com> | 
|  | 26 | */ | 
|  | 27 |  | 
|  | 28 | #include "xglrenderframework.h" | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 29 |  | 
| Courtney Goeltzenleuchter | 53d8d89 | 2014-10-08 12:20:26 -0600 | [diff] [blame] | 30 | XglRenderFramework::XglRenderFramework() : | 
|  | 31 | m_colorBlend( XGL_NULL_HANDLE ), | 
|  | 32 | m_stateMsaa( XGL_NULL_HANDLE ), | 
|  | 33 | m_stateDepthStencil( XGL_NULL_HANDLE ), | 
|  | 34 | m_stateRaster( XGL_NULL_HANDLE ), | 
|  | 35 | m_cmdBuffer( XGL_NULL_HANDLE ), | 
| Courtney Goeltzenleuchter | 02d33c1 | 2014-10-08 14:26:40 -0600 | [diff] [blame] | 36 | m_stateViewport( XGL_NULL_HANDLE ), | 
|  | 37 | m_width( 256.0 ),                   // default window width | 
|  | 38 | m_height( 256.0 )                   // default window height | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 39 | { | 
|  | 40 | m_render_target_fmt.channelFormat = XGL_CH_FMT_R8G8B8A8; | 
|  | 41 | m_render_target_fmt.numericFormat = XGL_NUM_FMT_UNORM; | 
| Courtney Goeltzenleuchter | 32e486c | 2014-10-22 14:12:38 -0600 | [diff] [blame^] | 42 |  | 
|  | 43 | m_colorBinding.view = XGL_NULL_HANDLE; | 
|  | 44 | m_depthStencilBinding.view = XGL_NULL_HANDLE; | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 45 | } | 
|  | 46 |  | 
|  | 47 | XglRenderFramework::~XglRenderFramework() | 
|  | 48 | { | 
| Courtney Goeltzenleuchter | 53d8d89 | 2014-10-08 12:20:26 -0600 | [diff] [blame] | 49 |  | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | void XglRenderFramework::InitFramework() | 
|  | 53 | { | 
|  | 54 | XGL_RESULT err; | 
|  | 55 |  | 
|  | 56 | memset(&m_vtxBufferView, 0, sizeof(m_vtxBufferView)); | 
|  | 57 | m_vtxBufferView.sType = XGL_STRUCTURE_TYPE_MEMORY_VIEW_ATTACH_INFO; | 
|  | 58 |  | 
|  | 59 | memset(&m_constantBufferView, 0, sizeof(m_constantBufferView)); | 
|  | 60 | m_constantBufferView.sType = XGL_STRUCTURE_TYPE_MEMORY_VIEW_ATTACH_INFO; | 
|  | 61 |  | 
|  | 62 | err = xglInitAndEnumerateGpus(&app_info, NULL, | 
|  | 63 | MAX_GPUS, &this->gpu_count, objs); | 
|  | 64 | ASSERT_XGL_SUCCESS(err); | 
|  | 65 | ASSERT_GE(1, this->gpu_count) << "No GPU available"; | 
|  | 66 |  | 
|  | 67 | m_device = new XglDevice(0, objs[0]); | 
|  | 68 | m_device->get_device_queue(); | 
|  | 69 | } | 
|  | 70 |  | 
|  | 71 | void XglRenderFramework::ShutdownFramework() | 
|  | 72 | { | 
|  | 73 | if (m_colorBlend) xglDestroyObject(m_colorBlend); | 
|  | 74 | if (m_stateMsaa) xglDestroyObject(m_stateMsaa); | 
|  | 75 | if (m_stateDepthStencil) xglDestroyObject(m_stateDepthStencil); | 
|  | 76 | if (m_stateRaster) xglDestroyObject(m_stateRaster); | 
|  | 77 | if (m_cmdBuffer) xglDestroyObject(m_cmdBuffer); | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 78 |  | 
|  | 79 | if (m_stateViewport) { | 
|  | 80 | xglDestroyObject(m_stateViewport); | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | if (m_renderTarget) { | 
|  | 84 | // TODO: XglImage should be able to destroy itself | 
|  | 85 | //        m_renderTarget-> | 
|  | 86 | //        xglDestroyObject(*m_renderTarget); | 
|  | 87 | } | 
| Courtney Goeltzenleuchter | 53d8d89 | 2014-10-08 12:20:26 -0600 | [diff] [blame] | 88 |  | 
|  | 89 | // reset the driver | 
|  | 90 | xglInitAndEnumerateGpus(&this->app_info, XGL_NULL_HANDLE, 0, &gpu_count, XGL_NULL_HANDLE); | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 91 | } | 
|  | 92 |  | 
| Courtney Goeltzenleuchter | 53d8d89 | 2014-10-08 12:20:26 -0600 | [diff] [blame] | 93 | void XglRenderFramework::InitState() | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 94 | { | 
|  | 95 | XGL_RESULT err; | 
|  | 96 |  | 
|  | 97 | m_render_target_fmt.channelFormat = XGL_CH_FMT_R8G8B8A8; | 
|  | 98 | m_render_target_fmt.numericFormat = XGL_NUM_FMT_UNORM; | 
|  | 99 |  | 
|  | 100 | // create a raster state (solid, back-face culling) | 
|  | 101 | XGL_RASTER_STATE_CREATE_INFO raster = {}; | 
|  | 102 | raster.sType = XGL_STRUCTURE_TYPE_RASTER_STATE_CREATE_INFO; | 
|  | 103 | raster.fillMode = XGL_FILL_SOLID; | 
|  | 104 | raster.cullMode = XGL_CULL_NONE; | 
|  | 105 | raster.frontFace = XGL_FRONT_FACE_CCW; | 
|  | 106 | err = xglCreateRasterState( device(), &raster, &m_stateRaster ); | 
|  | 107 | ASSERT_XGL_SUCCESS(err); | 
|  | 108 |  | 
|  | 109 | XGL_COLOR_BLEND_STATE_CREATE_INFO blend = {}; | 
|  | 110 | blend.sType = XGL_STRUCTURE_TYPE_COLOR_BLEND_STATE_CREATE_INFO; | 
|  | 111 | err = xglCreateColorBlendState(device(), &blend, &m_colorBlend); | 
|  | 112 | ASSERT_XGL_SUCCESS( err ); | 
|  | 113 |  | 
|  | 114 | XGL_DEPTH_STENCIL_STATE_CREATE_INFO depthStencil = {}; | 
|  | 115 | depthStencil.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO; | 
|  | 116 | depthStencil.depthTestEnable      = XGL_FALSE; | 
|  | 117 | depthStencil.depthWriteEnable = XGL_FALSE; | 
|  | 118 | depthStencil.depthFunc = XGL_COMPARE_LESS_EQUAL; | 
|  | 119 | depthStencil.depthBoundsEnable = XGL_FALSE; | 
|  | 120 | depthStencil.minDepth = 0.f; | 
|  | 121 | depthStencil.maxDepth = 1.f; | 
|  | 122 | depthStencil.back.stencilDepthFailOp = XGL_STENCIL_OP_KEEP; | 
|  | 123 | depthStencil.back.stencilFailOp = XGL_STENCIL_OP_KEEP; | 
|  | 124 | depthStencil.back.stencilPassOp = XGL_STENCIL_OP_KEEP; | 
|  | 125 | depthStencil.back.stencilRef = 0x00; | 
|  | 126 | depthStencil.back.stencilFunc = XGL_COMPARE_ALWAYS; | 
|  | 127 | depthStencil.front = depthStencil.back; | 
|  | 128 |  | 
|  | 129 | err = xglCreateDepthStencilState( device(), &depthStencil, &m_stateDepthStencil ); | 
|  | 130 | ASSERT_XGL_SUCCESS( err ); | 
|  | 131 |  | 
|  | 132 | XGL_MSAA_STATE_CREATE_INFO msaa = {}; | 
|  | 133 | msaa.sType = XGL_STRUCTURE_TYPE_MSAA_STATE_CREATE_INFO; | 
|  | 134 | msaa.sampleMask = 1; | 
|  | 135 | msaa.samples = 1; | 
|  | 136 |  | 
|  | 137 | err = xglCreateMsaaState( device(), &msaa, &m_stateMsaa ); | 
|  | 138 | ASSERT_XGL_SUCCESS( err ); | 
|  | 139 |  | 
|  | 140 | XGL_CMD_BUFFER_CREATE_INFO cmdInfo = {}; | 
|  | 141 |  | 
|  | 142 | cmdInfo.sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO; | 
|  | 143 | cmdInfo.queueType = XGL_QUEUE_TYPE_GRAPHICS; | 
|  | 144 | err = xglCreateCommandBuffer(device(), &cmdInfo, &m_cmdBuffer); | 
|  | 145 | ASSERT_XGL_SUCCESS(err) << "xglCreateCommandBuffer failed"; | 
|  | 146 | } | 
|  | 147 |  | 
|  | 148 | void XglRenderFramework::InitConstantBuffer(int constantCount, int constantSize, | 
|  | 149 | const void* data) | 
|  | 150 | { | 
|  | 151 | XGL_RESULT err = XGL_SUCCESS; | 
|  | 152 |  | 
|  | 153 | XGL_MEMORY_ALLOC_INFO alloc_info = {}; | 
|  | 154 | XGL_UINT8 *pData; | 
|  | 155 |  | 
|  | 156 | alloc_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO; | 
|  | 157 | alloc_info.allocationSize = constantCount * constantSize; | 
|  | 158 | alloc_info.alignment = 0; | 
|  | 159 | alloc_info.heapCount = 1; | 
|  | 160 | alloc_info.heaps[0] = 0; // TODO: Use known existing heap | 
|  | 161 |  | 
|  | 162 | alloc_info.flags = XGL_MEMORY_HEAP_CPU_VISIBLE_BIT; | 
|  | 163 | alloc_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL; | 
|  | 164 |  | 
|  | 165 | err = xglAllocMemory(device(), &alloc_info, &m_constantBufferMem); | 
|  | 166 | ASSERT_XGL_SUCCESS(err); | 
|  | 167 |  | 
|  | 168 | err = xglMapMemory(m_constantBufferMem, 0, (XGL_VOID **) &pData); | 
|  | 169 | ASSERT_XGL_SUCCESS(err); | 
|  | 170 |  | 
|  | 171 | memcpy(pData, data, alloc_info.allocationSize); | 
|  | 172 |  | 
|  | 173 | err = xglUnmapMemory(m_constantBufferMem); | 
|  | 174 | ASSERT_XGL_SUCCESS(err); | 
|  | 175 |  | 
|  | 176 | // set up the memory view for the constant buffer | 
| Cody Northrop | e1ab9bf | 2014-10-14 14:10:26 -0600 | [diff] [blame] | 177 | this->m_constantBufferView.stride = 16; | 
|  | 178 | this->m_constantBufferView.range  = alloc_info.allocationSize; | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 179 | this->m_constantBufferView.offset = 0; | 
|  | 180 | this->m_constantBufferView.mem    = m_constantBufferMem; | 
|  | 181 | this->m_constantBufferView.format.channelFormat = XGL_CH_FMT_R32G32B32A32; | 
|  | 182 | this->m_constantBufferView.format.numericFormat = XGL_NUM_FMT_FLOAT; | 
|  | 183 | } | 
|  | 184 |  | 
| Courtney Goeltzenleuchter | fdcfb9f | 2014-10-10 18:04:39 -0600 | [diff] [blame] | 185 | /* | 
|  | 186 | * Update existing constant value with new data of exactly | 
|  | 187 | * the same size. | 
|  | 188 | */ | 
|  | 189 | void XglRenderFramework::UpdateConstantBuffer(const void* data) | 
|  | 190 | { | 
|  | 191 | XGL_RESULT err = XGL_SUCCESS; | 
|  | 192 | XGL_UINT8 *pData; | 
|  | 193 |  | 
|  | 194 | err = xglMapMemory(m_constantBufferMem, 0, (XGL_VOID **) &pData); | 
|  | 195 | ASSERT_XGL_SUCCESS(err); | 
|  | 196 |  | 
|  | 197 | memcpy(pData + this->m_constantBufferView.offset, data, this->m_constantBufferView.range); | 
|  | 198 |  | 
|  | 199 | err = xglUnmapMemory(m_constantBufferMem); | 
|  | 200 | ASSERT_XGL_SUCCESS(err); | 
|  | 201 | } | 
|  | 202 |  | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 203 | void XglRenderFramework::CreateQueryPool(XGL_QUERY_TYPE type, XGL_UINT slots, | 
|  | 204 | XGL_QUERY_POOL *pPool, XGL_GPU_MEMORY *pMem) | 
|  | 205 | { | 
|  | 206 | XGL_RESULT err; | 
|  | 207 |  | 
|  | 208 | XGL_QUERY_POOL_CREATE_INFO poolCreateInfo = {}; | 
|  | 209 | poolCreateInfo.sType = XGL_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; | 
|  | 210 | poolCreateInfo.pNext = NULL; | 
|  | 211 | poolCreateInfo.queryType = type; | 
|  | 212 | poolCreateInfo.slots = slots; | 
|  | 213 |  | 
|  | 214 | err = xglCreateQueryPool(device(), &poolCreateInfo, pPool); | 
|  | 215 | ASSERT_XGL_SUCCESS(err); | 
|  | 216 |  | 
|  | 217 | XGL_MEMORY_REQUIREMENTS mem_req; | 
|  | 218 | XGL_UINT data_size = sizeof(mem_req); | 
|  | 219 | err = xglGetObjectInfo(*pPool, XGL_INFO_TYPE_MEMORY_REQUIREMENTS, | 
|  | 220 | &data_size, &mem_req); | 
|  | 221 | ASSERT_XGL_SUCCESS(err); | 
|  | 222 | ASSERT_EQ(data_size, sizeof(mem_req)); | 
|  | 223 |  | 
|  | 224 | if (!mem_req.size) { | 
|  | 225 | *pMem = XGL_NULL_HANDLE; | 
|  | 226 | return; | 
|  | 227 | } | 
|  | 228 |  | 
|  | 229 | XGL_MEMORY_ALLOC_INFO mem_info; | 
|  | 230 |  | 
|  | 231 | memset(&mem_info, 0, sizeof(mem_info)); | 
|  | 232 | mem_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO; | 
|  | 233 | mem_info.allocationSize = mem_req.size; | 
|  | 234 | mem_info.alignment = mem_req.alignment; | 
|  | 235 | mem_info.heapCount = mem_req.heapCount; | 
|  | 236 | memcpy(mem_info.heaps, mem_req.heaps, sizeof(XGL_UINT)*XGL_MAX_MEMORY_HEAPS); | 
|  | 237 | mem_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL; | 
|  | 238 | mem_info.flags = XGL_MEMORY_ALLOC_SHAREABLE_BIT; | 
|  | 239 | err = xglAllocMemory(device(), &mem_info, pMem); | 
|  | 240 | ASSERT_XGL_SUCCESS(err); | 
|  | 241 |  | 
|  | 242 | err = xglBindObjectMemory(*pPool, *pMem, 0); | 
|  | 243 | ASSERT_XGL_SUCCESS(err); | 
|  | 244 | } | 
|  | 245 |  | 
|  | 246 | void XglRenderFramework::DestroyQueryPool(XGL_QUERY_POOL pool, XGL_GPU_MEMORY mem) | 
|  | 247 | { | 
|  | 248 | ASSERT_XGL_SUCCESS(xglBindObjectMemory(pool, XGL_NULL_HANDLE, 0)); | 
|  | 249 | ASSERT_XGL_SUCCESS(xglFreeMemory(mem)); | 
|  | 250 | ASSERT_XGL_SUCCESS(xglDestroyObject(pool)); | 
|  | 251 | } | 
|  | 252 |  | 
|  | 253 | void XglRenderFramework::CreateShader(XGL_PIPELINE_SHADER_STAGE stage, | 
|  | 254 | const char *shader_code, | 
|  | 255 | XGL_SHADER *pshader) | 
|  | 256 | { | 
| Courtney Goeltzenleuchter | bfde09b | 2014-10-10 16:29:46 -0600 | [diff] [blame] | 257 | XGL_RESULT err = XGL_SUCCESS; | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 258 | std::vector<unsigned int> bil; | 
|  | 259 | XGL_SHADER_CREATE_INFO createInfo; | 
| Courtney Goeltzenleuchter | bfde09b | 2014-10-10 16:29:46 -0600 | [diff] [blame] | 260 | size_t shader_len; | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 261 | XGL_SHADER shader; | 
|  | 262 |  | 
|  | 263 | createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO; | 
|  | 264 | createInfo.pNext = NULL; | 
|  | 265 |  | 
| Courtney Goeltzenleuchter | bfde09b | 2014-10-10 16:29:46 -0600 | [diff] [blame] | 266 | if (!this->m_use_bil) { | 
|  | 267 | shader_len = strlen(shader_code); | 
|  | 268 | createInfo.codeSize = 3 * sizeof(uint32_t) + shader_len + 1; | 
|  | 269 | createInfo.pCode = malloc(createInfo.codeSize); | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 270 | createInfo.flags = 0; | 
| Courtney Goeltzenleuchter | bfde09b | 2014-10-10 16:29:46 -0600 | [diff] [blame] | 271 |  | 
|  | 272 | /* try version 0 first: XGL_PIPELINE_SHADER_STAGE followed by GLSL */ | 
|  | 273 | ((uint32_t *) createInfo.pCode)[0] = ICD_BIL_MAGIC; | 
|  | 274 | ((uint32_t *) createInfo.pCode)[1] = 0; | 
|  | 275 | ((uint32_t *) createInfo.pCode)[2] = stage; | 
|  | 276 | memcpy(((uint32_t *) createInfo.pCode + 3), shader_code, shader_len + 1); | 
|  | 277 |  | 
|  | 278 | err = xglCreateShader(device(), &createInfo, &shader); | 
|  | 279 | if (err) { | 
|  | 280 | free((void *) createInfo.pCode); | 
|  | 281 | } | 
|  | 282 | } | 
|  | 283 |  | 
|  | 284 | // Only use BIL if GLSL compile fails or it's requested via m_use_bil | 
|  | 285 | if (this->m_use_bil || err) { | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 286 | // Use Reference GLSL to BIL compiler | 
|  | 287 | GLSLtoBIL(stage, shader_code, bil); | 
|  | 288 | createInfo.pCode = bil.data(); | 
|  | 289 | createInfo.codeSize = bil.size() * sizeof(unsigned int); | 
|  | 290 | createInfo.flags = 0; | 
| Courtney Goeltzenleuchter | bfde09b | 2014-10-10 16:29:46 -0600 | [diff] [blame] | 291 | err = xglCreateShader(device(), &createInfo, &shader); | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 292 | } | 
|  | 293 |  | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 294 | ASSERT_XGL_SUCCESS(err); | 
|  | 295 |  | 
|  | 296 | *pshader = shader; | 
|  | 297 | } | 
|  | 298 |  | 
|  | 299 | void XglRenderFramework::InitViewport(float width, float height) | 
|  | 300 | { | 
|  | 301 | XGL_RESULT err; | 
|  | 302 |  | 
|  | 303 | XGL_VIEWPORT_STATE_CREATE_INFO viewport = {}; | 
|  | 304 | viewport.viewportCount         = 1; | 
|  | 305 | viewport.scissorEnable         = XGL_FALSE; | 
|  | 306 | viewport.viewports[0].originX  = 0; | 
|  | 307 | viewport.viewports[0].originY  = 0; | 
|  | 308 | viewport.viewports[0].width    = 1.f * width; | 
|  | 309 | viewport.viewports[0].height   = 1.f * height; | 
|  | 310 | viewport.viewports[0].minDepth = 0.f; | 
|  | 311 | viewport.viewports[0].maxDepth = 1.f; | 
|  | 312 |  | 
|  | 313 | err = xglCreateViewportState( device(), &viewport, &m_stateViewport ); | 
|  | 314 | ASSERT_XGL_SUCCESS( err ); | 
|  | 315 | m_width = width; | 
|  | 316 | m_height = height; | 
|  | 317 | } | 
|  | 318 |  | 
| Courtney Goeltzenleuchter | 02d33c1 | 2014-10-08 14:26:40 -0600 | [diff] [blame] | 319 | void XglRenderFramework::InitViewport() | 
|  | 320 | { | 
|  | 321 | InitViewport(m_width, m_height); | 
|  | 322 | } | 
|  | 323 |  | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 324 | void XglRenderFramework::InitRenderTarget() | 
|  | 325 | { | 
|  | 326 | m_device->CreateImage(m_width, m_height, m_render_target_fmt, | 
|  | 327 | XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT | | 
|  | 328 | XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, | 
|  | 329 | &m_renderTarget); | 
|  | 330 | } | 
|  | 331 |  | 
| Courtney Goeltzenleuchter | 02d33c1 | 2014-10-08 14:26:40 -0600 | [diff] [blame] | 332 | void XglRenderFramework::CreateDefaultPipeline(XGL_PIPELINE* pipeline, XGL_SHADER vs, XGL_SHADER ps) | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 333 | { | 
|  | 334 | XGL_RESULT err; | 
|  | 335 | XGL_GRAPHICS_PIPELINE_CREATE_INFO info = {}; | 
|  | 336 | XGL_PIPELINE_SHADER_STAGE_CREATE_INFO vs_stage; | 
|  | 337 | XGL_PIPELINE_SHADER_STAGE_CREATE_INFO ps_stage; | 
|  | 338 |  | 
|  | 339 | #if 0 | 
|  | 340 | // Create descriptor set for our one resource | 
|  | 341 | XGL_DESCRIPTOR_SET_CREATE_INFO descriptorInfo = {}; | 
|  | 342 | descriptorInfo.sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_CREATE_INFO; | 
|  | 343 | descriptorInfo.slots = 1; // Vertex buffer only | 
|  | 344 |  | 
|  | 345 | // create a descriptor set with a single slot | 
|  | 346 | err = xglCreateDescriptorSet( device(), &descriptorInfo, &m_rsrcDescSet ); | 
|  | 347 | ASSERT_XGL_SUCCESS(err) << "xglCreateDescriptorSet failed"; | 
|  | 348 |  | 
|  | 349 | // bind memory to the descriptor set | 
|  | 350 | err = m_device->AllocAndBindGpuMemory(m_rsrcDescSet, "DescriptorSet", &m_descriptor_set_mem); | 
|  | 351 |  | 
|  | 352 | // set up the memory view for the vertex buffer | 
|  | 353 | this->m_vtxBufferView.stride = vbStride; | 
|  | 354 | this->m_vtxBufferView.range  = numVertices * vbStride; | 
|  | 355 | this->m_vtxBufferView.offset = 0; | 
|  | 356 | this->m_vtxBufferView.mem    = m_vtxBufferMem; | 
|  | 357 | this->m_vtxBufferView.format.channelFormat = XGL_CH_FMT_UNDEFINED; | 
|  | 358 | this->m_vtxBufferView.format.numericFormat = XGL_NUM_FMT_UNDEFINED; | 
|  | 359 | // write the vertex buffer view to the descriptor set | 
|  | 360 | xglBeginDescriptorSetUpdate( m_rsrcDescSet ); | 
|  | 361 | xglAttachMemoryViewDescriptors( m_rsrcDescSet, 0, 1, &m_vtxBufferView ); | 
|  | 362 | xglEndDescriptorSetUpdate( m_rsrcDescSet ); | 
|  | 363 | #endif | 
|  | 364 |  | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 365 | vs_stage.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; | 
|  | 366 | vs_stage.pNext = XGL_NULL_HANDLE; | 
|  | 367 | vs_stage.shader.stage = XGL_SHADER_STAGE_VERTEX; | 
| Courtney Goeltzenleuchter | 02d33c1 | 2014-10-08 14:26:40 -0600 | [diff] [blame] | 368 | vs_stage.shader.shader = vs; | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 369 | vs_stage.shader.descriptorSetMapping[0].descriptorCount = 0; | 
|  | 370 | vs_stage.shader.linkConstBufferCount = 0; | 
|  | 371 | vs_stage.shader.pLinkConstBufferInfo = XGL_NULL_HANDLE; | 
|  | 372 | vs_stage.shader.dynamicMemoryViewMapping.slotObjectType = XGL_SLOT_UNUSED; | 
|  | 373 | vs_stage.shader.dynamicMemoryViewMapping.shaderEntityIndex = 0; | 
|  | 374 |  | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 375 | ps_stage.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; | 
|  | 376 | ps_stage.pNext = &vs_stage; | 
|  | 377 | ps_stage.shader.stage = XGL_SHADER_STAGE_FRAGMENT; | 
| Courtney Goeltzenleuchter | 02d33c1 | 2014-10-08 14:26:40 -0600 | [diff] [blame] | 378 | ps_stage.shader.shader = ps; | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 379 |  | 
|  | 380 | const int slots = 1; | 
|  | 381 | XGL_DESCRIPTOR_SLOT_INFO *slotInfo = (XGL_DESCRIPTOR_SLOT_INFO*) malloc( slots * sizeof(XGL_DESCRIPTOR_SLOT_INFO) ); | 
|  | 382 | slotInfo[0].shaderEntityIndex = 0; | 
|  | 383 | slotInfo[0].slotObjectType = XGL_SLOT_SHADER_RESOURCE; | 
|  | 384 |  | 
|  | 385 | ps_stage.shader.descriptorSetMapping[0].pDescriptorInfo = (const XGL_DESCRIPTOR_SLOT_INFO*) slotInfo; | 
|  | 386 | ps_stage.shader.descriptorSetMapping[0].descriptorCount = 1; | 
|  | 387 |  | 
|  | 388 | ps_stage.shader.linkConstBufferCount = 0; | 
|  | 389 | ps_stage.shader.pLinkConstBufferInfo = XGL_NULL_HANDLE; | 
|  | 390 | ps_stage.shader.dynamicMemoryViewMapping.slotObjectType = XGL_SLOT_UNUSED; | 
|  | 391 | ps_stage.shader.dynamicMemoryViewMapping.shaderEntityIndex = 0; | 
|  | 392 |  | 
|  | 393 | XGL_PIPELINE_IA_STATE_CREATE_INFO ia_state = { | 
|  | 394 | XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO,  // sType | 
|  | 395 | &ps_stage,                                         // pNext | 
|  | 396 | XGL_TOPOLOGY_TRIANGLE_LIST,                        // XGL_PRIMITIVE_TOPOLOGY | 
|  | 397 | XGL_FALSE,                                         // disableVertexReuse | 
|  | 398 | XGL_PROVOKING_VERTEX_LAST,                         // XGL_PROVOKING_VERTEX_CONVENTION | 
|  | 399 | XGL_FALSE,                                         // primitiveRestartEnable | 
|  | 400 | 0                                                  // primitiveRestartIndex | 
|  | 401 | }; | 
|  | 402 |  | 
|  | 403 | XGL_PIPELINE_RS_STATE_CREATE_INFO rs_state = { | 
|  | 404 | XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO, | 
|  | 405 | &ia_state, | 
|  | 406 | XGL_FALSE,                                          // depthClipEnable | 
|  | 407 | XGL_FALSE,                                          // rasterizerDiscardEnable | 
|  | 408 | 1.0                                                 // pointSize | 
|  | 409 | }; | 
|  | 410 |  | 
|  | 411 | XGL_PIPELINE_CB_STATE cb_state = { | 
|  | 412 | XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO, | 
|  | 413 | &rs_state, | 
|  | 414 | XGL_FALSE,                                          // alphaToCoverageEnable | 
|  | 415 | XGL_FALSE,                                          // dualSourceBlendEnable | 
|  | 416 | XGL_LOGIC_OP_COPY,                                  // XGL_LOGIC_OP | 
|  | 417 | {                                                   // XGL_PIPELINE_CB_ATTACHMENT_STATE | 
|  | 418 | { | 
|  | 419 | XGL_FALSE,                                  // blendEnable | 
|  | 420 | m_render_target_fmt,                        // XGL_FORMAT | 
|  | 421 | 0xF                                         // channelWriteMask | 
|  | 422 | } | 
|  | 423 | } | 
|  | 424 | }; | 
|  | 425 |  | 
|  | 426 | // TODO: Should take depth buffer format from queried formats | 
|  | 427 | XGL_PIPELINE_DB_STATE_CREATE_INFO db_state = { | 
|  | 428 | XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO, | 
|  | 429 | &cb_state, | 
|  | 430 | {XGL_CH_FMT_R32, XGL_NUM_FMT_DS}                    // XGL_FORMAT | 
|  | 431 | }; | 
|  | 432 |  | 
|  | 433 | info.sType = XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; | 
|  | 434 | info.pNext = &db_state; | 
|  | 435 | info.flags = 0; | 
|  | 436 | err = xglCreateGraphicsPipeline(device(), &info, pipeline); | 
|  | 437 | ASSERT_XGL_SUCCESS(err); | 
|  | 438 |  | 
|  | 439 | err = m_device->AllocAndBindGpuMemory(*pipeline, "Pipeline", &m_pipe_mem); | 
|  | 440 | ASSERT_XGL_SUCCESS(err); | 
|  | 441 | } | 
|  | 442 |  | 
| Courtney Goeltzenleuchter | 02d33c1 | 2014-10-08 14:26:40 -0600 | [diff] [blame] | 443 | void XglRenderFramework::GenerateBindRenderTargetCmd() | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 444 | { | 
|  | 445 | // bind render target | 
| Courtney Goeltzenleuchter | 32e486c | 2014-10-22 14:12:38 -0600 | [diff] [blame^] | 446 | m_colorBinding.view  = m_renderTarget->targetView(); | 
|  | 447 | m_colorBinding.colorAttachmentState = XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL; | 
|  | 448 | if (m_depthStencilBinding.view) { | 
|  | 449 | xglCmdBindAttachments(m_cmdBuffer, 1, &m_colorBinding, &m_depthStencilBinding ); | 
|  | 450 | } else { | 
|  | 451 | xglCmdBindAttachments(m_cmdBuffer, 1, &m_colorBinding, XGL_NULL_HANDLE ); | 
|  | 452 | } | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 453 | } | 
|  | 454 |  | 
|  | 455 | void XglRenderFramework::GenerateBindStateAndPipelineCmds(XGL_PIPELINE* pipeline) | 
|  | 456 | { | 
|  | 457 | // set all states | 
|  | 458 | xglCmdBindStateObject( m_cmdBuffer, XGL_STATE_BIND_RASTER, m_stateRaster ); | 
|  | 459 | xglCmdBindStateObject( m_cmdBuffer, XGL_STATE_BIND_VIEWPORT, m_stateViewport ); | 
|  | 460 | xglCmdBindStateObject( m_cmdBuffer, XGL_STATE_BIND_COLOR_BLEND, m_colorBlend); | 
|  | 461 | xglCmdBindStateObject( m_cmdBuffer, XGL_STATE_BIND_DEPTH_STENCIL, m_stateDepthStencil ); | 
|  | 462 | xglCmdBindStateObject( m_cmdBuffer, XGL_STATE_BIND_MSAA, m_stateMsaa ); | 
|  | 463 |  | 
|  | 464 | // bind pipeline, vertex buffer (descriptor set) and WVP (dynamic memory view) | 
|  | 465 | xglCmdBindPipeline( m_cmdBuffer, XGL_PIPELINE_BIND_POINT_GRAPHICS, *pipeline ); | 
| Courtney Goeltzenleuchter | 02d33c1 | 2014-10-08 14:26:40 -0600 | [diff] [blame] | 466 |  | 
|  | 467 | // bind pipeline, vertex buffer (descriptor set) and WVP (dynamic memory view) | 
|  | 468 | xglCmdBindDescriptorSet(m_cmdBuffer, XGL_PIPELINE_BIND_POINT_GRAPHICS, 0, m_rsrcDescSet, 0 ); | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 469 | } | 
|  | 470 |  | 
| Courtney Goeltzenleuchter | 02d33c1 | 2014-10-08 14:26:40 -0600 | [diff] [blame] | 471 | void XglRenderFramework::GenerateClearAndPrepareBufferCmds() | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 472 | { | 
|  | 473 | // whatever we want to do, we do it to the whole buffer | 
|  | 474 | XGL_IMAGE_SUBRESOURCE_RANGE srRange = {}; | 
|  | 475 | srRange.aspect = XGL_IMAGE_ASPECT_COLOR; | 
|  | 476 | srRange.baseMipLevel = 0; | 
|  | 477 | srRange.mipLevels = XGL_LAST_MIP_OR_SLICE; | 
|  | 478 | srRange.baseArraySlice = 0; | 
|  | 479 | srRange.arraySize = XGL_LAST_MIP_OR_SLICE; | 
|  | 480 |  | 
|  | 481 | // prepare the whole back buffer for clear | 
|  | 482 | XGL_IMAGE_STATE_TRANSITION transitionToClear = {}; | 
|  | 483 | transitionToClear.image = m_renderTarget->image(); | 
|  | 484 | transitionToClear.oldState = m_renderTarget->state(); | 
|  | 485 | transitionToClear.newState = XGL_IMAGE_STATE_CLEAR; | 
|  | 486 | transitionToClear.subresourceRange = srRange; | 
|  | 487 | xglCmdPrepareImages( m_cmdBuffer, 1, &transitionToClear ); | 
|  | 488 | m_renderTarget->state(( XGL_IMAGE_STATE ) transitionToClear.newState); | 
|  | 489 |  | 
|  | 490 | // clear the back buffer to dark grey | 
|  | 491 | XGL_UINT clearColor[4] = {64, 64, 64, 0}; | 
|  | 492 | xglCmdClearColorImageRaw( m_cmdBuffer, m_renderTarget->image(), clearColor, 1, &srRange ); | 
|  | 493 |  | 
|  | 494 | // prepare back buffer for rendering | 
|  | 495 | XGL_IMAGE_STATE_TRANSITION transitionToRender = {}; | 
|  | 496 | transitionToRender.image = m_renderTarget->image(); | 
|  | 497 | transitionToRender.oldState = m_renderTarget->state(); | 
|  | 498 | transitionToRender.newState = XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL; | 
|  | 499 | transitionToRender.subresourceRange = srRange; | 
|  | 500 | xglCmdPrepareImages( m_cmdBuffer, 1, &transitionToRender ); | 
|  | 501 | m_renderTarget->state(( XGL_IMAGE_STATE ) transitionToClear.newState); | 
| Courtney Goeltzenleuchter | a4b278b | 2014-10-08 08:50:49 -0600 | [diff] [blame] | 502 | } |