blob: bd8d6755f674a884032b64d2ae97bf9bf04f72d4 [file] [log] [blame]
/*
* XGL
*
* Copyright (C) 2014 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "common.h"
void app_dev_init_formats(struct app_dev *dev)
{
XGL_CHANNEL_FORMAT ch;
XGL_NUM_FORMAT num;
for (ch = 0; ch < XGL_MAX_CH_FMT; ch++) {
for (num = 0; num < XGL_MAX_NUM_FMT; num++) {
const XGL_FORMAT fmt = {
.channelFormat = ch,
.numericFormat = num,
};
XGL_RESULT err;
XGL_SIZE size = sizeof(dev->format_props[ch][num]);
err = xglGetFormatInfo(dev->obj, fmt,
XGL_INFO_TYPE_FORMAT_PROPERTIES,
&size, &dev->format_props[ch][num]);
if (err) {
memset(&dev->format_props[ch][num], 0,
sizeof(dev->format_props[ch][num]));
}
else if (size != sizeof(dev->format_props[ch][num])) {
ERR_EXIT(XGL_ERROR_UNKNOWN);
}
}
}
}
void app_dev_init(struct app_dev *dev, struct app_gpu *gpu)
{
XGL_DEVICE_CREATE_INFO info = {
.sType = XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = NULL,
.queueRecordCount = 0,
.pRequestedQueues = NULL,
.extensionCount = 0,
.ppEnabledExtensionNames = NULL,
.maxValidationLevel = XGL_VALIDATION_LEVEL_END_RANGE,
.flags = XGL_DEVICE_CREATE_VALIDATION_BIT,
};
XGL_RESULT err;
XGL_SIZE size;
XGL_UINT i;
/* request all queues */
info.queueRecordCount = gpu->queue_count;
info.pRequestedQueues = gpu->queue_reqs;
/* enable all extensions */
info.extensionCount = gpu->extension_count;
info.ppEnabledExtensionNames = gpu->extensions;
dev->gpu = gpu;
err = xglCreateDevice(gpu->obj, &info, &dev->obj);
if (err)
ERR_EXIT(err);
err = xglGetMemoryHeapCount(dev->obj, &dev->heap_count);
if (err)
ERR_EXIT(err);
dev->heap_props =
malloc(sizeof(dev->heap_props[0]) * dev->heap_count);
if (!dev->heap_props)
ERR_EXIT(XGL_ERROR_OUT_OF_MEMORY);
for (i = 0; i < dev->heap_count; i++) {
size = sizeof(dev->heap_props[0]);
err = xglGetMemoryHeapInfo(dev->obj, i,
XGL_INFO_TYPE_MEMORY_HEAP_PROPERTIES,
&size, &dev->heap_props[i]);
if (err || size != sizeof(dev->heap_props[0]))
ERR_EXIT(err);
}
}
void app_dev_destroy(struct app_dev *dev)
{
free(dev->heap_props);
xglDestroyDevice(dev->obj);
}
void app_gpu_init_extensions(struct app_gpu *gpu)
{
XGL_RESULT err;
XGL_UINT i;
static const XGL_CHAR *known_extensions[] = {
(const XGL_CHAR *) "XGL_WSI_X11",
};
for (i = 0; i < ARRAY_SIZE(known_extensions); i++) {
err = xglGetExtensionSupport(gpu->obj, known_extensions[i]);
if (!err)
gpu->extension_count++;
}
gpu->extensions =
malloc(sizeof(gpu->extensions[0]) * gpu->extension_count);
if (!gpu->extensions)
ERR_EXIT(XGL_ERROR_OUT_OF_MEMORY);
gpu->extension_count = 0;
for (i = 0; i < ARRAY_SIZE(known_extensions); i++) {
err = xglGetExtensionSupport(gpu->obj, known_extensions[i]);
if (!err)
gpu->extensions[gpu->extension_count++] = known_extensions[i];
}
}
static const char *xgl_qtype_string(XGL_QUEUE_TYPE qtype) {
switch (qtype) {
#define STR(r) case r: return #r
STR(XGL_QUEUE_TYPE_GRAPHICS);
STR(XGL_QUEUE_TYPE_COMPUTE);
STR(XGL_QUEUE_TYPE_DMA);
default: return "UNKNOWN_RESULT";
}
}
// TODO: May need to extend to more than one queue per type
void app_dev_init_queue(struct app_dev *dev, XGL_QUEUE_TYPE qtype)
{
XGL_RESULT err;
/* abort before we go past the end of our queue array */
assert(qtype < MAX_QUEUE_TYPES);
err = xglGetDeviceQueue(dev->obj, qtype, 0, &dev->queues[qtype]);
if (err) {
printf("xglGetDeviceQueue: %s queue #%d: Failed\n",
xgl_qtype_string(qtype), 0);
}
}
void app_gpu_init(struct app_gpu *gpu, XGL_UINT id, XGL_PHYSICAL_GPU obj)
{
XGL_SIZE size;
XGL_RESULT err;
int i;
memset(gpu, 0, sizeof(*gpu));
gpu->id = id;
gpu->obj = obj;
size = sizeof(gpu->props);
err = xglGetGpuInfo(gpu->obj,
XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES,
&size, &gpu->props);
if (err || size != sizeof(gpu->props))
ERR_EXIT(err);
size = sizeof(gpu->perf);
err = xglGetGpuInfo(gpu->obj,
XGL_INFO_TYPE_PHYSICAL_GPU_PERFORMANCE,
&size, &gpu->perf);
if (err || size != sizeof(gpu->perf))
ERR_EXIT(err);
/* get queue count */
err = xglGetGpuInfo(gpu->obj,
XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES,
&size, NULL);
if (err || size % sizeof(gpu->queue_props[0]))
ERR_EXIT(err);
gpu->queue_count = size / sizeof(gpu->queue_props[0]);
gpu->queue_props =
malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count);
size = sizeof(gpu->queue_props[0]) * gpu->queue_count;
if (!gpu->queue_props)
ERR_EXIT(XGL_ERROR_OUT_OF_MEMORY);
err = xglGetGpuInfo(gpu->obj,
XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES,
&size, gpu->queue_props);
if (err || size != sizeof(gpu->queue_props[0]) * gpu->queue_count)
ERR_EXIT(err);
/* set up queue requests */
size = sizeof(*gpu->queue_reqs) * gpu->queue_count;
gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count);
if (!gpu->queue_reqs)
ERR_EXIT(XGL_ERROR_OUT_OF_MEMORY);
for (i = 0; i < gpu->queue_count; i++) {
gpu->queue_reqs[i].queueNodeIndex = i;
gpu->queue_reqs[i].queueCount = gpu->queue_props[i].queueCount;
}
size = sizeof(gpu->memory_props);
err = xglGetGpuInfo(gpu->obj,
XGL_INFO_TYPE_PHYSICAL_GPU_MEMORY_PROPERTIES,
&size, &gpu->memory_props);
if (err || size != sizeof(gpu->memory_props))
ERR_EXIT(err);
app_gpu_init_extensions(gpu);
app_dev_init(&gpu->dev, gpu);
app_dev_init_formats(&gpu->dev);
}
void app_gpu_destroy(struct app_gpu *gpu)
{
app_dev_destroy(&gpu->dev);
free(gpu->extensions);
free(gpu->queue_reqs);
free(gpu->queue_props);
}