[CDR 2017-2022] Потестируйте компоновщик

fersat

Участник
Топикстартер
Сообщения
50
Реакции
29
Здравствуйте. Написал экспериментальный компоновщик на шейдерах. Потестировал на встройке Ryzen 9 7900X - видеокарта не справляется с объектами большой площади, пришлось даже изменить алгоритм ухудшив результат, но улучшив при этом производительность. Хочу узнать будет ли оно работать на видеокартах NVIDIA и какую производительность покажет на нормальных игровых картах. Во вложении архив с тестовым набором кривых и компоновщиком. У меня на компоновку этого набора с параметрами по-умолчанию уходит 38 сек, на более слабых видеокартах может сработать TDR.
demo.gif
 

Вложения

Последнее редактирование:
  • Ого!
Реакции: ~RA~
Поздравляю! Вы изобрели велосипед eCut! 'congrats'
 


В частности, Corel-2022, ноут на i7 c win11 и 16 Гб оперативы, был так наглухо подвешен, что пришлось вырубать по питанию, чего с ним отродясь не случалось.
 
  • Спасибо
Реакции: _MBK_
ноут на i7 c win11 и 16 Гб оперативы
Так в ноуте есть что-то из этого?
Хочу узнать будет ли оно работать на видеокартах NVIDIA и какую производительность покажет на нормальных игровых картах

на более слабых видеокартах может сработать TDR
 
Последнее редактирование:
В частности, Corel-2022, ноут на i7 c win11 и 16 Гб оперативы, был так наглухо подвешен, что пришлось вырубать по питанию, чего с ним отродясь не случалось.
Спасибо, только рука потянулась к ноуту попробовать, ты меня удержал ;)
 

Jeine



На windows 7 нет такого понятия как TDR и шейдер будет работать до победного. На Win8 и выше если шейдер не отработал за 2 секунды (по умолчанию такой таймаут), то он считается зависшим и завершается. Попробуйте уменьшить размер кривых (скажем так 20% от начального). Там квадратичная зависимость производительности от площади фигуры. Ещё уменьшение количества вращений кратно ускоряет процесс.
 
Посмотрел на иконку - сперва решил, что Zest вернулся... ;)
А так, в принципе, в качестве лабораторки по OpenGL, сойдет, даже вполне потянет на статью на каком нибудь хабре ;)
Код:
in vec4 pos;
void main() {
    gl_Position = pos;
}
#version 460
const uint MAX_ROTATIONS_LEVEL = 6;
const uint MAX_ROTATIONS = 1 << MAX_ROTATIONS_LEVEL;
layout(binding = 0) buffer SSBO0 {
    ivec4 DistanceMap[MAX_ROTATIONS * 2];
    int HeightMap[];
};
in GS_OUT {
    vec2 TexCoord;
}
gs_out;
out vec4 Color;
layout(location = 0) uniform int ScreenWidth;
uniform sampler2D image;
void main() {
    if(texture(image, gs_out.TexCoord).r > 0) {
        atomicMax(HeightMap[gl_PrimitiveID * ScreenWidth + int(gl_FragCoord.x)], int(gl_FragCoord.y));
        atomicMax(DistanceMap[gl_PrimitiveID].x, (int(gl_FragCoord.y) << 16) + int(gl_FragCoord.x));
        atomicMin(DistanceMap[gl_PrimitiveID].z, (int(-gl_FragCoord.y) << 16) + int(gl_FragCoord.x));
    }
}
#version 460
const uint MAX_ROTATIONS_LEVEL = 6;
const uint MAX_ROTATIONS = 1 << MAX_ROTATIONS_LEVEL;
const vec2 center = vec2(0.5, 0.25);
layout(points, invocations = MAX_ROTATIONS) in;
layout(triangle_strip, max_vertices = 4) out;
out GS_OUT {
    vec2 TexCoord;
}
gs_out;
void main() {
    float a = 6.283185307179586476925286766559 / MAX_ROTATIONS * gl_InvocationID;
    mat4 RotMat = mat4(cos(a), -sin(a), 0.0, 0.0, sin(a), cos(a), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
    gl_PrimitiveID = gl_InvocationID;
    gl_Position = vec4(-gl_in[0].gl_Position.x, gl_in[0].gl_Position.y, 0.0, 1.0) * RotMat;
    gs_out.TexCoord = vec2(-gl_in[0].gl_Position.z, gl_in[0].gl_Position.w) + center;
    EmitVertex();
    gl_Position = vec4(gl_in[0].gl_Position.xy, 0.0, 1.0) * RotMat;
    gs_out.TexCoord = gl_in[0].gl_Position.zw + center;
    EmitVertex();
    gl_Position = vec4(-gl_in[0].gl_Position.xy, 0.0, 1.0) * RotMat;
    gs_out.TexCoord = center - gl_in[0].gl_Position.zw;
    EmitVertex();
    gl_Position = vec4(gl_in[0].gl_Position.x, -gl_in[0].gl_Position.y, 0.0, 1.0) * RotMat;
    gs_out.TexCoord = vec2(gl_in[0].gl_Position.z, -gl_in[0].gl_Position.w) + center;
    EmitVertex();
    EndPrimitive();
}
#version 460
const uint MAX_DIST = 50;
const uint MAX_ROTATIONS_LEVEL = 6;
const uint MAX_ROTATIONS = 1 << MAX_ROTATIONS_LEVEL;
const uint DIST_TOP = (MAX_ROTATIONS * 0) >> 2;
const uint DIST_RIGHT = (MAX_ROTATIONS * 1) >> 2;
const uint DIST_BOTTOM = (MAX_ROTATIONS * 2) >> 2;
const uint DIST_LEFT = (MAX_ROTATIONS * 3) >> 2;
layout(local_size_z = MAX_ROTATIONS) in;
layout(binding = 0) buffer SSBO0 {
    ivec4 DistanceMap[MAX_ROTATIONS * 2];
    uint HeightMap[];
};
layout(binding = 1) buffer SSBO1 {
    uint PlacementMap[];
};
layout(binding = 2) buffer SSBO2 {
    uint SheetWidth, HeightMapWidth, Rotations, reserved;
    uint SheetHeightMap[10000 + MAX_DIST];
    uvec2 NFP[];
};
void main() {
    uint i, j, k;
    if(gl_LocalInvocationID.z >> Rotations == 0) {
        uint angle = gl_LocalInvocationID.z << (MAX_ROTATIONS_LEVEL - Rotations);
        uint n = (gl_GlobalInvocationID.x << Rotations) + gl_LocalInvocationID.z;
        if(PlacementMap[n] == 0) {
            uvec2 curPlace = uvec2(NFP[gl_GlobalInvocationID.x].x & 0xFFFF, NFP[gl_GlobalInvocationID.x].x >> 16);
            switch(NFP[gl_GlobalInvocationID.x].y) {
                case 0:
                    curPlace = uvec2(curPlace.x, curPlace.y - (DistanceMap[angle + DIST_LEFT].z + DistanceMap[angle + DIST_BOTTOM].y));
                    break;
                case 1:
                    curPlace = uvec2(curPlace.x + (DistanceMap[angle + DIST_BOTTOM].x - DistanceMap[angle + DIST_LEFT].y), curPlace.y);
                    break;
                case 2:
                    curPlace = curPlace.xy - uvec2(DistanceMap[angle + DIST_RIGHT].y + DistanceMap[angle + DIST_LEFT].y, DistanceMap[angle + DIST_BOTTOM].y - DistanceMap[angle + DIST_RIGHT].x);
                    break;
            }
            uint Area = 0;
            for(i = 0; i < curPlace.x; i++) Area += SheetHeightMap[i];
            i = HeightMapWidth * angle;
            uint len = HeightMap[i] + curPlace.x;
            for(j = curPlace.x, k = i + 1; j < len; j++, k++) Area += max(SheetHeightMap[j], HeightMap[k] + curPlace.y);
            for(j = len; j < SheetWidth; j++) Area += SheetHeightMap[j];
            PlacementMap[n] = Area;
        }
    }
}
#version 460 in vec4 Pos;
void main() {
    gl_Position = vec4(Pos.xy, gl_VertexID, Pos.z);
}
#version 460 in GS_OUT {
    vec2 TexCoord;
}
gs_out;
layout(binding = 0) uniform sampler2D image;
layout(binding = 1) uniform sampler2DRect back;
layout(binding = 1) buffer SSBO1 {
    uint PlacementMap[];
};
void main() {
    if((texture(image, gs_out.TexCoord.xy).r * texture(back, gl_FragCoord.xy).r != 0)) {
        PlacementMap[gl_PrimitiveID] = 0xFFFFFFFF;
    }
}
#version 460
const uint MAX_ROTATIONS_LEVEL = 6;
const uint MAX_ROTATIONS = 1 << MAX_ROTATIONS_LEVEL;
const uint DIST_TOP = (MAX_ROTATIONS * 0) >> 2;
const uint DIST_RIGHT = (MAX_ROTATIONS * 1) >> 2;
const uint DIST_BOTTOM = (MAX_ROTATIONS * 2) >> 2;
const uint DIST_LEFT = (MAX_ROTATIONS * 3) >> 2;
layout(binding = 0) buffer SSBO0 {
    ivec4 DistanceMap[MAX_ROTATIONS * 2];
};
layout(binding = 1) buffer SSBO1 {
    uint PlacementMap[];
};
layout(binding = 2) buffer SSBO2 {
    uint FrameBuffer[];
};
layout(points, invocations = MAX_ROTATIONS) in;
layout(triangle_strip, max_vertices = 4) out;
out GS_OUT {
    vec2 TexCoord;
}
gs_out;
layout(location = 0) uniform vec4 Param;
layout(location = 1) uniform int Rotations;
void main() {
    const vec2 Center = vec2(0.5, 0.25);
    const float PI = 3.1415926535897932384626433832795;
    if(gl_InvocationID >> Rotations == 0) {
        uint i = gl_InvocationID << (MAX_ROTATIONS_LEVEL - Rotations);
        float a = i * (PI * 2) / MAX_ROTATIONS;
        ivec4 top = DistanceMap[i + DIST_TOP];
        ivec4 right = DistanceMap[i + DIST_RIGHT];
        ivec4 bottom = DistanceMap[i + DIST_BOTTOM];
        ivec4 left = DistanceMap[i + DIST_LEFT];
        ivec2 pos;
        switch(int(gl_in[0].gl_Position.w)) {
            case 0:
                pos = ivec2(gl_in[0].gl_Position.xy) - ivec2(0, left.z + bottom.y);
                break;
            case 1:
                pos = ivec2(gl_in[0].gl_Position.xy) + ivec2(bottom.x - left.y, 0);
                break;
            case 2:
                pos = ivec2(gl_in[0].gl_Position.xy) + ivec2(-left.y, right.x) - ivec2(right.y, bottom.y);
                break;
        }
        ivec2 UpperRight = ivec2(left.y, bottom.y) + ivec2(right.y, top.y) + pos;
        gl_PrimitiveID = (int(gl_in[0].gl_Position.z) << Rotations) + gl_InvocationID;
        if(any(lessThan(vec4(pos.xy, Param.zw), vec4(0, 0, UpperRight)))) {
            PlacementMap[gl_PrimitiveID] = 0xFFFFFFFF;
            return;
        }
        vec4 Rect = fma(vec4(pos, UpperRight), 2 / Param.zwzw, vec4(-1, -1, -1, -1));
        ivec2 center = ivec2(pos + ivec2(left.y, bottom.y));
        ivec3 index = (center.yyy - ivec3(-left.x, bottom.y, right.x)) * ivec3(Param.zzz) + center.xxx - ivec3(left.y + 1, bottom.x, 1 - right.y);
        if(any(greaterThan(uvec3(FrameBuffer[index.x], FrameBuffer[index.y], FrameBuffer[index.z]), uvec3(0, 0, 0)))) {
            PlacementMap[gl_PrimitiveID] = 0xFFFFFFFF;
            return;
        }
        float b = atan(left.y, top.y) - a;
        gl_Position = vec4(Rect.xw, 0, 1);
        gs_out.TexCoord = fma(vec2(-sin(b), cos(b)) * length(vec2(left.y, top.y)), Param.xy, Center);
        EmitVertex();
        b = -atan(right.y, top.y) - a;
        gl_Position = vec4(Rect.zw, 0, 1);
        gs_out.TexCoord = fma(vec2(-sin(b), cos(b)) * length(vec2(right.y, top.y)), Param.xy, Center);
        EmitVertex();
        b = PI - atan(left.y, bottom.y) - a;
        gl_Position = vec4(Rect.xy, 0, 1);
        gs_out.TexCoord = fma(vec2(-sin(b), cos(b)) * length(vec2(left.y, bottom.y)), Param.xy, Center);
        EmitVertex();
        b = PI + atan(right.y, bottom.y) - a;
        gl_Position = vec4(Rect.zy, 0, 1);
        gs_out.TexCoord = fma(vec2(-sin(b), cos(b)) * length(vec2(right.y, bottom.y)), Param.xy, Center);
        EmitVertex();
        EndPrimitive();
    }
}
 
Код:
#version 460 in GS_OUT {
    vec2 TexCoord;
}
gs_out;
out vec4 Color;
layout(location = 1) uniform vec4 DrawColor;
layout(binding = 0) uniform sampler2D image;
void main() {
    Color = texture(image, gs_out.TexCoord).rrrr * DrawColor;
}
#version 460
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
out GS_OUT {
    vec2 TexCoord;
}
gs_out;
layout(location = 0) uniform vec4 Param;
void main() {
    const float PI = 3.1415926535897932384626433832795;
    float a = gl_in[0].gl_Position.z * PI / 32;
    float b = atan(Param.x, Param.y);
    vec4 c = vec4(length(Param.xy) / Param.zw * 0.5, 0, 0);
    vec4 pos = vec4(gl_in[0].gl_Position.xy / Param.zw - vec2(1, 1), 0, 1);
    gl_Position = fma(vec4(-sin(a - b), cos(a - b), 0, 0), c, pos);
    gs_out.TexCoord = vec2(1, 0.5);
    EmitVertex();
    gl_Position = fma(vec4(-sin(a + b), cos(a + b), 0, 0), c, pos);
    gs_out.TexCoord = vec2(0, 0.5);
    EmitVertex();
    gl_Position = fma(vec4(-sin(PI + a + b), cos(PI + a + b), 0, 0), c, pos);
    gs_out.TexCoord = vec2(1, 0);
    EmitVertex();
    gl_Position = fma(vec4(-sin(PI + a - b), cos(PI + a - b), 0, 0), c, pos);
    gs_out.TexCoord = vec2(0, 0);
    EmitVertex();
    EndPrimitive();
}
#version 460
layout(points) in;
layout(triangle_strip, max_vertices = 8) out;
out GS_OUT {
    vec2 TexCoord;
    float alpha;
}
gs_out;
layout(location = 0) uniform vec4 Param;
layout(location = 1) uniform mat4 MVP;
void main() {
    const float PI = 3.1415926535897932384626433832795;
    float a = gl_in[0].gl_Position.z * PI / 32;
    float b = atan(Param.x, Param.y);
    float c = length(Param.xy) * 0.5;
    gs_out.alpha = 1;
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xy + vec2(-sin(a - b), cos(a - b)) * c, 0, 1);
    gs_out.TexCoord = vec2(1, 1);
    EmitVertex();
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xy + vec2(-sin(a + b), cos(a + b)) * c, 0, 1);
    gs_out.TexCoord = vec2(0, 1);
    EmitVertex();
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xy + vec2(-sin(PI + a + b), cos(PI + a + b)) * c, 0, 1);
    gs_out.TexCoord = vec2(1, 0.5);
    EmitVertex();
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xy + vec2(-sin(PI + a - b), cos(PI + a - b)) * c, 0, 1);
    gs_out.TexCoord = vec2(0, 0.5);
    EmitVertex();
    EndPrimitive();
    gs_out.alpha = 0.5;
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xy + vec2(-sin(a - b), cos(a - b)) * c, 0, 1);
    gs_out.TexCoord = vec2(1, 0.5);
    EmitVertex();
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xy + vec2(-sin(a + b), cos(a + b)) * c, 0, 1);
    gs_out.TexCoord = vec2(0, 0.5);
    EmitVertex();
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xy + vec2(-sin(PI + a + b), cos(PI + a + b)) * c, 0, 1);
    gs_out.TexCoord = vec2(1, 0);
    EmitVertex();
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xy + vec2(-sin(PI + a - b), cos(PI + a - b)) * c, 0, 1);
    gs_out.TexCoord = vec2(0, 0);
    EmitVertex();
    EndPrimitive();
}
#version 460 in GS_OUT {
    vec2 TexCoord;
    float alpha;
}
gs_out;
out vec4 Color;
layout(binding = 0) uniform sampler2D image;
void main() {
    Color = texture(image, gs_out.TexCoord).rrrr * vec4(0.45, 0.45, 0.45, gs_out.alpha);
}
 
Странно, что выполнение не прервалось по таймауту. Может быть в реестре установлено большее значение таймаута или он вообще отключен (раздел HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers).
 
Попробуйте уменьшить
Зачем мне это? 'hz'
Ваша загогулина не работает (либо работает при неких единичных условиях), а мне надо что-то уменьшать или увеличивать? Пф...
 
Так он изначально просил помочь потестировать
Так я и протестировал.

Оно-то и в принципе затея странная - лепить плагин (скрипт, макрос, экшн, – как хотите назовите) для корела в виде экзешника. Не всякий юзер согласится такое даже единожды пробовать. А уж если оно не работает от слова совсем, то зачем мне дальше ломать свою тачку ради чужой и не нужной мне поделки?
 
Так он изначально просил помочь потестировать
Но зачем? Практической ценность данная программа не представляет (ибо работает только на нормальном GPU, во взрослом софте такие вещи при инсталляции спрашивают, и если его нет - отлуп, сорян, ваша машина наш код не поддерживает)
Но можно конструктивно пообсуждать алгоритм компановки, я специально для этого код привет в приличный вид
 
Оно-то и в принципе затея странная - лепить плагин (скрипт, макрос, экшн, – как хотите назовите) для корела в виде экзешника. Не всякий юзер согласится такое даже единожды пробовать.
Тут ты тоже не совсем прав - ну не настолько же быть параноиком! Какое, по твоему, расширение кореловского плагина тебя бы успокоило? Даже в макрос легко вредоносного кода натолкать при желании, на который VirusTotal минимальное количество срабатываний показывать будет. А встроенный защитник так вообще половину несертифицированных EXE/DLL заворачивает (и, кстати, всех нативных плагинов, которыми они по сути и являются) Тут же простая и понятная софтина, видно, что не вирус, другое дело, что сам топик выглядит примерно: "Смотрите, я написал свой импортозаместительный корел на питоне, потестите, пожалуйста"
 
win11 32 оперативы, rizen 7 открылось моментально
 
В прикладных задачах слово "кратный" имеет иное значение чем в математике, например, ни у кого не вызывает недоумение выражение типа: "Наш колхоз добился полуторакратного роста надоев молока".