Compare commits

...

2 Commits

2 changed files with 42 additions and 21 deletions

View File

@ -4,15 +4,16 @@
*/ */
#version 450 #version 450
#extension GL_ARB_gpu_shader_fp64 : enable
#define MAXITER 1000 #define MAXITER 1000
layout(location = 0) out vec4 out_colour; layout(location = 0) out vec4 out_colour;
layout(push_constant) uniform Constants { layout(push_constant) uniform Constants {
vec2 img_size; dvec2 img_size;
vec2 shift; dvec2 shift;
float zoom; double zoom;
} params; } params;
vec2 ss_offsets[4] = vec2[]( vec2 ss_offsets[4] = vec2[](
@ -22,28 +23,31 @@ vec2 ss_offsets[4] = vec2[](
vec2( 0.25, 0.25) vec2( 0.25, 0.25)
); );
vec2 maptoz(vec2 xy) dvec2 maptoz(vec2 xy)
{ {
return params.zoom * ((xy / params.img_size.xy) * 4.0 - 2.0) + params.shift; dvec2 dxy = dvec2(xy);
dvec2 uv = ((dxy / params.img_size.xy) * 4.0LF - 2.0LF);
return params.zoom * uv + params.shift;
} }
float mandelbrot(vec2 c) { double mandelbrot(dvec2 c) {
vec2 z = vec2(0.0, 0.0); dvec2 z = dvec2(0.0LF, 0.0LF);
for (int i = 0; i < MAXITER; ++i) { for (int i = 0; i < MAXITER; ++i) {
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c; z = dvec2(z.x * z.x - z.y * z.y, 2.0LF * z.x * z.y) + c;
if (length(z) > 2.0) if (length(z) > 2.0LF)
return float(i) / float(MAXITER); return double(i) / double(MAXITER);
} }
return 0.0; return 0.0;
} }
vec3 colour(float i) { vec3 colour(double i) {
return vec3(i, i * i, i * i * i); float fi = float(i);
return vec3(fi, fi * fi, fi * fi * fi);
} }
void main() void main()
{ {
vec2 c; dvec2 c;
vec3 col = vec3(0.0, 0.0, 0.0); vec3 col = vec3(0.0, 0.0, 0.0);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
c = maptoz(gl_FragCoord.xy + ss_offsets[i]); c = maptoz(gl_FragCoord.xy + ss_offsets[i]);

33
main.c
View File

@ -15,6 +15,7 @@
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define CLAMP(x, min, max) MAX((min), MIN(x, (max))) #define CLAMP(x, min, max) MAX((min), MIN(x, (max)))
#define PHYSICAL_DEV_BUFFER_SIZE 8
#define QUEUE_FAMILY_PROP_BUFFER_SIZE 16 #define QUEUE_FAMILY_PROP_BUFFER_SIZE 16
#define EXT_PROP_BUFFER_SIZE 256 #define EXT_PROP_BUFFER_SIZE 256
#define SURFACE_FMT_BUFFER_SIZE 64 #define SURFACE_FMT_BUFFER_SIZE 64
@ -24,11 +25,11 @@
#define MAX_SHADER_SIZE (4 * 1024) #define MAX_SHADER_SIZE (4 * 1024)
typedef struct { typedef struct {
float width, height; double width, height;
struct { struct {
float x, y; double x, y;
} shift; } shift;
float zoom; double zoom;
} params_t; } params_t;
static const char *layers[] = { "VK_LAYER_KHRONOS_validation" }; static const char *layers[] = { "VK_LAYER_KHRONOS_validation" };
@ -96,10 +97,22 @@ int main(void)
assert(result == VK_SUCCESS); assert(result == VK_SUCCESS);
// Select a physical device // Select a physical device
VkPhysicalDevice physical_devs[PHYSICAL_DEV_BUFFER_SIZE];
uint32_t dev_count = PHYSICAL_DEV_BUFFER_SIZE;
result = vkEnumeratePhysicalDevices(inst, &dev_count, physical_devs);
assert(result == VK_SUCCESS);
bool found_physical_dev = false;
VkPhysicalDevice physical_dev; VkPhysicalDevice physical_dev;
uint32_t dev_count = 1; for (unsigned i = 0; i < dev_count; ++i) {
result = vkEnumeratePhysicalDevices(inst, &dev_count, &physical_dev); // Check that the device supports double precision
assert(result == VK_SUCCESS || result == VK_INCOMPLETE); VkPhysicalDeviceFeatures features;
vkGetPhysicalDeviceFeatures(physical_devs[i], &features);
if (features.shaderFloat64) {
physical_dev = physical_devs[i];
found_physical_dev = true;
}
}
assert(found_physical_dev);
// Select queue family // Select queue family
uint32_t queue_family_count = QUEUE_FAMILY_PROP_BUFFER_SIZE; uint32_t queue_family_count = QUEUE_FAMILY_PROP_BUFFER_SIZE;
@ -131,12 +144,16 @@ int main(void)
.queueCount = 1, .queueCount = 1,
.pQueuePriorities = &queue_priority, .pQueuePriorities = &queue_priority,
}; };
const VkPhysicalDeviceFeatures enabled_features = {
.shaderFloat64 = VK_TRUE,
};
const VkDeviceCreateInfo dev_create_info = { const VkDeviceCreateInfo dev_create_info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pQueueCreateInfos = &queue_create_info, .pQueueCreateInfos = &queue_create_info,
.queueCreateInfoCount = 1, .queueCreateInfoCount = 1,
.enabledExtensionCount = 1, .enabledExtensionCount = 1,
.ppEnabledExtensionNames = &swapchain_ext_name, .ppEnabledExtensionNames = &swapchain_ext_name,
.pEnabledFeatures = &enabled_features,
}; };
VkDevice dev; VkDevice dev;
result = vkCreateDevice(physical_dev, &dev_create_info, NULL, &dev); result = vkCreateDevice(physical_dev, &dev_create_info, NULL, &dev);
@ -462,8 +479,8 @@ int main(void)
assert(result == VK_SUCCESS); assert(result == VK_SUCCESS);
params_t params = { params_t params = {
.width = (float)swapchain_extent.width, .width = (double)swapchain_extent.width,
.height = (float)swapchain_extent.height, .height = (double)swapchain_extent.height,
.shift = { .shift = {
.x = -0.743643887037158704752191506114774, .x = -0.743643887037158704752191506114774,
.y = 0.131825904205311970493132056385139, .y = 0.131825904205311970493132056385139,