Conversation
ScratchImage is very convenient as it automatically compute the
number of images, pitches etc. On the other hand, when the user
has an already loaded texture, it still always allocate own buffer
and perform copying, which might be suboptimal, especially with
large textures.
Extend ScratchImage::Initialize() with an additional argument (with
the default value that behaves the same way as before) to allow it
to be non-owning. This means that it still computes the number of
images, pitches etc., but doesn't allocate the actual buffer. Then,
the user can update individual images using
ScratchImage::SetNonOwningImagePixels().
The actual ScratchImage doesn't own this memory, doesn't have own
buffer and doesn't perform any deallocation on destruction. Memory
management and lifetimes are fully on the user's side.
A non-owning ScratchImage differs from owning by having a non-zero
m_size and m_memory == nullptr.
An example of usage:
// create ScratchImage using Initialize(meta, cp_flags, false)
// set pixels pointer for each image using
auto& image = *scratch.SetNonOwningImagePixels(mip, face, depth, ptr);
The return value is optional and is the same as
ScratchImage.GetImage(mip, face, depth), only to avoid 2 external
calls per subimage when needed. For example, if the user has a
contiguous buffer with a mipmapped 2D image:
for (size_t i{0}, off{0}; i < scratch.GetMetadata().mipLevels; ++i)
off += scratch.SetNonOwningImagePixels(i, 0, 0, ptr + off)->slicePitch;
A non-owning ScratchImage can currently be initialized only using
Initialize() for simplicity and to indicate that the option is for
advanced users only. Other Initialize*() methods can be expanded
later if needed.
Signed-off-by: Alexander Lobakin <alobakin@mailbox.org>
|
@microsoft-github-policy-service agree |
|
The general model is for memory owned by the app, the The output, however, is currently always returned as a ScratchImage which is a container for the memory which generates Image structs. IOW, the whole point of ScratchImage is to be 'owning'. I could have function overloads that output to an What functions in particular are you wanting to use 'in-place' for output? |
|
Well, I'd be glad to see some sort of function which does everything that For example, I added KTX support to my engine recently and the image layout in KTX is different there, but using a Dunno, maybe a version of |
|
ScratchImage is designed to ensure the memory is laid out exactly the way a DDS file is written to disk which for the most part is how Direct3D expects 'row-linear' content to be provided as well as guarantee the memory is 16-byte aligned since DirectXTex uses SSE/SSE2 via DirectXMath. The problem is that the metadata for the target is NOT known prior to calling the loading function or other operation. The application would have to have a way to query the metadata, then do the allocation, then call the function again to complete it. Can you please confirm that this is limited to DDS loading, or is there some other DirectXTex functionality you are trying to use 'non-owning'? |
|
It's limited to loading, but to loading of non-DDS texture formats using other libraries. They might have a different layout etc, but I mean, I know DxTex is primarily for DDS, but OTOH it also has support for other formats and the corresponding functions also produce |
ScratchImageis very convenient as it automatically compute the number of images, pitches etc. On the other hand, when the user has an already loaded texture, it still always allocate own buffer and perform copying, which might be suboptimal, especially with large textures.Extend
ScratchImage::Initialize()with an additional argument (with the default value that behaves the same way as before) to allow it to be non-owning. This means that it still computes the number of images, pitches etc., but doesn't allocate the actual buffer. Then, the user can update individual images usingScratchImage::SetNonOwningImagePixels().The actual
ScratchImagedoesn't own this memory, doesn't have own buffer and doesn't perform any deallocation on destruction. Memory management and lifetimes are fully on the user's side.A non-owning
ScratchImagediffers from owning by having a non-zerom_sizeandm_memory == nullptr.An example of usage:
The return value is optional and is the same as
ScratchImage.GetImage(mip, face, depth), only to avoid 2 external calls per subimage when needed. For example, if the user has a contiguous buffer with a mipmapped 2D image:A non-owning
ScratchImagecan currently be initialized only usingInitialize()for simplicity and to indicate that the option is for advanced users only. OtherInitialize*()methods can be expanded later if needed.