anv: set maxFragmentDualSrcAttachments to 1
[mesa.git] / src / amd / vulkan / radv_device.c
index 6e06863f8eadab1ed0eb56c5d1714c519c3edd77..5a7ed045ca3ad765babbaf25846a5b988c509a15 100644 (file)
  * IN THE SOFTWARE.
  */
 
+#include <dlfcn.h>
 #include <stdbool.h>
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/stat.h>
 #include "radv_private.h"
 #include "util/strtod.h"
 
 #include "ac_llvm_util.h"
 #include "vk_format.h"
 #include "sid.h"
-#include "radv_timestamp.h"
 #include "util/debug.h"
 struct radv_dispatch_table dtable;
 
-struct radv_fence {
-       struct radeon_winsys_fence *fence;
-       bool submitted;
-       bool signalled;
-};
+static int
+radv_get_function_timestamp(void *ptr, uint32_t* timestamp)
+{
+       Dl_info info;
+       struct stat st;
+       if (!dladdr(ptr, &info) || !info.dli_fname) {
+               return -1;
+       }
+       if (stat(info.dli_fname, &st)) {
+               return -1;
+       }
+       *timestamp = st.st_mtim.tv_sec;
+       return 0;
+}
+
+static int
+radv_device_get_cache_uuid(enum radeon_family family, void *uuid)
+{
+       uint32_t mesa_timestamp, llvm_timestamp;
+       uint16_t f = family;
+       memset(uuid, 0, VK_UUID_SIZE);
+       if (radv_get_function_timestamp(radv_device_get_cache_uuid, &mesa_timestamp) ||
+           radv_get_function_timestamp(LLVMInitializeAMDGPUTargetInfo, &llvm_timestamp))
+               return -1;
+
+       memcpy(uuid, &mesa_timestamp, 4);
+       memcpy((char*)uuid + 4, &llvm_timestamp, 4);
+       memcpy((char*)uuid + 8, &f, 2);
+       snprintf((char*)uuid + 10, VK_UUID_SIZE - 10, "radv");
+       return 0;
+}
 
 static VkResult
 radv_physical_device_init(struct radv_physical_device *device,
@@ -95,8 +122,17 @@ radv_physical_device_init(struct radv_physical_device *device,
                goto fail;
        }
 
+       if (radv_device_get_cache_uuid(device->rad_info.family, device->uuid)) {
+               radv_finish_wsi(device);
+               device->ws->destroy(device->ws);
+               result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                                  "cannot generate UUID");
+               goto fail;
+       }
+
        fprintf(stderr, "WARNING: radv is not a conformant vulkan implementation, testing use only.\n");
        device->name = device->rad_info.name;
+       close(fd);
        return VK_SUCCESS;
 
 fail:
@@ -119,21 +155,39 @@ static const VkExtensionProperties global_extensions[] = {
 #ifdef VK_USE_PLATFORM_XCB_KHR
        {
                .extensionName = VK_KHR_XCB_SURFACE_EXTENSION_NAME,
-               .specVersion = 5,
+               .specVersion = 6,
+       },
+#endif
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+       {
+               .extensionName = VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
+               .specVersion = 6,
        },
 #endif
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
        {
                .extensionName = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
-               .specVersion = 4,
+               .specVersion = 5,
        },
 #endif
 };
 
 static const VkExtensionProperties device_extensions[] = {
+       {
+               .extensionName = VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
+               .specVersion = 1,
+       },
        {
                .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME,
-               .specVersion = 67,
+               .specVersion = 68,
+       },
+       {
+               .extensionName = VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME,
+               .specVersion = 1,
+       },
+       {
+               .extensionName = VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME,
+               .specVersion = 1,
        },
 };
 
@@ -203,7 +257,7 @@ VkResult radv_CreateInstance(
                        return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
        }
 
-       instance = radv_alloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
+       instance = vk_alloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
                               VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (!instance)
                return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -243,7 +297,7 @@ void radv_DestroyInstance(
 
        _mesa_locale_fini();
 
-       radv_free(&instance->alloc, instance);
+       vk_free(&instance->alloc, instance);
 }
 
 VkResult radv_EnumeratePhysicalDevices(
@@ -295,6 +349,8 @@ VkResult radv_EnumeratePhysicalDevices(
        } else if (*pPhysicalDeviceCount >= 1) {
                pPhysicalDevices[0] = radv_physical_device_to_handle(&instance->physicalDevice);
                *pPhysicalDeviceCount = 1;
+       } else if (*pPhysicalDeviceCount < instance->physicalDeviceCount) {
+               return VK_INCOMPLETE;
        } else {
                *pPhysicalDeviceCount = 0;
        }
@@ -330,7 +386,7 @@ void radv_GetPhysicalDeviceFeatures(
                .largePoints                              = true,
                .alphaToOne                               = true,
                .multiViewport                            = false,
-               .samplerAnisotropy                        = false, /* FINISHME */
+               .samplerAnisotropy                        = true,
                .textureCompressionETC2                   = false,
                .textureCompressionASTC_LDR               = false,
                .textureCompressionBC                     = true,
@@ -359,13 +415,6 @@ void radv_GetPhysicalDeviceFeatures(
        };
 }
 
-void
-radv_device_get_cache_uuid(void *uuid)
-{
-       memset(uuid, 0, VK_UUID_SIZE);
-       snprintf(uuid, VK_UUID_SIZE, "radv-%s", RADV_TIMESTAMP);
-}
-
 void radv_GetPhysicalDeviceProperties(
        VkPhysicalDevice                            physicalDevice,
        VkPhysicalDeviceProperties*                 pProperties)
@@ -422,7 +471,7 @@ void radv_GetPhysicalDeviceProperties(
                .maxGeometryTotalOutputComponents         = 1024,
                .maxFragmentInputComponents               = 128,
                .maxFragmentOutputAttachments             = 8,
-               .maxFragmentDualSrcAttachments            = 2,
+               .maxFragmentDualSrcAttachments            = 1,
                .maxFragmentCombinedOutputResources       = 8,
                .maxComputeSharedMemorySize               = 32768,
                .maxComputeWorkGroupCount                 = { 65535, 65535, 65535 },
@@ -496,7 +545,7 @@ void radv_GetPhysicalDeviceProperties(
        };
 
        strcpy(pProperties->deviceName, pdevice->name);
-       radv_device_get_cache_uuid(pProperties->pipelineCacheUUID);
+       memcpy(pProperties->pipelineCacheUUID, pdevice->uuid, VK_UUID_SIZE);
 }
 
 void radv_GetPhysicalDeviceQueueFamilyProperties(
@@ -526,42 +575,50 @@ void radv_GetPhysicalDeviceMemoryProperties(
 {
        RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
 
-       pMemoryProperties->memoryTypeCount = 3;
+       pMemoryProperties->memoryTypeCount = 4;
        pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
                .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
                .heapIndex = 0,
        };
        pMemoryProperties->memoryTypes[1] = (VkMemoryType) {
+               .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+               VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+               .heapIndex = 2,
+       };
+       pMemoryProperties->memoryTypes[2] = (VkMemoryType) {
                .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-               .heapIndex = 0,
+               .heapIndex = 1,
        };
-       pMemoryProperties->memoryTypes[2] = (VkMemoryType) {
-               .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|
+       pMemoryProperties->memoryTypes[3] = (VkMemoryType) {
+               .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
                VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
-               .heapIndex = 1,
+               .heapIndex = 2,
        };
 
-       pMemoryProperties->memoryHeapCount = 2;
+       pMemoryProperties->memoryHeapCount = 3;
        pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
-               .size = physical_device->rad_info.vram_size,
+               .size = physical_device->rad_info.vram_size -
+                               physical_device->rad_info.visible_vram_size,
                .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
        };
        pMemoryProperties->memoryHeaps[1] = (VkMemoryHeap) {
+               .size = physical_device->rad_info.visible_vram_size,
+               .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
+       };
+       pMemoryProperties->memoryHeaps[2] = (VkMemoryHeap) {
                .size = physical_device->rad_info.gart_size,
                .flags = 0,
        };
 }
 
-static VkResult
+static void
 radv_queue_init(struct radv_device *device, struct radv_queue *queue)
 {
        queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
        queue->device = device;
-
-       return VK_SUCCESS;
 }
 
 static void
@@ -592,7 +649,7 @@ VkResult radv_CreateDevice(
                        return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
        }
 
-       device = radv_alloc2(&physical_device->instance->alloc, pAllocator,
+       device = vk_alloc2(&physical_device->instance->alloc, pAllocator,
                             sizeof(*device), 8,
                             VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
        if (!device)
@@ -622,6 +679,7 @@ VkResult radv_CreateDevice(
        }
        device->allow_fast_clears = env_var_as_boolean("RADV_FAST_CLEARS", false);
        device->allow_dcc = !env_var_as_boolean("RADV_DCC_DISABLE", false);
+       device->shader_stats_dump = env_var_as_boolean("RADV_SHADER_STATS", false);
 
        if (device->allow_fast_clears && device->allow_dcc)
                radv_finishme("DCC fast clears have not been tested\n");
@@ -635,7 +693,7 @@ VkResult radv_CreateDevice(
        *pDevice = radv_device_to_handle(device);
        return VK_SUCCESS;
 fail_free:
-       radv_free(&device->alloc, device);
+       vk_free(&device->alloc, device);
        return result;
 }
 
@@ -649,7 +707,7 @@ void radv_DestroyDevice(
        radv_queue_finish(&device->queue);
        radv_device_finish_meta(device);
 
-       radv_free(&device->alloc, device);
+       vk_free(&device->alloc, device);
 }
 
 VkResult radv_EnumerateInstanceExtensionProperties(
@@ -657,17 +715,15 @@ VkResult radv_EnumerateInstanceExtensionProperties(
        uint32_t*                                   pPropertyCount,
        VkExtensionProperties*                      pProperties)
 {
-       unsigned i;
        if (pProperties == NULL) {
                *pPropertyCount = ARRAY_SIZE(global_extensions);
                return VK_SUCCESS;
        }
 
-       for (i = 0; i < *pPropertyCount; i++)
-               memcpy(&pProperties[i], &global_extensions[i], sizeof(VkExtensionProperties));
+       *pPropertyCount = MIN2(*pPropertyCount, ARRAY_SIZE(global_extensions));
+       typed_memcpy(pProperties, global_extensions, *pPropertyCount);
 
-       *pPropertyCount = i;
-       if (i < ARRAY_SIZE(global_extensions))
+       if (*pPropertyCount < ARRAY_SIZE(global_extensions))
                return VK_INCOMPLETE;
 
        return VK_SUCCESS;
@@ -679,19 +735,17 @@ VkResult radv_EnumerateDeviceExtensionProperties(
        uint32_t*                                   pPropertyCount,
        VkExtensionProperties*                      pProperties)
 {
-       unsigned i;
-
        if (pProperties == NULL) {
                *pPropertyCount = ARRAY_SIZE(device_extensions);
                return VK_SUCCESS;
        }
 
-       for (i = 0; i < *pPropertyCount; i++)
-               memcpy(&pProperties[i], &device_extensions[i], sizeof(VkExtensionProperties));
+       *pPropertyCount = MIN2(*pPropertyCount, ARRAY_SIZE(device_extensions));
+       typed_memcpy(pProperties, device_extensions, *pPropertyCount);
 
-       *pPropertyCount = i;
-       if (i < ARRAY_SIZE(device_extensions))
+       if (*pPropertyCount < ARRAY_SIZE(device_extensions))
                return VK_INCOMPLETE;
+
        return VK_SUCCESS;
 }
 
@@ -852,13 +906,13 @@ VkResult radv_AllocateMemory(
                return VK_SUCCESS;
        }
 
-       mem = radv_alloc2(&device->alloc, pAllocator, sizeof(*mem), 8,
+       mem = vk_alloc2(&device->alloc, pAllocator, sizeof(*mem), 8,
                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
        if (mem == NULL)
                return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
        uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
-       if (pAllocateInfo->memoryTypeIndex == 2)
+       if (pAllocateInfo->memoryTypeIndex == 1 || pAllocateInfo->memoryTypeIndex == 3)
                domain = RADEON_DOMAIN_GTT;
        else
                domain = RADEON_DOMAIN_VRAM;
@@ -867,6 +921,10 @@ VkResult radv_AllocateMemory(
                flags |= RADEON_FLAG_NO_CPU_ACCESS;
        else
                flags |= RADEON_FLAG_CPU_ACCESS;
+
+       if (pAllocateInfo->memoryTypeIndex == 1)
+               flags |= RADEON_FLAG_GTT_WC;
+
        mem->bo = device->ws->buffer_create(device->ws, alloc_size, 32768,
                                               domain, flags);
 
@@ -881,7 +939,7 @@ VkResult radv_AllocateMemory(
        return VK_SUCCESS;
 
 fail:
-       radv_free2(&device->alloc, pAllocator, mem);
+       vk_free2(&device->alloc, pAllocator, mem);
 
        return result;
 }
@@ -900,7 +958,7 @@ void radv_FreeMemory(
        device->ws->buffer_destroy(mem->bo);
        mem->bo = NULL;
 
-       radv_free2(&device->alloc, pAllocator, mem);
+       vk_free2(&device->alloc, pAllocator, mem);
 }
 
 VkResult radv_MapMemory(
@@ -1074,7 +1132,7 @@ VkResult radv_CreateFence(
        VkFence*                                    pFence)
 {
        RADV_FROM_HANDLE(radv_device, device, _device);
-       struct radv_fence *fence = radv_alloc2(&device->alloc, pAllocator,
+       struct radv_fence *fence = vk_alloc2(&device->alloc, pAllocator,
                                               sizeof(*fence), 8,
                                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
 
@@ -1103,7 +1161,7 @@ void radv_DestroyFence(
        if (!fence)
                return;
        device->ws->destroy_fence(fence->fence);
-       radv_free2(&device->alloc, pAllocator, fence);
+       vk_free2(&device->alloc, pAllocator, fence);
 }
 
 static uint64_t radv_get_absolute_timeout(uint64_t timeout)
@@ -1170,6 +1228,8 @@ VkResult radv_GetFenceStatus(VkDevice _device, VkFence _fence)
        RADV_FROM_HANDLE(radv_device, device, _device);
        RADV_FROM_HANDLE(radv_fence, fence, _fence);
 
+       if (fence->signalled)
+               return VK_SUCCESS;
        if (!fence->submitted)
                return VK_NOT_READY;
 
@@ -1211,7 +1271,7 @@ VkResult radv_CreateEvent(
        VkEvent*                                    pEvent)
 {
        RADV_FROM_HANDLE(radv_device, device, _device);
-       struct radv_event *event = radv_alloc2(&device->alloc, pAllocator,
+       struct radv_event *event = vk_alloc2(&device->alloc, pAllocator,
                                               sizeof(*event), 8,
                                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
 
@@ -1222,7 +1282,7 @@ VkResult radv_CreateEvent(
                                              RADEON_DOMAIN_GTT,
                                              RADEON_FLAG_CPU_ACCESS);
        if (!event->bo) {
-               radv_free2(&device->alloc, pAllocator, event);
+               vk_free2(&device->alloc, pAllocator, event);
                return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }
 
@@ -1244,7 +1304,7 @@ void radv_DestroyEvent(
        if (!event)
                return;
        device->ws->buffer_destroy(event->bo);
-       radv_free2(&device->alloc, pAllocator, event);
+       vk_free2(&device->alloc, pAllocator, event);
 }
 
 VkResult radv_GetEventStatus(
@@ -1289,7 +1349,7 @@ VkResult radv_CreateBuffer(
 
        assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
 
-       buffer = radv_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,
+       buffer = vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,
                             VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
        if (buffer == NULL)
                return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -1315,7 +1375,7 @@ void radv_DestroyBuffer(
        if (!buffer)
                return;
 
-       radv_free2(&device->alloc, pAllocator, buffer);
+       vk_free2(&device->alloc, pAllocator, buffer);
 }
 
 static inline unsigned
@@ -1600,7 +1660,7 @@ VkResult radv_CreateFramebuffer(
 
        size_t size = sizeof(*framebuffer) +
                sizeof(struct radv_attachment_info) * pCreateInfo->attachmentCount;
-       framebuffer = radv_alloc2(&device->alloc, pAllocator, size, 8,
+       framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8,
                                  VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
        if (framebuffer == NULL)
                return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -1635,7 +1695,7 @@ void radv_DestroyFramebuffer(
 
        if (!fb)
                return;
-       radv_free2(&device->alloc, pAllocator, fb);
+       vk_free2(&device->alloc, pAllocator, fb);
 }
 
 static unsigned radv_tex_wrap(VkSamplerAddressMode address_mode)
@@ -1732,15 +1792,29 @@ radv_tex_bordercolor(VkBorderColor bcolor)
        return 0;
 }
 
+static unsigned
+radv_tex_aniso_filter(unsigned filter)
+{
+       if (filter < 2)
+               return 0;
+       if (filter < 4)
+               return 1;
+       if (filter < 8)
+               return 2;
+       if (filter < 16)
+               return 3;
+       return 4;
+}
+
 static void
 radv_init_sampler(struct radv_device *device,
                  struct radv_sampler *sampler,
                  const VkSamplerCreateInfo *pCreateInfo)
 {
-       uint32_t max_aniso = 0;
-       uint32_t max_aniso_ratio = 0;//TODO
-       bool is_vi;
-       is_vi = (device->instance->physicalDevice.rad_info.chip_class >= VI);
+       uint32_t max_aniso = pCreateInfo->anisotropyEnable && pCreateInfo->maxAnisotropy > 1.0 ?
+                                       (uint32_t) pCreateInfo->maxAnisotropy : 0;
+       uint32_t max_aniso_ratio = radv_tex_aniso_filter(max_aniso);
+       bool is_vi = (device->instance->physicalDevice.rad_info.chip_class >= VI);
 
        sampler->state[0] = (S_008F30_CLAMP_X(radv_tex_wrap(pCreateInfo->addressModeU)) |
                             S_008F30_CLAMP_Y(radv_tex_wrap(pCreateInfo->addressModeV)) |
@@ -1748,10 +1822,13 @@ radv_init_sampler(struct radv_device *device,
                             S_008F30_MAX_ANISO_RATIO(max_aniso_ratio) |
                             S_008F30_DEPTH_COMPARE_FUNC(radv_tex_compare(pCreateInfo->compareOp)) |
                             S_008F30_FORCE_UNNORMALIZED(pCreateInfo->unnormalizedCoordinates ? 1 : 0) |
+                            S_008F30_ANISO_THRESHOLD(max_aniso_ratio >> 1) |
+                            S_008F30_ANISO_BIAS(max_aniso_ratio) |
                             S_008F30_DISABLE_CUBE_WRAP(0) |
                             S_008F30_COMPAT_MODE(is_vi));
        sampler->state[1] = (S_008F34_MIN_LOD(S_FIXED(CLAMP(pCreateInfo->minLod, 0, 15), 8)) |
-                            S_008F34_MAX_LOD(S_FIXED(CLAMP(pCreateInfo->maxLod, 0, 15), 8)));
+                            S_008F34_MAX_LOD(S_FIXED(CLAMP(pCreateInfo->maxLod, 0, 15), 8)) |
+                            S_008F34_PERF_MIP(max_aniso_ratio ? max_aniso_ratio + 6 : 0));
        sampler->state[2] = (S_008F38_LOD_BIAS(S_FIXED(CLAMP(pCreateInfo->mipLodBias, -16, 16), 8)) |
                             S_008F38_XY_MAG_FILTER(radv_tex_filter(pCreateInfo->magFilter, max_aniso)) |
                             S_008F38_XY_MIN_FILTER(radv_tex_filter(pCreateInfo->minFilter, max_aniso)) |
@@ -1775,7 +1852,7 @@ VkResult radv_CreateSampler(
 
        assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
 
-       sampler = radv_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
+       sampler = vk_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
                              VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
        if (!sampler)
                return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -1796,5 +1873,5 @@ void radv_DestroySampler(
 
        if (!sampler)
                return;
-       radv_free2(&device->alloc, pAllocator, sampler);
+       vk_free2(&device->alloc, pAllocator, sampler);
 }