Access violation when initializing a D3DBuffer - c++11

I'm trying to load an obj file full of vertices and render it as a point cloud.
when I try to run my code it crashes and gives me the following error:
Unhandled exception at 0x66463E50 (nvwgf2um.dll) in Tutorial06.exe: 0xC0000005: Access violation reading location 0x00E9D000.
I followed the tutorial code Microsoft provide with DirectX and changed it to suite my layout and everything but I must have done something wrong and I'm not sure what it is.
This is how I try to initialize my buffer:
CloudLoader::getInstance().loadCloudData("cloud.obj");
std::vector<CloudVertex>* data = CloudLoader::getInstance().getCloudData();
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( CloudVertex ) * data->size();
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = data;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
And this my cloud loading code:
void CloudLoader::loadCloudData(std::string fileName)
{
if (m_loaded == false){
m_loadedData = new std::vector<CloudVertex>();
std::wifstream fileIn(fileName.c_str()); //Open file
wchar_t checkChar;
if (fileIn){
while (fileIn){
checkChar = fileIn.get(); //Get next char
switch (checkChar){
case 'v':
checkChar = fileIn.get();
if (checkChar == ' ') //v - vert position
{
float vz, vy, vx;
fileIn >> vx >> vy >> vz; //Store the next three types
m_loadedData->push_back(CloudVertex(vx, vy, vz));
}
break;
}
}
}
}
m_loaded = true;
}
I guess its a C++ thing and not directX and its probably really simple but I've been stuck on this for a while now, I would really appreciate the help.

pSysMem cannot point at "data", as this is a pointer to the std::vector class and not actually the data contained within the vector.
Try:
InitData.pSysMem = data->data();

Related

Understand the working on FltGetVolumeGuidName()

I want to know the implementation sequence of the function FltGetVolumeGuidName(), I basically want to get the Guid of all volumes from my system ?
Below is the code, which I tried, any help will be greatly appreciated , thanks in advance.
volumeContext->GUIDinfo.Buffer = NULL; //kernel crash here <<<<======
volumeContext->GUIDinfo.Length = 0;
volumeContext->GUIDinfo.MaximumLength = 0;
//fetching correct size
(void) FltGetVolumeGuidName(pVolumeList, &volumeContext->GUIDinfo, &BufferSizeNeeded);
//Allocating space
if (NULL == volumeContext->GUIDinfo.Buffer) {
status = STATUS_INSUFFICIENT_RESOURCES;
DbgPrint("\n STATUS_INSUFFICIENT_RESOURCES");
break;
}
//Memory allocation
volumeContext->GUIDinfo.Buffer = (PWCHAR)ExAllocatePoolWithTag(PagedPool, BufferSizeNeeded, MEMTAG_VOL_GUID);
volumeContext->GUIDinfo.Length = 0;
ASSERT(BufferSizeNeeded <= UNICODE_STRING_MAX_BYTES);
volumeContext->GUIDinfo.MaximumLength = (ULONG)BufferSizeNeeded;
ntStatus = FltGetVolumeGuidName(pVolumeList, &volumeContext->GUIDinfo, &BufferSizeNeeded);
if (ntStatus == STATUS_BUFFER_TOO_SMALL) {
DbgPrint("\n STATUS_BUFFER_TOO_SMALL");
}
Eryk, thank you very much. Agreed that each of the PFLT_VOLUME I get a valid pointer. Now when I call FltGetVolumeGuidName(PFLT_VOLUME (pVolumeList) &volumeContext->GUIDinfo, BufferSizeNeeded) as mentioned above and print the values in the &volumeContext->GUIDinfo = (Null) and BufferSizeNeeded = 96.
With the literature around on FltGetVolumeGuidName, I understand 1st call FltGetVolumeGuidName to get the BufferSizeNeeded and use this size and allocate memory and call again FltGetVolumeGuidName to fetch Guid.
I have a problem (kernel panic) when I initialize as below
volumeContext->GUIDinfo.Buffer = NULL; //kernel crash here <<<<======
volumeContext->GUIDinfo.Length = 0;
volumeContext->GUIDinfo.MaximumLength = 0;

OpenCL 2.1 C++ HelloWorld: invalid context?

Similar to this question, I'm trying to implement the HelloWorld example from this video by Wesley Shillingford, except this time with OpenCL 2.1. I can get it to run if I use the default context, but not if I create my own (as the video does).
When I use my own context, it produces a cl::Error (-34 = CL_INVALID_CONTEXT):
From here:
CL_INVALID_CONTEXT = the given context is invalid OpenCL context, or the context associated with certain parameters are not the same.
I'm not sure how I could tell that the context is invalid. I've tried comparing the defaultContext to myContext, and they match of everything except CL_CONTEXT_REFERENCE_COUNT. Which doesn't seem to matter (but maybe it does).
I could be mixing contexts. However, I assign the context I want to use to chosenContext and use that everywhere I need a context.
It seems that something is somehow using the default context instead of my supplied context, but I haven't been able to spot where. Any insights would be appreciated.
The code:
#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_TARGET_OPENCL_VERSION 200
#include <CL/cl2.hpp>
#include <fstream>
#include <iostream>
int main()
{
// Get Platform and Device
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
auto platform = platforms.front();
std::vector<cl::Device> devices;
platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
auto device = devices.front();
//This context doesn't work. Causes CL_INVALID_CONTEXT (-34)
cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform(), 0};
cl::Context myContext(device, properties);
//If I stick with the default context, things work.
cl::Context defaultContext = cl::Context::getDefault();
//The choice of context here determines whether it works or not:
// myContext -> Fails with CL_INVALID_CONTEXT (-34)
// defaultContext -> works
auto chosenContext = myContext;
std::ifstream helloWorldFile("hello_world.cl");
std::string src(std::istreambuf_iterator<char>(helloWorldFile), (std::istreambuf_iterator<char>()));
cl::Program program(chosenContext, src);
program.build("-cl-std=CL2.1");
//Debugging code: Check to make sure that the contexts are similar
auto myContextDevices = myContext.getInfo<CL_CONTEXT_DEVICES>();
auto defaultContextDevices = defaultContext.getInfo<CL_CONTEXT_DEVICES>();
auto devicesMatch = myContextDevices == defaultContextDevices; //true
auto myContextProperties = myContext.getInfo<CL_CONTEXT_PROPERTIES>();
auto defaultContextProperties = defaultContext.getInfo<CL_CONTEXT_PROPERTIES>();
auto propertiesMatch = myContextProperties == defaultContextProperties; //true
auto myContextNumDevices = myContext.getInfo<CL_CONTEXT_NUM_DEVICES>();
auto defaultContextNumDevices = defaultContext.getInfo<CL_CONTEXT_NUM_DEVICES>();
auto numDevicesMatch = myContextNumDevices == defaultContextNumDevices; //true
auto myContextRefCount = myContext.getInfo<CL_CONTEXT_REFERENCE_COUNT>(); // 1 if defaultContext, 3 if myContext
auto defaultContextRefCount = defaultContext.getInfo<CL_CONTEXT_REFERENCE_COUNT>(); // 4 if defaultContext, 2 if myContext
auto refCountsMatch = myContextRefCount == defaultContextRefCount; // false
auto contextsMatch = myContext == defaultContext; //false
//End of debugging code
//Continuing with computation
char buf[16];
cl::Buffer outputBuffer = cl::Buffer(CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(buf));
cl::Kernel kernel(program, "HelloWorld");
kernel.setArg(0, outputBuffer);
cl::CommandQueue commandQueue(chosenContext, device);
auto result = commandQueue.enqueueNDRangeKernel(kernel, 0, 1, 1); //CL_SUCCESS
commandQueue.enqueueReadBuffer(outputBuffer, CL_TRUE, 0, sizeof(buf), buf); // Execution fails here, raises cl::Error (-34)
std::cout << buf;
return EXIT_SUCCESS;
}
Build Command:
g++ -g hello_world_21.cpp -IOpenCL-Headers/opencl21 -std=c++11 -lOpenCL
hello_world.cl:
__kernel void HelloWorld(__global char* output) {
output[0] = 'H';
output[1] = 'e';
output[2] = 'l';
output[3] = 'l';
output[4] = 'o';
output[5] = ' ';
output[6] = 'W';
output[7] = 'o';
output[8] = 'r';
output[9] = 'l';
output[10] = 'd';
output[11] = '!';
output[12] = '\n';
}
You are still using the default context for the global memory buffer instead of using your own context:
cl::Buffer outputBuffer = cl::Buffer(CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(buf));
Just change this line to the following and it should work:
cl::Buffer outputBuffer = cl::Buffer(myContext, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(buf));

GetOpenFileNameW results in FNERR_INVALIDFILENAME, or CDERR_INITIALIZATION if I call GetOpenFileNameA

Here's the code using GetOpenFileNameW:
import core.sys.windows.windows;
import std.stdio, std.string, std.utf;
pragma(lib, "comdlg32");
// Fill in some missing holes in core.sys.windows.windows.
extern (Windows) DWORD CommDlgExtendedError();
enum OFN_FILEMUSTEXIST = 0x001000;
void main()
{
auto buf = new wchar[1024];
OPENFILENAMEW ofn;
ofn.lStructSize = ofn.sizeof;
ofn.lpstrFile = buf.ptr;
ofn.nMaxFile = buf.length;
ofn.lpstrInitialDir = null;
ofn.Flags = OFN_FILEMUSTEXIST;
BOOL retval = GetOpenFileNameW(&ofn);
if (retval == 0) {
// Get 0x3002 for W and 0x0002 for A. ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms646916(v=vs.85).aspx )
throw new Exception(format("GetOpenFileName failure: 0x%04X.", CommDlgExtendedError()));
}
writeln(buf);
}
This results in FNERR_INVALIDFILENAME, but I don't see any non-optional strings that I haven't filled in. And here's the code (only differences shown) for GetOpenFileNameA:
auto buf = new char[1024];
OPENFILENAMEA ofn;
// ...
BOOL retval = GetOpenFileNameA(&ofn);
This results in CDERR_INITIALIZATION, and the only elaboration MSDN gives me is
The common dialog box function failed during initialization.
This error often occurs when sufficient memory is not available.
This is on Windows 7 64 bit, DMD v2.059.
buf has to be zeroed completely. The problem here is that wchar.init == wchar.max (for error detection reasons), so your array is essentially 1024 instances of wchar.max. A simple buf[] = 0; should fix that.

Images saved with D3DXSaveSurfaceToFile will open in Paint, not Photoshop

I'm using D3DXSaveSurfaceToFile to save windowed Direct3D 9 surfaces to PNG, BMP and JPG files. There are no errors returned from the D3DXSaveSurfaceToFile call and all files open fine in Windows Photo Viewer and Paint. But they will not open in a higher end image editing program such as Paint Shop Pro or Photoshop. The error messages from these programs basically say that the file is corrupted. If I open the files in Paint and then save them in the same file format with a different file name, then they'll open fine in the other programs.
This leads me to believe that D3DXSaveSurfaceToFile is writing out non-standard versions of these file formats. Is there some way I can get this function to write out files that can be opened in programs like Photoshop without the intermediate step of resaving the files in Paint? Or is there another function I should be using that does a better job of saving a Direct3D surfaces to an image?
Take a look at the file in a image meta viewer. What does it tell you?
Unfortunately D3DXSaveSurfaceToFile() isn't the most stable (it's also exceptionally slow). Personally I do something like the below code. It works even on Anti-aliased displays by doing an offscreen render to take the screenshot then getting it into a buffer. It also supports only the most common of the pixel formats. Sorry for any errors in it, pulled it out of an app I used to work on.
You can then, in your code and probably in another thread, then convert said 'bitmap' to anything you like using a variety of different code.
void HandleScreenshot(IDirect3DDevice9* device)
{
DWORD tcHandleScreenshot = GetTickCount();
LPDIRECT3DSURFACE9 pd3dsBack = NULL;
LPDIRECT3DSURFACE9 pd3dsTemp = NULL;
// Grab the back buffer into a surface
if ( SUCCEEDED ( device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pd3dsBack) ))
{
D3DSURFACE_DESC desc;
pd3dsBack->GetDesc(&desc);
LPDIRECT3DSURFACE9 pd3dsCopy = NULL;
if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
{
if (SUCCEEDED(device->CreateRenderTarget(desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pd3dsCopy, NULL)))
{
if (SUCCEEDED(device->StretchRect(pd3dsBack, NULL, pd3dsCopy, NULL, D3DTEXF_NONE)))
{
pd3dsBack->Release();
pd3dsBack = pd3dsCopy;
}
else
{
pd3dsCopy->Release();
}
}
}
if (SUCCEEDED(device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pd3dsTemp, NULL)))
{
DWORD tmpTimeGRTD = GetTickCount();
if (SUCCEEDED(device->GetRenderTargetData(pd3dsBack, pd3dsTemp)))
{
D3DLOCKED_RECT lockedSrcRect;
if (SUCCEEDED(pd3dsTemp->LockRect(&lockedSrcRect, NULL, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK | D3DLOCK_NO_DIRTY_UPDATE)))
{
int nSize = desc.Width * desc.Height * 3;
BYTE* pixels = new BYTE[nSize +1];
int iSrcPitch = lockedSrcRect.Pitch;
BYTE* pSrcRow = (BYTE*)lockedSrcRect.pBits;
LPBYTE lpDest = pixels;
LPDWORD lpSrc;
switch (desc.Format)
{
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
for (int y = desc.Height - 1; y >= 0; y--)
{
lpSrc = reinterpret_cast<LPDWORD>(lockedSrcRect.pBits) + y * desc.Width;
for (unsigned int x = 0; x < desc.Width; x++)
{
*reinterpret_cast<LPDWORD>(lpDest) = *lpSrc;
lpSrc++; // increment source pointer by 1 DWORD
lpDest += 3; // increment destination pointer by 3 bytes
}
}
break;
default:
ZeroMemory(pixels, nSize);
}
pd3dsTemp->UnlockRect();
BITMAPINFOHEADER header;
header.biWidth = desc.Width;
header.biHeight = desc.Height;
header.biSizeImage = nSize;
header.biSize = sizeof(BITMAPINFOHEADER);
header.biPlanes = 1;
header.biBitCount = 3 * 8; // RGB
header.biCompression = 0;
header.biXPelsPerMeter = 0;
header.biYPelsPerMeter = 0;
header.biClrUsed = 0;
header.biClrImportant = 0;
BITMAPFILEHEADER bfh = {0};
bfh.bfType = 0x4d42;
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bfh.bfSize = bfh.bfOffBits + nSize;
unsigned int rough_size = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + nSize;
unsigned char* p = new unsigned char[rough_size]
memcpy(p, &bfh, sizeof(BITMAPFILEHEADER));
p += sizeof(BITMAPFILEHEADER);
memcpy(p, &header, sizeof(BITMAPINFOHEADER));
p += sizeof(BITMAPINFOHEADER);
memcpy(p, pixels, nSize);
delete [] pixels;
/**********************************************/
// p now has a full BMP file, write it out here
}
}
pd3dsTemp->Release();
}
pd3dsBack->Release();
}
}
Turns out that it was a combination of a bug in my code and Paint being more forgiving than Photoshop when it comes to reading files. The bug in my code caused the files to be saved with the wrong extension (i.e. Image.bmp was actually saved using D3DXIFF_JPG). When opening a file that contained a JPG image, but had a BMP extension, Photoshop just failed the file. I guess Paint worked since it ignored the file extension and just decoded the file contents.
Looking at a file in an image meta viewer helped me to see the problem.

Audio Unit and Writing to file

I'm creating real-time audio sequencer app on OS X.
Real-time synth part is implemented by using AURenderCallback.
Now I'm making function to write rendered result to Wave File (44100Hz 16bit Stereo).
Format for render-callback function is 44100Hz 32bit float Stereo interleaved.
I'm using ExtAudioFileWrite to write to file.
But ExtAudioFileWrite function returns error code 1768846202;
I searched 1768846202 but I couldn't get information.
Would you give me some hints?
Thank you.
Here is code.
outFileFormat.mSampleRate = 44100;
outFileFormat.mFormatID = kAudioFormatLinearPCM;
outFileFormat.mFormatFlags =
kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
outFileFormat.mBitsPerChannel = 16;
outFileFormat.mChannelsPerFrame = 2;
outFileFormat.mFramesPerPacket = 1;
outFileFormat.mBytesPerFrame =
outFileFormat.mBitsPerChannel / 8 * outFileFormat.mChannelsPerFrame;
outFileFormat.mBytesPerPacket =
outFileFormat.mBytesPerFrame * outFileFormat.mFramesPerPacket;
AudioBufferList *ioList;
ioList = (AudioBufferList*)calloc(1, sizeof(AudioBufferList)
+ 2 * sizeof(AudioBuffer));
ioList->mNumberBuffers = 2;
ioList->mBuffers[0].mNumberChannels = 1;
ioList->mBuffers[0].mDataByteSize = allocByteSize / 2;
ioList->mBuffers[0].mData = ioDataL;
ioList->mBuffers[1].mNumberChannels = 1;
ioList->mBuffers[1].mDataByteSize = allocByteSize / 2;
ioList->mBuffers[1].mData = ioDataR;
...
while (1) {
//Fill buffer by using render callback func.
RenderCallback(self, nil, nil, 0, frames, ioList);
//i want to create one sec file.
if (renderedFrames >= 44100) break;
err = ExtAudioFileWrite(outAudioFileRef, frames , ioList);
if (err != noErr){
NSLog(#"ERROR AT WRITING TO FILE");
goto errorExit;
}
}
Some of the error codes are actually four character strings. The Core Audio book provides a nice function to handle errors.
static void CheckError(OSStatus error, const char *operation)
{
if (error == noErr) return;
char str[20];
// see if it appears to be a 4-char-code
*(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error);
if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
str[0] = str[5] = '\'';
str[6] = '\0';
} else
// no, format it as an integer
sprintf(str, "%d", (int)error);
fprintf(stderr, "Error: %s (%s)\n", operation, str);
exit(1);
}
Use it like this:
CheckError(ExtAudioFileSetProperty(outputFile,
kExtAudioFileProperty_CodecManufacturer,
sizeof(codec),
&codec), "Setting codec.");
Before you can do any sort of debugging, you probably need to figure out what that error message actually means. Have you tried passing that status code to GetMacOSStatusErrorString() or GetMacOSStatusCommentString()? They aren't documented so well, but they are declared in CoreServices/CarbonCore/Debugging.h.

Resources