PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Direct3D] Probleme beim Zurücklesen von 2D-Texturen


Nasenbaer
2010-04-22, 20:32:33
Ich versuche mich gerade an Compute Shadern allerdings habe ich schon beim Zurücklesen von Texturen Probleme (das Auslesen im Shader und manipulieren der Texturen klappt ohne Probleme).
Das Problem ist, dass ich über den Pointer p (siehe 2. Code-Fragment) immer nur die erste Zeile der Textur auslesen kann.

Hier mal mein Code mit dem ich die Textur erstellt habe:

D3D11_TEXTURE2D_DESC cstestTexDesc;
cstestTexDesc.Width = 2;
cstestTexDesc.Height = 2;
cstestTexDesc.MipLevels = 1;
cstestTexDesc.ArraySize = 1;
cstestTexDesc.Format = DXGI_FORMAT_R32_FLOAT;
cstestTexDesc.SampleDesc.Count = 1;
cstestTexDesc.SampleDesc.Quality = 0;
cstestTexDesc.Usage = D3D11_USAGE_DEFAULT;
cstestTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
cstestTexDesc.CPUAccessFlags = 0;
cstestTexDesc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA cstestSubData;
cstestSubData.pSysMem = &(rwdata[0]); // vector<float> rwdata;
cstestSubData.SysMemPitch = sizeof(float) * 2; // size of one row
pd3dDevice->CreateTexture2D( &cstestTexDesc, &cstestSubData, &_cstestTexture );

Und so versuche ich diese wieder auszulesen
(Den Code zum Auslesen habe ich aus dem DX-SDK Beispiel BasicCompute11 und habe ihn gepasst um ne Texture2D statt nen Buffer auszulesen):

ID3D11Texture2D* resultTex = NULL;
D3D11_TEXTURE2D_DESC resultDesc;
ZeroMemory( &resultDesc, sizeof(resultDesc) );
_cstestTexture->GetDesc( &resultDesc );
resultDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
resultDesc.Usage = D3D11_USAGE_STAGING;
resultDesc.BindFlags = 0;
resultDesc.MiscFlags = 0;
pd3dDevice->CreateTexture2D(&resultDesc, NULL, &resultTex);

d3dContext->CopyResource( resultTex , _cstestTexture );
D3D11_MAPPED_SUBRESOURCE csResultMappedResource;
float *p;
d3dContext->Map( resultTex, 0, D3D11_MAP_READ, 0, &csResultMappedResource );

p = (float *)csResultMappedResource.pData;

Wenn ich die Textur als eine einzelne Zeile erstelle klappt alles aber das ist ja nicht Sinn der Sache. Ich vermute, dass das Problem im zweiten Teil des Codes liegt, da ich ihn aus dem SDK-Beispiel habe und dort ein einfacher Buffer verwendet wurde.

Demirug
2010-04-22, 20:47:00
Bei Direct3D müssen die einzelnen Zeilen nicht zwingend direkt hintereinander im Speicher liegen. Am Performancegründen kann am Ende ein Padding sein. Deswegen gibt es das RowPitch Element in der Struktur. Es sagt dir wie viele Bytes eine Zeile im Speicher belegt. Mit diesem Wert kann man den Offset für jeden Pixel berechnen.

Nasenbaer
2010-04-22, 21:06:32
Ah danke das war genau die Info, die mir fehlte. :)

Für alle, die ähnliche Probleme haben - so habe ichs fix gelöst:

d3dContext->CopyResource( resultTex, _cstestTexture );
D3D11_MAPPED_SUBRESOURCE csResultMappedResource;
char *rowStartPointer;
float *perRowPointer;
d3dContext->Map( resultTex, 0, D3D11_MAP_READ, 0, &csResultMappedResource );

rowStartPointer = (char*)csResultMappedResource.pData;

float result[4];
for (int y=0; y < 2; ++y)
{
perRowPointer = (float*)rowStartPointer;
for (int x=0; x < 2; ++x)
{
result[y*2+x] = *perRowPointer;
++perRowPointer;
}
rowStartPointer += csResultMappedResource.RowPitch;
}


Ne Hilfsfunktion (in DXUT oder D3DX oder so), die einem die Daten schön in nem 2D-Array zurückliefert gibts nicht zufällig?

Demirug
2010-04-22, 21:15:12
Ne Hilfsfunktion (in DXUT oder D3DX oder so), die einem die Daten schön in nem 2D-Array zurückliefert gibts nicht zufällig?

Nein. Zurücklesen gehört ja zu den eher wenig genutzten Funktionen.

Nasenbaer
2010-04-22, 21:20:45
Nein. Zurücklesen gehört ja zu den eher wenig genutzten Funktionen.
Mit ComputeShadern dann ja bald nicht mehr denke ich. Man findet leider aber kaum Code-Beispiele zu diesem Teil - wie man sie anlegt usw. dagegen genug.

Gast
2010-04-23, 00:32:02
Ich will jetzt keine Diskussion damit lostreten, aber falls du noch in der "Erforschungsphase" bist (dein Problem liest sich für mich so) wäre es einen Versuch wert sich CUDA für diese Dinge anzuschauen. Dafür gibts nämlich so praktische Helferlein wie die CUDA Templates klick (http://cudatemplates.sourceforge.net/doc/html/), die einem all diese Dinge ungemein erleichtern. Richtig angewandt brauchst du dich dann um genau solche Dinge wie Pitch berücksichtigen usw. nicht mehr kümmern :)

Falls CUDA für dich (aus welchen Gründen auch immer) keine Option ist vergiss meinen Post einfach wieder.

Nasenbaer
2010-04-23, 09:15:20
Ich will jetzt keine Diskussion damit lostreten, aber falls du noch in der "Erforschungsphase" bist (dein Problem liest sich für mich so) wäre es einen Versuch wert sich CUDA für diese Dinge anzuschauen. Dafür gibts nämlich so praktische Helferlein wie die CUDA Templates klick (http://cudatemplates.sourceforge.net/doc/html/), die einem all diese Dinge ungemein erleichtern. Richtig angewandt brauchst du dich dann um genau solche Dinge wie Pitch berücksichtigen usw. nicht mehr kümmern :)

Falls CUDA für dich (aus welchen Gründen auch immer) keine Option ist vergiss meinen Post einfach wieder.
Jup ist aus mehreren Gründen keine Option - die wichtigste ist wahrscheinlich meine ATI-Graka. :D