상훈 김
asked on
rgb32 data resource mapping. using directx memcpy
I have been trying to solve the problem for a month with googling. But Now I have to ask for help here.
I want to render using ffmpeg decoded frame. and using frame, I try to render frame with DX2D texture.
Question 1 : It has any problem creating 2D texture for mapping?
Question 2 : What size of the memcpy parameters should I enter (related to formatting)?
I based on the link below.
https://www.gamedev.net/forums/topic/667097-copy-2d-array-into-texture2d/
https://www.gamedev.net/forums/topic/645514-directx-11-maping-id3d11texture2d/
https://www.gamedev.net/forums/topic/606100-solved-dx11-updating-texture-data/
Thank U for watching, Please reply.
I want to render using ffmpeg decoded frame. and using frame, I try to render frame with DX2D texture.
ZeroMemory(&TextureDesc, sizeof(TextureDesc));
TextureDesc.Height = pFrame->height;
TextureDesc.Width = pFrame->width;
TextureDesc.MipLevels = 1;
TextureDesc.ArraySize = 1;
TextureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; //size 16
TextureDesc.SampleDesc.Count = 1;
TextureDesc.SampleDesc.Quality = 0;
TextureDesc.Usage = D3D11_USAGE_DYNAMIC;
TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
TextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
TextureDesc.MiscFlags = 0;
result = m_device->CreateTexture2D(&TextureDesc, NULL, &m_2DTex);
if (FAILED(result)) return false;
ShaderResourceViewDesc.Format = TextureDesc.Format;
ShaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
ShaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
ShaderResourceViewDesc.Texture2D.MipLevels = 1;
D3D11_MAPPED_SUBRESOURCE S_mappedResource_tt = { 0, };
ZeroMemory(&S_mappedResource_tt, sizeof(D3D11_MAPPED_SUBRESOURCE));
result = m_deviceContext->Map(m_2DTex, 0, D3D11_MAP_WRITE_DISCARD, 0, &S_mappedResource_tt);
if (FAILED(result)) return false;
BYTE* mappedData = reinterpret_cast<BYTE *>(S_mappedResource_tt.pData);
for (auto i = 0; i < pFrame->height; ++i) {
memcpy(mappedData, pFrame->data, pFrame->linesize[0]);
mappedData += S_mappedResource_tt.RowPitch;
pFrame->data[0] += pFrame->linesize[0];
}
m_deviceContext->Unmap(m_2DTex, 0);
result = m_device->CreateShaderResourceView(m_2DTex, &ShaderResourceViewDesc, &m_ShaderResourceView);
if (FAILED(result)) return false;
m_deviceContext->PSSetShaderResources(0, 1, &m_ShaderResourceView);
but it shows me just black screen(nothing render). I guess it's wrong memcpy size. The biggest problem is that I don't know what is the problem.Question 1 : It has any problem creating 2D texture for mapping?
Question 2 : What size of the memcpy parameters should I enter (related to formatting)?
I based on the link below.
https://www.gamedev.net/forums/topic/667097-copy-2d-array-into-texture2d/
https://www.gamedev.net/forums/topic/645514-directx-11-maping-id3d11texture2d/
https://www.gamedev.net/forums/topic/606100-solved-dx11-updating-texture-data/
Thank U for watching, Please reply.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIALMembers can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
(A)
Open in new window
the D3D11_MAPPED_SUBRESOURCE is a structure of size 'sizeof(D3D11_MAPPED_SUBRE
(B)
Open in new window
because of (A) already sets all zero, the statement (B) doesn't change anything and should be removed. it would be different if the structure variable would be used in a for loop or while loop what is not the case in your code.
(C)
Open in new window
this statement should get the resource (image) from a map shich is a member of your current device context. if should return a failed result if the 'm_2DTex' key wasn't found in the map. the 'D3D11_MAP_WRITE_DISCARD' has the following meaning:
anyway, if it returned without failed return code, the structure S_mappedResource_tt passed by pointer should be properly filled.
(D)
Open in new window
this cast would define a pointer to the structure such that it could be used as a byte array (buffer). the pointer now can be incremented by byte counts. so if you do 'mappedData += 5' the pointer would point to the sixth byte within the buffer if it has pointed to the begin before.(E)
Open in new window
the i counter would count the rows of the texture.
note, pFrame was not defined in your snippet, but as you defined texture width and texture height from pFrame->width and pFrame-height, things looked ok.
(F)
Open in new window
what is pFrame->linesize[0]? it was not used to create the texture. instead pFrame->width was used. as pFrame->linesize[0] is the row size in bytes, you may check if pFrame->linesize[0] is calculated by pFrame->width times 'cellsize' where 'cellsize' is the size of the unit in bytes counted by pFrame->width.
the memcpy copies bytes from right buffer to left buffer. in your case it copies from frame to resource what seems to me is the wrong direction. if you want the pFrame to be filled with data from the map, you have to use
Open in new window
and it is clear that the pFrame can't be rendered if you wanted to do that because it was not filled with any data.
(G)
Open in new window
now you were using a member of the resource structure what is explained as 'row pitch' or 'width' of the 'data' in bytes.
the statement looks fine as it was explained in the docs by
(I)
Open in new window
this is a bad mistake again. you are incrementing the value of pFrame->data[0] what is the first byte of pFrameData. because of that only the first row of pFrame would get data (if the memcpy would have ben correct).
to make it right, you need an extra pointer which initially points to pFrame->data. then this pointer must be incremented by linesize[0] (or linesize[ i ], if the array is well set. you may use linesize[0] if all lines have same size).
Open in new window
Sara