HLSL (compute shader, shader model 5_1) conundrum - gpgpu

So I had this HLSL structure that compiled successfully in VS2015 when used:
struct SpatialHashingCellData
{
uint count;
uint specks[MAX_SPECKS_PER_CELL];
};
It was used like this:
gSPCells[cellID].specks[posToWrite]= speckIndex;
But then I switched to VS2017 and I had to make this change in order for it to compile because there was an error:
internal error : l-value expected
struct SpatialHashingCellData
{
uint count;
struct { uint index; } specks[MAX_SPECKS_PER_CELL];
};
... and changed:
gSPCells[cellID].specks[posToWrite].index = speckIndex;
I feel kinda stupid for not knowing what is happening here. Hope anyone could clear this out for me, please :)
Best regards,
Bojan

Related

How to use vectors (of C++ STL) with WebAssembly

#include <iostream>
#include<vector>
using namespace std;
vector<int> ver;
int pushData(int n)
{
for(int i=0;i<n;i++)
{
ver.push_back(i);
}
}
I want to call pushData function from JS and push some data to vector "ver" and use it later.
please explain how to do that using WebAssembly.
i'm do something like you.In my opinion, using STL in WASM is very difficult.
My solution is to create a simulate vector.Wasm only supports int32, int64, float32 and float64 and wasm's adderess is differnt from other process.So it is not feasible to import the library directly. You can call the library function through a proxy or conversion.Or you can write it by yourself.
In this case, vector can't be imported directly.You can create a class named vector,and implement the push_back function.
class vector{
public:
bool push_back(int i){
// do something
}
int& at(uint index){
// do something
}
private:
int* int_ptr;
}
More details here
https://aransentin.github.io/cwasm/

C++11 Observers Pass parameters on Notify

I'm coming from C# and trying to implement a simple Events/EventHandler pattern in c++11 which i believe the common name is Observers and signals, i know there are boost library and others but i dont want to use any external libs.
While searching online I found a simple implementation for what I need, so I took and modified the code and it works ok.
My problem is that the parameters are passed when registering events/observers, and not when raising/signaling/notifying which I find a bit awkward.
class EventManager
{
private:
static std::map<EventType, std::vector<std::function<void()>>> _eventHandlers;
public:
EventManager() = default;
template <typename EventHandler>
static void RegisterEventHandler(EventType&& eventType, EventHandler&& eventHandler)
{
EventManager::_eventHandlers[std::move(eventType)].push_back(std::forward<EventHandler>(eventHandler));
}
static void Raise(const EventType& event)
{
for (const auto& eventHandler : EventManager::_eventHandlers.at(event))
{
eventHandler();
}
}
// disallow copying and assigning
EventManager(const EventManager&) = delete;
EventManager& operator=(const EventManager&) = delete;
};
Can anyone help me to extend the following code by adding the functionality to accept parameters when raising the event as well ?
I believe this solves your question:
// g++ -std=c++11 -o /tmp/events /tmp/events.cpp && /tmp/events
// handler=1 arg=1
// handler=2 arg=1
// handler=1 arg=2
// handler=2 arg=2
#include <functional>
#include <map>
#include <vector>
template<class EventType, class... HandlerArgs>
class EventManager
{
public:
using EventHandler = std::function< void(HandlerArgs...) >;
void register_event(EventType&& event, EventHandler&& handler)
{
_handlers[std::move(event)].push_back(std::forward<EventHandler>(handler));
}
void raise_event(const EventType& event, HandlerArgs&&... args)
{
for (const auto& handler: EventManager::_handlers.at(event)) {
handler(std::forward<HandlerArgs>(args)...);
}
}
private:
std::map<EventType, std::vector<EventHandler>> _handlers;
};
int main(int argc, char **argv)
{
EventManager<int, int> m;
m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 1, arg); });
m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 2, arg); });
m.raise_event(1, 1);
m.raise_event(1, 2);
}
PS: I removed all the code regarding non-copiability and such, since it is not relevant to this question.
Since i havent got any answers on this, i figured a way to do so but i dont like it since i wanted a better way but well creating a static class that has static variables for each event, before raising the event , the caller will set those variables and the handler will read then reset them . this is dangerous approach especially with multi-threading since one or more threads might change the values while raising same event by mutli threads, so i had to implement some locking features to ensure thread safety.
Yes i know its not the best approach but as i'm not an expert in C++ and this question didnt get any comments nor answers, so this is the approach im following.

waveOutGetPosition always returns zero

I'm using waveOutWrite to write several small buffers (80ms each). As they are playing, I'm calling this function to get the playback position:
uint GetWaveOutPosInMS()
{
WinMM.MMTIME mmtime = new WinMM.MMTIME();
mmtime.wType = 1;
WinMM.MMRESULT ret = WinMM.waveOutGetPosition(WaveOut, ref mmtime, (uint)Marshal.SizeOf(typeof(WinMM.MMTIME)));
return (mmtime.val);
}
Here are the relative extras as well:
[DllImport("winmm.dll")]
public static extern MMRESULT waveOutGetPosition(IntPtr hwo, ref MMTIME info, uint cbi);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MMTIME
{
public uint wType;
public uint val;
}
The waveOutGetPosition returns 0 (no error), but mmtime.val is always zero. MSDN isn't really clear on what "playback position" is relative to, just that it is reset on waveOutOpen and waveOutReset.. but does it always continue to increase across multiple waveOutWrite() calls? Any ideas as to why it would always be returning zero for me?
I had the MMTIME struct declared incorrectly. Odd that the function didn't report error, but based on other stuff I've read this function is dependant on the OEM so could see various weird results. It also appears asking for MS isn't as well tested as asking for SAMPLES, so I'll just ask for samples instead, and calculate MS myself.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MMTIME
{
public uint wType;
public uint val;
// Padding because val is actually a union
public uint pad;
}

codeblock vs VS2010

I have got following code:-
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
char ay[256]={0};//HWND hwnd= GetForegroundWindow();
if( GetClassName(hwnd,ay,256))
{
char x[70]={0};
GetWindowText(hwnd,x,70);
if(IsWindowVisible(hwnd))
{
// CaptureAnImage(hwNd,hwnd);
HINSTANCE hins= (HINSTANCE) GetWindowLong(hwnd,GWL_HINSTANCE);
WNDCLASSEX lpwcx;
GetClassInfoEx(hins,ay,&lpwcx);
if (MessageBox(0,
strcat(strcat(x, "\r\n"), lpwcx.lpszClassName),
"Info", 0x06L) == IDTRYAGAIN)
{
return false;
}
}
}
return true;
}
void cstm()
{
EnumWindows(EnumWindowsProc,0);
}
This runs fine on Codeblocks (with VS 2010 compiler(cl)) but VS2010 gives a corrupted lpwcx value, I have tried the Unicode as well as Ascii to tackle this but no good result at
all. The first lpwcx is correct but later they return class not found(1411) ,although the hinstance and class name is correct.
Please help.
strcat(strcat(x, "\r\n"), lpwcx.lpszClassName),
The odds that this will overflow the x buffer and stomp some local variable values, like *lpwcx", are very high. 70 chars is unreasonably frugal. If you don't want to use strcat_s() then at least make it bigger. And yes, initialize lpwcx.cbSize
Always fill in the cbSize member of data blocks before calling any API functions. Many of them rely upon this value to know which version of the data structure they should fill in.

Why does GCC not find my non-template function? ("no matching function for call to...")

In MSVC 2008, I have the following code:
class Foo {
// Be a little smarter about deriving the vertex type, to save the user some typing.
template<typename Vertex> inline void drawVertices(
Elements vCount, RenPrim primitiveType, PixMaterial *mtl, Vertex const *vertices)
{
this->drawVertices(vCount, primitiveType, mtl, vertices, Vertex::VertexType);
}
virtual void drawVertices(
Elements vCount,
RenPrim primitiveType,
PixMaterial *mtl,
void const *vertices,
uint vertexType) = 0;
};
I use it something like:
struct RenFlexibleVertexPc
{
enum { VertexType = RenVbufVertexComponentsPc };
float x;
float y;
float z;
GraVideoRgba8 c; // Video format, not external!
};
PixMaterial *material;
struct Pc : RenFlexibleVertexPc
{
void set(Triple t, uint cl) { x = (float)t.x_; y = (float)t.y_; z = (float)t.z_; c = cl; }
} vpc[4];
...
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
This works fine in MSVC 2008 SP1. However, GCC (3.4 and 4.1,2) throws a "no matching function for call to function" error, apparently not seeing the template when there is a non-template function with more arguments.
Is GCC broken, or is my code broken, and if so, why?
There is no problem with overloading or inheritance:
#include <iostream>
#include <memory>
namespace {
struct A {
virtual void f()
{
std::cout<<"inside A's f()\n";
}
template <typename T> void f(T t)
{
std::cout<<T::i<<'\t';
this->f();
}
};
struct B : A {
void f()
{
std::cout<<"hello\t";
A::f();
}
};
struct C {
static const unsigned int i = 5;
};
struct D {
enum { i = 6 };
};
}
int main()
{
std::auto_ptr<A> b(new B());
b->f(C());
b->f(D());
}
Works correctly. On the other hand, the smallest example I can find that exhibits your problem does not have inheritance or overloading:
#include <iostream>
namespace {
struct A {
template<class C> void print(C c)
{
c.print();
}
};
}
int main()
{
struct B {
void print()
{
std::cout << "whee!\n";
}
};
A a;
B b;
a.print(b);
}
Note that if struct B is defined in a namespace (whether it's an unnamed namespace, or a completely different namespace, or the global namespace) instead of inside main() that this compiles without error.
I don't know enough of the standard to say if this is a bug, but it appears to be one. I've gone ahead and reported it to the GCC bug database.
And here's your answer from the GCC developers (from the link above): "Local classes cannot be template arguments."
So the code is broken. Not that it's a bad idea. In fact, C++0x removes this restriction.
I noticed the line
Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
And since RenFlexibleVertexPc is not a local class this makes sense. However Pc is a local class/struct, so it is not allowed.
#OP: Specifying the template parameter is a valid approach.
renderer->drawVertices<RenFlexibleVertexPc>(4, RenPrimTriangleFan, material, vpc);
With Pete's additions, you code also compiles on Apple's GCC 4.0.1, so I suspect there's something your posted code is missing that's causing the problem.
#Max: GCC's treatment of your source is standard. Struct B is local to main(), so B (and thus main()::B::print()) is not visible outside main(). As you're probably aware, moving the definition of B outside of main() and it will compile.
The definition of VertexType is already in the code (an enum). Elements is an unsigned long. Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
If it's an enum why pass an object of type array 4 of struct? What is RenFlexibleVertexPc? The last argument to drawVertices should either be a constant pointer to a Vertex object or a const* to an object of a class derived from Vertex.
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
You are calling a function on an uninitialized pointer. I hope this is not the real code. \

Resources