2016-04-08 15 views
0

CPU-GPU-hibrit bir JPEG kodlayıcı oluşturmaya çalışmak için IOS üzerinde bazı hileler oynuyorum. CPU'yla yaptığım testlerden, DCT'yi yapmak için GPU kullanmanın ve niceleme adımlarının iyi bir anlam ifade ettiğini ve performansın önemli ölçüde artmasını sağladığına inanıyorum (çok sayıda JPEG'i sıkıştırmak, benim app'ımdaki şişe boynunu sıkıştırmaktır). GPGPU hesaplamalarında mükemmel sonuçlar elde etmek için kullanmış olduğumdan, dönüşüm geri bildirimi ile bu yapılmalıdır. Zor kısım, verilere (imzasız int8'ler RGBA) nasıl verimli bir şekilde ulaşılacağıdır. belirtildiği gibiOpenGL ES 3.0 içinde tamsayı/bayt doku verileri "olduğu gibi" getiriliyor

ben GPGPU işlem yapmak OpenGL ES 3.0 kullanmak için kullanılır, bu yüzden sadece şamandıra noktalı dokuları ile deneyime sahip olan

ile shaderlara teslim

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA32F,WIDTH,HEIGHT,0,GL_RGBA,GL_GLOAT,data); 

tarafından belirlenen alma ve bir

texelFetch() 

Fakat şimdi giriş verilerim imzalanmamış bayt dizisi (veya uint8) olarak depolanıyor ve her seferinde 64 tanesi sırayla almam gerekiyor. Onları imzasız baytların bir dokusu olarak ya da daha etkin bir şekilde, imzasız tam sayıların bir dokusu olarak getirebilirim ve sonra bunları bit vardiyalarıyla ayırabilirim.

Sorum şu ki, aslında bunlardan birini nasıl yaparım? Daha spesifik olarak, internalFormat, biçimi ve tip glTexImage2D() için nasıl ayarlamalıyım? Çok fazla kombinasyon denedim ama hepsi gölgelendiricilerde sadece 0 veriyor ve veri kaynağını hiç sıfır olmadıkları için çift kontrol ettim.

+0

Normal bir RGBA için piksel başına 4 bayta sahipsiniz. GlTexImage2D(), vec4 bileşeninin her biri bu baytın birini temsil ettiğinden, bayt bayt olarak almak için kullanılabilir.Değerler normalize edilir, bu nedenle baytları temsil eden bir tamsayı değeri elde etmek için 255 ile çarpmanız gerekir. Böylece glTexImage2D() için 16 (64/4) çağrı yaparak 64 bayt alabilirsiniz. Yoksa burada bir şey mi özlüyorum? –

+0

Üzgünüz, glTexImage2D(). Shader'daki texel getiriyi kastediyorum. –

+0

Evet, bu benim planımdı. Bu konuda sahip olduğum problem, imzasız bayt olarak depolanmış dokuların nasıl alınacağını bilmem (veya bunun için glTexImage2D'yi nasıl yapılandıracağımı bilmem). Mümkünse plan-A'ya atlamayı çok isterim, burada bir tek bayt yerine bir "piksel" olarak bir tamsayı (dört bayt) alıyorum, bu da 64/4/4 = 4'e getirme sayısını azaltacaktır. –

cevap

0

ES 3'te, piksel verilerinizi formüle edeceğiniz bir konum elde etmek için bir piksel paket açma arabelleği oluşturmayı ve eşleme yapmayı ciddi olarak düşünebilirsiniz. En azından bir sürücü iç memcpy kaydedecek ve eşitleme azaltmak için önemli ölçüde kullanılabilir. glBindBuffer ve gl[Un]MapBuffer[Range]'da bulunan GL_PIXEL_UNPACK_BUFFER; piksel ayırma arabelleğini bir kaynak olarak belirtmek için glTexImage2D(..., (void *)0); ile bir kaynak olarak, bağımlı tamponların öznitelikler, öğeler vb. için kaynak olarak belirtildiği şekilde benzer bir şekilde sonuçlanırsınız. GL_MAP_UNSYNCHRONIZED_BIT'u kullandığınız varsayılarak eşitleme için glFenceSync'a bakın ve işlenmeyi düşünün. senkronizasyon kendiniz.

Tam sayımlı RGBA için (ölçeklendirme yok), dahili biçim olarak GL_RGBA8UI kullanın; biçim olarak GL_RGBA_INTEGER, biçim olarak GL_UNSIGNED_BYTE; sonra bir usampler2d ('imzasız, tam olarak tamsayı için' u ') bildirin ve örnek almak için standart bir texture(sampler, coordinate) kullanın.

Ayrıca GL_CLAMP_TO_EDGE ve GL_NEAREST doku parametrelerini de isteyeceksiniz.

DÜZENLEME: ayrıca potansiyel olarak belirtmeye değer, usampler2d'dan gelen değerler, uvec4 türündedir, bu nedenle bunlar ayrılmazdır. ES 2'den farklı olarak, ES3 bitümlü operatörler de dahil olmak üzere gerçek tamsayılara sahiptir - ES2, yüzdelikler tarafından taklit edilmelerine izin verir (90'lılardan gelenler için bu, beklenmedik bir gelecek).

vec4 rgb_sample(usampler2D sampler, vec2 coordinate) 
{ 
    uint texValue = texture(sampler, coordinate).r; 
    return vec4(texValue & 4u, texValue & 2u, texValue & 1u, 1.0); 
} 

hangisi, bir TTL tarzı açma edilir tabii RGB-in-one-byte tek kanallı doku için: Yani, basitleştirilmiş ve yeterince önemsiz benim bir son emülasyon projesinden pasajı kayda değer olması gl_FragColor (doygunluğa dayanarak) için uygun bir format.

+0

Ayrıntılar için teşekkürler! Bana mantıklı geliyor ve denedikten sonra nasıl çalıştığını anlatacağım. :) –