Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

1367 Excellent

About tivolo

  • Rank

Personal Information

  1. Well no, that was my point. While it's the correct thing to do (from a security point of view), it does not lead to 100% identical code being executed. Not only is (this is rather pedantic since it should hopefully make no difference, but who knows) the function binding and calling different between "same executable" and "in a shared library", but also, more importantly, you can expect a modern compiler to perform whole program optimizations on "same executable" code that are simply impossible across shared modules where the respective part isn't present at link time. Hopefully, you never see a difference (and I guess most of the time you won't), but you can never be 100.0% sure (only 99%). The things that are most nasty to debug are the ones where it works fine on one machine, but doesn't on another, and then it turns out that's because they were running kind-of-the-same code, but not exactly.     Ok, if I understand you correctly, you're talking about the difference between a development build and a retail build? If so, then well, yes, that is true for every game I've ever worked on. Development builds usually have lots of features which are stripped out in retail builds. Console games always had the "happens only when being started from the DVD"-kind of bugs, so debugging retail builds without symbols was the way to go.   Or did you mean something different? But then I didn't get your point, I guess :-/.
  2.   In Molecule, the scripts are always compiled to native code. In a development build, each script is compiled into a single shared library for hot-reloading, fast iteration times, etc. In a retail build, all scripts are compiled into the game executable, so the builds that go through QA are also what ends up in the user's hands - 100% identical.   There recently was a similar question on the Handmade Hero forums where my engine was also mentioned, and I provided a bit more info over there for anybody who's interested.
  3. On Windows, use the following on a command-line: dir *.mp4 /s /b > myFile.txt Execute in any directory you want to gather all the .mp4s in that directory and all sub-directories, recursively.
  4. Ready for takeoff!   I proudly present Molecular Matters' new solutions for extracting layers and other kinds of information from Photoshop .PSD files thoroughly, reliably and in no time.   For artists and designers, we offer our new tool called PsdExtract, which allows them to extract Adobe® Photoshop® .PSD files directly from within Windows Explorer with a few simple clicks. Exporting layer data to individual files has never been this easy.   For programmers and development studios, we offer the PsdLibrary SDK, which enables them to directly load data from .PSD files once the SDK has been integrated into their engine/asset pipeline. This can be a huge time saver for the whole team, because developers don't need to export their Photoshop data into individual files any longer.   Please let us know if you have any questions regarding the products, or want to setup an SDK evaluation!  
  5. tivolo

    Cache In A Multi-Core Environment

    I'm with frob on this one. I have seen far too many abuses of volatile in the past, which horribly failed time and time again. volatile in C++ was never intended for it to have anything to do with threads. You only ever need it to talk to hardware, e.g. a fixed piece of hardware sitting at a certain address that you're writing to, so you need to use volatile in order to ensure that the compiler won't optimize away certain write accesses. The write-gather pipe in the Wii is such an example.   Furthermore, when using MSVC as a compiler, wrong code often ends up working seemingly fine, because MSVC gives stronger guarantees about what volatile means - guarantees you won't get from other compilers.   Bruce Dawson has some good advice on this subject: https://msdn.microsoft.com/en-us/library/windows/desktop/ee418650(v=vs.85).aspx Check the chapter about "Volatile Variables and Reordering".   I also wrote about this in the past on my blog: https://molecularmusings.wordpress.com/2012/03/05/volatile-thread-synchronization/
  6. My company Molecular Matters launched a new tool called "mFusion" for 3d artists yesterday!   mFusion is a powerful material authoring tool, designed to simplify and boost your texturing workflow.   It lets you: build material layers, tweak their contributions, create different variations, and bake them into textures that work with any game engine and 3d package. If you have a library of standard materials lying around, you can quickly combine & mix their textures using vector masks and mFusion, as if your material was made of several distinct layers like iron, rust, dirt, etc. When you're happy with the result, simply bake it into one single texture map for diffuse, specular, gloss & normal. This lets you work in a layered manner, but use the resulting material in any game engine and 3d package without the heavy run-time cost associated with blending several materials.   mFusion works directly with layers, groups, vector masks and smart objects contained in Adobe® Photoshop® files, so you never have to leave your favorite tool when doing texturing work. The tool directly reads from .psd files, no export steps needed!   Go check it out now, and download the demo version at: http://molecular-matters.com/products_mfusion.html    
  7. These two might be of help: https://software.intel.com/en-us/articles/x87-and-sse-floating-point-assists-in-ia-32-flush-to-zero-ftz-and-denormals-are-zero-daz http://msdn.microsoft.com/en-us/library/e9b52ceh.aspx   You likely want to enable Denormals-are-Zero (DAZ). I had to do that in my real-time radiosity simulation, because denormals also caused huge performance drops whenever values became too small.
  8.   The problem is that &Sprite::vPos::z is not a pointer-to-member of class Sprite, but rather a pointer-to-member of math::Vector2f, which is entirely unrelated to Sprite. One solution to your problem would be to implement a generic (but typesafe!) pointer-to-member, something using inheritance and type erasure should do the trick.
  9. The behavior is correct and indended. You're not overloading here, but overriding. Overriding a base class function in a derived class hides the base class definition unless explicitly qualified with the base class name as you discovered. This applies to non-static member functions as well, not just static ones.   You can "unhide" the base class symbols in the derived class with the using statement. Something like this should work: class DerivedClass : public BaseClass< DerivedClass, InitDataType_t > { using BaseClass::GetInstance; public: static T1* GetInstance(const cstring& somestring); } I understand overriding for non static methods makes complete sense to me.  But overriding static methods, I didn't knew if that was even possible ? (mind blown) Can you please provide a little insight into how does it works with regards to  memory mapping, vtable and stuff ? Is it like non static methods ?   (This problem reminded me of a quote I read somewhere on the internet - "C++ is too much of a language to learn in a single life time".)       I'm pretty sure Brother Bob wanted to say it the other way around. You are creating a new overload in the derived class, and that will hide all overloads from all base classes, unless you explicitly "pull" them into the derived class via "using". That is intended, and correct.   There is no such thing as overriding static methods.
  10. This looks like indeed a nice idea for applying radix sort. There's so few places where it really fits.   I couldn't tell whether it's worth the trouble (still always using std::sort, which for anything practical surprisingly turns out just good enough every time, I've never had enough of a justification for actually using radix sort in my entire life), but from playing with it a decade or two ago, I remember that radix sort can easily be 3-4 times faster than e.g. quicksort/introsort. So if the sort is indeed bottlenecking you out (that is, you don't meet your frame time, and profiling points to the sort), that would probably be a viable option.   Slight nitpick, though: One doesn't of course sort the indices, which would be somewhat pointless. You most certainly didn't mean to say that, but it kind of sounded like it. One sorts the keys (moving indices). Or well, one sorts indices by key, or whatever one would call it. Which means that most likely, 3 passes won't be enough, sadly (or you need bigger buckets), since you will almost certainly have at least 48 or 64-bit numbers to deal with (except if you have very few passes and render states, and are very unkind to your depth info). Not using a stable radix sort to save temp memory may be viable (can instead concat the indices like described above if needed, even if this means an extra pass... the storage size difference alone likely outweights the extra pass because of fitting L1).   Thanks for pointing out my mistake, yes I wanted to say that one should sort the keys :). What you get back are the indices which are then used to access your data.   Fully generic rendering-related data might not fit into a 32-bit key, that's true. But there are certain occasions where 32 bits are more than enough (or even 16 might suffice), e.g. for sorting particles. As a quick note on performance, sorting 50k particles back-to-front using an ordinary std::sort on 16-bit keys takes 3.2ms on my machine, whereas an optimized radix-sort needs 0.25ms. If all you need to sort are keys that somehow index other data, it's almost always better to just sort that, and correctly index the data on access because this causes much fewer memory accesses during the sort.
  11. To answer the original question: just sort the indices, and use a radix sort. If your indices are 32-bit, you can use a three-pass radix sort with 11-bit buckets that will nicely fit into the CPU's L1 cache. And you can also make the radix sort benefit from temporal coherence. But even if you don't, it will be much, much faster than a std::sort in comparison.
  12. tivolo

    Simple Question BYTE->float C++

      I'd argue that in the general case it would be better to use a solution with explicit static_casts as presented by ApochPiQ, because you can immediately see the four casts (and can also search for them), also making it easier to spot potentially expensive operations (load-hit-stores on PowerPC architectures). But that's probably a matter of taste.
  13. What you are probably looking for is a conversion function (or cast operator). However, if you tell us the kind of problem you are trying to solve, maybe a solution that doesn't involve conversions can be found. I would only use a conversion function and non-explicit constructors under very special circumstances, and try to convert implicit conversions when possible.   In your case, just adding a constructor to A that takes a const-reference to B would also work (and be more safe).
  14. I know the problem you're dealing with, this is tedious to solve (more so when static libraries are involved across multiple platforms ). The issue you are seeing is not caused by the linker, but rather by the compiler. You can easily verify that by using dumpbin.exe /SYMBOLS on the object file - snafu2 won't be in there, whereas snafu1 will be. So the linker never even has a chance of seeing the symbol.   The problem is that snafu2 is not used directly anywhere in the code you posted. It is never accessed, nor is its address taken. The compiler (unfortunately) doesn't care about the __declspec(allocate()) statements and the fact that you are merging sections, in order to iterate through them later. It will simply never emit the symbol "static int Test<int>::snafu2" into the object file.   There is one workaround, however. Tell the compiler you use this symbol by handing it to something he can't see, e.g. a function with external linkage defined in another translation unit, something akin to the following:   anyTranslationUnit.cpp:   void DummyRegister(int) {   // doesn't need to do anything }   and in your code: template<class T> class Test {     static __declspec(allocate(".xyz$b")) int snafu1;     static __declspec(allocate(".xyz$b")) int snafu2; public:     static void doSomething() { OutputDebugStringW(L"\ndoing something\n"); snafu1 = (answer + snafu1) / 2; }     static void Register()   {    extern void DummyRegister();    DummyRegister(snafu1);    DummyRegister(snafu2);    } };   I guess the code you posted is the result of some macro invocations, or other means of automatic code generation. I hope you're able to change the process to also include the dummy-registration process. I fear there's no other way around your issue other than letting the compiler believe you are somehow using those symbols (at least not in MSVC).   HTH, -tiv
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!