Compare commits

...

2 Commits

2 changed files with 42 additions and 21 deletions

View File

@ -4,15 +4,16 @@
*/
#version 450
#extension GL_ARB_gpu_shader_fp64 : enable
#define MAXITER 1000
layout(location = 0) out vec4 out_colour;
layout(push_constant) uniform Constants {
vec2 img_size;
vec2 shift;
float zoom;
dvec2 img_size;
dvec2 shift;
double zoom;
} params;
vec2 ss_offsets[4] = vec2[](
@ -22,28 +23,31 @@ vec2 ss_offsets[4] = vec2[](
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) {
vec2 z = vec2(0.0, 0.0);
double mandelbrot(dvec2 c) {
dvec2 z = dvec2(0.0LF, 0.0LF);
for (int i = 0; i < MAXITER; ++i) {
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
if (length(z) > 2.0)
return float(i) / float(MAXITER);
z = dvec2(z.x * z.x - z.y * z.y, 2.0LF * z.x * z.y) + c;
if (length(z) > 2.0LF)
return double(i) / double(MAXITER);
}
return 0.0;
}
vec3 colour(float i) {
return vec3(i, i * i, i * i * i);
vec3 colour(double i) {
float fi = float(i);
return vec3(fi, fi * fi, fi * fi * fi);
}
void main()
{
vec2 c;
dvec2 c;
vec3 col = vec3(0.0, 0.0, 0.0);
for (int i = 0; i < 4; ++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 CLAMP(x, min, max) MAX((min), MIN(x, (max)))
#define PHYSICAL_DEV_BUFFER_SIZE 8
#define QUEUE_FAMILY_PROP_BUFFER_SIZE 16
#define EXT_PROP_BUFFER_SIZE 256
#define SURFACE_FMT_BUFFER_SIZE 64
@ -24,11 +25,11 @@
#define MAX_SHADER_SIZE (4 * 1024)
typedef struct {
float width, height;
double width, height;
struct {
float x, y;
double x, y;
} shift;
float zoom;
double zoom;
} params_t;
static const char *layers[] = { "VK_LAYER_KHRONOS_validation" };
@ -96,10 +97,22 @@ int main(void)
assert(result == VK_SUCCESS);
// 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;
uint32_t dev_count = 1;
result = vkEnumeratePhysicalDevices(inst, &dev_count, &physical_dev);
assert(result == VK_SUCCESS || result == VK_INCOMPLETE);
for (unsigned i = 0; i < dev_count; ++i) {
// Check that the device supports double precision
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
uint32_t queue_family_count = QUEUE_FAMILY_PROP_BUFFER_SIZE;
@ -131,12 +144,16 @@ int main(void)
.queueCount = 1,
.pQueuePriorities = &queue_priority,
};
const VkPhysicalDeviceFeatures enabled_features = {
.shaderFloat64 = VK_TRUE,
};
const VkDeviceCreateInfo dev_create_info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pQueueCreateInfos = &queue_create_info,
.queueCreateInfoCount = 1,
.enabledExtensionCount = 1,
.ppEnabledExtensionNames = &swapchain_ext_name,
.pEnabledFeatures = &enabled_features,
};
VkDevice dev;
result = vkCreateDevice(physical_dev, &dev_create_info, NULL, &dev);
@ -462,8 +479,8 @@ int main(void)
assert(result == VK_SUCCESS);
params_t params = {
.width = (float)swapchain_extent.width,
.height = (float)swapchain_extent.height,
.width = (double)swapchain_extent.width,
.height = (double)swapchain_extent.height,
.shift = {
.x = -0.743643887037158704752191506114774,
.y = 0.131825904205311970493132056385139,