Rendering NV12/YUV image in DirectX 12 - yuv

Having a bit of trouble mapping the texture data correctly in order to read Chrominance and Luminance in the shader. The Luminance is rendering fine, but the Chrominance is all zeros... I know I need to create two SRVs and map the Y to 1 channel, UV to 2. I'm assuming there's something really obvious I'm missing but the docs on the Microsoft website are very unhelpful.
Data is 1920 * 1080, meaning the size per frame is 1920 * 1080 * 1.5. I know I should get 3 bytes per pixel, giving me a larger pitch, but when I add this to the code I get an illegal write exception.
The code is otherwise working, just my inability to map the texture properly. I'd really appreciate any help.
Code below:
Creating my PSO:
CD3DX12_DESCRIPTOR_RANGE descRanges[2];
descRanges[(uint32_t)DescriptorTableIndex::Texture].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0, 0); // t0, t1
descRanges[(uint32_t)DescriptorTableIndex::Sampler].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); // s0
CD3DX12_ROOT_PARAMETER rootParams[2];
rootParams[(uint32_t)DescriptorTableIndex::Texture].InitAsDescriptorTable(1, &descRanges[(uint32_t)DescriptorTableIndex::Texture], D3D12_SHADER_VISIBILITY_PIXEL);
rootParams[(uint32_t)DescriptorTableIndex::Sampler].InitAsDescriptorTable(1, &descRanges[(uint32_t)DescriptorTableIndex::Sampler], D3D12_SHADER_VISIBILITY_PIXEL);
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureLayout(ARRAYSIZE(rootParams), rootParams, 0, 0,
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS);
ComPtr<ID3DBlob> serializedRootSignature;
DxUtil::ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureLayout, D3D_ROOT_SIGNATURE_VERSION_1, &serializedRootSignature, nullptr));
ComPtr<ID3D12RootSignature> pNv12RootSignature = nullptr;
DxUtil::ThrowIfFailed(mDevice->CreateRootSignature(
1,
serializedRootSignature->GetBufferPointer(),
serializedRootSignature->GetBufferSize(),
IID_PPV_ARGS(&pNv12RootSignature)));
ComPtr<ID3DBlob> serializedRootSignature;
DxUtil::ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureLayout, D3D_ROOT_SIGNATURE_VERSION_1, &serializedRootSignature, nullptr));
ComPtr<ID3D12RootSignature> pNv12RootSignature = nullptr;
DxUtil::ThrowIfFailed(mDevice->CreateRootSignature(
1,
serializedRootSignature->GetBufferPointer(),
serializedRootSignature->GetBufferSize(),
IID_PPV_ARGS(&pNv12RootSignature)));
// Define the vertex input layout.
D3D12_INPUT_ELEMENT_DESC inputElementDescription[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
// Instance data
{ "ID", 0, DXGI_FORMAT_R32_UINT, 1, 0, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
{ "MATRIX", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
{ "MATRIX", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
{ "MATRIX", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
{ "MATRIX", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}
};
// Describe and create the graphics pipeline state object (PSO).
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.InputLayout = { inputElementDescription, _countof(inputElementDescription) };
psoDesc.pRootSignature = pNv12RootSignature.Get();
psoDesc.VS = CD3DX12_SHADER_BYTECODE(g_nv12Vs, sizeof(g_nv12Vs));
psoDesc.PS = CD3DX12_SHADER_BYTECODE(g_nv12Ps, sizeof(g_nv12Ps));
psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
psoDesc.BlendState = blendDesc;
psoDesc.DepthStencilState.DepthEnable = FALSE;
psoDesc.DepthStencilState.StencilEnable = FALSE;
psoDesc.SampleMask = UINT_MAX;
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
psoDesc.NumRenderTargets = 1;
psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
psoDesc.SampleDesc.Count = 2;
DxUtil::ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pPipelineState)));
StateSignaturePair stateSignaturePair(pPipelineState, pNv12RootSignature);
mPipelineStateObjects.insert(std::pair<PipelineState, StateSignaturePair>(PipelineState::NV12, stateSignaturePair));
Create my SRVs:
D3D12_SHADER_RESOURCE_VIEW_DESC luminanceDesc = {};
luminanceDesc.Format = DXGI_FORMAT_R8_UNORM;
luminanceDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
luminanceDesc.Texture2D.MipLevels = 1;
luminanceDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
mDevice->CreateShaderResourceView(layerCache->mTexture->getTexture(), &luminanceDesc, layerCache->mSrvHeap->GetCpuHandle(NV12SrvIndex::Y));
D3D12_SHADER_RESOURCE_VIEW_DESC chrominaceDesc = {};
chrominaceDesc.Format = DXGI_FORMAT_R8G8_UNORM;
chrominaceDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
chrominaceDesc.Texture2D.MipLevels = 1;
chrominaceDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
chrominaceDesc.Texture2D.PlaneSlice = 1;
mDevice->CreateShaderResourceView(layerCache->mTexture->getTexture(), &chrominaceDesc, layerCache->mSrvHeap->GetCpuHandle(NV12SrvIndex::UV));
Texture:
mTextureDescription.Width = 1920;
mTextureDescription.Height = 1080;
mTextureDescription.Format = DXGI_FORMAT_NV12;
mTextureDescription.Flags = D3D12_RESOURCE_FLAG_NONE;
mTextureDescription.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
mTextureDescription.MipLevels = 1;
mTextureDescription.DepthOrArraySize = 1;
mTextureDescription.SampleDesc.Count = 1;
mTextureDescription.SampleDesc.Quality = 0;
mTextureData.pData = pData;
// Row pitch is how wide our line is in bytes.
mTextureData.RowPitch = mTextureDescription.Width; // I'm pretty sure this isn't right...
mTextureData.SlicePitch = mTextureData.RowPitch * mTextureDescription.Height;

Related

How to set agents location using for loop in Java

I am using this code for assigning dfferent node to different agents
int[] node = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i = 0; i < node.length; i++) {
if(agent.participant == i + 1){
agent.setLocation(node[i]);
}
}
The only problem is setLocation() function only accept point arguments not integer.
I also try to make the list of points but it does not work. Let me know how to solve this issue.
As per Emile:
Node[] nodes = {node0, node1, ...};
int counter=0;
for (Node currNode : nodes) {
if(agent.participant == counter + 1){
agent.setLocation(nodes [i]);
counter++;
}
}
You need to understand function arguments. setLocation(...) cannot work with an int, it needs something that is an actual location. Check the API, code-complete help, etc

GraphicsBuffer's GetData always returning 0s

I'm trying to clone a mesh using GraphicsBuffer because its read/write option is false, and I can't change that. This is my current code:
public static bool Run(Mesh sourceMesh, out Mesh generatedMesh)
{
GraphicsBuffer sourceDataBuffer = sourceMesh.GetVertexBuffer(0);
GraphicsBuffer sourceIndexBuffer = sourceMesh.GetIndexBuffer();
var vertexCount = sourceDataBuffer.count;
var indexCount = sourceIndexBuffer.count;
byte[] sourceData = new byte[vertexCount * (sourceDataBuffer.stride / sizeof(byte))];
byte[] sourceIndex = new byte[(int)(indexCount * ((float)sourceIndexBuffer.stride / sizeof(byte)))];
sourceDataBuffer.GetData(sourceData);
sourceIndexBuffer.GetData(sourceIndex);
var attributes = sourceMesh.GetVertexAttributes();
generatedMesh = new Mesh();
generatedMesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
generatedMesh.SetVertexBufferParams(vertexCount, attributes);
generatedMesh.SetVertexBufferData(sourceData, 0, 0, sourceData.Length);
generatedMesh.SetIndexBufferParams(indexCount, sourceMesh.indexFormat);
generatedMesh.SetIndexBufferData(sourceIndex, 0, 0, sourceIndex.Length);
generatedMesh.subMeshCount = sourceMesh.subMeshCount;
for (int i = 0; i < sourceMesh.subMeshCount; i++)
{
var subMeshDescriptor = sourceMesh.GetSubMesh(i);
generatedMesh.SetSubMesh(i, subMeshDescriptor);
}
sourceDataBuffer.Release();
sourceIndexBuffer.Release();
generatedMesh.RecalculateBounds();
return true; // No error
}
It works like a charm in my test project. But when I try to clone things in my main project, GetData(sourceData) and GetData(sourceIndex) both return arrays of 0s. What could be causing that? Could it be because of the read/write being disabled?
Edit: The problem only happens in bundles with non-readable meshes. I thought GraphicsBuffer should work with them, but it doesn't.

Java 3 Hashing Programme

The directions in this section of code are giving me trouble and I don't know how to follow through with them properly. (We have to write code where there are dollar signs.)
Instructions: write a code that repetitively invokes the HashPerformanceClass mainDriver. Then the repetitive code starts the number of insertions at statrInsertions, increase the insert count by the deltaInsertions until end insertions value.
Problem
I am having trouble repetitively invoking the HashPerformanceClass mainDriver, and I don't know what to do. If anyone has any advise I would be grateful.
public class MainClass {
static int displayResultsNo = 0;
void displayHashResults() {
displayResultsNo++;
System.out.println("\nDisplay No. - "+displayResultsNo);
System.out.println("\n\nHash Instrumented Performance:\n-----------------------------");
System.out.println("Trials: " + HashPerformanceClass.trials + ", " +
"Insert Count: " + HashPerformanceClass.insertCount + ", " +
"Load: " + HashPerformanceClass.payload + ", " +
"Table Start Size: " + HashPerformanceClass.startingSize);
System.out.println("\nLinear Hashing:");
System.out.println("Insertion Total Probes: " + HashPerformanceClass.insertionLinearProbes) ;
System.out.println("Insertion Average Probes: " + HashPerformanceClass.insertionLinearProbesAvg);
System.out.println("\nDouble Hashing:");
System.out.println("Insertion Total Probes: " + HashPerformanceClass.insertionDoubleProbes) ;
System.out.println("Insertion Average Probes: " + HashPerformanceClass.insertionDoubleProbesAvg);
System.out.println("\nPerfect Hashing:");
System.out.println("Insertion Total Probes: " + HashPerformanceClass.insertionPerfectProbes) ;
System.out.println("Insertion Average Probes: " + HashPerformanceClass.insertionPerfectProbesAvg);
}//displayHashResults()
static int displayNo = 0;
void displayHashAvgProbesTable(int trials, int startInsertions, int endInsertions, int deltaInsertions, double load, int startSize) {
displayNo++;
System.out.println("\n\nDisplay No. - "+displayNo);
System.out.println("\nAverage Number of Probes Table \n------------------------------\ntrials: "+trials+" Load: "+load+" Start Size: "+startSize+"\n");
System.out.println(String.format("%-15s %-15s %-15s %-15s", "No Of Items","Linear Hash" ,"Double Hash" ,"Perfect Hash ") );
System.out.println(String.format("%-15s %-15s %-15s %-15s", "Inserted" ,"Probe Average","Probe Average","Probe Average") );
System.out.println(String.format("%-15s %-15s %-15s %-15s", "-----------","-------------","-------------","-------------") );
//$ write a code that repetitively invokes the HashPerformanceClass mainDriver
// The the repetitive code starts the number of insertions at startInsertions, increases the insert count by the deltaInsertions
//until end insertions value
}//displayHashAvgProbesTable()
MainClass () {
//$Invoke HashPerformanceClass mainDriver using arguments of insertCount=1, trials =10, payLoad=100%, Starting Size =7, display results
HashPerformanceClass.mainDriver( 1, 1, 1.0, 7); displayHashResults();
HashPerformanceClass.mainDriver(100, 80, 0.5, 101); displayHashResults(); //third column 1.0 = 100%
HashPerformanceClass.mainDriver(100, 80, 0.9, 101); displayHashResults();
HashPerformanceClass.mainDriver( 20, 1000, 0.5, 503); displayHashResults();
HashPerformanceClass.mainDriver( 20, 1000, 1.0, 1009); displayHashResults();
HashPerformanceClass.mainDriver( 20, 1000, 1.0, 4999); displayHashResults();
HashPerformanceClass.mainDriver(100, 2400, 0.5, 4999); displayHashResults();
displayHashAvgProbesTable ( 10, 100, 2000, 100, 0.5, 1009);
displayHashAvgProbesTable ( 10, 100, 2500, 1000, 0.5, 4999);
displayHashAvgProbesTable ( 10, 100, 2500, 1000, 0.5, 4999);
}//MainClass
public static void main(String[] args) {
new MainClass();
}//main()
}//MainClass
___________________________________________________________
import java.util.*;
/**
* A class for generating statistical information hash table insertion.
*/
public class HashPerformanceClass {
static int insertionLinearProbes = 0, insertionDoubleProbes = 0, insertionPerfectProbes = 0;
static float insertionLinearProbesAvg = 0, insertionDoubleProbesAvg = 0, insertionPerfectProbesAvg = 0;
static int trials;
static int insertCount;
static double payload;
static int startingSize;
public static void mainDriver(int trials, int insertCount, double payLoad, int startingSize) {
HashPerformanceClass.trials = trials;
HashPerformanceClass.insertCount = insertCount;
HashPerformanceClass.payload = payLoad;
HashPerformanceClass.startingSize= startingSize;
insertionLinearProbes = insertionDoubleProbes = insertionPerfectProbes = 0;
insertionLinearProbesAvg = insertionDoubleProbesAvg = insertionPerfectProbesAvg = 0;
//$ Declare all 3 hash table objects (linear, double, perfect) using the generic parameterized types as String and setting Starting Size from the mainDriver input parameter
DictionaryInstrumentedLinearImplementation <String, String> linearHashTableObj;
DictionaryInstrumentedDoubleImplementation <String, String> doubleHashTableObj;
DictionaryInstrumentedPerfectImplementation<String, String> perfectHashTableObj;
//Array used to hold random data inserted
String dataArray[];
//$
//For each trial set the inputs for the hash table Implementation
// Generate the Random Data array using insert count, do only once for each trial so that all hash table types have same source data set
// For all 3 hash table types
// Instantiate new hash table object
// Set the pay load factor hashtableobject.set payload
// Insert all the data from the array into the table insertalldata( , );
// Reset the probe counters for the hash table insertionlinear probes +=
// Sum up the probe statistics
//do this for all insertionlinearprobes double and perfect . . .
//$ Calculate all the insertion probes averages into the class variables for each hash type
}//mainDriver()
/* Generate an array of random of pseudo words. Each word will be composed of three randomly chosen syllables.
* #param arraySize The number of strings to generate.
* #return The array of strings.
*/
private static String[] generateRandomData(int arraySize) {
String uniqueWordStringArray[] = new String[arraySize];
DictionaryInstrumentedLinearImplementation<String,String> checkTable = new DictionaryInstrumentedLinearImplementation<String,String>();
String firstSylStringArray [] = {"ther", "fal", "sol", "cal", "com", "don", "gan", "tel", "fren", "ras", "tar", "men", "tri", "cap", "har"};
String secondSylStringArray[] = {"mo", "ta", "ra", "te", "bo", "bi", "du", "ca", "dan", "sen", "di", "no", "fe", "mi", "so" };
String thirdSylStringArray [] = {"tion", "ral", "tal", "ly", "nance", "tor", "ing", "ger", "ten", "ful", "son", "dar", "der", "den", "ton"};
Random generator = new Random();
int i=0;
while (i < arraySize) {
String valueString;
valueString = firstSylStringArray [generator.nextInt( firstSylStringArray.length) ];
valueString += secondSylStringArray[generator.nextInt(secondSylStringArray.length) ];
valueString += thirdSylStringArray [generator.nextInt( thirdSylStringArray.length) ];
if (!checkTable.contains(valueString)) {
// Have not seen pseudo word string before, so add it to the list array list
uniqueWordStringArray[i] = valueString;
checkTable.add(valueString,valueString);
i++;
}//end if
}//while
return uniqueWordStringArray;
}
/* Insert all of the values in the array into the hash table.
* #param dict The dictionary to insert all the words into.
*/
private static void insertAllData(DictionaryInterface<String,String> dict, String[] dataArray) {
for (String wordString : dataArray) {
dict.add(wordString, wordString);
}
}//insertAllData()
}//HashPerformanceClass

attempt to index global 'physics' (a nil value)

I'm new with corona/lua and i'm i can't find a solution to this thing. I'm trying to spawn a object that fall from top to down and should stop at the bottom of the screen. Then i'll create the touch event etc etc..
but for now the problem is that i recieve this error:
attempt to index global 'physics' (a nil value)
and objects ofc doesn't fall down.
here is my code:
-----------------------------------------------------------------------------------------
--
-- main.lua
--
-----------------------------------------------------------------------------------------
local buttonY = display.contentWidth * 0.02
local buttonWidth = display.contentWidth * 0.1
local buttonHeight = display.contentWidth * 0.1
background = display.newImage("graphics/background.jpg")
local localGroup = display.newGroup()
local spawnTable = {}
function spawnLattina(params)
local object = display.newImage(params.image, params.buttonX,50);
object.objTable = params.objTable;
object.index = #object.objTable+1;
object.name = "object:".. object.index;
--fisica
if params.hasBody then
object.density = params.density or 0;
object.friction = params.friction or 0;
object.bounce = params.bounce or 0;
object.isSensor = params.isSensor or false;
object.bodyType = params.bodyType or "dynamic";
print(object.density .. " Friction: ".. object.friction .."bodyType: "..object.bodyType)
physics.addBody(object, object.bodyType,
{density = object.density,
friction = object.friction,
bounce = object.bounce}
)
end
object.group = params.group or nil
object.group:insert(object)
object.objTable[object.index] = object
return object
end
for i = 1, 2 do
local spawns = spawnLattina(
{
image = "graphics/lattina.png",
objTable = spawnTable,
buttonX = math.random(50,480),
hasBody = true,
density = 0,
friction = 12,
bodyType = "static",
group = localGroup,
}
)
end
You haven't started the physics engine. Write the following lines on the top of your class:
local physics = require "physics"
physics.start()
Keep Coding.................. :)

Set Time Range of a Zend Dojo TextTimeBox

Hi is it possible to set the time range of a Dojo textTimeBox to 09:00 - 18:30.
I can't find anything in either the Zend or Dojo documentation that show how this can be done or if it can be done.
Many thanks in advance.
You can set max and min constraints for widget:
new dijit.form.TimeTextBox({
name: "prog_val",
value: new Date(),
constraints: {
timePattern: 'HH:mm:ss',
clickableIncrement: 'T00:15:00',
visibleIncrement: 'T00:15:00',
visibleRange: 'T01:00:00',
min:'T09:00:00',
max:'T18:30:00'
}
},
"prog_val");
It does not allow the user to enter data beyond the allowed values.
However this still allows user to scroll to the disabled times, user just cannot select them.
For hiding disabled times you should do some hack :)
You should override _getFilteredNodes method of dijit._TimePicker. For example :
dojo.declare("my._TimePicker", dijit._TimePicker, {
// extend the default show() method
_getFilteredNodes: function (/*number*/start, /*number*/maxNum, /*Boolean*/before) {
// summary:
// Returns an array of nodes with the filter applied. At most maxNum nodes
// will be returned - but fewer may be returned as well. If the
// before parameter is set to true, then it will return the elements
// before the given index
// tags:
// private
var nodes = [], n, i = start, max = this._maxIncrement + Math.abs(i),
chk = before ? -1 : 1, dec = before ? 1 : 0, inc = before ? 0 : 1;
do {
i = i - dec;
var date = new Date(this._refDate);
var incrementDate = this._clickableIncrementDate;
date.setHours(date.getHours() + incrementDate.getHours() * i,
date.getMinutes() + incrementDate.getMinutes() * i,
date.getSeconds() + incrementDate.getSeconds() * i);
if (!this.isDisabledDate(date)) {
n = this._createOption(i);
if (n) { nodes.push(n); }
}
i = i + inc;
} while (nodes.length < maxNum && (i * chk) < max);
if (before) { nodes.reverse(); }
return nodes;
}
});
And you need to set this new class ('my._TimePicker') as a popupClass property of your text time box:
dojo.addOnLoad(function () {
dijit.byId("prog_val").popupClass = "my._TimePicker";
});
And you can see : it works!